File indexing completed on 2024-04-06 12:10:27
0001
0002
0003
0004
0005
0006 #include "EventFilter/CSCRawToDigi/interface/CSCTMBData.h"
0007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0008
0009 #include <iomanip> // dump for JK
0010 #include <iostream>
0011 #include <cstdio>
0012 #include "EventFilter/CSCRawToDigi/interface/bitset_append.h"
0013 #include "EventFilter/CSCRawToDigi/interface/cscPackerCompare.h"
0014
0015 #ifdef LOCAL_UNPACK
0016 bool CSCTMBData::debug = false;
0017 #else
0018 std::atomic<bool> CSCTMBData::debug{false};
0019 #endif
0020
0021 CSCTMBData::CSCTMBData()
0022 : theOriginalBuffer(nullptr),
0023 theB0CLine(0),
0024 theE0FLine(0),
0025 theTMBHeader(2007, 0x50c3),
0026 theComparatorData(&theTMBHeader),
0027 theGEMData(),
0028 theTMBScopeIsPresent(false),
0029 theTMBScope(nullptr),
0030 theTMBMiniScopeIsPresent(false),
0031 theTMBMiniScope(nullptr),
0032 theBlockedCFEBIsPresent(false),
0033 theTMBBlockedCFEB(nullptr),
0034 theTMBTrailer(theTMBHeader.sizeInWords() + theComparatorData.sizeInWords(), 2007),
0035 size_(0),
0036 cWordCnt(0),
0037 theRPCDataIsPresent(false),
0038 theGEMDataIsPresent(false) {}
0039
0040 CSCTMBData::CSCTMBData(int firmwareVersion, int firmwareRevision, int cfebs)
0041 : theOriginalBuffer(nullptr),
0042 theB0CLine(0),
0043 theE0FLine(0),
0044 theTMBHeader(firmwareVersion, firmwareRevision),
0045 theComparatorData(&theTMBHeader),
0046 theGEMData(),
0047 theTMBScopeIsPresent(false),
0048 theTMBScope(nullptr),
0049 theTMBMiniScopeIsPresent(false),
0050 theTMBMiniScope(nullptr),
0051 theBlockedCFEBIsPresent(false),
0052 theTMBBlockedCFEB(nullptr),
0053 theTMBTrailer(theTMBHeader.sizeInWords() + theComparatorData.sizeInWords(), firmwareVersion),
0054 size_(0),
0055 cWordCnt(0),
0056 theRPCDataIsPresent(false),
0057 theGEMDataIsPresent(false) {
0058 theTMBHeader.setNCFEBs(cfebs);
0059 theComparatorData = CSCComparatorData(&theTMBHeader);
0060 int wordCnt = theTMBHeader.sizeInWords() + theComparatorData.sizeInWords();
0061
0062 if ((firmwareVersion == 2020) && (((firmwareRevision >> 9) & 0x3) == 3)) {
0063 theGEMDataIsPresent = true;
0064 wordCnt += theGEMData.sizeInWords();
0065 }
0066 theTMBTrailer = CSCTMBTrailer(wordCnt, firmwareVersion);
0067 }
0068
0069 CSCTMBData::CSCTMBData(const uint16_t* buf)
0070 : theOriginalBuffer(buf),
0071 theTMBHeader(2007, 0x50c3),
0072 theComparatorData(&theTMBHeader),
0073 theTMBScopeIsPresent(false),
0074 theTMBScope(nullptr),
0075 theTMBMiniScopeIsPresent(false),
0076 theTMBMiniScope(nullptr),
0077 theBlockedCFEBIsPresent(false),
0078 theTMBBlockedCFEB(nullptr),
0079 theTMBTrailer(theTMBHeader.sizeInWords() + theComparatorData.sizeInWords(), 2007),
0080 theRPCDataIsPresent(false),
0081 theGEMDataIsPresent(false) {
0082 size_ = UnpackTMB(buf);
0083 }
0084
0085
0086
0087 CSCTMBData::CSCTMBData(const CSCTMBData& data)
0088 : theOriginalBuffer(data.theOriginalBuffer),
0089 theB0CLine(data.theB0CLine),
0090 theE0FLine(data.theE0FLine),
0091 theTMBHeader(data.theTMBHeader),
0092 theComparatorData(data.theComparatorData),
0093 theRPCData(data.theRPCData),
0094 theGEMData(data.theGEMData),
0095 theTMBScopeIsPresent(data.theTMBScopeIsPresent),
0096 theTMBMiniScopeIsPresent(data.theTMBMiniScopeIsPresent),
0097 theBlockedCFEBIsPresent(data.theBlockedCFEBIsPresent),
0098 theTMBTrailer(data.theTMBTrailer),
0099 size_(data.size_),
0100 cWordCnt(data.cWordCnt),
0101 theRPCDataIsPresent(data.theRPCDataIsPresent),
0102 theGEMDataIsPresent(data.theGEMDataIsPresent) {
0103 if (theTMBScopeIsPresent) {
0104 theTMBScope = new CSCTMBScope(*(data.theTMBScope));
0105 } else {
0106 theTMBScope = nullptr;
0107 }
0108
0109 if (theTMBMiniScopeIsPresent) {
0110 theTMBMiniScope = new CSCTMBMiniScope(*(data.theTMBMiniScope));
0111 } else {
0112 theTMBMiniScope = nullptr;
0113 }
0114
0115 if (theBlockedCFEBIsPresent) {
0116 theTMBBlockedCFEB = new CSCTMBBlockedCFEB(*(data.theTMBBlockedCFEB));
0117 } else {
0118 theTMBBlockedCFEB = nullptr;
0119 }
0120 }
0121
0122 CSCTMBData::~CSCTMBData() {
0123 if (theTMBScopeIsPresent) {
0124 delete theTMBScope;
0125 theTMBScopeIsPresent = false;
0126 }
0127
0128 if (theTMBMiniScopeIsPresent) {
0129 delete theTMBMiniScope;
0130 theTMBMiniScopeIsPresent = false;
0131 }
0132
0133 if (theBlockedCFEBIsPresent) {
0134 delete theTMBBlockedCFEB;
0135 theBlockedCFEBIsPresent = false;
0136 }
0137 }
0138
0139
0140
0141 int findLine(const uint16_t* buf, uint16_t marker, int first, int maxToDo) {
0142 for (int i = first; i < maxToDo; ++i) {
0143 if (buf[i] == marker) {
0144 return i;
0145 }
0146 }
0147 return -1;
0148 }
0149
0150 int CSCTMBData::TMBCRCcalc() {
0151 std::vector<std::bitset<16> > theTotalTMBData(theE0FLine + 1 - theB0CLine);
0152 unsigned i = 0;
0153 for (unsigned int line = theB0CLine; line < theE0FLine + 1; ++line) {
0154 theTotalTMBData[i] = std::bitset<16>(theOriginalBuffer[line]);
0155 ++i;
0156 }
0157 if (!theTotalTMBData.empty()) {
0158 std::bitset<22> CRC = calCRC22(theTotalTMBData);
0159 LogTrace("CSCTMBData|CSCRawToDigi") << " Test here " << CRC.to_ulong();
0160 return CRC.to_ulong();
0161 } else {
0162 LogTrace("CSCTMBData|CSCRawToDigi") << "theTotalTMBData doesn't exist";
0163 return 0;
0164 }
0165 }
0166
0167 int CSCTMBData::UnpackTMB(const uint16_t* buf) {
0168
0169 unsigned short int firmwareVersion = 0;
0170 unsigned short int firmwareRevision = 0;
0171 int Ntbins = 0;
0172 int NRPCtbins = 0;
0173 int NGEMtbins = 0;
0174 int NGEMEnabled = 0;
0175 int GEMFibersMask = 0;
0176 bool isGEMfirmware = false;
0177
0178 int b0cLine = 0;
0179
0180
0181
0182 if (buf[b0cLine] == 0xdb0c) {
0183 firmwareVersion = 2007;
0184 firmwareRevision = buf[b0cLine + 7] & 0x7fff;
0185 Ntbins = buf[b0cLine + 19] & 0xF8;
0186 if ((firmwareRevision < 0x4000)
0187 && (((firmwareRevision >> 9) & 0x3) == 0x3))
0188 isGEMfirmware = true;
0189
0190 if (isGEMfirmware) {
0191 GEMFibersMask = buf[b0cLine + 36] & 0xf;
0192
0193
0194
0195 NGEMEnabled = 4;
0196 NGEMtbins = (buf[b0cLine + 36] >> 5) & 0x1F;
0197 }
0198 NRPCtbins = (buf[b0cLine + 36] >> 5) & 0x1F;
0199 } else if (buf[b0cLine] == 0x6b0c) {
0200 firmwareVersion = 2006;
0201 Ntbins = buf[b0cLine + 1] & 0x1f;
0202 NRPCtbins = Ntbins;
0203 } else {
0204 LogTrace("CSCTMBData|CSCRawToDigi") << "+++ Can't find b0C flag";
0205 }
0206
0207 if ((firmwareVersion == 2007) &&
0208 (!(((buf[b0cLine] & 0xFFFF) == 0xDB0C) && ((buf[b0cLine + 1] & 0xf000) == 0xD000) &&
0209 ((buf[b0cLine + 2] & 0xf000) == 0xD000) && ((buf[b0cLine + 3] & 0xf000) == 0xD000)))) {
0210 LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: error in header in 2007 format!";
0211 }
0212
0213 int MaxSizeRPC = 1 + NRPCtbins * 2 * 4 + 1;
0214 int MaxSizeGEM = 1 + NGEMEnabled * NGEMtbins * 4 + 1;
0215
0216 int e0bLine = -1;
0217 switch (firmwareVersion) {
0218 case 2007:
0219 e0bLine = 42;
0220 break;
0221 case 2006:
0222 e0bLine = 26;
0223 break;
0224 default:
0225 edm::LogError("CSCTMBData|CSCRawToDigi") << "+++ undetermined firmware format - cant find e0bLine";
0226 }
0227
0228 theTMBHeader = CSCTMBHeader(buf);
0229
0230 if (!theTMBHeader.check()) {
0231 LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: Bad TMB header e0bLine=" << std::hex
0232 << buf[e0bLine];
0233 return 0;
0234 }
0235
0236 int currentPosition = theTMBHeader.sizeInWords();
0237 int theFirmwareVersion = theTMBHeader.FirmwareVersion();
0238
0239 theComparatorData =
0240 CSCComparatorData(theTMBHeader.NCFEBs(), theTMBHeader.NTBins(), buf + e0bLine + 1, theFirmwareVersion);
0241
0242 if (!theComparatorData.check()) {
0243 LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: Bad CLCT data";
0244 } else {
0245 currentPosition += theComparatorData.sizeInWords();
0246 }
0247
0248
0249 int b04Line = currentPosition;
0250
0251 if (buf[b04Line] == 0x6b04) {
0252
0253 int e04Line = findLine(buf, 0x6e04, currentPosition, currentPosition + MaxSizeRPC);
0254 if (e04Line != -1) {
0255 theRPCDataIsPresent = true;
0256 theRPCData = CSCRPCData(buf + b04Line, e04Line - b04Line + 1);
0257 currentPosition += theRPCData.sizeInWords();
0258 } else {
0259 LogTrace("CSCTMBData|CSCRawToDigi") << "CSCTMBData::corrupt RPC data! Failed to find end! ";
0260 return 0;
0261 }
0262 }
0263
0264
0265 int c04Line = currentPosition;
0266
0267 if (buf[c04Line] == 0x6c04) {
0268
0269 int d04Line = findLine(buf, 0x6d04, currentPosition, currentPosition + MaxSizeGEM);
0270 if (d04Line != -1) {
0271 theGEMDataIsPresent = true;
0272 theGEMData = CSCGEMData(buf + c04Line, d04Line - c04Line + 1, GEMFibersMask);
0273 currentPosition += theGEMData.sizeInWords();
0274 } else {
0275 LogTrace("CSCTMBData|CSCRawToDigi") << "CSCTMBData::corrupt GEM data! Failed to find end! ";
0276 return 0;
0277 }
0278 }
0279
0280 int TotTMBReadout = 0;
0281 switch (firmwareVersion) {
0282 case 2007:
0283 if (theGEMDataIsPresent) {
0284 TotTMBReadout = 43 + Ntbins * 6 * 5 + 1 + NGEMEnabled * NGEMtbins * 4 + 2 + 8 * 256 + 8;
0285 } else {
0286 TotTMBReadout = 43 + Ntbins * 6 * 5 + 1 + NRPCtbins * 2 * 4 + 2 + 8 * 256 + 8;
0287 };
0288 break;
0289 case 2006:
0290 TotTMBReadout =
0291 27 + Ntbins * 6 * 5 + 1 + NRPCtbins * 2 * 4 + 2 + 8 * 256 + 8;
0292 break;
0293 default:
0294 edm::LogError("CSCTMBData|CSCRawToDigi") << "can't find TotTMBReadout - unknown firmware version!";
0295 break;
0296 }
0297
0298
0299 if (buf[currentPosition] == 0x6b05) {
0300 int b05Line = currentPosition;
0301 LogTrace("CSCTMBData|CSCRawToDigi") << "found scope!";
0302 int e05Line = findLine(buf, 0x6e05, currentPosition, TotTMBReadout - currentPosition);
0303 if (e05Line != -1) {
0304 theTMBScopeIsPresent = true;
0305 theTMBScope = new CSCTMBScope(buf, b05Line, e05Line);
0306
0307
0308
0309 currentPosition += (e05Line - b05Line + 1);
0310 } else {
0311 LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: found 0x6b05 line, but not 0x6e05! +++";
0312 }
0313 }
0314
0315
0316 if (buf[currentPosition] == 0x6b07) {
0317 int Line6b07 = currentPosition;
0318 LogTrace("CSCTMBData") << " TMBData ---> Begin of MiniScope found ";
0319 int Line6E07 = findLine(buf, 0x6E07, currentPosition, TotTMBReadout - currentPosition);
0320 if (Line6E07 != -1) {
0321 LogTrace("CSCTMBData") << " TMBData --> End of MiniScope found " << Line6E07 - Line6b07 + 1 << " words ";
0322 theTMBMiniScopeIsPresent = true;
0323 theTMBMiniScope = new CSCTMBMiniScope(buf, Line6b07, Line6E07);
0324 currentPosition += (Line6E07 - Line6b07 + 1);
0325 } else {
0326 LogTrace("CSCTMBData") << "+++ CSCTMBData warning MiniScope!: found 0x6b07 line, but not 0x6e07! +++";
0327 }
0328 }
0329
0330
0331
0332 if (buf[currentPosition] == 0x6BCB) {
0333 int Line6BCB = currentPosition;
0334 LogTrace("CSCTMBData") << " TMBData ---> Begin of Blocked CFEB found ";
0335 int Line6ECB = findLine(buf, 0x6ECB, currentPosition, TotTMBReadout - currentPosition);
0336 if (Line6ECB != -1) {
0337 LogTrace("CSCTMBData") << " TMBData --> End of Blocked CFEB found " << Line6ECB - Line6BCB + 1 << " words ";
0338 theBlockedCFEBIsPresent = true;
0339 theTMBBlockedCFEB = new CSCTMBBlockedCFEB(buf, Line6BCB, Line6ECB);
0340 currentPosition += (Line6ECB - Line6BCB + 1);
0341 } else {
0342 LogTrace("CSCTMBData") << "+++ CSCTMBData warning Blocked CFEB!: found 0x6BCB line, but not 0x6ECB! +++";
0343 }
0344 }
0345
0346
0347 int maxLine = findLine(buf, 0xde0f, currentPosition, TotTMBReadout - currentPosition);
0348 if (maxLine == -1) {
0349 LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: No e0f line!";
0350 return 0;
0351 }
0352
0353
0354
0355 theB0CLine = b0cLine;
0356 theE0FLine = maxLine;
0357
0358
0359 int e0cLine = findLine(buf, 0x6e0c, currentPosition, maxLine);
0360 if (e0cLine == -1) {
0361 LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: No e0c line!";
0362 } else {
0363 theTMBTrailer = CSCTMBTrailer(buf + e0cLine, firmwareVersion);
0364 LogTrace("CSCTMBData|CSCRawToDigi") << "TMB trailer size: " << theTMBTrailer.sizeInWords();
0365 }
0366
0367 checkSize();
0368
0369
0370 #ifdef TMBDUMP
0371 LogTrace("CSCTMBData") << "Dump of TMB data:";
0372 for (int line = b0cLine; line <= maxLine + 3; line++) {
0373 LogTrace("CSCTMBData") << "Adr= " << std::setw(4) << line << " Data= " << std::setfill('0') << std::setw(5)
0374 << std::uppercase << std::hex << buf[line] << std::dec << std::endl;
0375 }
0376 #endif
0377
0378
0379
0380 return e0cLine - b0cLine + theTMBTrailer.sizeInWords();
0381 }
0382
0383 bool CSCTMBData::checkSize() const {
0384
0385 return true;
0386 }
0387
0388 std::bitset<22> CSCTMBData::calCRC22(const std::vector<std::bitset<16> >& datain) {
0389 std::bitset<22> CRC;
0390 CRC.reset();
0391 for (unsigned int i = 0; i < datain.size() - 3; ++i) {
0392 CRC = nextCRC22_D16(datain[i], CRC);
0393 }
0394 return CRC;
0395 }
0396
0397 CSCTMBScope& CSCTMBData::tmbScope() const {
0398 if (!theTMBScopeIsPresent)
0399 throw("No TMBScope in this chamber");
0400 return *theTMBScope;
0401 }
0402
0403 CSCTMBMiniScope& CSCTMBData::tmbMiniScope() const {
0404 if (!theTMBMiniScopeIsPresent)
0405 throw("No TMBScope in this chamber");
0406 return *theTMBMiniScope;
0407 }
0408
0409 CSCGEMData* CSCTMBData::gemData() {
0410 if (!theGEMDataIsPresent)
0411 throw("No GEM Data in this chamber");
0412 return &theGEMData;
0413 }
0414
0415 std::bitset<22> CSCTMBData::nextCRC22_D16(const std::bitset<16>& D, const std::bitset<22>& C) {
0416 std::bitset<22> NewCRC;
0417
0418 NewCRC[0] = D[0] ^ C[6];
0419 NewCRC[1] = D[1] ^ D[0] ^ C[6] ^ C[7];
0420 NewCRC[2] = D[2] ^ D[1] ^ C[7] ^ C[8];
0421 NewCRC[3] = D[3] ^ D[2] ^ C[8] ^ C[9];
0422 NewCRC[4] = D[4] ^ D[3] ^ C[9] ^ C[10];
0423 NewCRC[5] = D[5] ^ D[4] ^ C[10] ^ C[11];
0424 NewCRC[6] = D[6] ^ D[5] ^ C[11] ^ C[12];
0425 NewCRC[7] = D[7] ^ D[6] ^ C[12] ^ C[13];
0426 NewCRC[8] = D[8] ^ D[7] ^ C[13] ^ C[14];
0427 NewCRC[9] = D[9] ^ D[8] ^ C[14] ^ C[15];
0428 NewCRC[10] = D[10] ^ D[9] ^ C[15] ^ C[16];
0429 NewCRC[11] = D[11] ^ D[10] ^ C[16] ^ C[17];
0430 NewCRC[12] = D[12] ^ D[11] ^ C[17] ^ C[18];
0431 NewCRC[13] = D[13] ^ D[12] ^ C[18] ^ C[19];
0432 NewCRC[14] = D[14] ^ D[13] ^ C[19] ^ C[20];
0433 NewCRC[15] = D[15] ^ D[14] ^ C[20] ^ C[21];
0434 NewCRC[16] = D[15] ^ C[0] ^ C[21];
0435 NewCRC[17] = C[1];
0436 NewCRC[18] = C[2];
0437 NewCRC[19] = C[3];
0438 NewCRC[20] = C[4];
0439 NewCRC[21] = C[5];
0440
0441 return NewCRC;
0442 }
0443
0444 boost::dynamic_bitset<> CSCTMBData::pack() {
0445 boost::dynamic_bitset<> result =
0446 bitset_utilities::ushortToBitset(theTMBHeader.sizeInWords() * 16, theTMBHeader.data());
0447 boost::dynamic_bitset<> comparatorData =
0448 bitset_utilities::ushortToBitset(theComparatorData.sizeInWords() * 16, theComparatorData.data());
0449 result = bitset_utilities::append(result, comparatorData);
0450
0451
0452 if (theGEMDataIsPresent) {
0453 boost::dynamic_bitset<> gemData =
0454 bitset_utilities::ushortToBitset(theGEMData.sizeInWords() * 16, theGEMData.data());
0455 result = bitset_utilities::append(result, gemData);
0456 }
0457
0458 boost::dynamic_bitset<> newResult = result;
0459
0460 boost::dynamic_bitset<> tmbTrailer =
0461 bitset_utilities::ushortToBitset(theTMBTrailer.sizeInWords() * 16, theTMBTrailer.data());
0462 result = bitset_utilities::append(result, tmbTrailer);
0463
0464
0465 std::vector<std::bitset<16> > wordVector;
0466
0467 for (unsigned pos = 0; pos < result.size() - 16; pos += 16) {
0468 std::bitset<16> word;
0469 for (int i = 0; i < 16; ++i) {
0470 word[i] = result[pos + i];
0471 }
0472 wordVector.push_back(word);
0473 }
0474 theTMBTrailer.setCRC(calCRC22(wordVector).to_ulong());
0475 tmbTrailer = bitset_utilities::ushortToBitset(theTMBTrailer.sizeInWords() * 16, theTMBTrailer.data());
0476 newResult = bitset_utilities::append(newResult, tmbTrailer);
0477
0478 return newResult;
0479 }
0480
0481 void CSCTMBData::selfTest() {
0482 CSCTMBData tmbData;
0483 cscClassPackerCompare(tmbData);
0484 }