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 // std::cout<<"val : "<<val<<std::endl;
155  }
156 
157  if (!channelDigis.empty()) lFrame.baseline = lFrame.baseline/channelDigis.size();
158  lFrame.digitalLow = min;
159  lFrame.digitalHigh = max;
160 // std::cout<<"lFrame.digitalLow : "<<lFrame.digitalLow<<std::endl;
161 // std::cout<<"lFrame.digitalHigh : "<<lFrame.digitalHigh<<std::endl;
162 
163  const uint16_t threshold = static_cast<uint16_t>( (2.0 * static_cast<double>(max-min)) / 3.0 );
164 
165  if (aPrintDebug){
166  if ( edm::isDebugEnabled() ) {
167  LogDebug("SiStripSpyUtilities") << "Channel with key: " << lFrame.detId
168  << " Min: " << min << " Max: " << max
169  << " Range: " << (max-min) << " Threshold: " << threshold;
170  }
171  if (numzeroes>0 || numsats>0) {
172  edm::LogWarning("SiStripSpyUtilities") << "Channel with key: " << lFrame.detId << " has "
173  << numzeroes << " zero and "
174  << numsats << " saturated samples.";
175  }
176  }
177 
178  lFrame.firstHeaderBit = findHeaderBits(channelDigis,threshold);
179  lFrame.firstTrailerBit = findTrailerBits(channelDigis,threshold);
180 
181  lFrame.apvErrorBit = findAPVErrorBits(channelDigis,threshold,lFrame.firstHeaderBit);
182  lFrame.apvAddress = findAPVAddresses(channelDigis,threshold,lFrame.firstHeaderBit);
183 
184  return lFrame;
185 
186  }
187 
188  const uint16_t SpyUtilities::range(const SpyUtilities::Frame & aFrame)
189  {
190  if (aFrame.digitalHigh < aFrame.digitalLow) return 0;
191  else return aFrame.digitalHigh-aFrame.digitalLow;
192  }
193 
194  const uint16_t SpyUtilities::threshold(const SpyUtilities::Frame & aFrame)
195  {
196  return static_cast<uint16_t>( (2.0 * static_cast<double>(range(aFrame))) / 3.0 );
197  }
198 
200  {
201 
202  if (aFrame.apvErrorBit.first == false) return aFrame.apvAddress.first;
203  else if (aFrame.apvErrorBit.second == false) {
204  return aFrame.apvAddress.second;
205  }
206  else {
207  return 0;
208  }
209 
210  }
211 
213  uint16_t & aFirstHeaderBit,
214  bool printResult)
215  {
216 
217  std::vector<uint16_t> lFirstBitVec;
218  lFirstBitVec.reserve(aInputDigis->size());
219  aFirstHeaderBit = 0;
221 
222  for ( ; lDigis != aInputDigis->end(); lDigis++){
224  lFirstBitVec.push_back(lFrame.firstHeaderBit);
225  }
226 
227  std::pair<uint16_t,uint32_t> lMaj = sistrip::SpyUtilities::findMajorityValue(lFirstBitVec);
228  aFirstHeaderBit = lMaj.first;
229  uint32_t lMajorityCounter = lMaj.second;
230 
231  //header is 24-sample long (2*8+2+6)
232  uint16_t lFirstTrailerBit = aFirstHeaderBit+24+sistrip::STRIPS_PER_FEDCH;
233 
234  if (printResult)
235  {
236  LogInfo("SiStripSpyUtilities") << " -- Found majority position of first header (trailer) bit: "
237  << aFirstHeaderBit
238  << " (" << lFirstTrailerBit
239  << ") for " << lMajorityCounter << " out of " << lFirstBitVec.size() << " channels."
240  << std::endl;
241  }
242  }
243 
244 
245  const bool SpyUtilities::isValid(const SpyUtilities::Frame & aFrame,
246  const FrameQuality & aQuality,
247  const uint16_t aExpectedPos)
248  {
249 
250  uint16_t lRange = sistrip::SpyUtilities::range(aFrame);
251 
252  if (lRange < aQuality.minDigiRange || lRange > aQuality.maxDigiRange) {
253  return false;
254  }
255  else if (aFrame.digitalLow < aQuality.minZeroLight || aFrame.digitalLow > aQuality.maxZeroLight) {
256  return false;
257  }
258  else if (aFrame.digitalHigh < aQuality.minTickHeight || aFrame.digitalHigh > aQuality.maxTickHeight){
259  return false;
260  }
261  //if expectedPos=0: return true whatever the position of header is...
262  else if ( aExpectedPos > 0 &&
263  (
264  !(aFrame.firstHeaderBit == aExpectedPos &&
265  aFrame.firstTrailerBit == aExpectedPos+24+sistrip::STRIPS_PER_FEDCH)
266  )
267  ) {
268  return false;
269  }
270  else if (aFrame.apvErrorBit.first && aFrame.apvErrorBit.second) {
271  return false;
272  }
273 
274  return true;
275  }
276 
277 
279  const uint16_t threshold)
280  {
281 
282  // Loop over digis looking for first above threshold
283  uint8_t aboveThreshold = 0;
284  bool foundHeader = false;
285  uint16_t count = 0;
286 
288  const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
289 
290  for (; iDigi != endChannelDigis; ++iDigi) {
291  if ( iDigi->adc() > threshold) {
292  aboveThreshold++;
293  }
294  else {
295  aboveThreshold = 0;
296  }
297  if (aboveThreshold == 6) {foundHeader = true; break; }
298  count++;
299  }//end of loop over digis
300 
301  //break before incrementing the last time... so count-5 is the first header sample.
302  if (foundHeader && count < 5) return 0;
303  if (foundHeader) return count-5;
305 
306  }
307 
309  const uint16_t threshold)
310  {
311 
312  // Loop over digis looking for last above threshold
313  uint8_t aboveThreshold = 0;
314  bool foundTrailer = false;
315 
316  //discard the first 30 values, which will have some digital high in them...
317  //start searching from the expected position : sometimes after 24+256 samples,
318  //normally at 6+24+256 if 6-bit low before tickmark header bits...
319  uint16_t count = 24+sistrip::STRIPS_PER_FEDCH;
320 
322 
324  const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
325 
326  for (; iDigi != endChannelDigis; ++iDigi) {
327  if ( iDigi->adc() > threshold) {
328  aboveThreshold++;
329  }
330  else {
331  aboveThreshold = 0;
332  }
333  if (aboveThreshold == 2) {foundTrailer = true; break; }
334  count++;
335  }//end of loop over digis
336 
337  //break before incrementing the last time... so count-1 is the first trailer sample.
338  if (foundTrailer && count < 1) return 0;
339  if (foundTrailer) return count-1;
341 
342  }
343 
344 
345 
346  const std::pair<bool,bool>
348  const uint16_t threshold,
349  const uint16_t aFirstBits)
350  {
351 
352  // Loop over digis looking for firstHeader+6+16
353  uint16_t count = aFirstBits+22;
354 
355  std::pair<bool,bool> lPair = std::pair<bool,bool>(false,false);
356 
357  //if header invalid: we don't know what apverr is....
358  if (count >= sistrip::SPY_SAMPLES_PER_CHANNEL-1) return lPair;
359 
361  const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
362 
363  //double check....
364  if (iDigi == endChannelDigis) return lPair;
365 
366  if ( iDigi->adc() <= threshold) lPair.first = true;
367  ++iDigi;
368 
369  //triple check...
370  if (iDigi == endChannelDigis) return std::pair<bool,bool>(false,false);
371 
372  if ( iDigi->adc() <= threshold) lPair.second = true;
373 
374  return lPair;
375  }
376 
377 
378  const std::pair<uint8_t,uint8_t>
380  const uint16_t threshold,
381  const uint16_t aFirstBits)
382  {
383 
384  // Loop over digis looking for firstHeader+6
385  uint16_t count = aFirstBits+6;
386  std::pair<uint8_t,uint8_t> lPair = std::pair<uint8_t,uint8_t>(0,0);
387 
388  //check enough room to have 16 values....
389  if (count >= sistrip::SPY_SAMPLES_PER_CHANNEL-15) return lPair;
390 
392  const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
393 
394  //double check....
395  if (iDigi == endChannelDigis) return lPair;
396 
397  for (uint8_t i = 0; i < 16; ++i) {
398  if ( iDigi->adc() > threshold) {
399  //data is MSB first
400  if (i%2==0)
401  lPair.first |= (0x80 >> static_cast<uint8_t>(i/2));
402  else
403  lPair.second |= (0x80 >> static_cast<uint8_t>(i/2));
404  }
405  ++iDigi;
406  }
407 
408  return lPair;
409 
410  }
411 
412 
414  std::string aErr)
415  {
416 
417  std::ostringstream lOs;
418  lOs << " ------------------------------------------------------" << std::endl
419  << " -- Error: " << aErr << std::endl
420  << " ------- Printing Frame for detId " << aFrame.detId << " --------" << std::endl
421  << " -- firstHeaderBit = " << aFrame.firstHeaderBit << std::endl
422  << " -- firstTrailerBit = " << aFrame.firstTrailerBit << std::endl
423  << " -- digitalLow = " << aFrame.digitalLow << std::endl
424  << " -- digitalHigh = " << aFrame.digitalHigh << std::endl
425  << " -- baseline = " << aFrame.baseline << std::endl
426  << " -- apvErrorBits = " << aFrame.apvErrorBit.first
427  << " " << aFrame.apvErrorBit.second << std::endl
428  << " -- apvAddresses = " << static_cast<uint16_t>(aFrame.apvAddress.first)
429  << " " << static_cast<uint16_t>(aFrame.apvAddress.second) << std::endl
430  << " ------------------------------------------------------" << std::endl;
431  return lOs.str();
432 
433  }
434 
435 
436  void SpyUtilities::fedIndex(const uint32_t aFedIndex,
437  uint16_t & aFedId,
438  uint16_t & aFedChannel){
439 
440  //find the corresponding detId (for the pedestals)
441  aFedId = static_cast<uint16_t>(aFedIndex/sistrip::FEDCH_PER_FED);
442  aFedChannel = static_cast<uint16_t>(aFedIndex%sistrip::FEDCH_PER_FED);
443 
444  if (aFedId < sistrip::FED_ID_MIN ||
445  aFedId > sistrip::FED_ID_MAX ||
446  aFedChannel >= sistrip::FEDCH_PER_FED ) {
447  aFedId = sistrip::invalid_;
448  aFedChannel = sistrip::invalid_;
449  }
450 
451  }
452 
453  std::pair<uint16_t,uint32_t> SpyUtilities::findMajorityValue(std::vector<uint16_t>& values,
454  const uint16_t aFedId)
455  {
456 
457  uint32_t lTot = values.size();
458  if (!lTot) return std::pair<uint16_t,uint32_t>(0,0);
459 
460  std::sort(values.begin(),values.end());
461  uint32_t lMajorityCounter = 0;
462  uint16_t lMaj = 0;
463 
464  std::vector<uint16_t>::iterator lIter = values.begin();
465  for ( ; lIter != values.end(); ) {
466  uint32_t lCounter = std::count(lIter,values.end(),*lIter);
467  if (lCounter > lMajorityCounter) {
468  lMajorityCounter = lCounter;
469  lMaj = *lIter;
470  }
471  lIter += lCounter;
472  }
473 
474  //std::cout << " -- Found majority value " << lMaj << " for " << lMajorityCounter << " elements out of " << values.size() << "." << std::endl;
475 
476  if (static_cast<float>(lMajorityCounter)/lTot < 0.5) {
477  LogError("SiStripSpyUtilities") << " -- Found majority position for index "
478  << aFedId
479  << ": " << lMaj
480  << " for less than half the values : " << lMajorityCounter << " out of " << lTot << " values."
481  << std::endl;
482  }
483 
484  return std::pair<uint16_t,uint32_t>(lMaj,lMajorityCounter);
485 
486  }
487 
488  void SpyUtilities::fillFEDMajorities(const std::map<uint32_t,uint32_t>& channelValues,
489  std::vector<uint32_t> & fedMajoritiesToFill)
490  {
491 
492  std::map<uint32_t,uint32_t>::const_iterator lMapIter = channelValues.begin();
493  uint16_t lPreviousFedId = 0;
494  std::vector<uint16_t> lAddrVec;
495  lAddrVec.reserve(sistrip::FEDCH_PER_FED);
496  fedMajoritiesToFill.resize(sistrip::FED_ID_MAX-sistrip::FED_ID_MIN+1,0);
497  uint32_t lChCount = 0;
498 
499  for ( ; lMapIter != channelValues.end(); ++lMapIter,++lChCount){
500 
501  uint16_t lFedId = static_cast<uint16_t>(lMapIter->first/sistrip::FEDCH_PER_FED);
502 
503  if (lPreviousFedId == 0) {
504  lPreviousFedId = lFedId;
505  }
506  if (lFedId == lPreviousFedId) {
507  lAddrVec.push_back(lMapIter->second);
508  }
509  if (lFedId != lPreviousFedId || (lChCount == channelValues.size()-1)) {
510  //extract majority address
511 
512  uint32_t lMaj = sistrip::SpyUtilities::findMajorityValue(lAddrVec,lPreviousFedId).first;
513  fedMajoritiesToFill[lPreviousFedId] = lMaj;
514 
515  lAddrVec.clear();
516 
517  //if new fed, fill the first channel
518  if (lFedId != lPreviousFedId) {
519  lAddrVec.push_back(lMapIter->second);
520  lPreviousFedId = lFedId;
521  }
522 
523  }
524  }
525 
526  }
527 
528 }//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:72
edm::ESHandle< SiStripNoises > getNoiseHandle(const edm::EventSetup &eventSetup)
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:1
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)
#define nullptr
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.
const T & get() const
Definition: EventSetup.h:59
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
if(dp >Float(M_PI)) dp-
static const uint16_t FEDCH_PER_FED
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)