File indexing completed on 2024-04-06 12:10:25
0001 #include "EventFilter/CSCRawToDigi/interface/CSCALCTHeader.h"
0002 #include "EventFilter/CSCRawToDigi/interface/CSCDMBHeader.h"
0003 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
0004 #include "EventFilter/CSCRawToDigi/interface/bitset_append.h"
0005 #include "EventFilter/CSCRawToDigi/interface/cscPackerCompare.h"
0006 #include <iomanip>
0007
0008 #ifdef LOCAL_UNPACK
0009
0010 bool CSCALCTHeader::debug = false;
0011 short unsigned int CSCALCTHeader::firmwareVersion = 2007;
0012
0013 #else
0014
0015 #include <atomic>
0016
0017 std::atomic<bool> CSCALCTHeader::debug{false};
0018 std::atomic<short unsigned int> CSCALCTHeader::firmwareVersion{2007};
0019
0020 #endif
0021
0022 CSCALCTHeader::CSCALCTHeader(int chamberType)
0023 : header2006(chamberType), header2007(chamberType) {
0024 if (firmwareVersion == 2006) {
0025 memcpy(theOriginalBuffer, &header2006, header2006.sizeInWords() * 2);
0026 } else if (firmwareVersion == 2007) {
0027 memcpy(theOriginalBuffer, &header2007, header2007.sizeInWords() * 2);
0028
0029 sizeInWords2007_ = header2007.sizeInWords() + header2007.lctBins * CSCALCT::sizeInWords() * 2;
0030 theALCTs.resize(header2007.lctBins * 2);
0031 } else {
0032 edm::LogError("CSCALCTHeader|CSCRawToDigi")
0033 << "Cannot construct ALCT header: ALCT firmware version is bad/not defined!" << firmwareVersion;
0034 }
0035 }
0036
0037 CSCALCTHeader::CSCALCTHeader(const unsigned short *buf) {
0038
0039
0040
0041
0042 constexpr unsigned short int collisionMaskWordcount[7] = {8, 8, 12, 16, 16, 24, 28};
0043 constexpr unsigned short int hotChannelMaskWordcount[7] = {18, 18, 24, 36, 36, 48, 60};
0044
0045
0046 if (buf[0] == 0xDB0A) {
0047 firmwareVersion = 2007;
0048 } else if ((buf[0] & 0xF800) == 0x6000) {
0049 firmwareVersion = 2006;
0050 } else {
0051 edm::LogError("CSCALCTHeader|CSCRawToDigi") << "failed to determine ALCT firmware version!!";
0052 }
0053
0054 LogTrace("CSCALCTHeader|CSCRawToDigi") << "firmware version - " << firmwareVersion;
0055
0056
0057 #ifdef LOCAL_UNPACK
0058 switch (firmwareVersion) {
0059 #else
0060 switch (firmwareVersion.load()) {
0061 #endif
0062 case 2006:
0063 header2006.setFromBuffer(buf);
0064 buf += header2006.sizeInWords();
0065 alcts2006.setFromBuffer(buf);
0066 buf += alcts2006.sizeInWords();
0067 break;
0068
0069 case 2007:
0070 header2007.setFromBuffer(buf);
0071 buf += header2007.sizeInWords();
0072 sizeInWords2007_ = header2007.sizeInWords();
0073
0074 if (header2007.configPresent == 1) {
0075 virtexID.setFromBuffer(buf);
0076 buf += virtexID.sizeInWords();
0077 sizeInWords2007_ = virtexID.sizeInWords();
0078 configRegister.setFromBuffer(buf);
0079 buf += configRegister.sizeInWords();
0080 sizeInWords2007_ += configRegister.sizeInWords();
0081
0082 collisionMasks.resize(collisionMaskWordcount[header2007.boardType]);
0083 for (unsigned int i = 0; i < collisionMaskWordcount[header2007.boardType]; ++i) {
0084 collisionMasks[i].setFromBuffer(buf);
0085 buf += collisionMasks[i].sizeInWords();
0086 sizeInWords2007_ += collisionMasks[i].sizeInWords();
0087 }
0088
0089 hotChannelMasks.resize(hotChannelMaskWordcount[header2007.boardType]);
0090 for (unsigned int i = 0; i < hotChannelMaskWordcount[header2007.boardType]; ++i) {
0091 hotChannelMasks[i].setFromBuffer(buf);
0092 buf += hotChannelMasks[i].sizeInWords();
0093 sizeInWords2007_ += hotChannelMasks[i].sizeInWords();
0094 }
0095 }
0096
0097 theALCTs.resize(header2007.lctBins * 2);
0098 for (int i = 0; i < header2007.lctBins * 2; ++i) {
0099 theALCTs[i].setFromBuffer(buf);
0100 buf += theALCTs[i].sizeInWords();
0101 sizeInWords2007_ += theALCTs[i].sizeInWords();
0102 }
0103
0104 ALCTDigis();
0105 break;
0106
0107 default:
0108 edm::LogError("CSCALCTHeader|CSCRawToDigi") << "couldn't construct: ALCT firmware version is bad/not defined!";
0109 break;
0110 }
0111
0112
0113 if ((firmwareVersion == 2006) || (firmwareVersion == 2007))
0114 memcpy(theOriginalBuffer, buf - sizeInWords(), sizeInWords() * 2);
0115 }
0116
0117 CSCALCTHeader::CSCALCTHeader(const CSCALCTStatusDigi &digi) { CSCALCTHeader(digi.header()); }
0118
0119 void CSCALCTHeader::setEventInformation(const CSCDMBHeader &dmb) {
0120 #ifdef LOCAL_UNPACK
0121 switch (firmwareVersion) {
0122 #else
0123 switch (firmwareVersion.load()) {
0124 #endif
0125 case 2006: {
0126 header2006.setEventInformation(dmb);
0127 break;
0128 }
0129 case 2007: {
0130 header2007.setEventInformation(dmb);
0131 break;
0132 }
0133 default:
0134 edm::LogError("CSCALCTHeader|CSCRawToDigi")
0135 << "setEventInformation: ALCT firmware version is bad/not defined!" << firmwareVersion;
0136 break;
0137 }
0138 }
0139
0140 unsigned short CSCALCTHeader::nLCTChipRead() const {
0141 if (firmwareVersion == 2006) {
0142 return header2006.nLCTChipRead();
0143 } else {
0144
0145
0146
0147
0148 }
0149 return 0;
0150 }
0151
0152 std::vector<CSCALCTDigi> CSCALCTHeader::ALCTDigis() const {
0153 std::vector<CSCALCTDigi> result;
0154
0155 #ifdef LOCAL_UNPACK
0156 switch (firmwareVersion) {
0157 #else
0158 switch (firmwareVersion.load()) {
0159 #endif
0160 case 2006: {
0161 result = alcts2006.ALCTDigis();
0162 break;
0163 }
0164 case 2007: {
0165 result.reserve(theALCTs.size());
0166 for (unsigned int i = 0; i < theALCTs.size(); ++i) {
0167 CSCALCTDigi digi(theALCTs[i].valid,
0168 theALCTs[i].quality,
0169 theALCTs[i].accel,
0170 theALCTs[i].pattern,
0171 theALCTs[i].keyWire,
0172 (int)i / 2,
0173 i % 2 + 1);
0174 result.push_back(digi);
0175 }
0176 break;
0177 }
0178 default:
0179 edm::LogError("CSCALCTHeader|CSCRawToDigi")
0180 << "Empty Digis: ALCT firmware version is bad/not defined!" << firmwareVersion;
0181 break;
0182 }
0183 for (unsigned i = 0; i < result.size(); ++i) {
0184 result[i].setFullBX(BXNCount());
0185 }
0186 return result;
0187 }
0188
0189 void CSCALCTHeader::add(const std::vector<CSCALCTDigi> &digis) {
0190 if (firmwareVersion == 2006) {
0191 alcts2006.add(digis);
0192 } else if (firmwareVersion == 2007) {
0193 if (theALCTs.empty()) {
0194 theALCTs.resize(header2007.lctBins * 2);
0195 }
0196 for (std::vector<CSCALCTDigi>::const_iterator digi = digis.begin(); digi != digis.end(); ++digi) {
0197 int bx = digi->getBX();
0198 if (bx < (int)header2007.lctBins) {
0199
0200 int i = bx * 2;
0201 int q1 = theALCTs[i].quality;
0202 int q2 = theALCTs[i + 1].quality;
0203
0204 if (!theALCTs[i].valid) {
0205 theALCTs[i] = CSCALCT(*digi);
0206 }
0207
0208 else if (digi->getQuality() > q1) {
0209 theALCTs[i + 1] = theALCTs[i];
0210 theALCTs[i] = CSCALCT(*digi);
0211 }
0212
0213 else if (!theALCTs[i + 1].valid || (digi->getQuality() > q2)) {
0214 theALCTs[i + 1] = CSCALCT(*digi);
0215 }
0216 }
0217 }
0218 }
0219 }
0220
0221
0222 void CSCALCTHeader::addShower(const std::vector<CSCShowerDigi> &digis) {
0223 if (firmwareVersion == 2007) {
0224 if (theALCTs.empty()) {
0225 theALCTs.resize(header2007.lctBins * 2);
0226 }
0227 for (std::vector<CSCShowerDigi>::const_iterator digi = digis.begin(); digi != digis.end(); ++digi) {
0228 int bx = digi - digis.begin();
0229 if (bx < (int)header2007.lctBins) {
0230 const CSCShowerDigi &digi = digis[bx];
0231 int i = bx * 2;
0232 unsigned hmt_bits = digi.isValid() ? digi.bitsInTime() : 0;
0233 theALCTs[i].reserved = hmt_bits & 0x3;
0234 theALCTs[i + 1].reserved = hmt_bits & 0x3;
0235 }
0236 }
0237 }
0238 }
0239
0240 boost::dynamic_bitset<> CSCALCTHeader::pack() {
0241 boost::dynamic_bitset<> result;
0242 if (firmwareVersion == 2006) {
0243 boost::dynamic_bitset<> header =
0244 bitset_utilities::ushortToBitset(header2006.sizeInWords() * 16, (unsigned short *)&header2006);
0245 boost::dynamic_bitset<> alcts =
0246 bitset_utilities::ushortToBitset(alcts2006.sizeInWords() * 16, (unsigned short *)&alcts2006);
0247 result = bitset_utilities::append(header, alcts);
0248
0249 bitset_utilities::bitsetToChar(result, (unsigned char *)data());
0250 }
0251
0252 else if (firmwareVersion == 2007) {
0253 result = bitset_utilities::ushortToBitset(header2007.sizeInWords() * 16, (unsigned short *)&header2007);
0254
0255 for (unsigned i = 0; i < theALCTs.size(); ++i) {
0256 boost::dynamic_bitset<> alct =
0257 bitset_utilities::ushortToBitset(theALCTs[i].sizeInWords() * 16, (unsigned short *)&theALCTs[i]);
0258 result = bitset_utilities::append(result, alct);
0259 }
0260
0261 bitset_utilities::bitsetToChar(result, (unsigned char *)data());
0262 }
0263 return result;
0264 }
0265
0266 void CSCALCTHeader::selfTest(int firmware) {
0267 firmwareVersion = firmware;
0268 CSCALCTDigi alct0(true, 1, 1, 1, 10, 6, 1);
0269 CSCALCTDigi alct1(true, 1, 1, 0, 11, 6, 2);
0270
0271
0272 for (int station = 1; station <= 4; ++station) {
0273 CSCDetId detId(1, station, 1, 1, 0);
0274
0275 std::vector<CSCALCTDigi> oldAlcts;
0276 oldAlcts.push_back(alct0);
0277 oldAlcts.push_back(alct1);
0278 CSCALCTHeader alctHeader(detId.iChamberType());
0279
0280 alctHeader.add(oldAlcts);
0281
0282 std::vector<CSCALCTDigi> alcts = alctHeader.ALCTDigis();
0283
0284 std::vector<CSCALCTDigi> validALCTs;
0285 for (std::vector<CSCALCTDigi>::const_iterator alctItr = alcts.begin(); alctItr != alcts.end(); ++alctItr) {
0286 if (alctItr->isValid()) {
0287 validALCTs.push_back(*alctItr);
0288 }
0289 }
0290 assert(validALCTs[0] == alct0);
0291 assert(validALCTs[1] == alct1);
0292
0293 }
0294 }
0295
0296 std::ostream &operator<<(std::ostream &os, const CSCALCTHeader &header) {
0297 os << "ALCT HEADER CSCID " << header.CSCID() << " L1ACC " << header.L1Acc() << std::endl;
0298 os << " time samples " << header.NTBins() << std::endl;
0299 return os;
0300 }