CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SiStripSpyUtilities.cc
Go to the documentation of this file.
2 
5 
6 using edm::LogError;
7 using edm::LogInfo;
8 using edm::LogWarning;
9 
10 namespace sistrip {
12  const edm::DetSetVector<SiStripRawDigi>::detset& channelDigis, bool aPrintDebug) {
13  SpyUtilities::Frame lFrame;
14  lFrame.detId = channelDigis.detId();
15  lFrame.firstHeaderBit = 0;
16  lFrame.firstTrailerBit = 0;
17  lFrame.digitalLow = 0;
18  lFrame.digitalHigh = 0;
19  lFrame.baseline = 0;
20  lFrame.apvErrorBit.first = false;
21  lFrame.apvErrorBit.second = false;
22  lFrame.apvAddress.first = 0;
23  lFrame.apvAddress.second = 0;
24 
25  uint16_t min = 0x3FF;
26  uint16_t max = 0;
28  const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
29 
30  //counters for outputting warnings
31  uint16_t numzeroes = 0, numsats = 0;
32 
33  if (iDigi == endChannelDigis)
34  return lFrame;
35 
36  for (; iDigi != endChannelDigis; ++iDigi) {
37  const uint16_t val = iDigi->adc();
38  if (val < min)
39  min = val;
40  if (val > max)
41  max = val;
42  if (val == 0)
43  numzeroes++;
44  if (val == 0x3FF)
45  numsats++;
46  lFrame.baseline += val;
47  }
48 
49  if (!channelDigis.empty())
50  lFrame.baseline = lFrame.baseline / channelDigis.size();
51  lFrame.digitalLow = min;
52  lFrame.digitalHigh = max;
53 
54  const uint16_t threshold = static_cast<uint16_t>((2.0 * static_cast<double>(max - min)) / 3.0);
55 
56  if (aPrintDebug) {
57  if (edm::isDebugEnabled()) {
58  LogDebug("SiStripSpyUtilities") << "Channel with key: " << lFrame.detId << " Min: " << min << " Max: " << max
59  << " Range: " << (max - min) << " Threshold: " << threshold;
60  }
61  if (numzeroes > 0 || numsats > 0) {
62  edm::LogWarning("SiStripSpyUtilities") << "Channel with key: " << lFrame.detId << " has " << numzeroes
63  << " zero and " << numsats << " saturated samples.";
64  }
65  }
66 
67  lFrame.firstHeaderBit = findHeaderBits(channelDigis, threshold);
68  lFrame.firstTrailerBit = findTrailerBits(channelDigis, threshold);
69 
70  lFrame.apvErrorBit = findAPVErrorBits(channelDigis, threshold, lFrame.firstHeaderBit);
71  lFrame.apvAddress = findAPVAddresses(channelDigis, threshold, lFrame.firstHeaderBit);
72 
73  return lFrame;
74  }
75 
76  const uint16_t SpyUtilities::range(const SpyUtilities::Frame& aFrame) {
77  if (aFrame.digitalHigh < aFrame.digitalLow)
78  return 0;
79  else
80  return aFrame.digitalHigh - aFrame.digitalLow;
81  }
82 
83  const uint16_t SpyUtilities::threshold(const SpyUtilities::Frame& aFrame) {
84  return static_cast<uint16_t>((2.0 * static_cast<double>(range(aFrame))) / 3.0);
85  }
86 
88  if (aFrame.apvErrorBit.first == false)
89  return aFrame.apvAddress.first;
90  else if (aFrame.apvErrorBit.second == false) {
91  return aFrame.apvAddress.second;
92  } else {
93  return 0;
94  }
95  }
96 
98  uint16_t& aFirstHeaderBit,
99  bool printResult) {
100  std::vector<uint16_t> lFirstBitVec;
101  lFirstBitVec.reserve(aInputDigis->size());
102  aFirstHeaderBit = 0;
104 
105  for (; lDigis != aInputDigis->end(); lDigis++) {
107  lFirstBitVec.push_back(lFrame.firstHeaderBit);
108  }
109 
110  std::pair<uint16_t, uint32_t> lMaj = sistrip::SpyUtilities::findMajorityValue(lFirstBitVec);
111  aFirstHeaderBit = lMaj.first;
112  uint32_t lMajorityCounter = lMaj.second;
113 
114  //header is 24-sample long (2*8+2+6)
115  uint16_t lFirstTrailerBit = aFirstHeaderBit + 24 + sistrip::STRIPS_PER_FEDCH;
116 
117  if (printResult) {
118  LogInfo("SiStripSpyUtilities") << " -- Found majority position of first header (trailer) bit: " << aFirstHeaderBit
119  << " (" << lFirstTrailerBit << ") for " << lMajorityCounter << " out of "
120  << lFirstBitVec.size() << " channels." << std::endl;
121  }
122  }
123 
124  const bool SpyUtilities::isValid(const SpyUtilities::Frame& aFrame,
125  const FrameQuality& aQuality,
126  const uint16_t aExpectedPos) {
127  uint16_t lRange = sistrip::SpyUtilities::range(aFrame);
128 
129  if (lRange < aQuality.minDigiRange || lRange > aQuality.maxDigiRange) {
130  return false;
131  } else if (aFrame.digitalLow < aQuality.minZeroLight || aFrame.digitalLow > aQuality.maxZeroLight) {
132  return false;
133  } else if (aFrame.digitalHigh < aQuality.minTickHeight || aFrame.digitalHigh > aQuality.maxTickHeight) {
134  return false;
135  }
136  //if expectedPos=0: return true whatever the position of header is...
137  else if (aExpectedPos > 0 && (!(aFrame.firstHeaderBit == aExpectedPos &&
138  aFrame.firstTrailerBit == aExpectedPos + 24 + sistrip::STRIPS_PER_FEDCH))) {
139  return false;
140  } else if (aFrame.apvErrorBit.first && aFrame.apvErrorBit.second) {
141  return false;
142  }
143 
144  return true;
145  }
146 
148  const uint16_t threshold) {
149  // Loop over digis looking for first above threshold
150  uint8_t aboveThreshold = 0;
151  bool foundHeader = false;
152  uint16_t count = 0;
153 
155  const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
156 
157  for (; iDigi != endChannelDigis; ++iDigi) {
158  if (iDigi->adc() > threshold) {
159  aboveThreshold++;
160  } else {
161  aboveThreshold = 0;
162  }
163  if (aboveThreshold == 6) {
164  foundHeader = true;
165  break;
166  }
167  count++;
168  } //end of loop over digis
169 
170  //break before incrementing the last time... so count-5 is the first header sample.
171  if (foundHeader && count < 5)
172  return 0;
173  if (foundHeader)
174  return count - 5;
176  }
177 
179  const uint16_t threshold) {
180  // Loop over digis looking for last above threshold
181  uint8_t aboveThreshold = 0;
182  bool foundTrailer = false;
183 
184  //discard the first 30 values, which will have some digital high in them...
185  //start searching from the expected position : sometimes after 24+256 samples,
186  //normally at 6+24+256 if 6-bit low before tickmark header bits...
187  uint16_t count = 24 + sistrip::STRIPS_PER_FEDCH;
188 
191 
193  const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
194 
195  for (; iDigi != endChannelDigis; ++iDigi) {
196  if (iDigi->adc() > threshold) {
197  aboveThreshold++;
198  } else {
199  aboveThreshold = 0;
200  }
201  if (aboveThreshold == 2) {
202  foundTrailer = true;
203  break;
204  }
205  count++;
206  } //end of loop over digis
207 
208  //break before incrementing the last time... so count-1 is the first trailer sample.
209  if (foundTrailer && count < 1)
210  return 0;
211  if (foundTrailer)
212  return count - 1;
214  }
215 
216  const std::pair<bool, bool> SpyUtilities::findAPVErrorBits(
217  const edm::DetSetVector<SiStripRawDigi>::detset& channelDigis,
218  const uint16_t threshold,
219  const uint16_t aFirstBits) {
220  // Loop over digis looking for firstHeader+6+16
221  uint16_t count = aFirstBits + 22;
222 
223  std::pair<bool, bool> lPair = std::pair<bool, bool>(false, false);
224 
225  //if header invalid: we don't know what apverr is....
226  if (count >= sistrip::SPY_SAMPLES_PER_CHANNEL - 1)
227  return lPair;
228 
230  const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
231 
232  //double check....
233  if (iDigi == endChannelDigis)
234  return lPair;
235 
236  if (iDigi->adc() <= threshold)
237  lPair.first = true;
238  ++iDigi;
239 
240  //triple check...
241  if (iDigi == endChannelDigis)
242  return std::pair<bool, bool>(false, false);
243 
244  if (iDigi->adc() <= threshold)
245  lPair.second = true;
246 
247  return lPair;
248  }
249 
250  const std::pair<uint8_t, uint8_t> SpyUtilities::findAPVAddresses(
251  const edm::DetSetVector<SiStripRawDigi>::detset& channelDigis,
252  const uint16_t threshold,
253  const uint16_t aFirstBits) {
254  // Loop over digis looking for firstHeader+6
255  uint16_t count = aFirstBits + 6;
256  std::pair<uint8_t, uint8_t> lPair = std::pair<uint8_t, uint8_t>(0, 0);
257 
258  //check enough room to have 16 values....
259  if (count >= sistrip::SPY_SAMPLES_PER_CHANNEL - 15)
260  return lPair;
261 
263  const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
264 
265  //double check....
266  if (iDigi == endChannelDigis)
267  return lPair;
268 
269  for (uint8_t i = 0; i < 16; ++i) {
270  if (iDigi->adc() > threshold) {
271  //data is MSB first
272  if (i % 2 == 0)
273  lPair.first |= (0x80 >> static_cast<uint8_t>(i / 2));
274  else
275  lPair.second |= (0x80 >> static_cast<uint8_t>(i / 2));
276  }
277  ++iDigi;
278  }
279 
280  return lPair;
281  }
282 
284  std::ostringstream lOs;
285  lOs << " ------------------------------------------------------" << std::endl
286  << " -- Error: " << aErr << std::endl
287  << " ------- Printing Frame for detId " << aFrame.detId << " --------" << std::endl
288  << " -- firstHeaderBit = " << aFrame.firstHeaderBit << std::endl
289  << " -- firstTrailerBit = " << aFrame.firstTrailerBit << std::endl
290  << " -- digitalLow = " << aFrame.digitalLow << std::endl
291  << " -- digitalHigh = " << aFrame.digitalHigh << std::endl
292  << " -- baseline = " << aFrame.baseline << std::endl
293  << " -- apvErrorBits = " << aFrame.apvErrorBit.first << " " << aFrame.apvErrorBit.second << std::endl
294  << " -- apvAddresses = " << static_cast<uint16_t>(aFrame.apvAddress.first) << " "
295  << static_cast<uint16_t>(aFrame.apvAddress.second) << std::endl
296  << " ------------------------------------------------------" << std::endl;
297  return lOs.str();
298  }
299 
300  void SpyUtilities::fedIndex(const uint32_t aFedIndex, uint16_t& aFedId, uint16_t& aFedChannel) {
301  //find the corresponding detId (for the pedestals)
302  aFedId = static_cast<uint16_t>(aFedIndex / sistrip::FEDCH_PER_FED);
303  aFedChannel = static_cast<uint16_t>(aFedIndex % sistrip::FEDCH_PER_FED);
304 
305  if (aFedId < sistrip::FED_ID_MIN || aFedId > sistrip::FED_ID_MAX || aFedChannel >= sistrip::FEDCH_PER_FED) {
306  aFedId = sistrip::invalid_;
307  aFedChannel = sistrip::invalid_;
308  }
309  }
310 
311  std::pair<uint16_t, uint32_t> SpyUtilities::findMajorityValue(std::vector<uint16_t>& values, const uint16_t aFedId) {
312  uint32_t lTot = values.size();
313  if (!lTot)
314  return std::pair<uint16_t, uint32_t>(0, 0);
315 
316  std::sort(values.begin(), values.end());
317  uint32_t lMajorityCounter = 0;
318  uint16_t lMaj = 0;
319 
320  std::vector<uint16_t>::iterator lIter = values.begin();
321  for (; lIter != values.end();) {
322  uint32_t lCounter = std::count(lIter, values.end(), *lIter);
323  if (lCounter > lMajorityCounter) {
324  lMajorityCounter = lCounter;
325  lMaj = *lIter;
326  }
327  lIter += lCounter;
328  }
329 
330  //std::cout << " -- Found majority value " << lMaj << " for " << lMajorityCounter << " elements out of " << values.size() << "." << std::endl;
331 
332  if (static_cast<float>(lMajorityCounter) / lTot < 0.5) {
333  LogError("SiStripSpyUtilities") << " -- Found majority position for index " << aFedId << ": " << lMaj
334  << " for less than half the values : " << lMajorityCounter << " out of " << lTot
335  << " values." << std::endl;
336  }
337 
338  return std::pair<uint16_t, uint32_t>(lMaj, lMajorityCounter);
339  }
340 
341  void SpyUtilities::fillFEDMajorities(const std::map<uint32_t, uint32_t>& channelValues,
342  std::vector<uint32_t>& fedMajoritiesToFill) {
343  std::map<uint32_t, uint32_t>::const_iterator lMapIter = channelValues.begin();
344  uint16_t lPreviousFedId = 0;
345  std::vector<uint16_t> lAddrVec;
346  lAddrVec.reserve(sistrip::FEDCH_PER_FED);
347  fedMajoritiesToFill.resize(sistrip::FED_ID_MAX - sistrip::FED_ID_MIN + 1, 0);
348  uint32_t lChCount = 0;
349 
350  for (; lMapIter != channelValues.end(); ++lMapIter, ++lChCount) {
351  uint16_t lFedId = static_cast<uint16_t>(lMapIter->first / sistrip::FEDCH_PER_FED);
352 
353  if (lPreviousFedId == 0) {
354  lPreviousFedId = lFedId;
355  }
356  if (lFedId == lPreviousFedId) {
357  lAddrVec.push_back(lMapIter->second);
358  }
359  if (lFedId != lPreviousFedId || (lChCount == channelValues.size() - 1)) {
360  //extract majority address
361 
362  uint32_t lMaj = sistrip::SpyUtilities::findMajorityValue(lAddrVec, lPreviousFedId).first;
363  fedMajoritiesToFill[lPreviousFedId] = lMaj;
364 
365  lAddrVec.clear();
366 
367  //if new fed, fill the first channel
368  if (lFedId != lPreviousFedId) {
369  lAddrVec.push_back(lMapIter->second);
370  lPreviousFedId = lFedId;
371  }
372  }
373  }
374  }
375 
376 } // namespace sistrip
iterator end()
Definition: DetSet.h:58
const uint16_t findHeaderBits(const edm::DetSetVector< SiStripRawDigi >::detset &channelDigis, const uint16_t threshold)
void fillFEDMajorities(const std::map< uint32_t, uint32_t > &channelValues, std::vector< uint32_t > &fedMajoritiesToFill)
bool isDebugEnabled()
std::pair< uint8_t, uint8_t > apvAddress
static const uint16_t FED_ID_MIN
const bool isValid(const Frame &aFrame, const FrameQuality &aQuality, const uint16_t aExpectedPos)
det_id_type detId() const
Definition: DetSet.h:74
std::string print(const Frame &aFrame, std::string aErr)
static const uint16_t SPY_SAMPLES_PER_CHANNEL
const Frame extractFrameInfo(const edm::DetSetVector< SiStripRawDigi >::detset &channelDigis, bool aPrintDebug=false)
void fedIndex(uint32_t aFedIndex, uint16_t &aFedId, uint16_t &aFedChannel)
Log< level::Error, false > LogError
const uint16_t threshold(const Frame &aFrame)
const uint16_t range(const Frame &aFrame)
size_type size() const
Definition: DetSet.h:61
std::pair< bool, bool > apvErrorBit
void getMajorityHeader(const edm::DetSetVector< SiStripRawDigi > *aInputDigis, uint16_t &firstHeaderBit, bool printResult=true)
if(conf_.getParameter< bool >("UseStripCablingDB"))
const uint8_t extractAPVaddress(const Frame &aFrame)
T min(T a, T b)
Definition: MathUtil.h:58
std::pair< uint16_t, uint32_t > findMajorityValue(std::vector< uint16_t > &values, const uint16_t aFedId=0)
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
iterator begin()
Definition: DetSet.h:57
Log< level::Info, false > LogInfo
static const uint16_t STRIPS_PER_FEDCH
static const uint16_t invalid_
Definition: Constants.h:16
const std::pair< bool, bool > findAPVErrorBits(const edm::DetSetVector< SiStripRawDigi >::detset &channelDigis, const uint16_t threshold, const uint16_t aFirstBits)
bool empty() const
Definition: DetSet.h:62
static const uint16_t FEDCH_PER_FED
iterator begin()
Return an iterator to the first DetSet.
Definition: DetSetVector.h:314
static const uint16_t FED_ID_MAX
Log< level::Warning, false > LogWarning
collection_type::const_iterator const_iterator
Definition: DetSet.h:31
collection_type::const_iterator const_iterator
Definition: DetSetVector.h:102
const uint16_t findTrailerBits(const edm::DetSetVector< SiStripRawDigi >::detset &channelDigis, const uint16_t threshold)
const std::pair< uint8_t, uint8_t > findAPVAddresses(const edm::DetSetVector< SiStripRawDigi >::detset &channelDigis, const uint16_t threshold, const uint16_t aFirstBits)
#define LogDebug(id)