File indexing completed on 2024-04-06 12:10:25
0001 #include "EventFilter/CSCRawToDigi/interface/CSCCFEBData.h"
0002 #include "EventFilter/CSCRawToDigi/interface/CSCCFEBTimeSlice.h"
0003 #include "EventFilter/CSCRawToDigi/interface/CSCBadCFEBTimeSlice.h"
0004 #include "DataFormats/CSCDigi/interface/CSCStripDigi.h"
0005 #include "DataFormats/CSCDigi/interface/CSCCFEBStatusDigi.h"
0006 #include "DataFormats/CSCDigi/interface/CSCConstants.h"
0007 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
0008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0009 #include <cassert>
0010
0011 CSCCFEBData::CSCCFEBData(unsigned number, const uint16_t *buf, uint16_t format_version, bool f_dcfeb)
0012 : theSize(0), boardNumber_(number), theNumberOfSamples(0), theFormatVersion(format_version), fDCFEB(f_dcfeb) {
0013
0014
0015 unsigned pos = 0;
0016
0017 unsigned maxSamples = 8;
0018 theSliceStarts.reserve(8);
0019 while (theNumberOfSamples < maxSamples) {
0020
0021 const CSCBadCFEBTimeSlice *badSlice = reinterpret_cast<const CSCBadCFEBTimeSlice *>(buf + pos);
0022 if (badSlice->check()) {
0023
0024 theSliceStarts.push_back(std::pair<int, bool>(pos, false));
0025 pos += badSlice->sizeInWords();
0026
0027 bWords.push_back(badSlice->word(1).data());
0028 } else {
0029
0030 const CSCCFEBTimeSlice *goodSlice = reinterpret_cast<const CSCCFEBTimeSlice *>(buf + pos);
0031 if (goodSlice->check()) {
0032
0033 theSliceStarts.push_back(std::pair<int, bool>(pos, true));
0034
0035
0036
0037
0038
0039
0040 if (goodSlice->sixteenSamples())
0041 LogTrace("CSCCFEBData|CSCRawToDigi")
0042 << "CFEB DATA slice " << theNumberOfSamples << " 16 samples flag is detected";
0043 pos += goodSlice->sizeInWords();
0044 } else {
0045 LogTrace("CSCCFEBData|CSCRawToDigi")
0046 << "CORRUPT CFEB DATA slice " << theNumberOfSamples << std::hex << " " << *(buf + pos + 3) << " "
0047 << *(buf + pos + 2) << " " << *(buf + pos + 1) << " " << *(buf + pos);
0048
0049 theSliceStarts.push_back(std::pair<int, bool>(pos, false));
0050 pos += 100;
0051 }
0052 }
0053 ++theNumberOfSamples;
0054 }
0055 theSize = pos;
0056 memcpy(theData, buf, theSize * 2);
0057 }
0058
0059 CSCCFEBData::CSCCFEBData(unsigned number, bool sixteenSamples, uint16_t format_version, bool f_dcfeb)
0060 : boardNumber_(number),
0061 theNumberOfSamples(sixteenSamples ? 16 : 8),
0062 theFormatVersion(format_version),
0063 fDCFEB(f_dcfeb) {
0064 theSliceStarts.reserve(theNumberOfSamples);
0065
0066
0067 CSCCFEBSCAControllerWord scaWord;
0068 scaWord.ts_flag = sixteenSamples;
0069
0070
0071 CSCCFEBTimeSlice slice;
0072 slice.setControllerWord(scaWord);
0073
0074 for (unsigned i = 0; i < theNumberOfSamples; ++i) {
0075 unsigned short *pos = theData + i * 100;
0076 memcpy(pos, &slice, 200);
0077 theSliceStarts.push_back(std::pair<int, bool>(i * 100, true));
0078 }
0079 theSize = theNumberOfSamples * 100;
0080 }
0081
0082 void CSCCFEBData::add(const CSCStripDigi &digi, int layer) {
0083 std::vector<int> scaCounts = digi.getADCCounts();
0084 for (unsigned itime = 0; itime < theNumberOfSamples; ++itime) {
0085 unsigned channel = (digi.getStrip() - 1) % 16 + 1;
0086 unsigned value = scaCounts[itime] & 0xFFF;
0087
0088 CSCCFEBTimeSlice *slice = timeSlice(itime);
0089 assert(slice != nullptr);
0090 slice->timeSample(layer, channel, fDCFEB)->adcCounts = value;
0091
0092 slice->setCRC();
0093 }
0094 }
0095
0096 const CSCCFEBTimeSlice *CSCCFEBData::timeSlice(unsigned i) const {
0097 assert(i < theNumberOfSamples);
0098 std::pair<int, bool> start = theSliceStarts[i];
0099
0100 return start.second ? reinterpret_cast<const CSCCFEBTimeSlice *>(theData + start.first) : nullptr;
0101 }
0102
0103 CSCCFEBTimeSlice *CSCCFEBData::timeSlice(unsigned i) {
0104 assert(i < theNumberOfSamples);
0105 std::pair<int, bool> start = theSliceStarts[i];
0106
0107 return start.second ? reinterpret_cast<CSCCFEBTimeSlice *>(theData + start.first) : nullptr;
0108 }
0109
0110 unsigned CSCCFEBData::adcCounts(unsigned layer, unsigned channel, unsigned timeBin) const {
0111 unsigned result = 0;
0112 const CSCCFEBTimeSlice *slice = timeSlice(timeBin);
0113
0114 if (slice)
0115 result = slice->timeSample(layer, channel, fDCFEB)->adcCounts;
0116 return result;
0117 }
0118 unsigned CSCCFEBData::adcOverflow(unsigned layer, unsigned channel, unsigned timeBin) const {
0119 unsigned result = 0;
0120 const CSCCFEBTimeSlice *slice = timeSlice(timeBin);
0121
0122 if (slice)
0123 result = slice->timeSample(layer, channel, fDCFEB)->adcOverflow;
0124 return result;
0125 }
0126
0127 unsigned CSCCFEBData::controllerData(unsigned uglay, unsigned ugchan, unsigned timeBin) const {
0128
0129
0130
0131
0132
0133
0134 unsigned result = 0;
0135 const CSCCFEBTimeSlice *slice = timeSlice(timeBin);
0136
0137 if (slice)
0138 result = slice->timeSample((ugchan - 1) * 6 + uglay - 1)->controllerData;
0139 return result;
0140 }
0141
0142 unsigned CSCCFEBData::overlappedSampleFlag(unsigned layer, unsigned channel, unsigned timeBin) const {
0143 unsigned result = 0;
0144 const CSCCFEBTimeSlice *slice = timeSlice(timeBin);
0145
0146 if (slice)
0147 result = slice->timeSample(layer, channel, fDCFEB)->overlappedSampleFlag;
0148 return result;
0149 }
0150 unsigned CSCCFEBData::errorstat(unsigned layer, unsigned channel, unsigned timeBin) const {
0151 unsigned result = 0;
0152 const CSCCFEBTimeSlice *slice = timeSlice(timeBin);
0153
0154 if (slice)
0155 result = slice->timeSample(layer, channel, fDCFEB)->errorstat;
0156 return result;
0157 }
0158
0159 void CSCCFEBData::setL1A(unsigned l1a) {
0160 for (unsigned i = 0; i < theNumberOfSamples; i++)
0161 setL1A(i, l1a);
0162 }
0163
0164 void CSCCFEBData::setL1A(unsigned i, unsigned l1a) {
0165 assert(i < theNumberOfSamples);
0166 std::pair<int, bool> start = theSliceStarts[i];
0167
0168 if (start.second) {
0169 (reinterpret_cast<CSCCFEBTimeSlice *>(theData + start.first))->set_L1Anumber(l1a);
0170 }
0171 }
0172
0173 CSCCFEBStatusDigi CSCCFEBData::statusDigi() const {
0174
0175
0176
0177
0178 std::vector<uint16_t> crcWords(nTimeSamples());
0179 std::vector<uint16_t> contrWords(nTimeSamples());
0180
0181 if (nTimeSamples() == 0) {
0182 LogTrace("CSCCFEBData|CSCRawToDigi") << "nTimeSamples is zero - CFEB data corrupt?";
0183 } else {
0184 for (unsigned itime = 0; itime < nTimeSamples(); ++itime) {
0185 const CSCCFEBTimeSlice *slice = timeSlice(itime);
0186
0187 if (slice)
0188 crcWords[itime] = slice->get_crc();
0189 if (slice) {
0190 int layer = 1;
0191 for (unsigned i = 0; i < 16; ++i) {
0192 contrWords[itime] |= slice->timeSample(i * 6 + layer - 1)->controllerData << i;
0193 }
0194 }
0195 }
0196 }
0197
0198 CSCCFEBStatusDigi result(boardNumber_ + 1, crcWords, contrWords, bWords);
0199 return result;
0200 }
0201
0202 void CSCCFEBData::digis(uint32_t idlayer, std::vector<CSCStripDigi> &result) const {
0203 LogTrace("CSCCFEBData|CSCRawToDigi") << "nTimeSamples in CSCCFEBData::digis = " << nTimeSamples();
0204 if (nTimeSamples() == 0) {
0205 LogTrace("CSCCFEBData|CSCRawToDigi") << "nTimeSamples is zero - CFEB data corrupt?";
0206 return;
0207 }
0208
0209 result.reserve(16);
0210
0211 std::vector<int> sca(nTimeSamples());
0212 std::vector<uint16_t> overflow(nTimeSamples());
0213 std::vector<uint16_t> overlap(nTimeSamples());
0214 std::vector<uint16_t> errorfl(nTimeSamples());
0215
0216 bool me1a = (CSCDetId::station(idlayer) == 1) && (CSCDetId::ring(idlayer) == 4);
0217 bool zplus = (CSCDetId::endcap(idlayer) == 1);
0218 bool me1b = (CSCDetId::station(idlayer) == 1) && (CSCDetId::ring(idlayer) == 1);
0219
0220 unsigned layer = CSCDetId::layer(idlayer);
0221
0222 std::vector<uint16_t> l1a_phase(nTimeSamples());
0223 for (unsigned itime = 0; itime < nTimeSamples(); ++itime) {
0224 l1a_phase[itime] = controllerData(layer, 13, itime);
0225 LogTrace("CSCCFEBData|CSCRawToDigi") << CSCDetId(idlayer) << " time sample " << itime + 1
0226 << " l1a_phase = " << controllerData(layer, 13, itime);
0227 LogTrace("CSCCFEBData|CSCRawToDigi") << CSCDetId(idlayer) << " time sample " << itime + 1
0228 << " lct_phase = " << controllerData(layer, 14, itime);
0229 LogTrace("CSCCFEBData|CSCRawToDigi") << CSCDetId(idlayer) << " time sample " << itime + 1
0230 << " # samples = " << controllerData(layer, 16, itime);
0231 };
0232
0233 for (unsigned ichannel = 1; ichannel <= 16; ++ichannel) {
0234
0235
0236
0237
0238
0239
0240
0241 for (unsigned itime = 0; itime < nTimeSamples(); ++itime) {
0242 const CSCCFEBTimeSlice *slice = timeSlice(itime);
0243 if (slice) {
0244 CSCCFEBDataWord *word;
0245 word = slice->timeSample(layer, ichannel, fDCFEB);
0246 if (word) {
0247 sca[itime] = word->adcCounts;
0248 overflow[itime] = word->adcOverflow;
0249 overlap[itime] = word->overlappedSampleFlag;
0250 errorfl[itime] = word->errorstat;
0251
0252
0253
0254
0255 overlap[itime] = ((l1a_phase[itime] & 0x1) << 8) | (word->overlappedSampleFlag & 0x1);
0256 }
0257 }
0258 }
0259 if (sca.empty()) {
0260 LogTrace("CSCCFEBData|CSCRawToDigi") << "ADC counts empty - CFEB data corrupt?";
0261 break;
0262 }
0263 int strip = ichannel + 16 * boardNumber_;
0264
0265 if (theFormatVersion >= 2013) {
0266
0267 if (me1a)
0268 strip = strip % CSCConstants::NUM_STRIPS_ME1B;
0269 if (me1a && zplus) {
0270 strip = CSCConstants::NUM_STRIPS_ME1A_UNGANGED + 1 - strip;
0271 }
0272 if (me1b && !zplus) {
0273 strip = CSCConstants::NUM_STRIPS_ME1B + 1 - strip;
0274 }
0275
0276 } else {
0277
0278 if (me1a)
0279 strip = strip % CSCConstants::NUM_STRIPS_ME1B;
0280 if (me1a && zplus) {
0281 strip = CSCConstants::NUM_STRIPS_ME1A_GANGED + 1 - strip;
0282 }
0283 if (me1b && !zplus) {
0284 strip = CSCConstants::NUM_STRIPS_ME1B + 1 - strip;
0285 }
0286 }
0287 result.push_back(CSCStripDigi(strip, sca, overflow, overlap, errorfl));
0288 }
0289 }
0290
0291 std::vector<CSCStripDigi> CSCCFEBData::digis(unsigned idlayer) const {
0292 std::vector<CSCStripDigi> result;
0293 uint32_t layer = idlayer;
0294 digis(layer, result);
0295 return result;
0296 }
0297
0298 bool CSCCFEBData::check() const {
0299 bool result = true;
0300 for (unsigned i = 0; i < theNumberOfSamples; ++i) {
0301 const CSCCFEBTimeSlice *slice = timeSlice(i);
0302 if (slice == nullptr || !timeSlice(i)->check())
0303 result = false;
0304 }
0305 return result;
0306 }
0307
0308 std::ostream &operator<<(std::ostream &os, const CSCCFEBData &data) {
0309 os << "printing CFEB data sample by sample " << std::endl;
0310 for (int ilayer = CSCDetId::minLayerId(); ilayer <= CSCDetId::maxLayerId(); ++ilayer) {
0311 for (unsigned channel = 1; channel <= 16; ++channel) {
0312 unsigned strip = channel + data.boardNumber_ * 16;
0313 os << "Strip " << strip << " ";
0314 for (unsigned timeBin = 0; timeBin < data.nTimeSamples(); ++timeBin) {
0315 os << data.adcCounts(ilayer, channel, timeBin) << " ";
0316 }
0317 os << std::endl;
0318 }
0319 }
0320 return os;
0321 }
0322
0323 std::vector<std::vector<CSCStripDigi> > CSCCFEBData::stripDigis() {
0324 std::vector<std::vector<CSCStripDigi> > result;
0325 for (int layer = CSCDetId::minLayerId(); layer <= CSCDetId::maxLayerId(); ++layer) {
0326 result.push_back(digis(layer));
0327 }
0328 return result;
0329 }