File indexing completed on 2021-02-14 13:15:06
0001 #include "EventFilter/HcalRawToDigi/interface/HcalUnpacker.h"
0002 #include "EventFilter/HcalRawToDigi/interface/HcalDCCHeader.h"
0003 #include "EventFilter/HcalRawToDigi/interface/HcalDTCHeader.h"
0004 #include "EventFilter/HcalRawToDigi/interface/AMC13Header.h"
0005 #include "EventFilter/HcalRawToDigi/interface/HcalHTRData.h"
0006 #include "EventFilter/HcalRawToDigi/interface/HcalUHTRData.h"
0007 #include "DataFormats/HcalDetId/interface/HcalOtherDetId.h"
0008 #include "DataFormats/HcalDigi/interface/HcalQIESample.h"
0009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0010 #include "EventFilter/HcalRawToDigi/interface/HcalTTPUnpacker.h"
0011
0012
0013
0014 namespace HcalUnpacker_impl {
0015 template <class DigiClass>
0016 const HcalQIESample* unpack(const HcalQIESample* startPoint,
0017 const HcalQIESample* limit,
0018 DigiClass& digi,
0019 int presamples,
0020 const HcalElectronicsId& eid,
0021 int startSample,
0022 int endSample,
0023 int expectedTime,
0024 const HcalHTRData& hhd) {
0025
0026 digi.setPresamples(presamples);
0027 digi.setReadoutIds(eid);
0028
0029 int fiber = startPoint->fiber();
0030 int fiberchan = startPoint->fiberChan();
0031 uint32_t zsmask = hhd.zsBunchMask() >> startSample;
0032 digi.setZSInfo(hhd.isUnsuppressed(), hhd.wasMarkAndPassZS(fiber, fiberchan), zsmask);
0033
0034 if (expectedTime >= 0 && !hhd.isUnsuppressed()) {
0035 #ifdef DebugLog
0036 std::cout << hhd.getFibOrbMsgBCN(fiber) << " " << expectedTime << std::endl;
0037 #endif
0038 digi.setFiberIdleOffset(hhd.getFibOrbMsgBCN(fiber) - expectedTime);
0039 }
0040
0041
0042 int myFiberChan = startPoint->fiberAndChan();
0043 int ncurr = 0, ntaken = 0;
0044 const HcalQIESample* qie_work = startPoint;
0045 while (qie_work != limit && qie_work->fiberAndChan() == myFiberChan) {
0046 if (ncurr >= startSample && ncurr <= endSample) {
0047 digi.setSample(ntaken, *qie_work);
0048 ++ntaken;
0049 }
0050 ncurr++;
0051 qie_work++;
0052 }
0053 digi.setSize(ntaken);
0054 return qie_work;
0055 }
0056
0057 template <class DigiClass>
0058 const unsigned short* unpack_compact(const unsigned short* startPoint,
0059 const unsigned short* limit,
0060 DigiClass& digi,
0061 int presamples,
0062 const HcalElectronicsId& eid,
0063 int startSample,
0064 int endSample,
0065 int expectedTime,
0066 const HcalHTRData& hhd) {
0067
0068 digi.setPresamples(presamples);
0069 digi.setReadoutIds(eid);
0070 int flavor, error_flags, capid0, channelid;
0071
0072 HcalHTRData::unpack_per_channel_header(*startPoint, flavor, error_flags, capid0, channelid);
0073 bool isCapRotating = !(error_flags & 0x1);
0074 bool fiberErr = (error_flags & 0x2);
0075 bool dataValid = !(error_flags & 0x2);
0076 int fiberchan = channelid & 0x3;
0077 int fiber = ((channelid >> 2) & 0x7) + 1;
0078
0079 uint32_t zsmask = hhd.zsBunchMask() >> startSample;
0080 digi.setZSInfo(hhd.isUnsuppressed(), hhd.wasMarkAndPassZS(fiber, fiberchan), zsmask);
0081
0082 if (expectedTime >= 0 && !hhd.isUnsuppressed()) {
0083 #ifdef DebugLog
0084 std::cout << hhd.getFibOrbMsgBCN(fiber) << " " << expectedTime << std::endl;
0085 #endif
0086 digi.setFiberIdleOffset(hhd.getFibOrbMsgBCN(fiber) - expectedTime);
0087 }
0088
0089
0090 int ncurr = 0, ntaken = 0;
0091 const unsigned short* qie_work = startPoint;
0092
0093 if (flavor == 5) {
0094 for (qie_work++; qie_work != limit && !HcalHTRData::is_channel_header(*qie_work); qie_work++) {
0095 int capidn = (isCapRotating) ? ((capid0 + ncurr) % 4) : (capid0);
0096 int capidn1 = (isCapRotating) ? ((capid0 + ncurr + 1) % 4) : (capid0);
0097
0098 HcalQIESample s0((*qie_work) & 0x7F, capidn, fiber, fiberchan, dataValid, fiberErr);
0099 HcalQIESample s1(((*qie_work) >> 8) & 0x7F, capidn1, fiber, fiberchan, dataValid, fiberErr);
0100
0101 if (ncurr >= startSample && ncurr <= endSample) {
0102 digi.setSample(ntaken, s0);
0103 ++ntaken;
0104 }
0105 ncurr++;
0106 if (ncurr >= startSample && ncurr <= endSample) {
0107 digi.setSample(ntaken, s1);
0108 ++ntaken;
0109 }
0110 ncurr++;
0111 }
0112 digi.setSize(ntaken);
0113 } else if (flavor == 6) {
0114 for (qie_work++; qie_work != limit && !HcalHTRData::is_channel_header(*qie_work); qie_work++) {
0115 if (ncurr >= startSample && ncurr <= endSample) {
0116 HcalQIESample sample((*qie_work) & 0x7F,
0117 ((*qie_work) >> 8) & 0x3,
0118 fiber,
0119 fiberchan,
0120 ((*qie_work) >> 10) & 0x1,
0121 ((*qie_work) >> 11) & 0x1);
0122 digi.setSample(ntaken, sample);
0123 ++ntaken;
0124 }
0125
0126 ncurr++;
0127 }
0128 digi.setSize(ntaken);
0129 } else {
0130 edm::LogWarning("Bad Data") << "Invalid flavor " << flavor;
0131 qie_work = limit;
0132 }
0133 return qie_work;
0134 }
0135
0136 template <class DigiClass>
0137 void unpack_compact(HcalUHTRData::const_iterator& i,
0138 const HcalUHTRData::const_iterator& iend,
0139 DigiClass& digi,
0140 int presamples,
0141 const HcalElectronicsId& eid,
0142 int startSample,
0143 int endSample) {
0144
0145 digi.setPresamples(presamples - startSample);
0146 digi.setReadoutIds(eid);
0147 int error_flags = i.errFlags();
0148 int capid0 = i.capid0();
0149 int flavor = i.flavor();
0150
0151 bool isCapRotating = !(error_flags & 0x1);
0152 bool fiberErr = (error_flags & 0x2);
0153 bool dataValid = !(error_flags & 0x2);
0154 int fiberchan = i.channelid() & 0x3;
0155 int fiber = ((i.channelid() >> 2) & 0x7) + 1;
0156
0157
0158
0159
0160 int ncurr = 0, ntaken = 0;
0161 if (flavor == 5) {
0162 for (++i; i != iend && !i.isHeader(); ++i) {
0163 int capidn = (isCapRotating) ? ((capid0 + ncurr) % 4) : (capid0);
0164
0165 HcalQIESample s(i.adc(), capidn, fiber, fiberchan, dataValid, fiberErr);
0166
0167 if (ncurr >= startSample && ncurr <= endSample) {
0168 digi.setSample(ntaken, s);
0169 ++ntaken;
0170 }
0171 ncurr++;
0172 }
0173 digi.setSize(ntaken);
0174 } else if (flavor == 7) {
0175 for (++i; i != iend && !i.isHeader(); ++i) {
0176 if (ncurr >= startSample && ncurr <= endSample) {
0177 HcalQIESample sample(i.adc(), i.capid(), fiber, fiberchan, i.dataValid(), i.errFlags());
0178 digi.setSample(ntaken, sample);
0179 ++ntaken;
0180 }
0181 ncurr++;
0182 }
0183 digi.setSize(ntaken);
0184 }
0185 }
0186
0187 }
0188
0189 static inline bool isTPGSOI(const HcalTriggerPrimitiveSample& s) { return (s.raw() & 0x200) != 0; }
0190
0191 struct HOUnrolledTP {
0192 bool valid, checked;
0193 int ieta, iphi, samples, soi;
0194 unsigned int databits;
0195 HOUnrolledTP() {
0196 valid = false;
0197 checked = false;
0198 ieta = 0;
0199 iphi = 0;
0200 samples = 0;
0201 soi = 0;
0202 databits = 0;
0203 }
0204 void setbit(int i) { databits |= (1 << i); }
0205 };
0206
0207 void HcalUnpacker::unpack(const FEDRawData& raw,
0208 const HcalElectronicsMap& emap,
0209 Collections& colls,
0210 HcalUnpackerReport& report,
0211 bool silent) {
0212 if (raw.size() < 16) {
0213 if (!silent)
0214 edm::LogWarning("Invalid Data") << "Empty/invalid data, size = " << raw.size();
0215 return;
0216 }
0217
0218
0219 const HcalDCCHeader* dccHeader = (const HcalDCCHeader*)(raw.data());
0220
0221 if (dccHeader->BOEshouldBeZeroAlways() == 0)
0222 unpackVME(raw, emap, colls, report, silent);
0223 else
0224 unpackUTCA(raw, emap, colls, report, silent);
0225 }
0226
0227 static int slb(uint16_t theSample) { return ((theSample >> 13) & 0x7); }
0228 static int slbChan(uint16_t theSample) { return (theSample >> 11) & 0x3; }
0229 static int slbAndChan(uint16_t theSample) { return (theSample >> 11) & 0x1F; }
0230
0231 void HcalUnpacker::unpackVME(const FEDRawData& raw,
0232 const HcalElectronicsMap& emap,
0233 Collections& colls,
0234 HcalUnpackerReport& report,
0235 bool silent) {
0236
0237 const HcalDCCHeader* dccHeader = (const HcalDCCHeader*)(raw.data());
0238 const HcalDTCHeader* dtcHeader = (const HcalDTCHeader*)(raw.data());
0239 bool is_VME_DCC = (dccHeader->getDCCDataFormatVersion() < 0x10) || ((mode_ & 0x1) == 0);
0240
0241 int dccid =
0242 (is_VME_DCC) ? (dccHeader->getSourceId() - sourceIdOffset_) : (dtcHeader->getSourceId() - sourceIdOffset_);
0243
0244
0245
0246
0247 HcalHTRData htr;
0248 const unsigned short *daq_first, *daq_last, *tp_first, *tp_last;
0249 const HcalQIESample *qie_begin, *qie_end, *qie_work;
0250 const HcalTriggerPrimitiveSample *tp_begin, *tp_end, *tp_work;
0251 for (int spigot = 0; spigot < HcalDCCHeader::SPIGOT_COUNT; spigot++) {
0252 if (is_VME_DCC) {
0253 if (!dccHeader->getSpigotPresent(spigot))
0254 continue;
0255
0256 int retval = dccHeader->getSpigotData(spigot, htr, raw.size());
0257 if (retval != 0) {
0258 if (retval == -1) {
0259 if (!silent)
0260 edm::LogWarning("Invalid Data") << "Invalid HTR data (data beyond payload size) observed on spigot "
0261 << spigot << " of DCC with source id " << dccHeader->getSourceId();
0262 report.countSpigotFormatError();
0263 }
0264 continue;
0265 }
0266
0267 if (dccHeader->getSpigotCRCError(spigot)) {
0268 if (!silent)
0269 edm::LogWarning("Invalid Data") << "CRC Error on HTR data observed on spigot " << spigot
0270 << " of DCC with source id " << dccHeader->getSourceId();
0271 report.countSpigotFormatError();
0272 continue;
0273 }
0274 } else {
0275 int slot = spigot + 1;
0276 if (slot > HcalDTCHeader::MAXIMUM_SLOT)
0277 continue;
0278
0279 if (!dtcHeader->getSlotPresent(slot))
0280 continue;
0281
0282 int retval = dtcHeader->getSlotData(slot, htr, raw.size());
0283 if (retval != 0) {
0284 if (retval == -1) {
0285 if (!silent)
0286 edm::LogWarning("Invalid Data") << "Invalid uHTR data (data beyond payload size) observed on slot " << slot
0287 << " of DTC with source id " << dtcHeader->getSourceId();
0288 report.countSpigotFormatError();
0289 }
0290 continue;
0291 }
0292
0293 if (dtcHeader->getSlotCRCError(slot)) {
0294 if (!silent)
0295 edm::LogWarning("Invalid Data") << "CRC Error on uHTR data observed on slot " << slot
0296 << " of DTC with source id " << dtcHeader->getSourceId();
0297 report.countSpigotFormatError();
0298 continue;
0299 }
0300 }
0301
0302
0303 if (htr.isEmptyEvent()) {
0304 report.countEmptyEventSpigot();
0305 }
0306 if (htr.isOverflowWarning()) {
0307 report.countOFWSpigot();
0308 }
0309 if (htr.isBusy()) {
0310 report.countBusySpigot();
0311 }
0312 if (!htr.check()) {
0313 if (!silent)
0314 edm::LogWarning("Invalid Data") << "Invalid HTR data observed on spigot " << spigot << " of DCC with source id "
0315 << dccHeader->getSourceId();
0316 report.countSpigotFormatError();
0317 continue;
0318 }
0319 if (htr.isHistogramEvent()) {
0320 if (!silent)
0321 edm::LogWarning("Invalid Data") << "Histogram data passed to non-histogram unpacker on spigot " << spigot
0322 << " of DCC with source id " << dccHeader->getSourceId();
0323 continue;
0324 }
0325 if ((htr.getFirmwareFlavor() & 0xE0) == 0x80) {
0326 if (colls.ttp != nullptr) {
0327 HcalTTPUnpacker ttpUnpack;
0328 colls.ttp->push_back(HcalTTPDigi());
0329 ttpUnpack.unpack(htr, colls.ttp->back());
0330 } else {
0331 LogDebug("HcalTechTrigProcessor")
0332 << "Skipping data on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId()
0333 << " which is from the TechTrigProcessor (use separate unpacker!)";
0334 }
0335 continue;
0336 }
0337 if (htr.getFirmwareFlavor() >= 0x80) {
0338 if (!silent)
0339 edm::LogWarning("HcalUnpacker") << "Skipping data on spigot " << spigot << " of DCC with source id "
0340 << dccHeader->getSourceId() << " which is of unknown flavor "
0341 << htr.getFirmwareFlavor();
0342 continue;
0343 }
0344
0345
0346 int nps = htr.getNPS() - startSample_;
0347
0348
0349 htr.dataPointers(&daq_first, &daq_last, &tp_first, &tp_last);
0350 unsigned int smid = htr.getSubmodule();
0351 int htr_tb = smid & 0x1;
0352 int htr_slot = (smid >> 1) & 0x1F;
0353 int htr_cr = (smid >> 6) & 0x1F;
0354
0355 tp_begin = (const HcalTriggerPrimitiveSample*)tp_first;
0356 tp_end = (const HcalTriggerPrimitiveSample*)(tp_last + 1);
0357
0358
0359 int currFiberChan = 0x3F;
0360 int ncurr = 0;
0361 bool valid = false;
0362
0363 bool tpgSOIbitInUse = htr.getFormatVersion() >= 3;
0364 bool isHOtpg = htr.getFormatVersion() >= 3 && htr.getFirmwareFlavor() == 0;
0365 int npre = 0;
0366
0367
0368
0369 if (isHOtpg) {
0370 HOUnrolledTP unrolled[24];
0371 for (tp_work = tp_begin; tp_work != tp_end; tp_work++) {
0372 if (tp_work->raw() == 0xFFFF)
0373 continue;
0374 int sector = slbChan(tp_work->raw());
0375 if (sector > 2)
0376 continue;
0377
0378 for (int ibit = 0; ibit < 8; ibit++) {
0379 int linear = sector * 8 + ibit;
0380 if (!unrolled[linear].checked) {
0381 unrolled[linear].checked = true;
0382 int fiber = (linear / 3) + 1;
0383 int fc = (linear % 3);
0384
0385 HcalElectronicsId eid(fc, fiber, spigot, dccid);
0386 eid.setHTR(htr_cr, htr_slot, htr_tb);
0387 DetId did = emap.lookup(eid);
0388 if (!did.null()) {
0389 if (did.det() == DetId::Hcal && ((HcalSubdetector)did.subdetId()) == HcalOuter) {
0390 HcalDetId hid(did);
0391 unrolled[linear].valid = true;
0392 unrolled[linear].ieta = hid.ieta();
0393 unrolled[linear].iphi = hid.iphi();
0394 }
0395 } else {
0396 report.countUnmappedTPDigi(eid);
0397 }
0398 }
0399 if (unrolled[linear].valid) {
0400 if (isTPGSOI(*tp_work))
0401 unrolled[linear].soi = unrolled[linear].samples;
0402 if (tp_work->raw() & (1 << ibit))
0403 unrolled[linear].setbit(unrolled[linear].samples);
0404 unrolled[linear].samples++;
0405 }
0406 }
0407 }
0408 for (int i = 0; i < 24; i++) {
0409 if (unrolled[i].valid)
0410 colls.tphoCont->push_back(HOTriggerPrimitiveDigi(
0411 unrolled[i].ieta, unrolled[i].iphi, unrolled[i].samples, unrolled[i].soi, unrolled[i].databits));
0412 }
0413 } else {
0414 for (tp_work = tp_begin; tp_work != tp_end; tp_work++) {
0415 if (tp_work->raw() == 0xFFFF)
0416 continue;
0417 if (slbAndChan(tp_work->raw()) != currFiberChan) {
0418 npre = 0;
0419 currFiberChan = slbAndChan(tp_work->raw());
0420
0421 HcalElectronicsId eid(slbChan(tp_work->raw()), slb(tp_work->raw()), spigot, dccid, htr_cr, htr_slot, htr_tb);
0422 DetId did = emap.lookupTrigger(eid);
0423 if (did.null()) {
0424 report.countUnmappedTPDigi(eid);
0425 if (unknownIdsTrig_.find(eid) == unknownIdsTrig_.end()) {
0426 if (!silent)
0427 edm::LogWarning("HCAL") << "HcalUnpacker: No trigger primitive match found for electronics id :" << eid;
0428 unknownIdsTrig_.insert(eid);
0429 }
0430 valid = false;
0431 continue;
0432 } else if (did == HcalTrigTowerDetId::Undefined || (did.det() == DetId::Hcal && did.subdetId() == 0)) {
0433
0434 valid = false;
0435 continue;
0436 }
0437 HcalTrigTowerDetId id(did);
0438 colls.tpCont->push_back(HcalTriggerPrimitiveDigi(id));
0439
0440 if (!tpgSOIbitInUse)
0441 colls.tpCont->back().setPresamples(nps);
0442 colls.tpCont->back().setZSInfo(htr.isUnsuppressed(),
0443 htr.wasMarkAndPassZSTP(slb(tp_work->raw()), slbChan(tp_work->raw())));
0444
0445
0446 ncurr = 0;
0447 valid = true;
0448 }
0449
0450 if (valid && ((tpgSOIbitInUse && ncurr < 10) || (ncurr >= startSample_ && ncurr <= endSample_))) {
0451 colls.tpCont->back().setSample(colls.tpCont->back().size(), *tp_work);
0452 colls.tpCont->back().setSize(colls.tpCont->back().size() + 1);
0453 }
0454
0455 if (valid && tpgSOIbitInUse && isTPGSOI(*tp_work)) {
0456 colls.tpCont->back().setPresamples(ncurr);
0457 }
0458 ncurr++;
0459 npre++;
0460 }
0461 }
0462
0463
0464 if (htr.getFormatVersion() < HcalHTRData::FORMAT_VERSION_COMPACT_DATA) {
0465 qie_begin = (const HcalQIESample*)daq_first;
0466 qie_end = (const HcalQIESample*)(daq_last + 1);
0467
0468
0469
0470 for (qie_work = qie_begin; qie_work != qie_end;) {
0471 if (qie_work->raw() == 0xFFFF) {
0472 qie_work++;
0473 continue;
0474 }
0475
0476
0477
0478 HcalElectronicsId eid(qie_work->fiberChan(), qie_work->fiber(), spigot, dccid);
0479 eid.setHTR(htr_cr, htr_slot, htr_tb);
0480 DetId did = emap.lookup(eid);
0481
0482 if (!did.null()) {
0483 if (did.det() == DetId::Calo && did.subdetId() == HcalZDCDetId::SubdetectorId) {
0484 colls.zdcCont->push_back(ZDCDataFrame(HcalZDCDetId(did)));
0485 qie_work = HcalUnpacker_impl::unpack<ZDCDataFrame>(qie_work,
0486 qie_end,
0487 colls.zdcCont->back(),
0488 nps,
0489 eid,
0490 startSample_,
0491 endSample_,
0492 expectedOrbitMessageTime_,
0493 htr);
0494 } else if (did.det() == DetId::Hcal) {
0495 switch (((HcalSubdetector)did.subdetId())) {
0496 case (HcalBarrel):
0497 case (HcalEndcap): {
0498 colls.hbheCont->push_back(HBHEDataFrame(HcalDetId(did)));
0499 qie_work = HcalUnpacker_impl::unpack<HBHEDataFrame>(qie_work,
0500 qie_end,
0501 colls.hbheCont->back(),
0502 nps,
0503 eid,
0504 startSample_,
0505 endSample_,
0506 expectedOrbitMessageTime_,
0507 htr);
0508 } break;
0509 case (HcalOuter): {
0510 colls.hoCont->push_back(HODataFrame(HcalDetId(did)));
0511 qie_work = HcalUnpacker_impl::unpack<HODataFrame>(qie_work,
0512 qie_end,
0513 colls.hoCont->back(),
0514 nps,
0515 eid,
0516 startSample_,
0517 endSample_,
0518 expectedOrbitMessageTime_,
0519 htr);
0520 } break;
0521 case (HcalForward): {
0522 colls.hfCont->push_back(HFDataFrame(HcalDetId(did)));
0523 qie_work = HcalUnpacker_impl::unpack<HFDataFrame>(qie_work,
0524 qie_end,
0525 colls.hfCont->back(),
0526 nps,
0527 eid,
0528 startSample_,
0529 endSample_,
0530 expectedOrbitMessageTime_,
0531 htr);
0532 } break;
0533 case (HcalOther): {
0534 HcalOtherDetId odid(did);
0535 if (odid.subdet() == HcalCalibration) {
0536 colls.calibCont->push_back(HcalCalibDataFrame(HcalCalibDetId(did)));
0537 qie_work = HcalUnpacker_impl::unpack<HcalCalibDataFrame>(qie_work,
0538 qie_end,
0539 colls.calibCont->back(),
0540 nps,
0541 eid,
0542 startSample_,
0543 endSample_,
0544 expectedOrbitMessageTime_,
0545 htr);
0546 }
0547 } break;
0548 case (HcalEmpty):
0549 default: {
0550 for (int fiberC = qie_work->fiberAndChan(); qie_work != qie_end && qie_work->fiberAndChan() == fiberC;
0551 qie_work++)
0552 ;
0553 } break;
0554 }
0555 }
0556 } else {
0557 report.countUnmappedDigi(eid);
0558 if (unknownIds_.find(eid) == unknownIds_.end()) {
0559 if (!silent)
0560 edm::LogWarning("HCAL") << "HcalUnpacker: No match found for electronics id :" << eid;
0561 unknownIds_.insert(eid);
0562 }
0563 for (int fiberC = qie_work->fiberAndChan(); qie_work != qie_end && qie_work->fiberAndChan() == fiberC;
0564 qie_work++)
0565 ;
0566 }
0567 }
0568 } else {
0569
0570 const unsigned short* ptr_header = daq_first;
0571 const unsigned short* ptr_end = daq_last + 1;
0572 int flavor, error_flags, capid0, channelid;
0573
0574 while (ptr_header != ptr_end) {
0575 if (*ptr_header == 0xFFFF) {
0576 ptr_header++;
0577 continue;
0578 }
0579
0580 bool isheader = HcalHTRData::unpack_per_channel_header(*ptr_header, flavor, error_flags, capid0, channelid);
0581 if (!isheader) {
0582 ptr_header++;
0583 continue;
0584 }
0585
0586 int fiberchan = channelid & 0x3;
0587 int fiber = ((channelid >> 2) & 0x7) + 1;
0588
0589
0590 HcalElectronicsId eid(fiberchan, fiber, spigot, dccid);
0591 eid.setHTR(htr_cr, htr_slot, htr_tb);
0592 DetId did = emap.lookup(eid);
0593
0594 if (!did.null()) {
0595 if (did.det() == DetId::Calo && did.subdetId() == HcalZDCDetId::SubdetectorId) {
0596 colls.zdcCont->push_back(ZDCDataFrame(HcalZDCDetId(did)));
0597 ptr_header = HcalUnpacker_impl::unpack_compact<ZDCDataFrame>(ptr_header,
0598 ptr_end,
0599 colls.zdcCont->back(),
0600 nps,
0601 eid,
0602 startSample_,
0603 endSample_,
0604 expectedOrbitMessageTime_,
0605 htr);
0606 } else if (did.det() == DetId::Hcal) {
0607 switch (((HcalSubdetector)did.subdetId())) {
0608 case (HcalBarrel):
0609 case (HcalEndcap): {
0610 colls.hbheCont->push_back(HBHEDataFrame(HcalDetId(did)));
0611 ptr_header = HcalUnpacker_impl::unpack_compact<HBHEDataFrame>(ptr_header,
0612 ptr_end,
0613 colls.hbheCont->back(),
0614 nps,
0615 eid,
0616 startSample_,
0617 endSample_,
0618 expectedOrbitMessageTime_,
0619 htr);
0620 } break;
0621 case (HcalOuter): {
0622 colls.hoCont->push_back(HODataFrame(HcalDetId(did)));
0623 ptr_header = HcalUnpacker_impl::unpack_compact<HODataFrame>(ptr_header,
0624 ptr_end,
0625 colls.hoCont->back(),
0626 nps,
0627 eid,
0628 startSample_,
0629 endSample_,
0630 expectedOrbitMessageTime_,
0631 htr);
0632 } break;
0633 case (HcalForward): {
0634 colls.hfCont->push_back(HFDataFrame(HcalDetId(did)));
0635 ptr_header = HcalUnpacker_impl::unpack_compact<HFDataFrame>(ptr_header,
0636 ptr_end,
0637 colls.hfCont->back(),
0638 nps,
0639 eid,
0640 startSample_,
0641 endSample_,
0642 expectedOrbitMessageTime_,
0643 htr);
0644 } break;
0645 case (HcalOther): {
0646 HcalOtherDetId odid(did);
0647 if (odid.subdet() == HcalCalibration) {
0648 colls.calibCont->push_back(HcalCalibDataFrame(HcalCalibDetId(did)));
0649 ptr_header = HcalUnpacker_impl::unpack_compact<HcalCalibDataFrame>(ptr_header,
0650 ptr_end,
0651 colls.calibCont->back(),
0652 nps,
0653 eid,
0654 startSample_,
0655 endSample_,
0656 expectedOrbitMessageTime_,
0657 htr);
0658 }
0659 } break;
0660 case (HcalEmpty):
0661 default: {
0662 for (ptr_header++; ptr_header != ptr_end && !HcalHTRData::is_channel_header(*ptr_header); ptr_header++)
0663 ;
0664 } break;
0665 }
0666 }
0667 } else {
0668 report.countUnmappedDigi(eid);
0669 if (unknownIds_.find(eid) == unknownIds_.end()) {
0670 if (!silent)
0671 edm::LogWarning("HCAL") << "HcalUnpacker: No match found for electronics id :" << eid;
0672 unknownIds_.insert(eid);
0673 }
0674 for (ptr_header++; ptr_header != ptr_end && !HcalHTRData::is_channel_header(*ptr_header); ptr_header++)
0675 ;
0676 }
0677 }
0678 }
0679 }
0680 }
0681
0682 void HcalUnpacker::unpackUTCA(const FEDRawData& raw,
0683 const HcalElectronicsMap& emap,
0684 Collections& colls,
0685 HcalUnpackerReport& report,
0686 bool silent) {
0687 const hcal::AMC13Header* amc13 = (const hcal::AMC13Header*)(raw.data());
0688
0689
0690 int namc = amc13->NAMC();
0691 for (int iamc = 0; iamc < namc; iamc++) {
0692
0693 if (!amc13->AMCEnabled(iamc))
0694 continue;
0695
0696 if (!amc13->AMCDataPresent(iamc)) {
0697 if (!silent)
0698 edm::LogWarning("Invalid Data") << "Missing data observed on iamc " << iamc << " of AMC13 with source id "
0699 << amc13->sourceId();
0700 report.countSpigotFormatError();
0701 continue;
0702 }
0703 if (!amc13->AMCCRCOk(iamc)) {
0704 if (!silent)
0705 edm::LogWarning("Invalid Data") << "CRC Error on uHTR data observed on iamc " << iamc
0706 << " of AMC13 with source id " << amc13->sourceId();
0707 report.countSpigotFormatError();
0708
0709 }
0710
0711 if (amc13->AMCSegmented(iamc)) {
0712 if (!silent)
0713 edm::LogWarning("Invalid Data") << "Unpacker cannot handle segmented data observed on iamc " << iamc
0714 << " of AMC13 with source id " << amc13->sourceId();
0715 report.countSpigotFormatError();
0716 continue;
0717 }
0718
0719
0720 int slot = amc13->AMCSlot(iamc);
0721 int crate = amc13->AMCId(iamc) & 0xFF;
0722
0723 HcalUHTRData uhtr(amc13->AMCPayload(iamc), amc13->AMCSize(iamc));
0724
0725 if (uhtr.getFormatVersion() != 1) {
0726 unpackUMNio(raw, slot, colls);
0727 continue;
0728 }
0729 #ifdef DebugLog
0730
0731 int nwords = uhtr.getRawLengthBytes() / 2;
0732 for (int iw = 0; iw < nwords; iw++)
0733 printf("%04d %04x\n", iw, uhtr.getRawData16()[iw]);
0734 #endif
0735
0736
0737 int nps = uhtr.presamples();
0738
0739 HcalUHTRData::const_iterator i = uhtr.begin(), iend = uhtr.end();
0740 while (i != iend) {
0741 #ifdef DebugLog
0742 std::cout << "This data is flavored:" << i.flavor() << std::endl;
0743 #endif
0744
0745 if (!i.isHeader()) {
0746 ++i;
0747 #ifdef DebugLog
0748 std::cout << "its not a header" << std::endl;
0749 #endif
0750 continue;
0751 }
0752
0753 if (i.flavor() == 1 || i.flavor() == 0 || i.flavor() == 3) {
0754 int ifiber = ((i.channelid() >> 3) & 0x1F);
0755 int ichan = (i.channelid() & 0x7);
0756 HcalElectronicsId eid(crate, slot, ifiber, ichan, false);
0757 DetId did = emap.lookup(eid);
0758
0759 const uint16_t* head_pos = i.raw();
0760 int ns = 0;
0761 for (++i; i != iend && !i.isHeader(); ++i) {
0762 ns++;
0763 }
0764
0765 if (colls.qie11 == nullptr) {
0766 colls.qie11 = new QIE11DigiCollection(ns);
0767 } else if (colls.qie11->samples() != ns) {
0768
0769
0770 if (colls.qie11Addtl.find(ns) == colls.qie11Addtl.end()) {
0771 printInvalidDataMessage("QIE11", colls.qie11->samples(), ns, true);
0772 }
0773 }
0774
0775
0776
0777 if (!did.null()) {
0778
0779 if (colls.qie11->samples() == ns) {
0780 colls.qie11->addDataFrame(did, head_pos);
0781 }
0782
0783 if (colls.qie11Addtl.find(ns) != colls.qie11Addtl.end()) {
0784 colls.qie11Addtl[ns]->addDataFrame(did, head_pos);
0785 }
0786 } else {
0787 report.countUnmappedDigi(eid);
0788 if (unknownIds_.find(eid) == unknownIds_.end()) {
0789 if (!silent)
0790 edm::LogWarning("HCAL") << "HcalUnpacker: No match found for electronics id :" << eid;
0791 unknownIds_.insert(eid);
0792 #ifdef DebugLog
0793 std::cout << "HcalUnpacker: No match found for electronics id :" << eid << std::endl;
0794 #endif
0795 }
0796 #ifdef DebugLog
0797 std::cout << "OH NO! detector id is null!" << std::endl;
0798 #endif
0799 }
0800 } else if (i.flavor() == 2) {
0801
0802
0803 int ifiber = ((i.channelid() >> 3) & 0x1F);
0804 int ichan = (i.channelid() & 0x7);
0805 HcalElectronicsId eid(crate, slot, ifiber, ichan, false);
0806 DetId did = emap.lookup(eid);
0807
0808
0809 const uint16_t* head_pos = i.raw();
0810 int ns = 0;
0811 for (++i; i != iend && !i.isHeader(); ++i) {
0812 ns++;
0813 }
0814
0815 bool isZDC = (did.det() == DetId::Calo && did.subdetId() == HcalZDCDetId::SubdetectorId);
0816 bool isLasmon = (did.det() == DetId::Hcal && (HcalSubdetector)did.subdetId() == HcalOther &&
0817 HcalCalibDetId(did).calibFlavor() == 5);
0818
0819 if (isZDC) {
0820 if (colls.qie10ZDC == nullptr) {
0821 colls.qie10ZDC = new QIE10DigiCollection(ns);
0822 } else if (colls.qie10ZDC->samples() != ns) {
0823 printInvalidDataMessage("QIE10ZDC", colls.qie10ZDC->samples(), ns, false);
0824 }
0825 } else if (isLasmon) {
0826 if (colls.qie10Lasermon == nullptr) {
0827 colls.qie10Lasermon = new QIE10DigiCollection(ns);
0828 } else if (colls.qie10Lasermon->samples() != ns) {
0829 printInvalidDataMessage("QIE10LASMON", colls.qie10Lasermon->samples(), ns, false);
0830 }
0831 } else {
0832 if (colls.qie10 == nullptr) {
0833 colls.qie10 = new QIE10DigiCollection(ns);
0834 } else if (colls.qie10->samples() != ns) {
0835
0836
0837 if (colls.qie10Addtl.find(ns) == colls.qie10Addtl.end()) {
0838 printInvalidDataMessage("QIE10", colls.qie10->samples(), ns, true);
0839 }
0840 }
0841 }
0842
0843
0844
0845 if (!did.null()) {
0846
0847 if (isZDC)
0848 colls.qie10ZDC->addDataFrame(did, head_pos);
0849 else if (isLasmon)
0850 colls.qie10Lasermon->addDataFrame(did, head_pos);
0851 else {
0852
0853 if (colls.qie10->samples() == ns) {
0854 colls.qie10->addDataFrame(did, head_pos);
0855 }
0856
0857
0858 if (colls.qie10Addtl.find(ns) != colls.qie10Addtl.end()) {
0859 colls.qie10Addtl[ns]->addDataFrame(did, head_pos);
0860 }
0861 }
0862 } else {
0863 report.countUnmappedDigi(eid);
0864 if (unknownIds_.find(eid) == unknownIds_.end()) {
0865 if (!silent)
0866 edm::LogWarning("HCAL") << "HcalUnpacker: No match found for electronics id :" << eid;
0867 unknownIds_.insert(eid);
0868 #ifdef DebugLog
0869 std::cout << "HcalUnpacker: No match found for electronics id :" << eid << std::endl;
0870 #endif
0871 }
0872 #ifdef DebugLog
0873 std::cout << "OH NO! HcalUnpacker: No match found for electronics id :" << eid << std::endl;
0874 #endif
0875 }
0876 } else if (i.flavor() == 5 || (i.flavor() == 7 && i.technicalDataType() == 15)) {
0877 int ifiber = ((i.channelid() >> 2) & 0x1F);
0878 int ichan = (i.channelid() & 0x3);
0879 HcalElectronicsId eid(crate, slot, ifiber, ichan, false);
0880 DetId did = emap.lookup(eid);
0881
0882 if (!did.null()) {
0883 if (did.det() == DetId::Calo && did.subdetId() == HcalZDCDetId::SubdetectorId) {
0884 colls.zdcCont->push_back(ZDCDataFrame(HcalZDCDetId(did)));
0885 HcalUnpacker_impl::unpack_compact<ZDCDataFrame>(
0886 i, iend, colls.zdcCont->back(), nps, eid, startSample_, endSample_);
0887 } else if (did.det() == DetId::Hcal) {
0888 switch (((HcalSubdetector)did.subdetId())) {
0889 case (HcalBarrel):
0890 case (HcalEndcap): {
0891 colls.hbheCont->push_back(HBHEDataFrame(HcalDetId(did)));
0892 HcalUnpacker_impl::unpack_compact<HBHEDataFrame>(
0893 i, iend, colls.hbheCont->back(), nps, eid, startSample_, endSample_);
0894 } break;
0895 case (HcalOuter): {
0896 colls.hoCont->push_back(HODataFrame(HcalDetId(did)));
0897 HcalUnpacker_impl::unpack_compact<HODataFrame>(
0898 i, iend, colls.hoCont->back(), nps, eid, startSample_, endSample_);
0899 } break;
0900 case (HcalForward): {
0901 colls.hfCont->push_back(HFDataFrame(HcalDetId(did)));
0902 HcalUnpacker_impl::unpack_compact<HFDataFrame>(
0903 i, iend, colls.hfCont->back(), nps, eid, startSample_, endSample_);
0904 } break;
0905 case (HcalOther): {
0906 HcalOtherDetId odid(did);
0907 if (odid.subdet() == HcalCalibration) {
0908 colls.calibCont->push_back(HcalCalibDataFrame(HcalCalibDetId(did)));
0909 HcalUnpacker_impl::unpack_compact<HcalCalibDataFrame>(
0910 i, iend, colls.calibCont->back(), nps, eid, startSample_, endSample_);
0911 }
0912 } break;
0913 case (HcalEmpty):
0914 default: {
0915 for (++i; i != iend && !i.isHeader(); ++i)
0916 ;
0917 } break;
0918 }
0919 }
0920 } else {
0921 report.countUnmappedDigi(eid);
0922 if (unknownIds_.find(eid) == unknownIds_.end()) {
0923 if (!silent)
0924 edm::LogWarning("HCAL") << "HcalUnpacker: No match found for electronics id :" << eid;
0925 unknownIds_.insert(eid);
0926 }
0927 for (++i; i != iend && !i.isHeader(); ++i)
0928 ;
0929 }
0930 } else if (i.flavor() == 0x4) {
0931 int ilink = ((i.channelid() >> 4) & 0xF);
0932 int itower = (i.channelid() & 0xF);
0933 HcalElectronicsId eid(crate, slot, ilink, itower, true);
0934 DetId did = emap.lookupTrigger(eid);
0935 #ifdef DebugLog
0936 std::cout << "Unpacking " << eid << " " << i.channelid() << std::endl;
0937 #endif
0938 if (did.null()) {
0939 report.countUnmappedTPDigi(eid);
0940 if (unknownIdsTrig_.find(eid) == unknownIdsTrig_.end()) {
0941 if (!silent)
0942 edm::LogWarning("HCAL") << "HcalUnpacker: No trigger primitive match found for electronics id :" << eid;
0943 unknownIdsTrig_.insert(eid);
0944 }
0945
0946 for (++i; i != iend && !i.isHeader(); ++i)
0947 ;
0948 } else if (did == HcalTrigTowerDetId::Undefined || (did.det() == DetId::Hcal && did.subdetId() == 0)) {
0949 for (++i; i != iend && !i.isHeader(); ++i)
0950 ;
0951 } else {
0952 HcalTrigTowerDetId id(did);
0953 #ifdef DebugLog
0954 std::cout << "Unpacking " << id << std::endl;
0955 #endif
0956 colls.tpCont->push_back(HcalTriggerPrimitiveDigi(id));
0957 int j = 0;
0958 for (++i; i != iend && !i.isHeader(); ++i) {
0959 colls.tpCont->back().setSample(j, i.value());
0960 if (i.soi())
0961 colls.tpCont->back().setPresamples(j);
0962 j++;
0963 }
0964 colls.tpCont->back().setSize(j);
0965 }
0966 } else {
0967
0968 for (++i; i != iend && !i.isHeader(); ++i)
0969 ;
0970 }
0971 }
0972 }
0973 }
0974
0975 HcalUnpacker::Collections::Collections() {
0976 hbheCont = nullptr;
0977 hoCont = nullptr;
0978 hfCont = nullptr;
0979 tpCont = nullptr;
0980 zdcCont = nullptr;
0981 calibCont = nullptr;
0982 ttp = nullptr;
0983 qie10 = nullptr;
0984 qie10ZDC = nullptr;
0985 qie10Lasermon = nullptr;
0986 qie11 = nullptr;
0987 umnio = nullptr;
0988 }
0989
0990 void HcalUnpacker::unpack(const FEDRawData& raw,
0991 const HcalElectronicsMap& emap,
0992 std::vector<HcalHistogramDigi>& histoDigis) {
0993
0994 const HcalDCCHeader* dccHeader = (const HcalDCCHeader*)(raw.data());
0995 int dccid = dccHeader->getSourceId() - sourceIdOffset_;
0996
0997
0998
0999
1000 HcalHTRData htr;
1001 for (int spigot = 0; spigot < HcalDCCHeader::SPIGOT_COUNT; spigot++) {
1002 if (!dccHeader->getSpigotPresent(spigot))
1003 continue;
1004
1005 int retval = dccHeader->getSpigotData(spigot, htr, raw.size());
1006
1007 if (retval || !htr.check()) {
1008 edm::LogWarning("Invalid Data") << "Invalid HTR data observed on spigot " << spigot << " of DCC with source id "
1009 << dccHeader->getSourceId();
1010 continue;
1011 }
1012 if (!htr.isHistogramEvent()) {
1013 edm::LogWarning("Invalid Data") << "Non-histogram data passed to histogram unpacker on spigot " << spigot
1014 << " of DCC with source id " << dccHeader->getSourceId();
1015 continue;
1016 }
1017
1018 unsigned int smid = htr.getSubmodule();
1019 int htr_tb = smid & 0x1;
1020 int htr_slot = (smid >> 1) & 0x1F;
1021 int htr_cr = (smid >> 6) & 0x1F;
1022
1023
1024 int f[2], fc;
1025 htr.getHistogramFibers(f[0], f[1]);
1026
1027 for (int nf = 0; nf < 2; nf++) {
1028 if (f[nf] < 0 || (nf == 1 && f[0] == f[1]))
1029 continue;
1030 for (fc = 0; fc <= 2; fc++) {
1031 HcalElectronicsId eid(fc, f[nf], spigot, dccid);
1032 eid.setHTR(htr_cr, htr_slot, htr_tb);
1033 DetId did = emap.lookup(eid);
1034
1035 if (did.null() || did.det() != DetId::Hcal || did.subdetId() == 0) {
1036 if (unknownIds_.find(eid) == unknownIds_.end()) {
1037 edm::LogWarning("HCAL") << "HcalHistogramUnpacker: No match found for electronics id :" << eid;
1038 unknownIds_.insert(eid);
1039 }
1040 continue;
1041 }
1042 histoDigis.push_back(HcalHistogramDigi(HcalDetId(did)));
1043 HcalHistogramDigi& digi = histoDigis.back();
1044
1045
1046 for (int capid = 0; capid < 4; capid++)
1047 htr.unpackHistogram(f[nf], fc, capid, digi.getArray(capid));
1048 }
1049 }
1050 }
1051 }
1052
1053 void HcalUnpacker::unpackUMNio(const FEDRawData& raw, int slot, Collections& colls) {
1054 const hcal::AMC13Header* amc13 = (const hcal::AMC13Header*)(raw.data());
1055 int namc = amc13->NAMC();
1056
1057 for (int iamc = 0; iamc < namc; iamc++) {
1058 if (amc13->AMCSlot(iamc) == slot)
1059 namc = iamc;
1060 }
1061 if (namc == amc13->NAMC()) {
1062 return;
1063 }
1064 const uint16_t* data = (const uint16_t*)(amc13->AMCPayload(namc));
1065 size_t nwords = amc13->AMCSize(namc) * (sizeof(uint64_t) / sizeof(uint16_t));
1066 *(colls.umnio) = HcalUMNioDigi(data, nwords);
1067 }
1068
1069 void HcalUnpacker::printInvalidDataMessage(const std::string& coll_type,
1070 int default_ns,
1071 int conflict_ns,
1072 bool extended) {
1073 nPrinted_++;
1074
1075 constexpr int limit = 2;
1076 if (nPrinted_ >= limit) {
1077 if (nPrinted_ == limit)
1078 edm::LogInfo("Invalid Data") << "Suppressing further error messages";
1079
1080 return;
1081 }
1082
1083 std::stringstream message;
1084
1085 message << "The default " << coll_type << " Collection has " << default_ns
1086 << " samples per digi, while the current data has " << conflict_ns
1087 << "! This data cannot be included with the default collection.";
1088
1089 if (extended) {
1090 message << "\nIn order to store this data in the event, it must have a unique tag. "
1091 << "To accomplish this, provide two lists to HcalRawToDigi \n"
1092 << "1) that specifies the number of samples and "
1093 << "2) that gives tags with which these data are saved.\n"
1094 << "For example in this case you might add \n"
1095 << "process.hcalDigis.save" << coll_type << "DataNSamples = cms.untracked.vint32( " << conflict_ns
1096 << ") \nprocess.hcalDigis.save" << coll_type << "DataTags = cms.untracked.vstring( \"MYDATA\" )";
1097 }
1098
1099 edm::LogWarning("Invalid Data") << message.str();
1100 }