File indexing completed on 2024-04-06 12:10:21
0001
0002
0003
0004
0005 #ifndef HTBDAQ_DATA_STANDALONE
0006 #include "EventFilter/CastorRawToDigi/interface/CastorCORData.h"
0007 #else
0008 #include "CastorCORData.h"
0009 #endif
0010 #include <cstring>
0011 #include <iostream>
0012 #include <algorithm>
0013 #include <iomanip>
0014
0015 using namespace std;
0016
0017 const int CastorCORData::CHANNELS_PER_SPIGOT = 36;
0018 const int CastorCORData::MAXIMUM_SAMPLES_PER_CHANNEL = 20;
0019
0020 CastorCORData::CastorCORData() : m_formatVersion(-2), m_rawLength(0), m_rawConst(nullptr), m_ownData(nullptr) {}
0021 CastorCORData::CastorCORData(const unsigned short* data, int length) {
0022 adoptData(data, length);
0023 m_ownData = nullptr;
0024 }
0025 CastorCORData::CastorCORData(const CastorCORData& hd)
0026 : m_formatVersion(hd.m_formatVersion), m_rawLength(hd.m_rawLength), m_rawConst(hd.m_rawConst), m_ownData(nullptr) {}
0027
0028 CastorCORData::CastorCORData(int version_to_create) : m_formatVersion(version_to_create) {
0029 allocate(version_to_create);
0030 }
0031
0032 void CastorCORData::allocate(int version_to_create) {
0033 m_formatVersion = version_to_create;
0034
0035 const int needed = 0x200;
0036
0037 m_ownData = new unsigned short[needed];
0038 m_rawLength = 0;
0039 m_rawConst = m_ownData;
0040 }
0041
0042 CastorCORData& CastorCORData::operator=(const CastorCORData& hd) {
0043 if (m_ownData == nullptr) {
0044 m_formatVersion = hd.m_formatVersion;
0045 m_rawLength = hd.m_rawLength;
0046 m_rawConst = hd.m_rawConst;
0047 }
0048 return (*this);
0049 }
0050
0051 void CastorCORData::adoptData(const unsigned short* data, int length) {
0052 m_rawLength = length;
0053 m_rawConst = data;
0054 if (m_rawLength < 5) {
0055 m_formatVersion = -2;
0056 } else {
0057 m_formatVersion = (m_rawConst[4] >> 12) & 0xF;
0058 }
0059 }
0060
0061
0062
0063
0064 bool CastorCORData::check() const {
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
0074 int tp, daq, header, trailer, trigger;
0075 determineSectionLengths(tp, daq, header, trailer, trigger);
0076 if (trigger + daq + header + trailer > m_rawLength)
0077 return false;
0078
0079 return true;
0080 }
0081
0082 void CastorCORData::determineSectionLengths(
0083 int& tpWords, int& daqWords, int& headerWords, int& trailerWords, int& triggerLen) const {
0084 tpWords = m_rawConst[5] >> 8;
0085 if (m_rawLength > 4)
0086 daqWords = m_rawConst[m_rawLength - 4] & 0x7FF;
0087
0088
0089
0090
0091 headerWords = 8;
0092 triggerLen = 12;
0093 trailerWords = 12;
0094 }
0095
0096 void CastorCORData::determineStaticLengths(int& headerWords, int& trailerWords, int& triggerLen) const {
0097 headerWords = 8;
0098 triggerLen = 12;
0099 trailerWords = 12;
0100 }
0101
0102 void CastorCORData::unpack(unsigned char* daq_lengths,
0103 unsigned short* daq_samples,
0104 unsigned char* tp_lengths,
0105 unsigned short* tp_samples) const {
0106 if (daq_lengths != nullptr)
0107 memset(daq_lengths, 0, CHANNELS_PER_SPIGOT);
0108 if (tp_lengths != nullptr)
0109 memset(tp_lengths, 0, 1);
0110
0111 int tp_words_total = 0;
0112 int daq_words_total = 0;
0113 int headerLen = 0;
0114 int trailerLen = 0;
0115 int triggerLen = 0;
0116 determineSectionLengths(tp_words_total, daq_words_total, headerLen, trailerLen, triggerLen);
0117
0118 int wordPtr;
0119 const unsigned short* tpBase = m_rawConst + headerLen;
0120
0121 if (tp_lengths != nullptr) {
0122 for (wordPtr = 0; wordPtr < tp_words_total; wordPtr++) {
0123 tp_samples[tp_lengths[0]] = tpBase[wordPtr];
0124 tp_lengths[0]++;
0125 }
0126 }
0127
0128 const unsigned short* daqBase = m_rawConst + headerLen + triggerLen;
0129 unsigned long dat;
0130
0131 int lastCapid = 0;
0132 int ts, dv;
0133 int tsamples = daq_words_total / 24;
0134 if (daq_lengths != nullptr) {
0135 for (ts = 0; ts < tsamples; ts++) {
0136 for (int j = 0; j < 12; j++) {
0137 dat = daqBase[(ts * 12 + j) * 2] << 16 | daqBase[(ts * 12 + j) * 2 + 1];
0138 dv = (dat & 0x80000000) >> 31;
0139 daq_samples[(j * 3) * MAXIMUM_SAMPLES_PER_CHANNEL + ts] =
0140 ((dat & 0x40000000) >> 20) | ((dat & 0x3fe00000) >> 21) | (dv << 9);
0141 daq_samples[(j * 3 + 1) * MAXIMUM_SAMPLES_PER_CHANNEL + ts] =
0142 ((dat & 0x00100000) >> 10) | ((dat & 0x000ff800) >> 11) | (dv << 9);
0143 daq_samples[(j * 3 + 2) * MAXIMUM_SAMPLES_PER_CHANNEL + ts] =
0144 ((dat & 0x00000400)) | ((dat & 0x000003fe) >> 1) | (dv << 9);
0145 }
0146 }
0147
0148 int ichan;
0149 for (ichan = 0; ichan < CHANNELS_PER_SPIGOT; ichan++) {
0150 daq_lengths[ichan] = tsamples;
0151 for (ts = 0; ts < tsamples; ts++) {
0152 int erdv = (daq_samples[ichan * MAXIMUM_SAMPLES_PER_CHANNEL + ts] & 0x600) >> 9;
0153 int capid = (daq_samples[ichan * MAXIMUM_SAMPLES_PER_CHANNEL + ts] & 0x180) >> 7;
0154 if (erdv != 1 || (ts != 0 && (capid != ((lastCapid + 1) % 4)))) {
0155 daq_lengths[ichan] |= 0x80;
0156 }
0157 lastCapid = capid;
0158 }
0159 }
0160 }
0161 }
0162
0163 void CastorCORData::pack(unsigned char* daq_lengths,
0164 unsigned short* daq_samples,
0165 unsigned char* tp_lengths,
0166 unsigned short* tp_samples,
0167 bool do_capid) {
0168 int tp_words_total = 0, daq_words_total = 0, headerLen, trailerLen, triggerLen;
0169 determineStaticLengths(headerLen, trailerLen, triggerLen);
0170
0171 tp_words_total = 0;
0172 daq_words_total = 0;
0173 int isample;
0174
0175
0176 unsigned short* ptr = m_ownData + headerLen;
0177 if (tp_samples != nullptr && tp_lengths != nullptr) {
0178 for (isample = 0; isample < tp_lengths[0] && isample < 12; isample++) {
0179 ptr[tp_words_total] = tp_samples[isample];
0180 tp_words_total++;
0181 }
0182 }
0183
0184
0185 ptr = m_ownData + headerLen + triggerLen;
0186 int timesamples = std::min(daq_lengths[0] & 0x3f, MAXIMUM_SAMPLES_PER_CHANNEL);
0187 int ts, capid, j;
0188 unsigned long dat;
0189 unsigned short s1, s2, s3;
0190 bool somevalid;
0191
0192 for (ts = 0; ts < timesamples; ts++) {
0193 capid = ts % 4;
0194 for (j = 0; j < 12; j++) {
0195 somevalid = false;
0196 if (daq_lengths[j * 3] == 0 || (daq_lengths[j * 3] & 0xc0)) {
0197 s1 = 0x400;
0198 } else {
0199 s1 = daq_samples[(j * 3) * MAXIMUM_SAMPLES_PER_CHANNEL + ts];
0200 somevalid = true;
0201 }
0202 if (daq_lengths[j * 3 + 1] == 0 || (daq_lengths[j * 3 + 1] & 0xc0)) {
0203 s2 = 0x400;
0204 } else {
0205 s2 = daq_samples[(j * 3 + 1) * MAXIMUM_SAMPLES_PER_CHANNEL + ts];
0206 somevalid = true;
0207 }
0208 if (daq_lengths[j * 3 + 2] == 0 || (daq_lengths[j * 3 + 2] & 0xc0)) {
0209 s3 = 0x400;
0210 } else {
0211 s3 = daq_samples[(j * 3 + 2) * MAXIMUM_SAMPLES_PER_CHANNEL + ts];
0212 somevalid = true;
0213 }
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224 dat = 0x00000001
0225
0226
0227
0228 | (s1 & 0x1ff) << 21 | (s2 & 0x1ff) << 11 | (s3 & 0x1ff) << 1 | (s1 & 0x400) << 20 | (s2 & 0x400) << 10 |
0229 (s3 & 0x400);
0230 if (somevalid)
0231 dat |= 0x80000000;
0232
0233 if (do_capid)
0234 dat = (dat & 0xcff3fcff) | capid << 28 | capid << 18 | capid << 8;
0235 ptr[daq_words_total++] = dat >> 16;
0236 ptr[daq_words_total++] = dat & 0xffff;
0237 }
0238 }
0239
0240 m_ownData[5] = (tp_words_total << 8) | 0x1;
0241 unsigned short totalLen = headerLen + 12 + daq_words_total + trailerLen;
0242
0243 m_rawLength = totalLen;
0244 m_ownData[totalLen - 2] = totalLen / 2;
0245 m_ownData[totalLen - 3] = totalLen;
0246 m_ownData[totalLen - 4] = daq_words_total;
0247 }
0248
0249 void CastorCORData::packHeaderTrailer(
0250 int L1Anumber, int bcn, int submodule, int orbitn, int pipeline, int ndd, int nps, int firmwareRev) {
0251 m_ownData[0] = L1Anumber & 0xFF;
0252 m_ownData[1] = (L1Anumber & 0xFFFF00) >> 8;
0253
0254 m_ownData[2] = 0x8000;
0255 m_ownData[3] = ((orbitn & 0x1F) << 11) | (submodule & 0x7FF);
0256 m_ownData[4] = ((m_formatVersion & 0xF) << 12) | (bcn & 0xFFF);
0257 m_ownData[5] |= ((nps & 0xF) << 4) | 0x1;
0258 m_ownData[6] = ((firmwareRev & 0x70000) >> 3) | (firmwareRev & 0x1FFF);
0259 m_ownData[7] = (pipeline & 0xFF) | ((ndd & 0x1F) << 8);
0260 m_ownData[m_rawLength - 4] &= 0x7FF;
0261 m_ownData[m_rawLength - 4] |= (ndd & 0x1F) << 11;
0262
0263 m_ownData[m_rawLength - 2] = m_rawLength / 2;
0264 m_ownData[m_rawLength - 1] = (L1Anumber & 0xFF) << 8;
0265 }
0266
0267 unsigned int CastorCORData::getOrbitNumber() const { return (m_rawConst[3] >> 11); }
0268 unsigned int CastorCORData::getSubmodule() const { return (m_rawConst[3] & 0x7FF); }
0269 unsigned int CastorCORData::htrSlot() const {
0270 const unsigned int smid = getSubmodule();
0271 return ((smid >> 1) & 0x1F);
0272 }
0273 unsigned int CastorCORData::htrTopBottom() const {
0274 const unsigned int smid = getSubmodule();
0275 return (smid & 0x01);
0276 }
0277 unsigned int CastorCORData::readoutVMECrateId() const {
0278 const unsigned int smid = getSubmodule();
0279 return ((smid >> 6) & 0x1F);
0280 }
0281 bool CastorCORData::isCalibrationStream() const { return (m_formatVersion == -1) ? (false) : (m_rawConst[2] & 0x4000); }
0282 bool CastorCORData::isUnsuppressed() const { return (m_formatVersion < 4) ? (false) : (m_rawConst[6] & 0x8000); }
0283 bool CastorCORData::wasMarkAndPassZS(int fiber, int fiberchan) const {
0284 if (fiber < 1 || fiber > 8 || fiberchan < 0 || fiberchan > 2)
0285 return false;
0286 if (!isUnsuppressed() || m_formatVersion < 5)
0287 return false;
0288 unsigned short val = (fiber < 5) ? (m_rawConst[m_rawLength - 12]) : (m_rawConst[m_rawLength - 11]);
0289 int shift = (((fiber - 1) % 4) * 3) + fiberchan;
0290 return ((val >> shift) & 0x1) != 0;
0291 }
0292
0293 bool CastorCORData::isPatternRAMEvent() const { return (m_formatVersion == -1) ? (false) : (m_rawConst[2] & 0x1000); }
0294 bool CastorCORData::isHistogramEvent() const {
0295 return (m_formatVersion == -1) ? (m_rawConst[2] & 0x2) : (m_rawConst[2] & 0x2000);
0296 }
0297 int CastorCORData::getNDD() const {
0298 return (m_formatVersion == -1) ? (m_rawConst[m_rawLength - 4] >> 8) : (m_rawConst[m_rawLength - 4] >> 11);
0299 }
0300 int CastorCORData::getNTP() const {
0301 int retval = -1;
0302 if (m_formatVersion == -1)
0303 retval = m_rawConst[m_rawLength - 4] & 0xFF;
0304 else if (m_formatVersion < 3)
0305 retval = m_rawConst[m_rawLength - 4] >> 11;
0306 return retval;
0307 }
0308 int CastorCORData::getNPrecisionWords() const {
0309 return (m_formatVersion == -1) ? (m_rawConst[m_rawLength - 4] & 0xFF) : (m_rawConst[m_rawLength - 4] & 0x7FF);
0310 }
0311 int CastorCORData::getNPS() const { return (m_formatVersion == -1) ? (0) : ((m_rawConst[5] >> 4) & 0xF); }
0312 unsigned int CastorCORData::getPipelineLength() const { return (m_rawConst[7] & 0xFF); }
0313 unsigned int CastorCORData::getFirmwareRevision() const { return (m_rawConst[6]); }
0314
0315 void CastorCORData::getHistogramFibers(int& a, int& b) const {
0316 a = -1;
0317 b = -1;
0318 if (m_formatVersion == -1) {
0319 a = ((m_rawConst[2] & 0x0F00) >> 8);
0320 b = ((m_rawConst[2] & 0xF000) >> 12);
0321 } else {
0322 a = ((m_rawConst[5] & 0x0F00) >> 8);
0323 b = ((m_rawConst[5] & 0xF000) >> 12);
0324 }
0325 }
0326
0327 bool CastorCORData::unpackHistogram(int myfiber, int mysc, int capid, unsigned short* histogram) const {
0328
0329 if (!isHistogramEvent())
0330 return false;
0331
0332 int fiber1, fiber2;
0333 getHistogramFibers(fiber1, fiber2);
0334 if (fiber1 != myfiber && fiber2 != myfiber)
0335 return false;
0336
0337 if (m_formatVersion == -1) {
0338 int offset = 6 + mysc * 4 * 32 + capid * 32;
0339 if (myfiber == fiber2)
0340 offset += 3 * 4 * 32;
0341 for (int i = 0; i < 32; i++)
0342 histogram[i] = m_rawConst[offset + i];
0343 return true;
0344 } else {
0345 int offset = 8 + mysc * 4 * 32 + capid * 32;
0346 if (myfiber == fiber2)
0347 offset += 3 * 4 * 32;
0348 for (int i = 0; i < 32; i++)
0349 histogram[i] = m_rawConst[offset + i];
0350 return true;
0351 }
0352 }