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