File indexing completed on 2024-04-06 12:08:51
0001 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0002
0003 #include "DQM/SiStripMonitorHardware/interface/SiStripFEDSpyBuffer.h"
0004 #include "DQM/SiStripMonitorHardware/interface/SiStripSpyUtilities.h"
0005
0006 using edm::LogError;
0007 using edm::LogInfo;
0008 using edm::LogWarning;
0009
0010 namespace sistrip {
0011 const SpyUtilities::Frame SpyUtilities::extractFrameInfo(
0012 const edm::DetSetVector<SiStripRawDigi>::detset& channelDigis, bool aPrintDebug) {
0013 SpyUtilities::Frame lFrame;
0014 lFrame.detId = channelDigis.detId();
0015 lFrame.firstHeaderBit = 0;
0016 lFrame.firstTrailerBit = 0;
0017 lFrame.digitalLow = 0;
0018 lFrame.digitalHigh = 0;
0019 lFrame.baseline = 0;
0020 lFrame.apvErrorBit.first = false;
0021 lFrame.apvErrorBit.second = false;
0022 lFrame.apvAddress.first = 0;
0023 lFrame.apvAddress.second = 0;
0024
0025 uint16_t min = 0x3FF;
0026 uint16_t max = 0;
0027 edm::DetSetVector<SiStripRawDigi>::detset::const_iterator iDigi = channelDigis.begin();
0028 const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
0029
0030
0031 uint16_t numzeroes = 0, numsats = 0;
0032
0033 if (iDigi == endChannelDigis)
0034 return lFrame;
0035
0036 for (; iDigi != endChannelDigis; ++iDigi) {
0037 const uint16_t val = iDigi->adc();
0038 if (val < min)
0039 min = val;
0040 if (val > max)
0041 max = val;
0042 if (val == 0)
0043 numzeroes++;
0044 if (val == 0x3FF)
0045 numsats++;
0046 lFrame.baseline += val;
0047 }
0048
0049 if (!channelDigis.empty())
0050 lFrame.baseline = lFrame.baseline / channelDigis.size();
0051 lFrame.digitalLow = min;
0052 lFrame.digitalHigh = max;
0053
0054 const uint16_t threshold = static_cast<uint16_t>((2.0 * static_cast<double>(max - min)) / 3.0);
0055
0056 if (aPrintDebug) {
0057 if (edm::isDebugEnabled()) {
0058 LogDebug("SiStripSpyUtilities") << "Channel with key: " << lFrame.detId << " Min: " << min << " Max: " << max
0059 << " Range: " << (max - min) << " Threshold: " << threshold;
0060 }
0061 if (numzeroes > 0 || numsats > 0) {
0062 edm::LogWarning("SiStripSpyUtilities") << "Channel with key: " << lFrame.detId << " has " << numzeroes
0063 << " zero and " << numsats << " saturated samples.";
0064 }
0065 }
0066
0067 lFrame.firstHeaderBit = findHeaderBits(channelDigis, threshold);
0068 lFrame.firstTrailerBit = findTrailerBits(channelDigis, threshold);
0069
0070 lFrame.apvErrorBit = findAPVErrorBits(channelDigis, threshold, lFrame.firstHeaderBit);
0071 lFrame.apvAddress = findAPVAddresses(channelDigis, threshold, lFrame.firstHeaderBit);
0072
0073 return lFrame;
0074 }
0075
0076 const uint16_t SpyUtilities::range(const SpyUtilities::Frame& aFrame) {
0077 if (aFrame.digitalHigh < aFrame.digitalLow)
0078 return 0;
0079 else
0080 return aFrame.digitalHigh - aFrame.digitalLow;
0081 }
0082
0083 const uint16_t SpyUtilities::threshold(const SpyUtilities::Frame& aFrame) {
0084 return static_cast<uint16_t>((2.0 * static_cast<double>(range(aFrame))) / 3.0);
0085 }
0086
0087 const uint8_t SpyUtilities::extractAPVaddress(const SpyUtilities::Frame& aFrame) {
0088 if (aFrame.apvErrorBit.first == false)
0089 return aFrame.apvAddress.first;
0090 else if (aFrame.apvErrorBit.second == false) {
0091 return aFrame.apvAddress.second;
0092 } else {
0093 return 0;
0094 }
0095 }
0096
0097 void SpyUtilities::getMajorityHeader(const edm::DetSetVector<SiStripRawDigi>* aInputDigis,
0098 uint16_t& aFirstHeaderBit,
0099 bool printResult) {
0100 std::vector<uint16_t> lFirstBitVec;
0101 lFirstBitVec.reserve(aInputDigis->size());
0102 aFirstHeaderBit = 0;
0103 edm::DetSetVector<SiStripRawDigi>::const_iterator lDigis = aInputDigis->begin();
0104
0105 for (; lDigis != aInputDigis->end(); lDigis++) {
0106 sistrip::SpyUtilities::Frame lFrame = sistrip::SpyUtilities::extractFrameInfo(*lDigis);
0107 lFirstBitVec.push_back(lFrame.firstHeaderBit);
0108 }
0109
0110 std::pair<uint16_t, uint32_t> lMaj = sistrip::SpyUtilities::findMajorityValue(lFirstBitVec);
0111 aFirstHeaderBit = lMaj.first;
0112 uint32_t lMajorityCounter = lMaj.second;
0113
0114
0115 uint16_t lFirstTrailerBit = aFirstHeaderBit + 24 + sistrip::STRIPS_PER_FEDCH;
0116
0117 if (printResult) {
0118 LogInfo("SiStripSpyUtilities") << " -- Found majority position of first header (trailer) bit: " << aFirstHeaderBit
0119 << " (" << lFirstTrailerBit << ") for " << lMajorityCounter << " out of "
0120 << lFirstBitVec.size() << " channels." << std::endl;
0121 }
0122 }
0123
0124 const bool SpyUtilities::isValid(const SpyUtilities::Frame& aFrame,
0125 const FrameQuality& aQuality,
0126 const uint16_t aExpectedPos) {
0127 uint16_t lRange = sistrip::SpyUtilities::range(aFrame);
0128
0129 if (lRange < aQuality.minDigiRange || lRange > aQuality.maxDigiRange) {
0130 return false;
0131 } else if (aFrame.digitalLow < aQuality.minZeroLight || aFrame.digitalLow > aQuality.maxZeroLight) {
0132 return false;
0133 } else if (aFrame.digitalHigh < aQuality.minTickHeight || aFrame.digitalHigh > aQuality.maxTickHeight) {
0134 return false;
0135 }
0136
0137 else if (aExpectedPos > 0 && (!(aFrame.firstHeaderBit == aExpectedPos &&
0138 aFrame.firstTrailerBit == aExpectedPos + 24 + sistrip::STRIPS_PER_FEDCH))) {
0139 return false;
0140 } else if (aFrame.apvErrorBit.first && aFrame.apvErrorBit.second) {
0141 return false;
0142 }
0143
0144 return true;
0145 }
0146
0147 const uint16_t SpyUtilities::findHeaderBits(const edm::DetSetVector<SiStripRawDigi>::detset& channelDigis,
0148 const uint16_t threshold) {
0149
0150 uint8_t aboveThreshold = 0;
0151 bool foundHeader = false;
0152 uint16_t count = 0;
0153
0154 edm::DetSetVector<SiStripRawDigi>::detset::const_iterator iDigi = channelDigis.begin();
0155 const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
0156
0157 for (; iDigi != endChannelDigis; ++iDigi) {
0158 if (iDigi->adc() > threshold) {
0159 aboveThreshold++;
0160 } else {
0161 aboveThreshold = 0;
0162 }
0163 if (aboveThreshold == 6) {
0164 foundHeader = true;
0165 break;
0166 }
0167 count++;
0168 }
0169
0170
0171 if (foundHeader && count < 5)
0172 return 0;
0173 if (foundHeader)
0174 return count - 5;
0175 return sistrip::SPY_SAMPLES_PER_CHANNEL;
0176 }
0177
0178 const uint16_t SpyUtilities::findTrailerBits(const edm::DetSetVector<SiStripRawDigi>::detset& channelDigis,
0179 const uint16_t threshold) {
0180
0181 uint8_t aboveThreshold = 0;
0182 bool foundTrailer = false;
0183
0184
0185
0186
0187 uint16_t count = 24 + sistrip::STRIPS_PER_FEDCH;
0188
0189 if (count >= sistrip::SPY_SAMPLES_PER_CHANNEL)
0190 return sistrip::SPY_SAMPLES_PER_CHANNEL;
0191
0192 edm::DetSetVector<SiStripRawDigi>::detset::const_iterator iDigi = channelDigis.begin() + count;
0193 const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
0194
0195 for (; iDigi != endChannelDigis; ++iDigi) {
0196 if (iDigi->adc() > threshold) {
0197 aboveThreshold++;
0198 } else {
0199 aboveThreshold = 0;
0200 }
0201 if (aboveThreshold == 2) {
0202 foundTrailer = true;
0203 break;
0204 }
0205 count++;
0206 }
0207
0208
0209 if (foundTrailer && count < 1)
0210 return 0;
0211 if (foundTrailer)
0212 return count - 1;
0213 return sistrip::SPY_SAMPLES_PER_CHANNEL;
0214 }
0215
0216 const std::pair<bool, bool> SpyUtilities::findAPVErrorBits(
0217 const edm::DetSetVector<SiStripRawDigi>::detset& channelDigis,
0218 const uint16_t threshold,
0219 const uint16_t aFirstBits) {
0220
0221 uint16_t count = aFirstBits + 22;
0222
0223 std::pair<bool, bool> lPair = std::pair<bool, bool>(false, false);
0224
0225
0226 if (count >= sistrip::SPY_SAMPLES_PER_CHANNEL - 1)
0227 return lPair;
0228
0229 edm::DetSetVector<SiStripRawDigi>::detset::const_iterator iDigi = channelDigis.begin() + count;
0230 const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
0231
0232
0233 if (iDigi == endChannelDigis)
0234 return lPair;
0235
0236 if (iDigi->adc() <= threshold)
0237 lPair.first = true;
0238 ++iDigi;
0239
0240
0241 if (iDigi == endChannelDigis)
0242 return std::pair<bool, bool>(false, false);
0243
0244 if (iDigi->adc() <= threshold)
0245 lPair.second = true;
0246
0247 return lPair;
0248 }
0249
0250 const std::pair<uint8_t, uint8_t> SpyUtilities::findAPVAddresses(
0251 const edm::DetSetVector<SiStripRawDigi>::detset& channelDigis,
0252 const uint16_t threshold,
0253 const uint16_t aFirstBits) {
0254
0255 uint16_t count = aFirstBits + 6;
0256 std::pair<uint8_t, uint8_t> lPair = std::pair<uint8_t, uint8_t>(0, 0);
0257
0258
0259 if (count >= sistrip::SPY_SAMPLES_PER_CHANNEL - 15)
0260 return lPair;
0261
0262 edm::DetSetVector<SiStripRawDigi>::detset::const_iterator iDigi = channelDigis.begin() + count;
0263 const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
0264
0265
0266 if (iDigi == endChannelDigis)
0267 return lPair;
0268
0269 for (uint8_t i = 0; i < 16; ++i) {
0270 if (iDigi->adc() > threshold) {
0271
0272 if (i % 2 == 0)
0273 lPair.first |= (0x80 >> static_cast<uint8_t>(i / 2));
0274 else
0275 lPair.second |= (0x80 >> static_cast<uint8_t>(i / 2));
0276 }
0277 ++iDigi;
0278 }
0279
0280 return lPair;
0281 }
0282
0283 std::string SpyUtilities::print(const SpyUtilities::Frame& aFrame, std::string aErr) {
0284 std::ostringstream lOs;
0285 lOs << " ------------------------------------------------------" << std::endl
0286 << " -- Error: " << aErr << std::endl
0287 << " ------- Printing Frame for detId " << aFrame.detId << " --------" << std::endl
0288 << " -- firstHeaderBit = " << aFrame.firstHeaderBit << std::endl
0289 << " -- firstTrailerBit = " << aFrame.firstTrailerBit << std::endl
0290 << " -- digitalLow = " << aFrame.digitalLow << std::endl
0291 << " -- digitalHigh = " << aFrame.digitalHigh << std::endl
0292 << " -- baseline = " << aFrame.baseline << std::endl
0293 << " -- apvErrorBits = " << aFrame.apvErrorBit.first << " " << aFrame.apvErrorBit.second << std::endl
0294 << " -- apvAddresses = " << static_cast<uint16_t>(aFrame.apvAddress.first) << " "
0295 << static_cast<uint16_t>(aFrame.apvAddress.second) << std::endl
0296 << " ------------------------------------------------------" << std::endl;
0297 return lOs.str();
0298 }
0299
0300 void SpyUtilities::fedIndex(const uint32_t aFedIndex, uint16_t& aFedId, uint16_t& aFedChannel) {
0301
0302 aFedId = static_cast<uint16_t>(aFedIndex / sistrip::FEDCH_PER_FED);
0303 aFedChannel = static_cast<uint16_t>(aFedIndex % sistrip::FEDCH_PER_FED);
0304
0305 if (aFedId < sistrip::FED_ID_MIN || aFedId > sistrip::FED_ID_MAX || aFedChannel >= sistrip::FEDCH_PER_FED) {
0306 aFedId = sistrip::invalid_;
0307 aFedChannel = sistrip::invalid_;
0308 }
0309 }
0310
0311 std::pair<uint16_t, uint32_t> SpyUtilities::findMajorityValue(std::vector<uint16_t>& values, const uint16_t aFedId) {
0312 uint32_t lTot = values.size();
0313 if (!lTot)
0314 return std::pair<uint16_t, uint32_t>(0, 0);
0315
0316 std::sort(values.begin(), values.end());
0317 uint32_t lMajorityCounter = 0;
0318 uint16_t lMaj = 0;
0319
0320 std::vector<uint16_t>::iterator lIter = values.begin();
0321 for (; lIter != values.end();) {
0322 uint32_t lCounter = std::count(lIter, values.end(), *lIter);
0323 if (lCounter > lMajorityCounter) {
0324 lMajorityCounter = lCounter;
0325 lMaj = *lIter;
0326 }
0327 lIter += lCounter;
0328 }
0329
0330
0331
0332 if (static_cast<float>(lMajorityCounter) / lTot < 0.5) {
0333 LogError("SiStripSpyUtilities") << " -- Found majority position for index " << aFedId << ": " << lMaj
0334 << " for less than half the values : " << lMajorityCounter << " out of " << lTot
0335 << " values." << std::endl;
0336 }
0337
0338 return std::pair<uint16_t, uint32_t>(lMaj, lMajorityCounter);
0339 }
0340
0341 void SpyUtilities::fillFEDMajorities(const std::map<uint32_t, uint32_t>& channelValues,
0342 std::vector<uint32_t>& fedMajoritiesToFill) {
0343 std::map<uint32_t, uint32_t>::const_iterator lMapIter = channelValues.begin();
0344 uint16_t lPreviousFedId = 0;
0345 std::vector<uint16_t> lAddrVec;
0346 lAddrVec.reserve(sistrip::FEDCH_PER_FED);
0347 fedMajoritiesToFill.resize(sistrip::FED_ID_MAX - sistrip::FED_ID_MIN + 1, 0);
0348 uint32_t lChCount = 0;
0349
0350 for (; lMapIter != channelValues.end(); ++lMapIter, ++lChCount) {
0351 uint16_t lFedId = static_cast<uint16_t>(lMapIter->first / sistrip::FEDCH_PER_FED);
0352
0353 if (lPreviousFedId == 0) {
0354 lPreviousFedId = lFedId;
0355 }
0356 if (lFedId == lPreviousFedId) {
0357 lAddrVec.push_back(lMapIter->second);
0358 }
0359 if (lFedId != lPreviousFedId || (lChCount == channelValues.size() - 1)) {
0360
0361
0362 uint32_t lMaj = sistrip::SpyUtilities::findMajorityValue(lAddrVec, lPreviousFedId).first;
0363 fedMajoritiesToFill[lPreviousFedId] = lMaj;
0364
0365 lAddrVec.clear();
0366
0367
0368 if (lFedId != lPreviousFedId) {
0369 lAddrVec.push_back(lMapIter->second);
0370 lPreviousFedId = lFedId;
0371 }
0372 }
0373 }
0374 }
0375
0376 }