CMS 3D CMS Logo

SiStripSpyUtilities.cc
Go to the documentation of this file.
4 
5 // Needed for the FED cabling and pedestals
11 
14 
15 using edm::LogError;
16 using edm::LogInfo;
17 using edm::LogWarning;
18 
19 namespace sistrip {
21  : cabling_(nullptr),
22  cacheId_(0),
23  detCabling_(nullptr),
24  cacheIdDet_(0),
25  pedsCacheId_(0),
26  pedsHandle_(nullptr),
27  noiseCacheId_(0),
28  noiseHandle_(nullptr) {}
29 
31  if (cabling_)
32  cabling_ = nullptr;
33  if (detCabling_)
34  detCabling_ = nullptr;
35  }
36 
38  uint32_t cache_id = setup.get<SiStripFedCablingRcd>().cacheIdentifier();
39 
40  if (cacheId_ != cache_id) { // If the cache ID has changed since the last update...
41  // Update the cabling object
43  setup.get<SiStripFedCablingRcd>().get(c);
44  cabling_ = c.product();
45 
46  // if ( edm::isDebugEnabled() ) {
47  // if ( !cacheId_ ) { // First time cabling has been retrieved - print it out in full.
48  // std::stringstream ss;
49  // ss << "[sistrip::SpyChannelUnpackerModule::" << __func__ << "]"
50  // << " Updating cabling for first time..." << std::endl
51  // << " Terse print out of FED cabling:" << std::endl;
52  // //cabling_->terse(ss);
53  // //LogTrace("SiStripMonitorHardwareUnpacker") << ss.str();
54  // } // end of cacheId_ check
55  // } // end of debugEnabled check
56 
57  // if ( edm::isDebugEnabled() ) {
58  // std::stringstream sss;
59  // sss << "[sistrip::SpyUtilities::" << __func__ << "]"
60  // << " Summary of FED cabling:" << std::endl;
61  // cabling_->summary(sss);
62  // LogTrace("SiStripSpyUtilities") << sss.str();
63  // }
64 
65  // Update the cache ID with the new value.
66  cacheId_ = cache_id;
67 
68  } // end of new cache ID check
69 
70  return cabling_;
71  }
72 
74  uint32_t cache_id = setup.get<SiStripDetCablingRcd>().cacheIdentifier(); //.get( cabling_ );
75 
76  if (cacheIdDet_ != cache_id) { // If the cache ID has changed since the last update...
77  // Update the cabling object
79  setup.get<SiStripDetCablingRcd>().get(c);
80  detCabling_ = c.product();
81  cacheIdDet_ = cache_id;
82  } // end of new cache ID check
83 
84  return detCabling_;
85  }
86 
88  //check if new pedestal values are available
89  uint32_t lCacheId = eventSetup.get<SiStripPedestalsRcd>().cacheIdentifier();
90  if (lCacheId != pedsCacheId_) {
91  eventSetup.get<SiStripPedestalsRcd>().get(pedsHandle_);
92  pedsCacheId_ = lCacheId;
93  }
94 
95  return pedsHandle_;
96  }
97 
99  //check if new noise values are available
100  uint32_t lCacheId = eventSetup.get<SiStripNoisesRcd>().cacheIdentifier();
101  if (lCacheId != noiseCacheId_) {
102  eventSetup.get<SiStripNoisesRcd>().get(noiseHandle_);
103  noiseCacheId_ = lCacheId;
104  }
105 
106  return noiseHandle_;
107  }
108 
110  const edm::DetSetVector<SiStripRawDigi>::detset& channelDigis, bool aPrintDebug) {
111  SpyUtilities::Frame lFrame;
112  lFrame.detId = channelDigis.detId();
113  lFrame.firstHeaderBit = 0;
114  lFrame.firstTrailerBit = 0;
115  lFrame.digitalLow = 0;
116  lFrame.digitalHigh = 0;
117  lFrame.baseline = 0;
118  lFrame.apvErrorBit.first = false;
119  lFrame.apvErrorBit.second = false;
120  lFrame.apvAddress.first = 0;
121  lFrame.apvAddress.second = 0;
122 
123  uint16_t min = 0x3FF;
124  uint16_t max = 0;
126  const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
127 
128  //counters for outputting warnings
129  uint16_t numzeroes = 0, numsats = 0;
130 
131  if (iDigi == endChannelDigis)
132  return lFrame;
133 
134  for (; iDigi != endChannelDigis; ++iDigi) {
135  const uint16_t val = iDigi->adc();
136  if (val < min)
137  min = val;
138  if (val > max)
139  max = val;
140  if (val == 0)
141  numzeroes++;
142  if (val == 0x3FF)
143  numsats++;
144  lFrame.baseline += val;
145  }
146 
147  if (!channelDigis.empty())
148  lFrame.baseline = lFrame.baseline / channelDigis.size();
149  lFrame.digitalLow = min;
150  lFrame.digitalHigh = max;
151 
152  const uint16_t threshold = static_cast<uint16_t>((2.0 * static_cast<double>(max - min)) / 3.0);
153 
154  if (aPrintDebug) {
155  if (edm::isDebugEnabled()) {
156  LogDebug("SiStripSpyUtilities") << "Channel with key: " << lFrame.detId << " Min: " << min << " Max: " << max
157  << " Range: " << (max - min) << " Threshold: " << threshold;
158  }
159  if (numzeroes > 0 || numsats > 0) {
160  edm::LogWarning("SiStripSpyUtilities") << "Channel with key: " << lFrame.detId << " has " << numzeroes
161  << " zero and " << numsats << " saturated samples.";
162  }
163  }
164 
165  lFrame.firstHeaderBit = findHeaderBits(channelDigis, threshold);
166  lFrame.firstTrailerBit = findTrailerBits(channelDigis, threshold);
167 
168  lFrame.apvErrorBit = findAPVErrorBits(channelDigis, threshold, lFrame.firstHeaderBit);
169  lFrame.apvAddress = findAPVAddresses(channelDigis, threshold, lFrame.firstHeaderBit);
170 
171  return lFrame;
172  }
173 
174  const uint16_t SpyUtilities::range(const SpyUtilities::Frame& aFrame) {
175  if (aFrame.digitalHigh < aFrame.digitalLow)
176  return 0;
177  else
178  return aFrame.digitalHigh - aFrame.digitalLow;
179  }
180 
181  const uint16_t SpyUtilities::threshold(const SpyUtilities::Frame& aFrame) {
182  return static_cast<uint16_t>((2.0 * static_cast<double>(range(aFrame))) / 3.0);
183  }
184 
186  if (aFrame.apvErrorBit.first == false)
187  return aFrame.apvAddress.first;
188  else if (aFrame.apvErrorBit.second == false) {
189  return aFrame.apvAddress.second;
190  } else {
191  return 0;
192  }
193  }
194 
196  uint16_t& aFirstHeaderBit,
197  bool printResult) {
198  std::vector<uint16_t> lFirstBitVec;
199  lFirstBitVec.reserve(aInputDigis->size());
200  aFirstHeaderBit = 0;
202 
203  for (; lDigis != aInputDigis->end(); lDigis++) {
205  lFirstBitVec.push_back(lFrame.firstHeaderBit);
206  }
207 
208  std::pair<uint16_t, uint32_t> lMaj = sistrip::SpyUtilities::findMajorityValue(lFirstBitVec);
209  aFirstHeaderBit = lMaj.first;
210  uint32_t lMajorityCounter = lMaj.second;
211 
212  //header is 24-sample long (2*8+2+6)
213  uint16_t lFirstTrailerBit = aFirstHeaderBit + 24 + sistrip::STRIPS_PER_FEDCH;
214 
215  if (printResult) {
216  LogInfo("SiStripSpyUtilities") << " -- Found majority position of first header (trailer) bit: " << aFirstHeaderBit
217  << " (" << lFirstTrailerBit << ") for " << lMajorityCounter << " out of "
218  << lFirstBitVec.size() << " channels." << std::endl;
219  }
220  }
221 
222  const bool SpyUtilities::isValid(const SpyUtilities::Frame& aFrame,
223  const FrameQuality& aQuality,
224  const uint16_t aExpectedPos) {
225  uint16_t lRange = sistrip::SpyUtilities::range(aFrame);
226 
227  if (lRange < aQuality.minDigiRange || lRange > aQuality.maxDigiRange) {
228  return false;
229  } else if (aFrame.digitalLow < aQuality.minZeroLight || aFrame.digitalLow > aQuality.maxZeroLight) {
230  return false;
231  } else if (aFrame.digitalHigh < aQuality.minTickHeight || aFrame.digitalHigh > aQuality.maxTickHeight) {
232  return false;
233  }
234  //if expectedPos=0: return true whatever the position of header is...
235  else if (aExpectedPos > 0 && (!(aFrame.firstHeaderBit == aExpectedPos &&
236  aFrame.firstTrailerBit == aExpectedPos + 24 + sistrip::STRIPS_PER_FEDCH))) {
237  return false;
238  } else if (aFrame.apvErrorBit.first && aFrame.apvErrorBit.second) {
239  return false;
240  }
241 
242  return true;
243  }
244 
246  const uint16_t threshold) {
247  // Loop over digis looking for first above threshold
248  uint8_t aboveThreshold = 0;
249  bool foundHeader = false;
250  uint16_t count = 0;
251 
253  const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
254 
255  for (; iDigi != endChannelDigis; ++iDigi) {
256  if (iDigi->adc() > threshold) {
257  aboveThreshold++;
258  } else {
259  aboveThreshold = 0;
260  }
261  if (aboveThreshold == 6) {
262  foundHeader = true;
263  break;
264  }
265  count++;
266  } //end of loop over digis
267 
268  //break before incrementing the last time... so count-5 is the first header sample.
269  if (foundHeader && count < 5)
270  return 0;
271  if (foundHeader)
272  return count - 5;
274  }
275 
277  const uint16_t threshold) {
278  // Loop over digis looking for last above threshold
279  uint8_t aboveThreshold = 0;
280  bool foundTrailer = false;
281 
282  //discard the first 30 values, which will have some digital high in them...
283  //start searching from the expected position : sometimes after 24+256 samples,
284  //normally at 6+24+256 if 6-bit low before tickmark header bits...
285  uint16_t count = 24 + sistrip::STRIPS_PER_FEDCH;
286 
289 
291  const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
292 
293  for (; iDigi != endChannelDigis; ++iDigi) {
294  if (iDigi->adc() > threshold) {
295  aboveThreshold++;
296  } else {
297  aboveThreshold = 0;
298  }
299  if (aboveThreshold == 2) {
300  foundTrailer = true;
301  break;
302  }
303  count++;
304  } //end of loop over digis
305 
306  //break before incrementing the last time... so count-1 is the first trailer sample.
307  if (foundTrailer && count < 1)
308  return 0;
309  if (foundTrailer)
310  return count - 1;
312  }
313 
314  const std::pair<bool, bool> SpyUtilities::findAPVErrorBits(
315  const edm::DetSetVector<SiStripRawDigi>::detset& channelDigis,
316  const uint16_t threshold,
317  const uint16_t aFirstBits) {
318  // Loop over digis looking for firstHeader+6+16
319  uint16_t count = aFirstBits + 22;
320 
321  std::pair<bool, bool> lPair = std::pair<bool, bool>(false, false);
322 
323  //if header invalid: we don't know what apverr is....
324  if (count >= sistrip::SPY_SAMPLES_PER_CHANNEL - 1)
325  return lPair;
326 
328  const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
329 
330  //double check....
331  if (iDigi == endChannelDigis)
332  return lPair;
333 
334  if (iDigi->adc() <= threshold)
335  lPair.first = true;
336  ++iDigi;
337 
338  //triple check...
339  if (iDigi == endChannelDigis)
340  return std::pair<bool, bool>(false, false);
341 
342  if (iDigi->adc() <= threshold)
343  lPair.second = true;
344 
345  return lPair;
346  }
347 
348  const std::pair<uint8_t, uint8_t> SpyUtilities::findAPVAddresses(
349  const edm::DetSetVector<SiStripRawDigi>::detset& channelDigis,
350  const uint16_t threshold,
351  const uint16_t aFirstBits) {
352  // Loop over digis looking for firstHeader+6
353  uint16_t count = aFirstBits + 6;
354  std::pair<uint8_t, uint8_t> lPair = std::pair<uint8_t, uint8_t>(0, 0);
355 
356  //check enough room to have 16 values....
357  if (count >= sistrip::SPY_SAMPLES_PER_CHANNEL - 15)
358  return lPair;
359 
361  const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
362 
363  //double check....
364  if (iDigi == endChannelDigis)
365  return lPair;
366 
367  for (uint8_t i = 0; i < 16; ++i) {
368  if (iDigi->adc() > threshold) {
369  //data is MSB first
370  if (i % 2 == 0)
371  lPair.first |= (0x80 >> static_cast<uint8_t>(i / 2));
372  else
373  lPair.second |= (0x80 >> static_cast<uint8_t>(i / 2));
374  }
375  ++iDigi;
376  }
377 
378  return lPair;
379  }
380 
382  std::ostringstream lOs;
383  lOs << " ------------------------------------------------------" << std::endl
384  << " -- Error: " << aErr << std::endl
385  << " ------- Printing Frame for detId " << aFrame.detId << " --------" << std::endl
386  << " -- firstHeaderBit = " << aFrame.firstHeaderBit << std::endl
387  << " -- firstTrailerBit = " << aFrame.firstTrailerBit << std::endl
388  << " -- digitalLow = " << aFrame.digitalLow << std::endl
389  << " -- digitalHigh = " << aFrame.digitalHigh << std::endl
390  << " -- baseline = " << aFrame.baseline << std::endl
391  << " -- apvErrorBits = " << aFrame.apvErrorBit.first << " " << aFrame.apvErrorBit.second << std::endl
392  << " -- apvAddresses = " << static_cast<uint16_t>(aFrame.apvAddress.first) << " "
393  << static_cast<uint16_t>(aFrame.apvAddress.second) << std::endl
394  << " ------------------------------------------------------" << std::endl;
395  return lOs.str();
396  }
397 
398  void SpyUtilities::fedIndex(const uint32_t aFedIndex, uint16_t& aFedId, uint16_t& aFedChannel) {
399  //find the corresponding detId (for the pedestals)
400  aFedId = static_cast<uint16_t>(aFedIndex / sistrip::FEDCH_PER_FED);
401  aFedChannel = static_cast<uint16_t>(aFedIndex % sistrip::FEDCH_PER_FED);
402 
403  if (aFedId < sistrip::FED_ID_MIN || aFedId > sistrip::FED_ID_MAX || aFedChannel >= sistrip::FEDCH_PER_FED) {
404  aFedId = sistrip::invalid_;
405  aFedChannel = sistrip::invalid_;
406  }
407  }
408 
409  std::pair<uint16_t, uint32_t> SpyUtilities::findMajorityValue(std::vector<uint16_t>& values, const uint16_t aFedId) {
410  uint32_t lTot = values.size();
411  if (!lTot)
412  return std::pair<uint16_t, uint32_t>(0, 0);
413 
414  std::sort(values.begin(), values.end());
415  uint32_t lMajorityCounter = 0;
416  uint16_t lMaj = 0;
417 
418  std::vector<uint16_t>::iterator lIter = values.begin();
419  for (; lIter != values.end();) {
420  uint32_t lCounter = std::count(lIter, values.end(), *lIter);
421  if (lCounter > lMajorityCounter) {
422  lMajorityCounter = lCounter;
423  lMaj = *lIter;
424  }
425  lIter += lCounter;
426  }
427 
428  //std::cout << " -- Found majority value " << lMaj << " for " << lMajorityCounter << " elements out of " << values.size() << "." << std::endl;
429 
430  if (static_cast<float>(lMajorityCounter) / lTot < 0.5) {
431  LogError("SiStripSpyUtilities") << " -- Found majority position for index " << aFedId << ": " << lMaj
432  << " for less than half the values : " << lMajorityCounter << " out of " << lTot
433  << " values." << std::endl;
434  }
435 
436  return std::pair<uint16_t, uint32_t>(lMaj, lMajorityCounter);
437  }
438 
439  void SpyUtilities::fillFEDMajorities(const std::map<uint32_t, uint32_t>& channelValues,
440  std::vector<uint32_t>& fedMajoritiesToFill) {
441  std::map<uint32_t, uint32_t>::const_iterator lMapIter = channelValues.begin();
442  uint16_t lPreviousFedId = 0;
443  std::vector<uint16_t> lAddrVec;
444  lAddrVec.reserve(sistrip::FEDCH_PER_FED);
445  fedMajoritiesToFill.resize(sistrip::FED_ID_MAX - sistrip::FED_ID_MIN + 1, 0);
446  uint32_t lChCount = 0;
447 
448  for (; lMapIter != channelValues.end(); ++lMapIter, ++lChCount) {
449  uint16_t lFedId = static_cast<uint16_t>(lMapIter->first / sistrip::FEDCH_PER_FED);
450 
451  if (lPreviousFedId == 0) {
452  lPreviousFedId = lFedId;
453  }
454  if (lFedId == lPreviousFedId) {
455  lAddrVec.push_back(lMapIter->second);
456  }
457  if (lFedId != lPreviousFedId || (lChCount == channelValues.size() - 1)) {
458  //extract majority address
459 
460  uint32_t lMaj = sistrip::SpyUtilities::findMajorityValue(lAddrVec, lPreviousFedId).first;
461  fedMajoritiesToFill[lPreviousFedId] = lMaj;
462 
463  lAddrVec.clear();
464 
465  //if new fed, fill the first channel
466  if (lFedId != lPreviousFedId) {
467  lAddrVec.push_back(lMapIter->second);
468  lPreviousFedId = lFedId;
469  }
470  }
471  }
472  }
473 
474 } // namespace sistrip
#define LogDebug(id)
iterator end()
Definition: DetSet.h:59
static void fedIndex(uint32_t aFedIndex, uint16_t &aFedId, uint16_t &aFedChannel)
bool isDebugEnabled()
std::pair< uint8_t, uint8_t > apvAddress
edm::ESHandle< SiStripNoises > noiseHandle_
static const uint16_t FED_ID_MIN
static const bool isValid(const Frame &aFrame, const FrameQuality &aQuality, const uint16_t aExpectedPos)
det_id_type detId() const
Definition: DetSet.h:75
edm::ESHandle< SiStripNoises > getNoiseHandle(const edm::EventSetup &eventSetup)
#define nullptr
static const std::pair< bool, bool > findAPVErrorBits(const edm::DetSetVector< SiStripRawDigi >::detset &channelDigis, const uint16_t threshold, const uint16_t aFirstBits)
static const uint16_t SPY_SAMPLES_PER_CHANNEL
const SiStripDetCabling * getDetCabling(const edm::EventSetup &)
Updates the det cabling object from the DB.
edm::ESHandle< SiStripPedestals > getPedestalHandle(const edm::EventSetup &eventSetup)
uint32_t cacheIdDet_
DB cache ID used to establish if the cabling has changed during the run.
static const std::pair< uint8_t, uint8_t > findAPVAddresses(const edm::DetSetVector< SiStripRawDigi >::detset &channelDigis, const uint16_t threshold, const uint16_t aFirstBits)
sistrip classes
static const uint16_t findHeaderBits(const edm::DetSetVector< SiStripRawDigi >::detset &channelDigis, const uint16_t threshold)
size_type size() const
Definition: DetSet.h:62
const SiStripDetCabling * detCabling_
The cabling object.
static void fillFEDMajorities(const std::map< uint32_t, uint32_t > &channelValues, std::vector< uint32_t > &fedMajoritiesToFill)
std::pair< bool, bool > apvErrorBit
static const Frame extractFrameInfo(const edm::DetSetVector< SiStripRawDigi >::detset &channelDigis, bool aPrintDebug=false)
static const uint16_t range(const Frame &aFrame)
T min(T a, T b)
Definition: MathUtil.h:58
iterator end()
Return the off-the-end iterator.
Definition: DetSetVector.h:325
size_type size() const
Return the number of contained DetSets.
Definition: DetSetVector.h:259
static std::pair< uint16_t, uint32_t > findMajorityValue(std::vector< uint16_t > &values, const uint16_t aFedId=0)
static const uint16_t threshold(const Frame &aFrame)
iterator begin()
Definition: DetSet.h:58
static const uint16_t STRIPS_PER_FEDCH
const SiStripFedCabling * cabling_
The cabling object.
const SiStripFedCabling * getCabling(const edm::EventSetup &)
Updates the cabling object from the DB.
static const uint16_t invalid_
Definition: Constants.h:16
static const uint16_t findTrailerBits(const edm::DetSetVector< SiStripRawDigi >::detset &channelDigis, const uint16_t threshold)
Contains cabling info at the device level, including DetId, APV pair numbers, hardware addresses...
bool empty() const
Definition: DetSet.h:63
static const uint16_t FEDCH_PER_FED
T get() const
Definition: EventSetup.h:73
static void getMajorityHeader(const edm::DetSetVector< SiStripRawDigi > *aInputDigis, uint16_t &firstHeaderBit, bool printResult=true)
iterator begin()
Return an iterator to the first DetSet.
Definition: DetSetVector.h:314
static const uint16_t FED_ID_MAX
edm::ESHandle< SiStripPedestals > pedsHandle_
collection_type::const_iterator const_iterator
Definition: DetSet.h:32
static std::string print(const Frame &aFrame, std::string aErr)
collection_type::const_iterator const_iterator
Definition: DetSetVector.h:102
T const * product() const
Definition: ESHandle.h:86
uint32_t cacheId_
DB cache ID used to establish if the cabling has changed during the run.
static const uint8_t extractAPVaddress(const Frame &aFrame)