00001 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00002 #include "FWCore/Framework/interface/EventSetup.h"
00003 #include "FWCore/Framework/interface/ESHandle.h"
00004
00005
00006 #include "CondFormats/DataRecord/interface/SiStripFedCablingRcd.h"
00007 #include "CalibTracker/Records/interface/SiStripDetCablingRcd.h"
00008 #include "CondFormats/SiStripObjects/interface/SiStripFedCabling.h"
00009 #include "CondFormats/DataRecord/interface/SiStripPedestalsRcd.h"
00010 #include "CondFormats/DataRecord/interface/SiStripNoisesRcd.h"
00011
00012 #include "DQM/SiStripMonitorHardware/interface/SiStripFEDSpyBuffer.h"
00013 #include "DQM/SiStripMonitorHardware/interface/SiStripSpyUtilities.h"
00014
00015 using edm::LogError;
00016 using edm::LogWarning;
00017 using edm::LogInfo;
00018
00019
00020 namespace sistrip {
00021 SpyUtilities::SpyUtilities() :
00022 cabling_(0),
00023 cacheId_(0),
00024 detCabling_(0),
00025 cacheIdDet_(0),
00026 pedsCacheId_(0),
00027 pedsHandle_(0),
00028 noiseCacheId_(0),
00029 noiseHandle_(0)
00030 {
00031
00032 }
00033
00034 SpyUtilities::~SpyUtilities()
00035 {
00036 if ( cabling_ ) cabling_ = 0;
00037 if ( detCabling_ ) detCabling_ = 0;
00038 }
00039
00040 const SiStripFedCabling* SpyUtilities::getCabling( const edm::EventSetup& setup )
00041 {
00042
00043 uint32_t cache_id = setup.get<SiStripFedCablingRcd>().cacheIdentifier();
00044
00045 if ( cacheId_ != cache_id ) {
00046
00047 edm::ESHandle<SiStripFedCabling> c;
00048 setup.get<SiStripFedCablingRcd>().get( c );
00049 cabling_ = c.product();
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 cacheId_ = cache_id;
00072
00073 }
00074
00075 return cabling_;
00076 }
00077
00078 const SiStripDetCabling* SpyUtilities::getDetCabling( const edm::EventSetup& setup )
00079 {
00080
00081 uint32_t cache_id = setup.get<SiStripDetCablingRcd>().cacheIdentifier();
00082
00083 if ( cacheIdDet_ != cache_id ) {
00084
00085 edm::ESHandle<SiStripDetCabling> c;
00086 setup.get<SiStripDetCablingRcd>().get( c );
00087 detCabling_ = c.product();
00088 cacheIdDet_ = cache_id;
00089 }
00090
00091 return detCabling_;
00092 }
00093
00094 edm::ESHandle<SiStripPedestals> SpyUtilities::getPedestalHandle(const edm::EventSetup& eventSetup)
00095 {
00096
00097 uint32_t lCacheId = eventSetup.get<SiStripPedestalsRcd>().cacheIdentifier();
00098 if (lCacheId != pedsCacheId_) {
00099 eventSetup.get<SiStripPedestalsRcd>().get(pedsHandle_);
00100 pedsCacheId_ = lCacheId;
00101 }
00102
00103 return pedsHandle_;
00104 }
00105
00106
00107 edm::ESHandle<SiStripNoises> SpyUtilities::getNoiseHandle(const edm::EventSetup& eventSetup)
00108 {
00109
00110 uint32_t lCacheId = eventSetup.get<SiStripNoisesRcd>().cacheIdentifier();
00111 if (lCacheId != noiseCacheId_) {
00112 eventSetup.get<SiStripNoisesRcd>().get(noiseHandle_);
00113 noiseCacheId_ = lCacheId;
00114 }
00115
00116 return noiseHandle_;
00117 }
00118
00119
00120 const SpyUtilities::Frame
00121 SpyUtilities::extractFrameInfo(const edm::DetSetVector<SiStripRawDigi>::detset & channelDigis,
00122 bool aPrintDebug)
00123 {
00124
00125 SpyUtilities::Frame lFrame;
00126 lFrame.detId = channelDigis.detId();
00127 lFrame.firstHeaderBit = 0;
00128 lFrame.firstTrailerBit = 0;
00129 lFrame.digitalLow = 0;
00130 lFrame.digitalHigh = 0;
00131 lFrame.baseline = 0;
00132 lFrame.apvErrorBit.first = false;
00133 lFrame.apvErrorBit.second = false;
00134 lFrame.apvAddress.first = 0;
00135 lFrame.apvAddress.second = 0;
00136
00137 uint16_t min = 0x3FF;
00138 uint16_t max = 0;
00139 edm::DetSetVector<SiStripRawDigi>::detset::const_iterator iDigi = channelDigis.begin();
00140 const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
00141
00142
00143 uint16_t numzeroes = 0, numsats = 0;
00144
00145 if (iDigi == endChannelDigis) return lFrame;
00146
00147 for (; iDigi != endChannelDigis; ++iDigi) {
00148 const uint16_t val = iDigi->adc();
00149 if (val < min) min = val;
00150 if (val > max) max = val;
00151 if (val==0) numzeroes++;
00152 if (val==0x3FF) numsats++;
00153 lFrame.baseline += val;
00154 }
00155
00156 if (channelDigis.size()>0) lFrame.baseline = lFrame.baseline/channelDigis.size();
00157 lFrame.digitalLow = min;
00158 lFrame.digitalHigh = max;
00159
00160 const uint16_t threshold = static_cast<uint16_t>( (2.0 * static_cast<double>(max-min)) / 3.0 );
00161
00162 if (aPrintDebug){
00163
00164
00165
00166
00167
00168 if (numzeroes>0 || numsats>0) {
00169 edm::LogWarning("SiStripSpyUtilities") << "Channel with key: " << lFrame.detId << " has "
00170 << numzeroes << " zero and "
00171 << numsats << " saturated samples.";
00172 }
00173 }
00174
00175 lFrame.firstHeaderBit = findHeaderBits(channelDigis,threshold);
00176 lFrame.firstTrailerBit = findTrailerBits(channelDigis,threshold);
00177
00178 lFrame.apvErrorBit = findAPVErrorBits(channelDigis,threshold,lFrame.firstHeaderBit);
00179 lFrame.apvAddress = findAPVAddresses(channelDigis,threshold,lFrame.firstHeaderBit);
00180
00181 return lFrame;
00182
00183 }
00184
00185 const uint16_t SpyUtilities::range(const SpyUtilities::Frame & aFrame)
00186 {
00187 if (aFrame.digitalHigh < aFrame.digitalLow) return 0;
00188 else return aFrame.digitalHigh-aFrame.digitalLow;
00189 }
00190
00191 const uint16_t SpyUtilities::threshold(const SpyUtilities::Frame & aFrame)
00192 {
00193 return static_cast<uint16_t>( (2.0 * static_cast<double>(range(aFrame))) / 3.0 );
00194 }
00195
00196 const uint8_t SpyUtilities::extractAPVaddress(const SpyUtilities::Frame & aFrame)
00197 {
00198
00199 if (aFrame.apvErrorBit.first == false) return aFrame.apvAddress.first;
00200 else if (aFrame.apvErrorBit.second == false) {
00201 return aFrame.apvAddress.second;
00202 }
00203 else {
00204 return 0;
00205 }
00206
00207 }
00208
00209 void SpyUtilities::getMajorityHeader(const edm::DetSetVector<SiStripRawDigi> *aInputDigis,
00210 uint16_t & aFirstHeaderBit,
00211 bool printResult)
00212 {
00213
00214 std::vector<uint16_t> lFirstBitVec;
00215 lFirstBitVec.reserve(aInputDigis->size());
00216 aFirstHeaderBit = 0;
00217 edm::DetSetVector<SiStripRawDigi>::const_iterator lDigis = aInputDigis->begin();
00218
00219 for ( ; lDigis != aInputDigis->end(); lDigis++){
00220 sistrip::SpyUtilities::Frame lFrame = sistrip::SpyUtilities::extractFrameInfo(*lDigis);
00221 lFirstBitVec.push_back(lFrame.firstHeaderBit);
00222 }
00223
00224 std::pair<uint16_t,uint32_t> lMaj = sistrip::SpyUtilities::findMajorityValue(lFirstBitVec);
00225 aFirstHeaderBit = lMaj.first;
00226 uint32_t lMajorityCounter = lMaj.second;
00227
00228
00229 uint16_t lFirstTrailerBit = aFirstHeaderBit+24+sistrip::STRIPS_PER_FEDCH;
00230
00231 if (printResult)
00232 {
00233 LogInfo("SiStripSpyUtilities") << " -- Found majority position of first header (trailer) bit: "
00234 << aFirstHeaderBit
00235 << " (" << lFirstTrailerBit
00236 << ") for " << lMajorityCounter << " out of " << lFirstBitVec.size() << " channels."
00237 << std::endl;
00238 }
00239 }
00240
00241
00242 const bool SpyUtilities::isValid(const SpyUtilities::Frame & aFrame,
00243 const FrameQuality & aQuality,
00244 const uint16_t aExpectedPos)
00245 {
00246
00247 uint16_t lRange = sistrip::SpyUtilities::range(aFrame);
00248
00249 if (lRange < aQuality.minDigiRange || lRange > aQuality.maxDigiRange) {
00250 return false;
00251 }
00252 else if (aFrame.digitalLow < aQuality.minZeroLight || aFrame.digitalLow > aQuality.maxZeroLight) {
00253 return false;
00254 }
00255 else if (aFrame.digitalHigh < aQuality.minTickHeight || aFrame.digitalHigh > aQuality.maxTickHeight){
00256 return false;
00257 }
00258
00259 else if ( aExpectedPos > 0 &&
00260 (
00261 !(aFrame.firstHeaderBit == aExpectedPos &&
00262 aFrame.firstTrailerBit == aExpectedPos+24+sistrip::STRIPS_PER_FEDCH)
00263 )
00264 ) {
00265 return false;
00266 }
00267 else if (aFrame.apvErrorBit.first && aFrame.apvErrorBit.second) {
00268 return false;
00269 }
00270
00271 return true;
00272 }
00273
00274
00275 const uint16_t SpyUtilities::findHeaderBits(const edm::DetSetVector<SiStripRawDigi>::detset & channelDigis,
00276 const uint16_t threshold)
00277 {
00278
00279
00280 uint8_t aboveThreshold = 0;
00281 bool foundHeader = false;
00282 uint16_t count = 0;
00283
00284 edm::DetSetVector<SiStripRawDigi>::detset::const_iterator iDigi = channelDigis.begin();
00285 const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
00286
00287 for (; iDigi != endChannelDigis; ++iDigi) {
00288 if ( iDigi->adc() > threshold) {
00289 aboveThreshold++;
00290 }
00291 else {
00292 aboveThreshold = 0;
00293 }
00294 if (aboveThreshold == 6) {foundHeader = true; break; }
00295 count++;
00296 }
00297
00298
00299 if (foundHeader && count < 5) return 0;
00300 if (foundHeader) return count-5;
00301 return sistrip::SPY_SAMPLES_PER_CHANNEL;
00302
00303 }
00304
00305 const uint16_t SpyUtilities::findTrailerBits(const edm::DetSetVector<SiStripRawDigi>::detset & channelDigis,
00306 const uint16_t threshold)
00307 {
00308
00309
00310 uint8_t aboveThreshold = 0;
00311 bool foundTrailer = false;
00312
00313
00314
00315
00316 uint16_t count = 24+sistrip::STRIPS_PER_FEDCH;
00317
00318 if (count >= sistrip::SPY_SAMPLES_PER_CHANNEL) return sistrip::SPY_SAMPLES_PER_CHANNEL;
00319
00320 edm::DetSetVector<SiStripRawDigi>::detset::const_iterator iDigi = channelDigis.begin()+count;
00321 const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
00322
00323 for (; iDigi != endChannelDigis; ++iDigi) {
00324 if ( iDigi->adc() > threshold) {
00325 aboveThreshold++;
00326 }
00327 else {
00328 aboveThreshold = 0;
00329 }
00330 if (aboveThreshold == 2) {foundTrailer = true; break; }
00331 count++;
00332 }
00333
00334
00335 if (foundTrailer && count < 1) return 0;
00336 if (foundTrailer) return count-1;
00337 return sistrip::SPY_SAMPLES_PER_CHANNEL;
00338
00339 }
00340
00341
00342
00343 const std::pair<bool,bool>
00344 SpyUtilities::findAPVErrorBits(const edm::DetSetVector<SiStripRawDigi>::detset & channelDigis,
00345 const uint16_t threshold,
00346 const uint16_t aFirstBits)
00347 {
00348
00349
00350 uint16_t count = aFirstBits+22;
00351
00352 std::pair<bool,bool> lPair = std::pair<bool,bool>(false,false);
00353
00354
00355 if (count >= sistrip::SPY_SAMPLES_PER_CHANNEL-1) return lPair;
00356
00357 edm::DetSetVector<SiStripRawDigi>::detset::const_iterator iDigi = channelDigis.begin()+count;
00358 const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
00359
00360
00361 if (iDigi == endChannelDigis) return lPair;
00362
00363 if ( iDigi->adc() <= threshold) lPair.first = true;
00364 ++iDigi;
00365
00366
00367 if (iDigi == endChannelDigis) return std::pair<bool,bool>(false,false);
00368
00369 if ( iDigi->adc() <= threshold) lPair.second = true;
00370
00371 return lPair;
00372 }
00373
00374
00375 const std::pair<uint8_t,uint8_t>
00376 SpyUtilities::findAPVAddresses(const edm::DetSetVector<SiStripRawDigi>::detset & channelDigis,
00377 const uint16_t threshold,
00378 const uint16_t aFirstBits)
00379 {
00380
00381
00382 uint16_t count = aFirstBits+6;
00383 std::pair<uint8_t,uint8_t> lPair = std::pair<uint8_t,uint8_t>(0,0);
00384
00385
00386 if (count >= sistrip::SPY_SAMPLES_PER_CHANNEL-15) return lPair;
00387
00388 edm::DetSetVector<SiStripRawDigi>::detset::const_iterator iDigi = channelDigis.begin()+count;
00389 const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
00390
00391
00392 if (iDigi == endChannelDigis) return lPair;
00393
00394 for (uint8_t i = 0; i < 16; ++i) {
00395 if ( iDigi->adc() > threshold) {
00396
00397 if (i%2==0)
00398 lPair.first |= (0x80 >> static_cast<uint8_t>(i/2));
00399 else
00400 lPair.second |= (0x80 >> static_cast<uint8_t>(i/2));
00401 }
00402 ++iDigi;
00403 }
00404
00405 return lPair;
00406
00407 }
00408
00409
00410 std::string SpyUtilities::print(const SpyUtilities::Frame & aFrame,
00411 std::string aErr)
00412 {
00413
00414 std::ostringstream lOs;
00415 lOs << " ------------------------------------------------------" << std::endl
00416 << " -- Error: " << aErr << std::endl
00417 << " ------- Printing Frame for detId " << aFrame.detId << " --------" << std::endl
00418 << " -- firstHeaderBit = " << aFrame.firstHeaderBit << std::endl
00419 << " -- firstTrailerBit = " << aFrame.firstTrailerBit << std::endl
00420 << " -- digitalLow = " << aFrame.digitalLow << std::endl
00421 << " -- digitalHigh = " << aFrame.digitalHigh << std::endl
00422 << " -- baseline = " << aFrame.baseline << std::endl
00423 << " -- apvErrorBits = " << aFrame.apvErrorBit.first
00424 << " " << aFrame.apvErrorBit.second << std::endl
00425 << " -- apvAddresses = " << static_cast<uint16_t>(aFrame.apvAddress.first)
00426 << " " << static_cast<uint16_t>(aFrame.apvAddress.second) << std::endl
00427 << " ------------------------------------------------------" << std::endl;
00428 return lOs.str();
00429
00430 }
00431
00432
00433 void SpyUtilities::fedIndex(const uint32_t aFedIndex,
00434 uint16_t & aFedId,
00435 uint16_t & aFedChannel){
00436
00437
00438 aFedId = static_cast<uint16_t>(aFedIndex/sistrip::FEDCH_PER_FED);
00439 aFedChannel = static_cast<uint16_t>(aFedIndex%sistrip::FEDCH_PER_FED);
00440
00441 if (aFedId < sistrip::FED_ID_MIN ||
00442 aFedId > sistrip::FED_ID_MAX ||
00443 aFedChannel >= sistrip::FEDCH_PER_FED ) {
00444 aFedId = sistrip::invalid_;
00445 aFedChannel = sistrip::invalid_;
00446 }
00447
00448 }
00449
00450 std::pair<uint16_t,uint32_t> SpyUtilities::findMajorityValue(std::vector<uint16_t>& values,
00451 const uint16_t aFedId)
00452 {
00453
00454 uint32_t lTot = values.size();
00455 if (!lTot) return std::pair<uint16_t,uint32_t>(0,0);
00456
00457 std::sort(values.begin(),values.end());
00458 uint32_t lMajorityCounter = 0;
00459 uint16_t lMaj = 0;
00460
00461 std::vector<uint16_t>::iterator lIter = values.begin();
00462 for ( ; lIter != values.end(); ) {
00463 uint32_t lCounter = std::count(lIter,values.end(),*lIter);
00464 if (lCounter > lMajorityCounter) {
00465 lMajorityCounter = lCounter;
00466 lMaj = *lIter;
00467 }
00468 lIter += lCounter;
00469 }
00470
00471
00472
00473 if (static_cast<float>(lMajorityCounter)/lTot < 0.5) {
00474 LogError("SiStripSpyUtilities") << " -- Found majority position for index "
00475 << aFedId
00476 << ": " << lMaj
00477 << " for less than half the values : " << lMajorityCounter << " out of " << lTot << " values."
00478 << std::endl;
00479 }
00480
00481 return std::pair<uint16_t,uint32_t>(lMaj,lMajorityCounter);
00482
00483 }
00484
00485 void SpyUtilities::fillFEDMajorities(const std::map<uint32_t,uint32_t>& channelValues,
00486 std::vector<uint32_t> & fedMajoritiesToFill)
00487 {
00488
00489 std::map<uint32_t,uint32_t>::const_iterator lMapIter = channelValues.begin();
00490 uint16_t lPreviousFedId = 0;
00491 std::vector<uint16_t> lAddrVec;
00492 lAddrVec.reserve(sistrip::FEDCH_PER_FED);
00493 fedMajoritiesToFill.resize(sistrip::FED_ID_MAX-sistrip::FED_ID_MIN+1,0);
00494 uint32_t lChCount = 0;
00495
00496 for ( ; lMapIter != channelValues.end(); ++lMapIter,++lChCount){
00497
00498 uint16_t lFedId = static_cast<uint16_t>(lMapIter->first/sistrip::FEDCH_PER_FED);
00499
00500 if (lPreviousFedId == 0) {
00501 lPreviousFedId = lFedId;
00502 }
00503 if (lFedId == lPreviousFedId) {
00504 lAddrVec.push_back(lMapIter->second);
00505 }
00506 if (lFedId != lPreviousFedId || (lChCount == channelValues.size()-1)) {
00507
00508
00509 uint32_t lMaj = sistrip::SpyUtilities::findMajorityValue(lAddrVec,lPreviousFedId).first;
00510 fedMajoritiesToFill[lPreviousFedId] = lMaj;
00511
00512 lAddrVec.clear();
00513
00514
00515 if (lFedId != lPreviousFedId) {
00516 lAddrVec.push_back(lMapIter->second);
00517 lPreviousFedId = lFedId;
00518 }
00519
00520 }
00521 }
00522
00523 }
00524
00525 }