File indexing completed on 2024-09-07 04:36:12
0001
0002
0003
0004
0005 #ifndef HTBDAQ_DATA_STANDALONE
0006 #include "EventFilter/HcalRawToDigi/interface/HcalHTRData.h"
0007 #else
0008 #include "HcalHTRData.h"
0009 const int HcalHTRData::CHANNELS_PER_SPIGOT = 24;
0010 const int HcalHTRData::MAXIMUM_SAMPLES_PER_CHANNEL = 20;
0011 #endif
0012 #include <cstring>
0013 #include <cstdio>
0014
0015 HcalHTRData::HcalHTRData() : m_formatVersion(-2), m_rawLength(0), m_rawConst(nullptr), m_ownData(nullptr) {}
0016 HcalHTRData::HcalHTRData(const unsigned short* data, int length) {
0017 adoptData(data, length);
0018 m_ownData = nullptr;
0019 }
0020 HcalHTRData::HcalHTRData(const HcalHTRData& hd)
0021 : m_formatVersion(hd.m_formatVersion), m_rawLength(hd.m_rawLength), m_rawConst(hd.m_rawConst), m_ownData(nullptr) {}
0022
0023 HcalHTRData::HcalHTRData(int version_to_create) : m_formatVersion(version_to_create) { allocate(version_to_create); }
0024
0025 void HcalHTRData::allocate(int version_to_create) {
0026 m_formatVersion = version_to_create;
0027
0028 const int needed = 0x200;
0029
0030 m_ownData = new unsigned short[needed];
0031
0032 memset(m_ownData, 0, sizeof(unsigned short) * needed);
0033 m_rawLength = 0;
0034 m_rawConst = m_ownData;
0035 }
0036
0037 HcalHTRData& HcalHTRData::operator=(const HcalHTRData& hd) {
0038 if (m_ownData == nullptr) {
0039 m_formatVersion = hd.m_formatVersion;
0040 m_rawLength = hd.m_rawLength;
0041 m_rawConst = hd.m_rawConst;
0042 }
0043 return (*this);
0044 }
0045
0046 void HcalHTRData::adoptData(const unsigned short* data, int length) {
0047 m_rawLength = length;
0048 m_rawConst = data;
0049 if (m_rawLength < 5) {
0050 m_formatVersion = -2;
0051 } else {
0052
0053 if ((m_rawConst[2] & 0x8000) == 0)
0054 m_formatVersion = -1;
0055 else
0056 m_formatVersion = (m_rawConst[4] >> 12) & 0xF;
0057 }
0058 }
0059
0060
0061
0062
0063 bool HcalHTRData::check() const {
0064 if (m_formatVersion == -1) {
0065
0066
0067 if (m_rawLength < 6 + 12)
0068 return false;
0069
0070 if (m_rawLength != m_rawConst[m_rawLength - 3])
0071 return false;
0072
0073 if (m_rawConst[2] & 0x20)
0074 return false;
0075 } else {
0076
0077
0078 if (m_rawLength < 8 + 4)
0079 return false;
0080 if (m_formatVersion <= 3) {
0081
0082 if (m_rawLength != m_rawConst[m_rawLength - 3]) {
0083 if (isHistogramEvent() && m_rawConst[m_rawLength - 3] == 786) {
0084
0085 } else
0086 return false;
0087 }
0088 } else {
0089
0090 }
0091
0092 if (m_rawConst[2] & 0x4)
0093 return false;
0094 }
0095
0096 if (!isHistogramEvent()) {
0097
0098 int tp, daq, header, trailer;
0099 determineSectionLengths(tp, daq, header, trailer);
0100 if (tp + daq + header + trailer > m_rawLength)
0101 return false;
0102 }
0103
0104 return true;
0105 }
0106
0107 bool HcalHTRData::isEmptyEvent() const {
0108 if (m_formatVersion == -1) {
0109 return (m_rawConst[2] & 0x20) != 0;
0110 } else {
0111 return (m_rawConst[2] & 0x4) != 0;
0112 }
0113 }
0114
0115 bool HcalHTRData::isOverflowWarning() const {
0116 if (m_formatVersion == -1) {
0117 return false;
0118 } else {
0119 return (m_rawConst[2] & 0x1) != 0;
0120 }
0121 }
0122
0123 bool HcalHTRData::isBusy() const {
0124 if (m_formatVersion == -1) {
0125 return false;
0126 } else {
0127 return (m_rawConst[2] & 0x2) != 0;
0128 }
0129 }
0130
0131 void HcalHTRData::determineSectionLengths(int& tpWords, int& daqWords, int& headerWords, int& trailerWords) const {
0132 if (m_formatVersion == -1) {
0133 tpWords = m_rawConst[5] >> 8;
0134 daqWords = CHANNELS_PER_SPIGOT * (m_rawConst[m_rawLength - 4] >> 8);
0135 headerWords = 6;
0136 trailerWords = 12;
0137 } else {
0138 tpWords = m_rawConst[5] >> 8;
0139 if (m_rawLength > 4)
0140 daqWords = m_rawConst[m_rawLength - 4] & 0x7FF;
0141 else
0142 daqWords = 0;
0143 headerWords = 8;
0144 trailerWords = 4;
0145 }
0146 }
0147
0148 void HcalHTRData::determineStaticLengths(int& headerWords, int& trailerWords) const {
0149 if (m_formatVersion == -1) {
0150 headerWords = 6;
0151 trailerWords = 12;
0152 } else if (m_formatVersion < 5) {
0153 headerWords = 8;
0154 trailerWords = 4;
0155 } else {
0156 headerWords = 8;
0157 trailerWords = 12;
0158 }
0159 }
0160
0161 void HcalHTRData::dataPointers(const unsigned short** daq_first,
0162 const unsigned short** daq_last,
0163 const unsigned short** tp_first,
0164 const unsigned short** tp_last) const {
0165 int tp_words_total, daq_words_total, headerLen, trailerLen;
0166 determineSectionLengths(tp_words_total, daq_words_total, headerLen, trailerLen);
0167
0168 *tp_first = m_rawConst + headerLen;
0169 *tp_last = *tp_first + (tp_words_total - 1);
0170 *daq_first = *tp_last + 1;
0171 *daq_last = *daq_first + (daq_words_total - 1);
0172 }
0173
0174
0175 static const int channelDecoder[32] = {0, 1, 2, 99, 3, 4, 5, 99, 6, 7, 8, 99, 9, 10, 11, 99,
0176 12, 13, 14, 99, 15, 16, 17, 99, 18, 19, 20, 99, 21, 22, 23, 99};
0177
0178 void HcalHTRData::unpack(unsigned char* daq_lengths,
0179 unsigned short* daq_samples,
0180 unsigned char* tp_lengths,
0181 unsigned short* tp_samples) const {
0182 if (daq_lengths != nullptr)
0183 memset(daq_lengths, 0, CHANNELS_PER_SPIGOT);
0184 if (tp_lengths != nullptr)
0185 memset(tp_lengths, 0, CHANNELS_PER_SPIGOT);
0186
0187
0188
0189
0190
0191 int tp_words_total, daq_words_total, headerLen, trailerLen;
0192 determineSectionLengths(tp_words_total, daq_words_total, headerLen, trailerLen);
0193
0194
0195 int wordPtr;
0196 const unsigned short* tpBase = m_rawConst + headerLen;
0197
0198 if (tp_lengths != nullptr) {
0199 for (wordPtr = 0; wordPtr < tp_words_total; wordPtr++) {
0200 int ichan = channelDecoder[tpBase[wordPtr] >> 11];
0201 if (ichan >= 24)
0202 continue;
0203 tp_samples[ichan * MAXIMUM_SAMPLES_PER_CHANNEL + tp_lengths[ichan]] = tpBase[wordPtr] & 0x3ff;
0204 tp_lengths[ichan]++;
0205 }
0206 }
0207
0208 const unsigned short* daqBase = m_rawConst + headerLen + tp_words_total;
0209
0210 int lastChan = -1;
0211 int lastCapid = 0;
0212 if (daq_lengths != nullptr) {
0213 for (wordPtr = 0; wordPtr < daq_words_total; wordPtr++) {
0214 int ichan = channelDecoder[daqBase[wordPtr] >> 11];
0215 if (ichan >= 24)
0216 continue;
0217 int capid = (daqBase[wordPtr] & 0x180) >> 7;
0218 int erdv = (daqBase[wordPtr] & 0x600) >> 9;
0219 if (erdv != 0x1 || (lastChan == ichan && (capid != ((lastCapid + 1) % 4)))) {
0220 daq_lengths[ichan] |= 0x80;
0221 }
0222 lastChan = ichan;
0223 lastCapid = capid;
0224
0225 int useLength = daq_lengths[ichan] & 0x1F;
0226
0227 daq_samples[ichan * MAXIMUM_SAMPLES_PER_CHANNEL + useLength] = daqBase[wordPtr] & 0x3ff;
0228 daq_lengths[ichan] = (useLength + 1) | (daq_lengths[ichan] & 0xE0);
0229 }
0230 }
0231 }
0232
0233 void HcalHTRData::pack(unsigned char* daq_lengths,
0234 unsigned short* daq_samples,
0235 unsigned char* tp_lengths,
0236 unsigned short* tp_samples,
0237 bool do_capid) {
0238 int tp_words_total = 0, daq_words_total = 0, headerLen, trailerLen;
0239 determineStaticLengths(headerLen, trailerLen);
0240
0241 tp_words_total = 0;
0242 daq_words_total = 0;
0243 int ichan, isample;
0244
0245
0246 unsigned short* ptr = m_ownData + headerLen;
0247 if (tp_samples != nullptr && tp_lengths != nullptr) {
0248 for (ichan = 0; ichan < 24; ichan++) {
0249 unsigned short chanid = ((ichan % 4) + (((ichan / 4) + 1) << 2)) << 11;
0250 for (isample = 0; isample < tp_lengths[ichan] && isample < MAXIMUM_SAMPLES_PER_CHANNEL; isample++) {
0251 ptr[tp_words_total] = chanid | (tp_samples[ichan * MAXIMUM_SAMPLES_PER_CHANNEL + isample] & 0x3FF);
0252 tp_words_total++;
0253 }
0254 }
0255 }
0256
0257
0258 ptr = m_ownData + headerLen + tp_words_total;
0259 for (ichan = 0; ichan < 24; ichan++) {
0260 unsigned short chanid = ((ichan % 3) + ((ichan / 3) << 2)) << 11;
0261 for (isample = 0; isample < daq_lengths[ichan] && isample < MAXIMUM_SAMPLES_PER_CHANNEL; isample++) {
0262 unsigned short basedata = daq_samples[ichan * MAXIMUM_SAMPLES_PER_CHANNEL + isample] & 0x7FF;
0263 if (do_capid)
0264 basedata = (basedata & 0x7F) | (0x200) | ((isample % 4) << 7);
0265 ptr[daq_words_total] = chanid | basedata;
0266 daq_words_total++;
0267 }
0268 }
0269 unsigned short totalLen;
0270 if (m_formatVersion == -1) {
0271 m_ownData[5] = (tp_words_total << 8) | 0x1;
0272 totalLen = headerLen + tp_words_total + daq_words_total + trailerLen;
0273 m_rawLength = totalLen;
0274 m_ownData[totalLen - 3] = totalLen;
0275 m_ownData[totalLen - 4] = (tp_words_total / CHANNELS_PER_SPIGOT) | ((daq_words_total / CHANNELS_PER_SPIGOT) << 8);
0276 } else {
0277 m_ownData[5] = (tp_words_total << 8) | 0x1;
0278 totalLen = headerLen + tp_words_total + daq_words_total + trailerLen;
0279 if ((totalLen % 2) == 1) {
0280 m_ownData[totalLen - 4] = 0xFFFF;
0281 totalLen++;
0282 }
0283 m_rawLength = totalLen;
0284 m_ownData[totalLen - 2] = totalLen / 2;
0285 m_ownData[totalLen - 3] = totalLen;
0286 m_ownData[totalLen - 4] = daq_words_total;
0287 }
0288 if (trailerLen == 12) {
0289 for (int i = 12; i > 4; i--)
0290 m_ownData[totalLen - i] = 0;
0291 }
0292 }
0293
0294 void HcalHTRData::packHeaderTrailer(int L1Anumber,
0295 int bcn,
0296 int submodule,
0297 int orbitn,
0298 int pipeline,
0299 int ndd,
0300 int nps,
0301 int firmwareRev,
0302 int firmwareFlav) {
0303 m_ownData[0] = L1Anumber & 0xFF;
0304 m_ownData[1] = (L1Anumber & 0xFFFF00) >> 8;
0305 if (m_formatVersion == -1) {
0306 m_ownData[2] = ((pipeline & 0x7F) << 8);
0307 m_ownData[3] = ((orbitn & 0xFF) << 8) | (submodule & 0xFF);
0308 m_ownData[4] = bcn & 0xFFF;
0309
0310 } else {
0311 m_ownData[2] = 0x8000;
0312 if (m_formatVersion == 0)
0313 m_ownData[3] = ((orbitn & 0x3F) << 10) | (submodule & 0x3FF);
0314 else
0315 m_ownData[3] = ((orbitn & 0x1F) << 11) | (submodule & 0x7FF);
0316 m_ownData[4] = ((m_formatVersion & 0xF) << 12) | (bcn & 0xFFF);
0317 m_ownData[5] |= ((nps & 0x1F) << 3) | 0x1;
0318 m_ownData[6] = ((firmwareRev & 0x70000) >> 3) | (firmwareRev & 0x1FFF);
0319 m_ownData[7] = (pipeline & 0xFF) | ((firmwareFlav & 0x3F) << 8);
0320 m_ownData[m_rawLength - 4] &= 0x7FF;
0321 m_ownData[m_rawLength - 4] |= (ndd & 0x1F) << 11;
0322 }
0323 m_ownData[m_rawLength - 2] = m_rawLength / 2;
0324 m_ownData[m_rawLength - 1] = (L1Anumber & 0xFF) << 8;
0325 }
0326
0327 void HcalHTRData::packUnsuppressed(const bool* mp) {
0328 if (m_formatVersion < 4)
0329 return;
0330
0331 for (int fiber = 1; fiber <= 8; fiber++) {
0332 for (int fiberchan = 0; fiberchan <= 2; fiberchan++) {
0333 int linchan = (fiber - 1) * 3 + fiberchan;
0334
0335 unsigned short& val = m_ownData[m_rawLength - 12 + (linchan / 8)];
0336 if (mp[linchan])
0337 val |= 1 << (linchan % 8);
0338 }
0339 }
0340
0341
0342 m_ownData[6] |= 0x8000;
0343 }
0344
0345 unsigned int HcalHTRData::getOrbitNumber() const {
0346 switch (m_formatVersion) {
0347 case (-1):
0348 return (m_rawConst[3] >> 8);
0349 case (0):
0350 return (m_rawConst[3] >> 10);
0351 default:
0352 return (m_rawConst[3] >> 11);
0353 }
0354 }
0355 unsigned int HcalHTRData::getSubmodule() const {
0356 switch (m_formatVersion) {
0357 case (-1):
0358 return (m_rawConst[3] & 0xFF);
0359 case (0):
0360 return (m_rawConst[3] & 0x3FF);
0361 default:
0362 return (m_rawConst[3] & 0x7FF);
0363 }
0364 }
0365 unsigned int HcalHTRData::htrSlot() const {
0366 const unsigned int smid = getSubmodule();
0367 return ((smid >> 1) & 0x1F);
0368 }
0369 unsigned int HcalHTRData::htrTopBottom() const {
0370 const unsigned int smid = getSubmodule();
0371 return (smid & 0x01);
0372 }
0373 unsigned int HcalHTRData::readoutVMECrateId() const {
0374 const unsigned int smid = getSubmodule();
0375 return ((smid >> 6) & 0x1F);
0376 }
0377 bool HcalHTRData::isCalibrationStream() const { return (m_formatVersion == -1) ? (false) : (m_rawConst[2] & 0x4000); }
0378 bool HcalHTRData::isUnsuppressed() const { return (m_formatVersion < 4) ? (false) : (m_rawConst[6] & 0x8000); }
0379 bool HcalHTRData::wasMarkAndPassZS(int fiber, int fiberchan) const {
0380 if (fiber < 1 || fiber > 8 || fiberchan < 0 || fiberchan > 2)
0381 return false;
0382 if (!isUnsuppressed() || m_formatVersion < 5)
0383 return false;
0384 int linchan = (fiber - 1) * 3 + fiberchan;
0385
0386 unsigned short val = m_rawConst[m_rawLength - 12 + (linchan / 8)];
0387 return ((val >> (linchan % 8)) & 0x1) != 0;
0388 }
0389 bool HcalHTRData::wasMarkAndPassZSTP(int slb, int slbchan) const {
0390 if (slb < 1 || slb > 6 || slbchan < 0 || slbchan > 3)
0391 return false;
0392 if (!isUnsuppressed() || m_formatVersion < 5)
0393 return false;
0394 int linchan = (slb - 1) * 4 + slbchan;
0395
0396 unsigned short val = m_rawConst[m_rawLength - 12 + (linchan / 8)];
0397 return ((val >> (linchan % 8)) & 0x100) != 0;
0398 }
0399
0400 uint32_t HcalHTRData::zsBunchMask() const {
0401 uint32_t mask = 0;
0402 if (isUnsuppressed() && m_formatVersion >= 5) {
0403 mask = m_rawConst[m_rawLength - 5] | ((m_rawConst[m_rawLength - 6] & 0xF000) << 4);
0404 }
0405 return mask;
0406 }
0407
0408 bool HcalHTRData::isPatternRAMEvent() const { return (m_formatVersion == -1) ? (false) : (m_rawConst[2] & 0x1000); }
0409 bool HcalHTRData::isHistogramEvent() const {
0410 return (m_formatVersion == -1) ? (m_rawConst[2] & 0x2) : (m_rawConst[2] & 0x2000);
0411 }
0412 int HcalHTRData::getNDD() const {
0413 return (m_formatVersion == -1) ? (m_rawConst[m_rawLength - 4] >> 8) : (m_rawConst[m_rawLength - 4] >> 11);
0414 }
0415 int HcalHTRData::getNTP() const {
0416 int retval = -1;
0417 if (m_formatVersion == -1)
0418 retval = m_rawConst[m_rawLength - 4] & 0xFF;
0419 else if (m_formatVersion < 3)
0420 retval = m_rawConst[m_rawLength - 4] >> 11;
0421 return retval;
0422 }
0423 int HcalHTRData::getNPrecisionWords() const {
0424 return (m_formatVersion == -1) ? (m_rawConst[m_rawLength - 4] & 0xFF) : (m_rawConst[m_rawLength - 4] & 0x7FF);
0425 }
0426 int HcalHTRData::getNPS() const { return (m_formatVersion == -1) ? (0) : ((m_rawConst[5] >> 3) & 0x1F); }
0427 unsigned int HcalHTRData::getPipelineLength() const {
0428 return (m_formatVersion == -1) ? (m_rawConst[2] >> 8) : (m_rawConst[7] & 0xFF);
0429 }
0430 unsigned int HcalHTRData::getFirmwareRevision() const {
0431 return (m_formatVersion == -1) ? (0) : ((m_rawConst[6] & 0x1FFF) + ((m_rawConst[6] & 0xE000) << 3));
0432 }
0433 int HcalHTRData::getFirmwareFlavor() const { return (m_formatVersion < 2) ? (-1) : ((m_rawConst[7] >> 8) & 0xFF); }
0434
0435 void HcalHTRData::getHistogramFibers(int& a, int& b) const {
0436 a = -1;
0437 b = -1;
0438 if (m_formatVersion == -1) {
0439 a = ((m_rawConst[2] & 0x0F00) >> 8);
0440 b = ((m_rawConst[2] & 0xF000) >> 12);
0441 } else {
0442 a = ((m_rawConst[5] & 0x0F00) >> 8) + 1;
0443 b = ((m_rawConst[5] & 0xF000) >> 12) + 1;
0444 }
0445 }
0446
0447 bool HcalHTRData::wasHistogramError(int ifiber) const {
0448 bool retval = !isHistogramEvent();
0449 if (!retval) {
0450 retval = ((m_rawConst[7]) & (1 << ifiber)) != 0;
0451 }
0452 return retval;
0453 }
0454
0455 bool HcalHTRData::unpack_per_channel_header(
0456 unsigned short header, int& flav, int& error_flags, int& capid0, int& channelid) {
0457 flav = (header >> 12) & 0x7;
0458 error_flags = (header >> 10) & 0x3;
0459 capid0 = (header >> 8) & 0x3;
0460 channelid = (header) & 0xFF;
0461 return (header & 0x8000) != 0;
0462 }
0463
0464 bool HcalHTRData::unpackHistogram(int myfiber, int mysc, int capid, unsigned short* histogram) const {
0465
0466 if (!isHistogramEvent())
0467 return false;
0468
0469 int fiber1, fiber2;
0470 getHistogramFibers(fiber1, fiber2);
0471 if (fiber1 != myfiber && fiber2 != myfiber)
0472 return false;
0473
0474 if (m_formatVersion == -1) {
0475 int offset = 6 + mysc * 4 * 32 + capid * 32;
0476 if (myfiber == fiber2)
0477 offset += 3 * 4 * 32;
0478 for (int i = 0; i < 32; i++)
0479 histogram[i] = m_rawConst[offset + i];
0480 return true;
0481 } else {
0482 int offset = 8 + mysc * 4 * 32 + capid * 32;
0483 if (myfiber == fiber2)
0484 offset += 3 * 4 * 32;
0485 for (int i = 0; i < 32; i++)
0486 histogram[i] = m_rawConst[offset + i];
0487 return true;
0488 }
0489 }