File indexing completed on 2023-03-17 10:59:18
0001 #include "EventFilter/CastorRawToDigi/interface/ZdcUnpacker.h"
0002 #include "EventFilter/HcalRawToDigi/interface/HcalUnpacker.h"
0003 #include "EventFilter/HcalRawToDigi/interface/HcalDCCHeader.h"
0004 #include "EventFilter/HcalRawToDigi/interface/HcalHTRData.h"
0005 #include "EventFilter/HcalRawToDigi/interface/HcalTTPUnpacker.h"
0006 #include "DataFormats/HcalDetId/interface/HcalOtherDetId.h"
0007 #include "DataFormats/HcalDigi/interface/HcalQIESample.h"
0008 #include "DataFormats/HcalDigi/interface/ZDCDataFrame.h"
0009 #include "DataFormats/HcalDigi/interface/HcalTriggerPrimitiveSample.h"
0010 #include "EventFilter/HcalRawToDigi/interface/AMC13Header.h"
0011 #include "EventFilter/HcalRawToDigi/interface/HcalDTCHeader.h"
0012 #include <iostream>
0013 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0014 #include <map>
0015
0016 namespace ZdcUnpacker_impl {
0017 template <class DigiClass>
0018 const unsigned short* unpack_compact(const unsigned short* startPoint,
0019 const unsigned short* limit,
0020 DigiClass& digi,
0021 int presamples,
0022 const HcalElectronicsId& eid,
0023 int startSample,
0024 int endSample,
0025 int expectedTime,
0026 const HcalHTRData& hhd) {
0027
0028 digi.setPresamples(presamples);
0029 digi.setReadoutIds(eid);
0030 int flavor, error_flags, capid0, channelid;
0031
0032 HcalHTRData::unpack_per_channel_header(*startPoint, flavor, error_flags, capid0, channelid);
0033 bool isCapRotating = !(error_flags & 0x1);
0034 bool fiberErr = (error_flags & 0x2);
0035 bool dataValid = !(error_flags & 0x2);
0036 int fiberchan = channelid & 0x3;
0037 int fiber = ((channelid >> 2) & 0x7) + 1;
0038
0039 uint32_t zsmask = hhd.zsBunchMask() >> startSample;
0040 digi.setZSInfo(hhd.isUnsuppressed(), hhd.wasMarkAndPassZS(fiber, fiberchan), zsmask);
0041
0042 if (expectedTime >= 0 && !hhd.isUnsuppressed()) {
0043 digi.setFiberIdleOffset(hhd.getFibOrbMsgBCN(fiber) - expectedTime);
0044 }
0045
0046
0047 int ncurr = 0, ntaken = 0;
0048 const unsigned short* qie_work = startPoint;
0049
0050 if (flavor == 5) {
0051 for (qie_work++; qie_work != limit && !HcalHTRData::is_channel_header(*qie_work); qie_work++) {
0052 int capidn = (isCapRotating) ? ((capid0 + ncurr) % 4) : (capid0);
0053 int capidn1 = (isCapRotating) ? ((capid0 + ncurr + 1) % 4) : (capid0);
0054
0055 HcalQIESample s0((*qie_work) & 0x7F, capidn, fiber, fiberchan, dataValid, fiberErr);
0056 HcalQIESample s1(((*qie_work) >> 8) & 0x7F, capidn1, fiber, fiberchan, dataValid, fiberErr);
0057
0058 if (ncurr >= startSample && ncurr <= endSample) {
0059 digi.setSample(ntaken, s0);
0060 ++ntaken;
0061 }
0062 ncurr++;
0063 if (ncurr >= startSample && ncurr <= endSample) {
0064 digi.setSample(ntaken, s1);
0065 ++ntaken;
0066 }
0067 ncurr++;
0068 }
0069 digi.setSize(ntaken);
0070 } else if (flavor == 6) {
0071 for (qie_work++; qie_work != limit && !HcalHTRData::is_channel_header(*qie_work); qie_work++) {
0072 if (ncurr >= startSample && ncurr <= endSample) {
0073 HcalQIESample sample((*qie_work) & 0x7F,
0074 ((*qie_work) >> 8) & 0x3,
0075 fiber,
0076 fiberchan,
0077 ((*qie_work) >> 10) & 0x1,
0078 ((*qie_work) >> 11) & 0x1);
0079 digi.setSample(ntaken, sample);
0080 ++ntaken;
0081 }
0082 ncurr++;
0083 }
0084 digi.setSize(ntaken);
0085 } else {
0086 edm::LogWarning("Bad Data") << "Invalid flavor " << flavor;
0087 qie_work = limit;
0088 }
0089 return qie_work;
0090 }
0091
0092 }
0093
0094 ZdcUnpacker::ZdcUnpacker(int sourceIdOffset, int beg, int end)
0095 : sourceIdOffset_(sourceIdOffset), expectedOrbitMessageTime_(-1) {
0096 if (beg >= 0 && beg <= ZDCDataFrame::MAXSAMPLES - 1) {
0097 startSample_ = beg;
0098 } else {
0099 startSample_ = 0;
0100 }
0101 if (end >= 0 && end <= ZDCDataFrame::MAXSAMPLES - 1 && end >= beg) {
0102 endSample_ = end;
0103 } else {
0104 endSample_ = ZDCDataFrame::MAXSAMPLES - 1;
0105 }
0106 }
0107
0108 void ZdcUnpacker::unpack(const FEDRawData& raw,
0109 const CastorElectronicsMap& emap,
0110 CastorRawCollections& colls,
0111 HcalUnpackerReport& report,
0112 bool silent) {
0113 if (raw.size() < 16) {
0114 if (!silent)
0115 edm::LogWarning("Invalid Data") << "Empty/invalid DCC data, size = " << raw.size();
0116 return;
0117 }
0118
0119
0120 const HcalDCCHeader* dccHeader = (const HcalDCCHeader*)(raw.data());
0121 int dccid = dccHeader->getSourceId() - sourceIdOffset_;
0122
0123
0124 HcalHTRData htr;
0125 const unsigned short *daq_first, *daq_last, *tp_first, *tp_last;
0126 std::map<HcalElectronicsId, DetId> myEMap;
0127
0128
0129
0130 HcalElectronicsId eid = HcalElectronicsId(0, 1, 0, 3);
0131 eid.setHTR(18, 8, 1);
0132 myEMap[eid] = DetId(0x54000051);
0133
0134 eid = HcalElectronicsId(1, 1, 0, 3);
0135 eid.setHTR(18, 8, 1);
0136 myEMap[eid] = DetId(0x54000052);
0137
0138 eid = HcalElectronicsId(2, 1, 0, 3);
0139 eid.setHTR(18, 8, 1);
0140 myEMap[eid] = DetId(0x54000053);
0141
0142 eid = HcalElectronicsId(0, 2, 0, 3);
0143 eid.setHTR(18, 8, 1);
0144 myEMap[eid] = DetId(0x54000061);
0145
0146 eid = HcalElectronicsId(1, 2, 0, 3);
0147 eid.setHTR(18, 8, 1);
0148 myEMap[eid] = DetId(0x54000054);
0149
0150 eid = HcalElectronicsId(2, 2, 0, 3);
0151 eid.setHTR(18, 8, 1);
0152 myEMap[eid] = DetId(0x54000055);
0153
0154 eid = HcalElectronicsId(0, 3, 0, 3);
0155 eid.setHTR(18, 8, 1);
0156 myEMap[eid] = DetId(0x54000062);
0157
0158 eid = HcalElectronicsId(1, 3, 0, 3);
0159 eid.setHTR(18, 8, 1);
0160 myEMap[eid] = DetId(0x54000063);
0161
0162 eid = HcalElectronicsId(2, 3, 0, 3);
0163 eid.setHTR(18, 8, 1);
0164 myEMap[eid] = DetId(0x54000064);
0165
0166
0167 eid = HcalElectronicsId(0, 1, 1, 3);
0168 eid.setHTR(18, 8, 0);
0169 myEMap[eid] = DetId(0x54000011);
0170
0171 eid = HcalElectronicsId(1, 1, 1, 3);
0172 eid.setHTR(18, 8, 0);
0173 myEMap[eid] = DetId(0x54000012);
0174
0175 eid = HcalElectronicsId(2, 1, 1, 3);
0176 eid.setHTR(18, 8, 0);
0177 myEMap[eid] = DetId(0x54000013);
0178
0179 eid = HcalElectronicsId(0, 2, 1, 3);
0180 eid.setHTR(18, 8, 0);
0181 myEMap[eid] = DetId(0x54000015);
0182
0183 eid = HcalElectronicsId(1, 2, 1, 3);
0184 eid.setHTR(18, 8, 0);
0185 myEMap[eid] = DetId(0x54000021);
0186
0187 eid = HcalElectronicsId(2, 2, 1, 3);
0188 eid.setHTR(18, 8, 0);
0189 myEMap[eid] = DetId(0x54000014);
0190
0191 eid = HcalElectronicsId(0, 3, 1, 3);
0192 eid.setHTR(18, 8, 0);
0193 myEMap[eid] = DetId(0x54000022);
0194
0195 eid = HcalElectronicsId(1, 3, 1, 3);
0196 eid.setHTR(18, 8, 0);
0197 myEMap[eid] = DetId(0x54000023);
0198
0199 eid = HcalElectronicsId(2, 3, 1, 3);
0200 eid.setHTR(18, 8, 0);
0201 myEMap[eid] = DetId(0x54000024);
0202
0203 for (int spigot = 0; spigot < HcalDCCHeader::SPIGOT_COUNT; spigot++) {
0204 if (!dccHeader->getSpigotPresent(spigot))
0205 continue;
0206 int retval = dccHeader->getSpigotData(spigot, htr, raw.size());
0207 if (retval != 0) {
0208 if (retval == -1) {
0209 if (!silent)
0210 edm::LogWarning("Invalid Data") << "Invalid HTR data (data beyond payload size) observed on spigot " << spigot
0211 << " of DCC with source id " << dccHeader->getSourceId();
0212 report.countSpigotFormatError();
0213 }
0214 continue;
0215 }
0216
0217 if (dccHeader->getSpigotCRCError(spigot)) {
0218 if (!silent)
0219 edm::LogWarning("Invalid Data") << "CRC Error on HTR data observed on spigot " << spigot
0220 << " of DCC with source id " << dccHeader->getSourceId();
0221 report.countSpigotFormatError();
0222 continue;
0223 }
0224 if (!htr.check()) {
0225 if (!silent)
0226 edm::LogWarning("Invalid Data") << "Invalid HTR data observed on spigot " << spigot << " of DCC with source id "
0227 << dccHeader->getSourceId();
0228 report.countSpigotFormatError();
0229 continue;
0230 }
0231 if (htr.isHistogramEvent()) {
0232 if (!silent)
0233 edm::LogWarning("Invalid Data") << "Histogram data passed to non-histogram unpacker on spigot " << spigot
0234 << " of DCC with source id " << dccHeader->getSourceId();
0235 continue;
0236 }
0237 if ((htr.getFirmwareFlavor() & 0xE0) == 0x80) {
0238 if (colls.ttp != nullptr) {
0239 HcalTTPUnpacker ttpUnpack;
0240 colls.ttp->push_back(HcalTTPDigi());
0241 ttpUnpack.unpack(htr, colls.ttp->back());
0242 } else {
0243 LogDebug("ZdcUnpackerHcalTechTrigProcessor")
0244 << "Skipping data on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId()
0245 << " which is from the TechTrigProcessor (use separate unpacker!)";
0246 }
0247 continue;
0248 }
0249 if (htr.getFirmwareFlavor() >= 0x80) {
0250 if (!silent)
0251 edm::LogWarning("ZdcUnpacker") << "Skipping data on spigot " << spigot << " of DCC with source id "
0252 << dccHeader->getSourceId() << " which is of unknown flavor "
0253 << htr.getFirmwareFlavor();
0254 continue;
0255 }
0256
0257 int nps = htr.getNPS() - startSample_;
0258
0259
0260 htr.dataPointers(&daq_first, &daq_last, &tp_first, &tp_last);
0261 unsigned int smid = htr.getSubmodule();
0262 int htr_tb = smid & 0x1;
0263 int htr_slot = (smid >> 1) & 0x1F;
0264 int htr_cr = (smid >> 6) & 0x1F;
0265
0266 const unsigned short* ptr_header = daq_first;
0267 const unsigned short* ptr_end = daq_last + 1;
0268 int flavor, error_flags, capid0, channelid;
0269
0270 while (ptr_header != ptr_end) {
0271 if (*ptr_header == 0xFFFF) {
0272 ptr_header++;
0273 continue;
0274 }
0275
0276 bool isheader = HcalHTRData::unpack_per_channel_header(*ptr_header, flavor, error_flags, capid0, channelid);
0277 if (!isheader) {
0278 ptr_header++;
0279 continue;
0280 }
0281 int fiberchan = channelid & 0x3;
0282 int fiber = ((channelid >> 2) & 0x7) + 1;
0283
0284
0285 HcalElectronicsId eid(fiberchan, fiber, spigot, dccid);
0286 eid.setHTR(htr_cr, htr_slot, htr_tb);
0287 auto it = myEMap.find(eid);
0288 DetId did;
0289 if (it != myEMap.end()) {
0290 did = it->second;
0291 }
0292
0293 if (!did.null()) {
0294 if (did.det() == DetId::Calo && did.subdetId() == HcalZDCDetId::SubdetectorId) {
0295 colls.zdcCont->push_back(ZDCDataFrame(HcalZDCDetId(did)));
0296 ptr_header = ZdcUnpacker_impl::unpack_compact<ZDCDataFrame>(ptr_header,
0297 ptr_end,
0298 colls.zdcCont->back(),
0299 nps,
0300 eid,
0301 startSample_,
0302 endSample_,
0303 expectedOrbitMessageTime_,
0304 htr);
0305 }
0306 } else {
0307 report.countUnmappedDigi(eid);
0308 for (ptr_header++; ptr_header != ptr_end && !HcalHTRData::is_channel_header(*ptr_header); ptr_header++)
0309 ;
0310 }
0311 }
0312 }
0313 }