File indexing completed on 2024-04-06 12:10:44
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 #include <iomanip>
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
0366
0367
0368 if (isHOtpg) {
0369 HOUnrolledTP unrolled[24];
0370 for (tp_work = tp_begin; tp_work != tp_end; tp_work++) {
0371 if (tp_work->raw() == 0xFFFF)
0372 continue;
0373 int sector = slbChan(tp_work->raw());
0374 if (sector > 2)
0375 continue;
0376
0377 for (int ibit = 0; ibit < 8; ibit++) {
0378 int linear = sector * 8 + ibit;
0379 if (!unrolled[linear].checked) {
0380 unrolled[linear].checked = true;
0381 int fiber = (linear / 3) + 1;
0382 int fc = (linear % 3);
0383
0384 HcalElectronicsId eid(fc, fiber, spigot, dccid);
0385 eid.setHTR(htr_cr, htr_slot, htr_tb);
0386 DetId did = emap.lookup(eid);
0387 if (!did.null()) {
0388 if (did.det() == DetId::Hcal && ((HcalSubdetector)did.subdetId()) == HcalOuter) {
0389 HcalDetId hid(did);
0390 unrolled[linear].valid = true;
0391 unrolled[linear].ieta = hid.ieta();
0392 unrolled[linear].iphi = hid.iphi();
0393 }
0394 } else {
0395 report.countUnmappedTPDigi(eid);
0396 }
0397 }
0398 if (unrolled[linear].valid) {
0399 if (isTPGSOI(*tp_work))
0400 unrolled[linear].soi = unrolled[linear].samples;
0401 if (tp_work->raw() & (1 << ibit))
0402 unrolled[linear].setbit(unrolled[linear].samples);
0403 unrolled[linear].samples++;
0404 }
0405 }
0406 }
0407 for (int i = 0; i < 24; i++) {
0408 if (unrolled[i].valid)
0409 colls.tphoCont->push_back(HOTriggerPrimitiveDigi(
0410 unrolled[i].ieta, unrolled[i].iphi, unrolled[i].samples, unrolled[i].soi, unrolled[i].databits));
0411 }
0412 } else {
0413 for (tp_work = tp_begin; tp_work != tp_end; tp_work++) {
0414 if (tp_work->raw() == 0xFFFF)
0415 continue;
0416 if (slbAndChan(tp_work->raw()) != currFiberChan) {
0417 currFiberChan = slbAndChan(tp_work->raw());
0418
0419 HcalElectronicsId eid(slbChan(tp_work->raw()), slb(tp_work->raw()), spigot, dccid, htr_cr, htr_slot, htr_tb);
0420 DetId did = emap.lookupTrigger(eid);
0421 if (did.null()) {
0422 report.countUnmappedTPDigi(eid);
0423 if (unknownIdsTrig_.find(eid) == unknownIdsTrig_.end()) {
0424 if (!silent)
0425 edm::LogWarning("HCAL") << "HcalUnpacker: No trigger primitive match found for electronics id :" << eid;
0426 unknownIdsTrig_.insert(eid);
0427 }
0428 valid = false;
0429 continue;
0430 } else if (did == HcalTrigTowerDetId::Undefined || (did.det() == DetId::Hcal && did.subdetId() == 0)) {
0431
0432 valid = false;
0433 continue;
0434 }
0435 HcalTrigTowerDetId id(did);
0436 colls.tpCont->push_back(HcalTriggerPrimitiveDigi(id));
0437
0438 if (!tpgSOIbitInUse)
0439 colls.tpCont->back().setPresamples(nps);
0440 colls.tpCont->back().setZSInfo(htr.isUnsuppressed(),
0441 htr.wasMarkAndPassZSTP(slb(tp_work->raw()), slbChan(tp_work->raw())));
0442
0443
0444 ncurr = 0;
0445 valid = true;
0446 }
0447
0448 if (valid && ((tpgSOIbitInUse && ncurr < 10) || (ncurr >= startSample_ && ncurr <= endSample_))) {
0449 colls.tpCont->back().setSample(colls.tpCont->back().size(), *tp_work);
0450 colls.tpCont->back().setSize(colls.tpCont->back().size() + 1);
0451 }
0452
0453 if (valid && tpgSOIbitInUse && isTPGSOI(*tp_work)) {
0454 colls.tpCont->back().setPresamples(ncurr);
0455 }
0456 ncurr++;
0457 }
0458 }
0459
0460
0461 if (htr.getFormatVersion() < HcalHTRData::FORMAT_VERSION_COMPACT_DATA) {
0462 qie_begin = (const HcalQIESample*)daq_first;
0463 qie_end = (const HcalQIESample*)(daq_last + 1);
0464
0465
0466
0467 for (qie_work = qie_begin; qie_work != qie_end;) {
0468 if (qie_work->raw() == 0xFFFF) {
0469 qie_work++;
0470 continue;
0471 }
0472
0473
0474
0475 HcalElectronicsId eid(qie_work->fiberChan(), qie_work->fiber(), spigot, dccid);
0476 eid.setHTR(htr_cr, htr_slot, htr_tb);
0477 DetId did = emap.lookup(eid);
0478
0479 if (!did.null()) {
0480 if (did.det() == DetId::Calo && did.subdetId() == HcalZDCDetId::SubdetectorId) {
0481 colls.zdcCont->push_back(ZDCDataFrame(HcalZDCDetId(did)));
0482 qie_work = HcalUnpacker_impl::unpack<ZDCDataFrame>(qie_work,
0483 qie_end,
0484 colls.zdcCont->back(),
0485 nps,
0486 eid,
0487 startSample_,
0488 endSample_,
0489 expectedOrbitMessageTime_,
0490 htr);
0491 } else if (did.det() == DetId::Hcal) {
0492 switch (((HcalSubdetector)did.subdetId())) {
0493 case (HcalBarrel):
0494 case (HcalEndcap): {
0495 colls.hbheCont->push_back(HBHEDataFrame(HcalDetId(did)));
0496 qie_work = HcalUnpacker_impl::unpack<HBHEDataFrame>(qie_work,
0497 qie_end,
0498 colls.hbheCont->back(),
0499 nps,
0500 eid,
0501 startSample_,
0502 endSample_,
0503 expectedOrbitMessageTime_,
0504 htr);
0505 } break;
0506 case (HcalOuter): {
0507 colls.hoCont->push_back(HODataFrame(HcalDetId(did)));
0508 qie_work = HcalUnpacker_impl::unpack<HODataFrame>(qie_work,
0509 qie_end,
0510 colls.hoCont->back(),
0511 nps,
0512 eid,
0513 startSample_,
0514 endSample_,
0515 expectedOrbitMessageTime_,
0516 htr);
0517 } break;
0518 case (HcalForward): {
0519 colls.hfCont->push_back(HFDataFrame(HcalDetId(did)));
0520 qie_work = HcalUnpacker_impl::unpack<HFDataFrame>(qie_work,
0521 qie_end,
0522 colls.hfCont->back(),
0523 nps,
0524 eid,
0525 startSample_,
0526 endSample_,
0527 expectedOrbitMessageTime_,
0528 htr);
0529 } break;
0530 case (HcalOther): {
0531 HcalOtherDetId odid(did);
0532 if (odid.subdet() == HcalCalibration) {
0533 colls.calibCont->push_back(HcalCalibDataFrame(HcalCalibDetId(did)));
0534 qie_work = HcalUnpacker_impl::unpack<HcalCalibDataFrame>(qie_work,
0535 qie_end,
0536 colls.calibCont->back(),
0537 nps,
0538 eid,
0539 startSample_,
0540 endSample_,
0541 expectedOrbitMessageTime_,
0542 htr);
0543 }
0544 } break;
0545 case (HcalEmpty):
0546 default: {
0547 for (int fiberC = qie_work->fiberAndChan(); qie_work != qie_end && qie_work->fiberAndChan() == fiberC;
0548 qie_work++)
0549 ;
0550 } break;
0551 }
0552 }
0553 } else {
0554 report.countUnmappedDigi(eid);
0555 if (unknownIds_.find(eid) == unknownIds_.end()) {
0556 if (!silent)
0557 edm::LogWarning("HCAL") << "HcalUnpacker: No match found for electronics id :" << eid;
0558 unknownIds_.insert(eid);
0559 }
0560 for (int fiberC = qie_work->fiberAndChan(); qie_work != qie_end && qie_work->fiberAndChan() == fiberC;
0561 qie_work++)
0562 ;
0563 }
0564 }
0565 } else {
0566
0567 const unsigned short* ptr_header = daq_first;
0568 const unsigned short* ptr_end = daq_last + 1;
0569 int flavor, error_flags, capid0, channelid;
0570
0571 while (ptr_header != ptr_end) {
0572 if (*ptr_header == 0xFFFF) {
0573 ptr_header++;
0574 continue;
0575 }
0576
0577 bool isheader = HcalHTRData::unpack_per_channel_header(*ptr_header, flavor, error_flags, capid0, channelid);
0578 if (!isheader) {
0579 ptr_header++;
0580 continue;
0581 }
0582
0583 int fiberchan = channelid & 0x3;
0584 int fiber = ((channelid >> 2) & 0x7) + 1;
0585
0586
0587 HcalElectronicsId eid(fiberchan, fiber, spigot, dccid);
0588 eid.setHTR(htr_cr, htr_slot, htr_tb);
0589 DetId did = emap.lookup(eid);
0590
0591 if (!did.null()) {
0592 if (did.det() == DetId::Calo && did.subdetId() == HcalZDCDetId::SubdetectorId) {
0593 colls.zdcCont->push_back(ZDCDataFrame(HcalZDCDetId(did)));
0594 ptr_header = HcalUnpacker_impl::unpack_compact<ZDCDataFrame>(ptr_header,
0595 ptr_end,
0596 colls.zdcCont->back(),
0597 nps,
0598 eid,
0599 startSample_,
0600 endSample_,
0601 expectedOrbitMessageTime_,
0602 htr);
0603 } else if (did.det() == DetId::Hcal) {
0604 switch (((HcalSubdetector)did.subdetId())) {
0605 case (HcalBarrel):
0606 case (HcalEndcap): {
0607 colls.hbheCont->push_back(HBHEDataFrame(HcalDetId(did)));
0608 ptr_header = HcalUnpacker_impl::unpack_compact<HBHEDataFrame>(ptr_header,
0609 ptr_end,
0610 colls.hbheCont->back(),
0611 nps,
0612 eid,
0613 startSample_,
0614 endSample_,
0615 expectedOrbitMessageTime_,
0616 htr);
0617 } break;
0618 case (HcalOuter): {
0619 colls.hoCont->push_back(HODataFrame(HcalDetId(did)));
0620 ptr_header = HcalUnpacker_impl::unpack_compact<HODataFrame>(ptr_header,
0621 ptr_end,
0622 colls.hoCont->back(),
0623 nps,
0624 eid,
0625 startSample_,
0626 endSample_,
0627 expectedOrbitMessageTime_,
0628 htr);
0629 } break;
0630 case (HcalForward): {
0631 colls.hfCont->push_back(HFDataFrame(HcalDetId(did)));
0632 ptr_header = HcalUnpacker_impl::unpack_compact<HFDataFrame>(ptr_header,
0633 ptr_end,
0634 colls.hfCont->back(),
0635 nps,
0636 eid,
0637 startSample_,
0638 endSample_,
0639 expectedOrbitMessageTime_,
0640 htr);
0641 } break;
0642 case (HcalOther): {
0643 HcalOtherDetId odid(did);
0644 if (odid.subdet() == HcalCalibration) {
0645 colls.calibCont->push_back(HcalCalibDataFrame(HcalCalibDetId(did)));
0646 ptr_header = HcalUnpacker_impl::unpack_compact<HcalCalibDataFrame>(ptr_header,
0647 ptr_end,
0648 colls.calibCont->back(),
0649 nps,
0650 eid,
0651 startSample_,
0652 endSample_,
0653 expectedOrbitMessageTime_,
0654 htr);
0655 }
0656 } break;
0657 case (HcalEmpty):
0658 default: {
0659 for (ptr_header++; ptr_header != ptr_end && !HcalHTRData::is_channel_header(*ptr_header); ptr_header++)
0660 ;
0661 } break;
0662 }
0663 }
0664 } else {
0665 report.countUnmappedDigi(eid);
0666 if (unknownIds_.find(eid) == unknownIds_.end()) {
0667 if (!silent)
0668 edm::LogWarning("HCAL") << "HcalUnpacker: No match found for electronics id :" << eid;
0669 unknownIds_.insert(eid);
0670 }
0671 for (ptr_header++; ptr_header != ptr_end && !HcalHTRData::is_channel_header(*ptr_header); ptr_header++)
0672 ;
0673 }
0674 }
0675 }
0676 }
0677 }
0678
0679 void HcalUnpacker::unpackUTCA(const FEDRawData& raw,
0680 const HcalElectronicsMap& emap,
0681 Collections& colls,
0682 HcalUnpackerReport& report,
0683 bool silent) {
0684 const hcal::AMC13Header* amc13 = (const hcal::AMC13Header*)(raw.data());
0685
0686
0687 int namc = amc13->NAMC();
0688 for (int iamc = 0; iamc < namc; iamc++) {
0689
0690 if (!amc13->AMCEnabled(iamc))
0691 continue;
0692
0693 if (!amc13->AMCDataPresent(iamc)) {
0694 if (!silent)
0695 edm::LogWarning("Invalid Data") << "Missing data observed on iamc " << iamc << " of AMC13 with source id "
0696 << amc13->sourceId();
0697 report.countSpigotFormatError();
0698 continue;
0699 }
0700 if (!amc13->AMCCRCOk(iamc)) {
0701 if (!silent)
0702 edm::LogWarning("Invalid Data") << "CRC Error on uHTR data observed on iamc " << iamc
0703 << " of AMC13 with source id " << amc13->sourceId();
0704 report.countSpigotFormatError();
0705
0706 }
0707
0708 if (amc13->AMCSegmented(iamc)) {
0709 if (!silent)
0710 edm::LogWarning("Invalid Data") << "Unpacker cannot handle segmented data observed on iamc " << iamc
0711 << " of AMC13 with source id " << amc13->sourceId();
0712 report.countSpigotFormatError();
0713 continue;
0714 }
0715
0716 if (!amc13->AMCLengthOk(iamc)) {
0717 if (!silent)
0718 edm::LogWarning("Invalid Data") << "Length mismatch between uHTR and AMC13 observed on iamc " << iamc
0719 << " of AMC13 with source id " << amc13->sourceId();
0720 report.countSpigotFormatError();
0721 continue;
0722 }
0723
0724
0725 int slot = amc13->AMCSlot(iamc);
0726 int crate = amc13->AMCId(iamc) & 0xFF;
0727
0728 HcalUHTRData uhtr(amc13->AMCPayload(iamc), amc13->AMCSize(iamc));
0729
0730 if (uhtr.getFormatVersion() != 1) {
0731 unpackUMNio(raw, slot, colls);
0732 continue;
0733 }
0734 #ifdef DebugLog
0735
0736 int nwords = uhtr.getRawLengthBytes() / 2;
0737 for (int iw = 0; iw < nwords; iw++)
0738 printf("%04d %04x\n", iw, uhtr.getRawData16()[iw]);
0739 #endif
0740
0741
0742 int nps = uhtr.presamples();
0743
0744 HcalUHTRData::const_iterator i = uhtr.begin(), iend = uhtr.end();
0745 while (i != iend) {
0746 #ifdef DebugLog
0747 std::cout << "This data is flavored:" << i.flavor() << std::endl;
0748 #endif
0749
0750 if (!i.isHeader()) {
0751 ++i;
0752 #ifdef DebugLog
0753 std::cout << "its not a header" << std::endl;
0754 #endif
0755 continue;
0756 }
0757
0758 if (i.flavor() == 1 || i.flavor() == 0 || i.flavor() == 3) {
0759 int ifiber = ((i.channelid() >> 3) & 0x1F);
0760 int ichan = (i.channelid() & 0x7);
0761 HcalElectronicsId eid(crate, slot, ifiber, ichan, false);
0762 DetId did = emap.lookup(eid);
0763
0764 const uint16_t* head_pos = i.raw();
0765 int ns = 0;
0766 for (++i; i != iend && !i.isHeader(); ++i) {
0767 ns++;
0768 }
0769
0770 if (colls.qie11 == nullptr) {
0771 colls.qie11 = new QIE11DigiCollection(ns);
0772 } else if (colls.qie11->samples() != ns) {
0773
0774
0775 if (colls.qie11Addtl.find(ns) == colls.qie11Addtl.end()) {
0776 printInvalidDataMessage("QIE11", colls.qie11->samples(), ns, true);
0777 }
0778 }
0779
0780
0781
0782 if (!did.null()) {
0783
0784 if (colls.qie11->samples() == ns) {
0785 colls.qie11->addDataFrame(did, head_pos);
0786 }
0787
0788 if (colls.qie11Addtl.find(ns) != colls.qie11Addtl.end()) {
0789 colls.qie11Addtl[ns]->addDataFrame(did, head_pos);
0790 }
0791 } else {
0792 report.countUnmappedDigi(eid);
0793 if (unknownIds_.find(eid) == unknownIds_.end()) {
0794 if (!silent)
0795 edm::LogWarning("HCAL") << "HcalUnpacker: No match found for electronics id :" << eid;
0796 unknownIds_.insert(eid);
0797 #ifdef DebugLog
0798 std::cout << "HcalUnpacker: No match found for electronics id :" << eid << std::endl;
0799 #endif
0800 }
0801 #ifdef DebugLog
0802 std::cout << "OH NO! detector id is null!" << std::endl;
0803 #endif
0804 }
0805 } else if (i.flavor() == 2) {
0806
0807
0808 int ifiber = ((i.channelid() >> 3) & 0x1F);
0809 int ichan = (i.channelid() & 0x7);
0810 HcalElectronicsId eid(crate, slot, ifiber, ichan, false);
0811 DetId did = emap.lookup(eid);
0812
0813
0814 const uint16_t* head_pos = i.raw();
0815 int ns = 0;
0816 for (++i; i != iend && !i.isHeader(); ++i) {
0817 ns++;
0818 }
0819
0820 bool isZDC = (did.det() == DetId::Calo && did.subdetId() == HcalZDCDetId::SubdetectorId);
0821 bool isLasmon = (did.det() == DetId::Hcal && (HcalSubdetector)did.subdetId() == HcalOther &&
0822 HcalCalibDetId(did).calibFlavor() == 5);
0823
0824 if (isZDC) {
0825 if (colls.qie10ZDC == nullptr) {
0826 colls.qie10ZDC = new QIE10DigiCollection(ns);
0827 } else if (colls.qie10ZDC->samples() != ns) {
0828 printInvalidDataMessage("QIE10ZDC", colls.qie10ZDC->samples(), ns, false);
0829 }
0830 } else if (isLasmon) {
0831 if (colls.qie10Lasermon == nullptr) {
0832 colls.qie10Lasermon = new QIE10DigiCollection(ns);
0833 } else if (colls.qie10Lasermon->samples() != ns) {
0834 printInvalidDataMessage("QIE10LASMON", colls.qie10Lasermon->samples(), ns, false);
0835 }
0836 } else {
0837 if (colls.qie10 == nullptr) {
0838 colls.qie10 = new QIE10DigiCollection(ns);
0839 } else if (colls.qie10->samples() != ns) {
0840
0841
0842 if (colls.qie10Addtl.find(ns) == colls.qie10Addtl.end()) {
0843 printInvalidDataMessage("QIE10", colls.qie10->samples(), ns, true);
0844 }
0845 }
0846 }
0847
0848
0849
0850 if (!did.null()) {
0851
0852 if (isZDC)
0853 colls.qie10ZDC->addDataFrame(did, head_pos);
0854 else if (isLasmon)
0855 colls.qie10Lasermon->addDataFrame(did, head_pos);
0856 else {
0857
0858 if (colls.qie10->samples() == ns) {
0859 colls.qie10->addDataFrame(did, head_pos);
0860 }
0861
0862
0863 if (colls.qie10Addtl.find(ns) != colls.qie10Addtl.end()) {
0864 colls.qie10Addtl[ns]->addDataFrame(did, head_pos);
0865 }
0866 }
0867 } else {
0868 report.countUnmappedDigi(eid);
0869 if (unknownIds_.find(eid) == unknownIds_.end()) {
0870 if (!silent)
0871 edm::LogWarning("HCAL") << "HcalUnpacker: No match found for electronics id :" << eid;
0872 unknownIds_.insert(eid);
0873 #ifdef DebugLog
0874 std::cout << "HcalUnpacker: No match found for electronics id :" << eid << std::endl;
0875 #endif
0876 }
0877 #ifdef DebugLog
0878 std::cout << "OH NO! HcalUnpacker: No match found for electronics id :" << eid << std::endl;
0879 #endif
0880 }
0881 } else if (i.flavor() == 5 || (i.flavor() == 7 && i.technicalDataType() == 15)) {
0882 int ifiber = ((i.channelid() >> 2) & 0x1F);
0883 int ichan = (i.channelid() & 0x3);
0884 HcalElectronicsId eid(crate, slot, ifiber, ichan, false);
0885 DetId did = emap.lookup(eid);
0886
0887 if (!did.null()) {
0888 if (did.det() == DetId::Calo && did.subdetId() == HcalZDCDetId::SubdetectorId) {
0889 colls.zdcCont->push_back(ZDCDataFrame(HcalZDCDetId(did)));
0890 HcalUnpacker_impl::unpack_compact<ZDCDataFrame>(
0891 i, iend, colls.zdcCont->back(), nps, eid, startSample_, endSample_);
0892 } else if (did.det() == DetId::Hcal) {
0893 switch (((HcalSubdetector)did.subdetId())) {
0894 case (HcalBarrel):
0895 case (HcalEndcap): {
0896 colls.hbheCont->push_back(HBHEDataFrame(HcalDetId(did)));
0897 HcalUnpacker_impl::unpack_compact<HBHEDataFrame>(
0898 i, iend, colls.hbheCont->back(), nps, eid, startSample_, endSample_);
0899 } break;
0900 case (HcalOuter): {
0901 colls.hoCont->push_back(HODataFrame(HcalDetId(did)));
0902 HcalUnpacker_impl::unpack_compact<HODataFrame>(
0903 i, iend, colls.hoCont->back(), nps, eid, startSample_, endSample_);
0904 } break;
0905 case (HcalForward): {
0906 colls.hfCont->push_back(HFDataFrame(HcalDetId(did)));
0907 HcalUnpacker_impl::unpack_compact<HFDataFrame>(
0908 i, iend, colls.hfCont->back(), nps, eid, startSample_, endSample_);
0909 } break;
0910 case (HcalOther): {
0911 HcalOtherDetId odid(did);
0912 if (odid.subdet() == HcalCalibration) {
0913 colls.calibCont->push_back(HcalCalibDataFrame(HcalCalibDetId(did)));
0914 HcalUnpacker_impl::unpack_compact<HcalCalibDataFrame>(
0915 i, iend, colls.calibCont->back(), nps, eid, startSample_, endSample_);
0916 }
0917 } break;
0918 case (HcalEmpty):
0919 default: {
0920 for (++i; i != iend && !i.isHeader(); ++i)
0921 ;
0922 } break;
0923 }
0924 }
0925 } else {
0926 report.countUnmappedDigi(eid);
0927 if (unknownIds_.find(eid) == unknownIds_.end()) {
0928 if (!silent)
0929 edm::LogWarning("HCAL") << "HcalUnpacker: No match found for electronics id :" << eid;
0930 unknownIds_.insert(eid);
0931 }
0932 for (++i; i != iend && !i.isHeader(); ++i)
0933 ;
0934 }
0935 } else if (i.flavor() == 0x4) {
0936 int ilink = ((i.channelid() >> 4) & 0xF);
0937 int itower = (i.channelid() & 0xF);
0938 HcalElectronicsId eid(crate, slot, ilink, itower, true);
0939 DetId did = emap.lookupTrigger(eid);
0940 #ifdef DebugLog
0941 std::cout << "Unpacking " << eid << " " << i.channelid() << std::endl;
0942 #endif
0943 if (did.null()) {
0944 report.countUnmappedTPDigi(eid);
0945 if (unknownIdsTrig_.find(eid) == unknownIdsTrig_.end()) {
0946 if (!silent)
0947 edm::LogWarning("HCAL") << "HcalUnpacker: No trigger primitive match found for electronics id :" << eid;
0948 unknownIdsTrig_.insert(eid);
0949 }
0950
0951 for (++i; i != iend && !i.isHeader(); ++i)
0952 ;
0953 } else if (did == HcalTrigTowerDetId::Undefined || (did.det() == DetId::Hcal && did.subdetId() == 0)) {
0954 for (++i; i != iend && !i.isHeader(); ++i)
0955 ;
0956 } else {
0957 HcalTrigTowerDetId id(did);
0958 #ifdef DebugLog
0959 std::cout << "Unpacking " << id << std::endl;
0960 #endif
0961 colls.tpCont->push_back(HcalTriggerPrimitiveDigi(id));
0962 int j = 0;
0963 for (++i; i != iend && !i.isHeader(); ++i) {
0964 colls.tpCont->back().setSample(j, i.value());
0965 if (i.soi())
0966 colls.tpCont->back().setPresamples(j);
0967 j++;
0968 }
0969 colls.tpCont->back().setSize(j);
0970 }
0971 } else {
0972
0973 for (++i; i != iend && !i.isHeader(); ++i)
0974 ;
0975 }
0976 }
0977 }
0978 }
0979
0980 HcalUnpacker::Collections::Collections() {
0981 hbheCont = nullptr;
0982 hoCont = nullptr;
0983 hfCont = nullptr;
0984 tpCont = nullptr;
0985 zdcCont = nullptr;
0986 calibCont = nullptr;
0987 ttp = nullptr;
0988 qie10 = nullptr;
0989 qie10ZDC = nullptr;
0990 qie10Lasermon = nullptr;
0991 qie11 = nullptr;
0992 umnio = nullptr;
0993 }
0994
0995 void HcalUnpacker::unpack(const FEDRawData& raw,
0996 const HcalElectronicsMap& emap,
0997 std::vector<HcalHistogramDigi>& histoDigis) {
0998
0999 const HcalDCCHeader* dccHeader = (const HcalDCCHeader*)(raw.data());
1000 int dccid = dccHeader->getSourceId() - sourceIdOffset_;
1001
1002
1003
1004
1005 HcalHTRData htr;
1006 for (int spigot = 0; spigot < HcalDCCHeader::SPIGOT_COUNT; spigot++) {
1007 if (!dccHeader->getSpigotPresent(spigot))
1008 continue;
1009
1010 int retval = dccHeader->getSpigotData(spigot, htr, raw.size());
1011
1012 if (retval || !htr.check()) {
1013 edm::LogWarning("Invalid Data") << "Invalid HTR data observed on spigot " << spigot << " of DCC with source id "
1014 << dccHeader->getSourceId();
1015 continue;
1016 }
1017 if (!htr.isHistogramEvent()) {
1018 edm::LogWarning("Invalid Data") << "Non-histogram data passed to histogram unpacker on spigot " << spigot
1019 << " of DCC with source id " << dccHeader->getSourceId();
1020 continue;
1021 }
1022
1023 unsigned int smid = htr.getSubmodule();
1024 int htr_tb = smid & 0x1;
1025 int htr_slot = (smid >> 1) & 0x1F;
1026 int htr_cr = (smid >> 6) & 0x1F;
1027
1028
1029 int f[2], fc;
1030 htr.getHistogramFibers(f[0], f[1]);
1031
1032 for (int nf = 0; nf < 2; nf++) {
1033 if (f[nf] < 0 || (nf == 1 && f[0] == f[1]))
1034 continue;
1035 for (fc = 0; fc <= 2; fc++) {
1036 HcalElectronicsId eid(fc, f[nf], spigot, dccid);
1037 eid.setHTR(htr_cr, htr_slot, htr_tb);
1038 DetId did = emap.lookup(eid);
1039
1040 if (did.null() || did.det() != DetId::Hcal || did.subdetId() == 0) {
1041 if (unknownIds_.find(eid) == unknownIds_.end()) {
1042 edm::LogWarning("HCAL") << "HcalHistogramUnpacker: No match found for electronics id :" << eid;
1043 unknownIds_.insert(eid);
1044 }
1045 continue;
1046 }
1047 histoDigis.push_back(HcalHistogramDigi(HcalDetId(did)));
1048 HcalHistogramDigi& digi = histoDigis.back();
1049
1050
1051 for (int capid = 0; capid < 4; capid++)
1052 htr.unpackHistogram(f[nf], fc, capid, digi.getArray(capid));
1053 }
1054 }
1055 }
1056 }
1057
1058 void HcalUnpacker::unpackUMNio(const FEDRawData& raw, int slot, Collections& colls) {
1059 const hcal::AMC13Header* amc13 = (const hcal::AMC13Header*)(raw.data());
1060 int namc = amc13->NAMC();
1061
1062 for (int iamc = 0; iamc < namc; iamc++) {
1063 if (amc13->AMCSlot(iamc) == slot)
1064 namc = iamc;
1065 }
1066 if (namc == amc13->NAMC()) {
1067 return;
1068 }
1069 const uint16_t* data = (const uint16_t*)(amc13->AMCPayload(namc));
1070 size_t nwords = amc13->AMCSize(namc) * (sizeof(uint64_t) / sizeof(uint16_t));
1071 *(colls.umnio) = HcalUMNioDigi(data, nwords);
1072 }
1073
1074 void HcalUnpacker::printInvalidDataMessage(const std::string& coll_type,
1075 int default_ns,
1076 int conflict_ns,
1077 bool extended) {
1078 nPrinted_++;
1079
1080 constexpr int limit = 2;
1081 if (nPrinted_ >= limit) {
1082 if (nPrinted_ == limit)
1083 edm::LogInfo("Invalid Data") << "Suppressing further error messages";
1084
1085 return;
1086 }
1087
1088 std::stringstream message;
1089
1090 message << "The default " << coll_type << " Collection has " << default_ns
1091 << " samples per digi, while the current data has " << conflict_ns
1092 << "! This data cannot be included with the default collection.";
1093
1094 if (extended) {
1095 message << "\nIn order to store this data in the event, it must have a unique tag. "
1096 << "To accomplish this, provide two lists to HcalRawToDigi \n"
1097 << "1) that specifies the number of samples and "
1098 << "2) that gives tags with which these data are saved.\n"
1099 << "For example in this case you might add \n"
1100 << "process.hcalDigis.save" << coll_type << "DataNSamples = cms.untracked.vint32( " << conflict_ns
1101 << ") \nprocess.hcalDigis.save" << coll_type << "DataTags = cms.untracked.vstring( \"MYDATA\" )";
1102 }
1103
1104 edm::LogWarning("Invalid Data") << message.str();
1105 }