CMS 3D CMS Logo

SiStripRawToDigiUnpacker.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <sstream>
3 #include <iomanip>
4 #include <ext/algorithm>
5 
6 #include <fmt/format.h>
7 
22 
24 
25 namespace sistrip {
26 
27  RawToDigiUnpacker::RawToDigiUnpacker(int16_t appended_bytes,
28  int16_t fed_buffer_dump_freq,
29  int16_t fed_event_dump_freq,
30  int16_t trigger_fed_id,
31  bool using_fed_key,
32  bool unpack_bad_channels,
33  bool mark_missing_feds,
34  const uint32_t errorThreshold)
35  : headerBytes_(appended_bytes),
36  fedBufferDumpFreq_(fed_buffer_dump_freq),
37  fedEventDumpFreq_(fed_event_dump_freq),
38  triggerFedId_(trigger_fed_id),
39  useFedKey_(using_fed_key),
40  unpackBadChannels_(unpack_bad_channels),
41  markMissingFeds_(mark_missing_feds),
42  event_(0),
43  once_(true),
44  first_(true),
45  useDaqRegister_(false),
46  quiet_(true),
47  extractCm_(false),
48  doFullCorruptBufferChecks_(false),
49  doAPVEmulatorCheck_(true),
50  errorThreshold_(errorThreshold),
51  warnings_(sistrip::mlRawToDigi_, "[sistrip::RawToDigiUnpacker::createDigis]", edm::isDebugEnabled()) {
52  if (edm::isDebugEnabled()) {
53  LogTrace("SiStripRawToDigi") << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
54  << " Constructing object...";
55  }
56  if (unpackBadChannels_) {
57  edm::LogWarning("SiStripRawToDigi")
58  << "Warning: Unpacking of bad channels enabled. Only enable this if you know what you are doing. "
59  << std::endl;
60  }
61  }
62 
64  if (edm::isDebugEnabled()) {
65  LogTrace("SiStripRawToDigi") << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
66  << " Destructing object...";
67  }
68  }
69 
70  namespace {
71 
72  edm::RunningAverage localRA(10000);
73 
74  void maskFED(DetIdCollection& maskedModules, SiStripFedCabling::ConnsConstIterRange fedConnections) {
75  maskedModules.reserve(maskedModules.size() + fedConnections.size());
76  for (const auto& conn : fedConnections) {
77  if (conn.detId() && (conn.detId() != sistrip::invalid32_)) {
78  maskedModules.push_back(conn.detId()); //@@ Possible multiple entries (ok for Giovanni)
79  }
80  }
81  }
82  } // namespace
83 
85  const FEDRawDataCollection& buffers,
87  RawDigis& scope_mode,
88  RawDigis& virgin_raw,
89  RawDigis& proc_raw,
90  Digis& zero_suppr,
91  DetIdCollection& detids,
92  RawDigis& cm_values) {
93  // Clear done at the end
94  assert(zs_work_digis_.empty());
95  zs_work_digis_.reserve(localRA.upper());
96  // Reserve space in bad module list
97  detids.reserve(100);
98 
99  // Check if FEDs found in cabling map and event data
100  if (cabling.fedIds().empty()) {
101  warnings_.add("No FEDs found in cabling map!");
102  if (edm::isDebugEnabled()) {
103  // Check which FED ids have non-zero size buffers
104  std::vector<uint16_t> feds;
105  for (uint16_t ifed = FEDNumbering::MINSiStripFEDID; ifed < FEDNumbering::MAXSiStripFEDID; ifed++) {
106  if (ifed != triggerFedId_ && buffers.FEDData(static_cast<int>(ifed)).size()) {
107  feds.push_back(ifed);
108  }
109  }
110  LogTrace("SiStripRawToDigi") << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
111  << " Found " << feds.size() << " FED buffers with non-zero size!";
112  }
113  }
114 
115  // Flag for EventSummary update using DAQ register
116  bool first_fed = true;
117 
118  // Retrieve FED ids from cabling map and iterate through
119  std::vector<uint16_t>::const_iterator ifed = cabling.fedIds().begin();
120  for (; ifed != cabling.fedIds().end(); ifed++) {
121  // ignore trigger FED
122  if (*ifed == triggerFedId_) {
123  continue;
124  }
125 
126  // Retrieve FED raw data for given FED
127  const FEDRawData& input = buffers.FEDData(static_cast<int>(*ifed));
128 
129  // Some debug on FED buffer size
130  if (edm::isDebugEnabled()) {
131  if (first_ && input.data()) {
132  std::stringstream ss;
133  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
134  << " Found FED id " << std::setw(4) << std::setfill(' ') << *ifed << " in FEDRawDataCollection"
135  << " with non-zero pointer 0x" << std::hex << std::setw(8) << std::setfill('0')
136  << reinterpret_cast<const uint32_t*>(input.data()) << std::dec << " and size " << std::setw(5)
137  << std::setfill(' ') << input.size() << " chars";
138  LogTrace("SiStripRawToDigi") << ss.str();
139  }
140  }
141 
142  // Dump of FEDRawData to stdout
143  if (edm::isDebugEnabled()) {
145  std::stringstream ss;
146  dumpRawData(*ifed, input, ss);
148  }
149  }
150 
151  // get the cabling connections for this FED
152  auto conns = cabling.fedConnections(*ifed);
153  // check FEDRawData pointer, size, and more
155  // construct FEDBuffer
156  if (FEDBufferStatusCode::SUCCESS != st_buffer) {
157  if (FEDBufferStatusCode::BUFFER_NULL == st_buffer) {
158  warnings_.add("NULL pointer to FEDRawData for FED", fmt::format("id {0}", *ifed));
159  } else if (!input.size()) {
160  warnings_.add("FEDRawData has zero size for FED", fmt::format("id {0}", *ifed));
161  } else {
162  warnings_.add("Exception caught when creating FEDBuffer object for FED",
163  fmt::format("id {0}: {1}", *ifed, static_cast<int>(st_buffer)));
164  }
165  // FED buffer is bad and should not be unpacked. Skip this FED and mark all modules as bad.
166  maskFED(detids, conns);
167  continue;
168  }
170  const FEDBufferStatusCode st_chan = buffer.findChannels();
171  if (FEDBufferStatusCode::SUCCESS != st_chan) {
172  warnings_.add("Exception caught when creating FEDBuffer object for FED",
173  fmt::format("id {0}: {1}", *ifed, static_cast<int>(st_chan)));
174  maskFED(detids, conns);
175  continue;
176  }
177  buffer.setLegacyMode(legacy_);
178  if ((!buffer.doChecks(true)) && (!unpackBadChannels_ || !buffer.checkNoFEOverflows())) {
179  warnings_.add("Exception caught when creating FEDBuffer object for FED",
180  fmt::format("id {0}: FED Buffer check fails for FED ID {0}.", *ifed));
181  maskFED(detids, conns);
182  continue;
183  }
184  if (doFullCorruptBufferChecks_ && !buffer.doCorruptBufferChecks()) {
185  warnings_.add("Exception caught when creating FEDBuffer object for FED",
186  fmt::format("id {0}: FED corrupt buffer check fails for FED ID {0}.", *ifed));
187  maskFED(detids, conns);
188  continue;
189  }
190 
191  // Check if EventSummary ("trigger FED info") needs updating
192  if (first_fed && useDaqRegister_) {
194  first_fed = false;
195  }
196 
197  // Check to see if EventSummary info is set
198  if (!quiet_ && !summary.isSet()) {
199  warnings_.add(
200  "EventSummary is not set correctly! Missing information from both \"trigger FED\" and \"DAQ registers\"!");
201  }
202 
203  // Check to see if event is to be analyzed according to EventSummary
204  if (!summary.valid()) {
205  if (edm::isDebugEnabled()) {
206  LogTrace("SiStripRawToDigi") << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
207  << " EventSummary is not valid: skipping...";
208  }
209  continue;
210  }
211 
213  const sistrip::FEDReadoutMode mode = buffer.readoutMode();
214  const sistrip::FEDLegacyReadoutMode lmode =
215  (legacy_) ? buffer.legacyReadoutMode() : sistrip::READOUT_MODE_LEGACY_INVALID;
216 
217  // Retrive run type
218  const sistrip::RunType runType_ = summary.runType();
219  if (runType_ == sistrip::APV_LATENCY || runType_ == sistrip::FINE_DELAY) {
220  useFedKey_ = false;
221  }
222 
223  // Dump of FED buffer
224  if (edm::isDebugEnabled()) {
226  std::stringstream ss;
227  buffer.dump(ss);
229  }
230  }
231 
232  // Iterate through FED channels, extract payload and create Digis
233  std::vector<FedChannelConnection>::const_iterator iconn = conns.begin();
234  for (; iconn != conns.end(); iconn++) {
236  uint16_t chan = iconn->fedCh();
237 
238  // Check if fed connection is valid
239  if (!iconn->isConnected()) {
240  continue;
241  }
242 
243  // Check DetId is valid (if to be used as key)
244  if (!useFedKey_ && (!iconn->detId() || iconn->detId() == sistrip::invalid32_)) {
245  continue;
246  }
247 
248  // Check FED channel
249  if (!buffer.channelGood(iconn->fedCh(), doAPVEmulatorCheck_)) {
250  if (!unpackBadChannels_ || !(buffer.fePresent(iconn->fedCh() / FEDCH_PER_FEUNIT) &&
251  buffer.feEnabled(iconn->fedCh() / FEDCH_PER_FEUNIT))) {
252  detids.push_back(iconn->detId()); //@@ Possible multiple entries (ok for Giovanni)
253  continue;
254  }
255  }
256 
257  // Determine whether FED key is inferred from cabling or channel loop
258  const uint32_t fed_key =
259  (summary.runType() == sistrip::FED_CABLING)
260  ? ((*ifed & sistrip::invalid_) << 16) | (chan & sistrip::invalid_)
261  : ((iconn->fedId() & sistrip::invalid_) << 16) | (iconn->fedCh() & sistrip::invalid_);
262 
263  // Determine whether DetId or FED key should be used to index digi containers
264  const uint32_t key = (useFedKey_ || (!legacy_ && mode == sistrip::READOUT_MODE_SCOPE) ||
266  ? fed_key
267  : iconn->detId();
268 
269  // Determine APV std::pair number (needed only when using DetId)
270  const uint16_t ipair = (useFedKey_ || (!legacy_ && mode == sistrip::READOUT_MODE_SCOPE) ||
272  ? 0
273  : iconn->apvPairNumber();
274 
275  const auto& fedChannel = buffer.channel(iconn->fedCh());
276 
277 #ifdef EDM_ML_DEBUG
278  std::stringstream smode;
279  if (!legacy_)
280  smode << mode;
281  else
282  smode << lmode;
283  LogDebug("SiStripRawToDigi") << "Unpacking FED " << *ifed << " channel " << iconn->fedCh()
284  << ((!legacy_) ? " " : " legacy ") << "data in mode " << smode.str()
285  << " for module " << iconn->detId() << " pair " << ipair;
286 #endif
288  Registry regItem(key, 0, zs_work_digis_.size(), 0);
289  const auto isNonLite = fedchannelunpacker::isNonLiteZS(mode, legacy_, lmode);
290  const uint8_t pCode = (isNonLite ? buffer.packetCode(legacy_, iconn->fedCh()) : 0);
291  if (isNonLite)
292  LogDebug("SiStripRawToDigi") << "Non-lite zero-suppressed mode. Packet code=0x" << std::hex
293  << uint16_t(pCode) << std::dec;
294  const auto st_ch = fedchannelunpacker::unpackZeroSuppressed(
295  fedChannel, std::back_inserter(zs_work_digis_), ipair * 256, isNonLite, mode, legacy_, lmode, pCode);
298  warnings_.add(fmt::format("Invalid packet code {0:#x} for zero-suppressed data", uint16_t(pCode)),
299  fmt::format("FED {0} channel {1}", *ifed, iconn->fedCh()));
300  } else if (fedchannelunpacker::StatusCode::SUCCESS != st_ch) {
301  warnings_.add("Clusters are not ordered",
302  fmt::format("FED {0} channel {1}: {2}", *ifed, iconn->fedCh(), toString(st_ch)));
303  detids.push_back(iconn->detId()); //@@ Possible multiple entries (ok for Giovanni)
304  continue;
305  }
306  if (regItem.index != zs_work_digis_.size()) {
307  regItem.length = zs_work_digis_.size() - regItem.index;
308  regItem.first = zs_work_digis_[regItem.index].strip();
309  zs_work_registry_.push_back(regItem);
310  }
311  // Common mode values
312  if (isNonLite && extractCm_) {
313  if ((pCode == PACKET_CODE_ZERO_SUPPRESSED) || (pCode == PACKET_CODE_ZERO_SUPPRESSED10) ||
315  Registry regItem2(key, 2 * ipair, cm_work_digis_.size(), 2);
316  cm_work_digis_.push_back(SiStripRawDigi(fedChannel.cmMedian(0)));
317  cm_work_digis_.push_back(SiStripRawDigi(fedChannel.cmMedian(1)));
318  cm_work_registry_.push_back(regItem2);
319  } else {
320  detids.push_back(iconn->detId()); //@@ Possible multiple entries (ok for Giovanni)
321  warnings_.add("Problem extracting common modes",
322  fmt::format("FED {0} channel {1}:\n Request for CM median from channel with non-ZS "
323  "packet code. Packet code is {2}.",
324  *ifed,
325  iconn->fedCh(),
326  pCode));
327  }
328  }
329  } else {
332  Registry regItem(key, 256 * ipair, virgin_work_digis_.size(), 0);
333  LogDebug("SiStripRawToDigi") << "Virgin raw packet code: 0x" << std::hex
334  << uint16_t(buffer.packetCode(legacy_)) << " 0x"
335  << uint16_t(fedChannel.packetCode()) << std::dec;
337  fedChannel, std::back_inserter(virgin_work_digis_), buffer.packetCode(legacy_));
338  if (regItem.index != virgin_work_digis_.size()) {
339  regItem.length = virgin_work_digis_.size() - regItem.index;
340  virgin_work_registry_.push_back(regItem);
341  }
342  } else if (fedchannelunpacker::isProcessedRaw(mode, legacy_, lmode)) {
343  Registry regItem(key, 256 * ipair, proc_work_digis_.size(), 0);
344  st_ch = fedchannelunpacker::unpackProcessedRaw(fedChannel, std::back_inserter(proc_work_digis_));
345  if (regItem.index != proc_work_digis_.size()) {
346  regItem.length = proc_work_digis_.size() - regItem.index;
347  proc_work_registry_.push_back(regItem);
348  }
349  } else if (fedchannelunpacker::isScopeMode(mode, legacy_, lmode)) {
350  Registry regItem(key, 0, scope_work_digis_.size(), 0);
351  st_ch = fedchannelunpacker::unpackScope(fedChannel, std::back_inserter(scope_work_digis_));
352  if (regItem.index != scope_work_digis_.size()) {
353  regItem.length = scope_work_digis_.size() - regItem.index;
354  scope_work_registry_.push_back(regItem);
355  }
356  } else { // Unknown readout mode! => assume scope mode
357  warnings_.add(fmt::format("Unknown FED readout mode ({0})! Assuming SCOPE MODE...", mode));
358  Registry regItem(key, 0, scope_work_digis_.size(), 0);
359  st_ch = fedchannelunpacker::unpackScope(fedChannel, std::back_inserter(scope_work_digis_));
360  if (regItem.index != scope_work_digis_.size()) {
361  regItem.length = scope_work_digis_.size() - regItem.index;
362  scope_work_registry_.push_back(regItem);
363  if (edm::isDebugEnabled()) {
364  std::stringstream ss;
365  ss << "Extracted " << regItem.length
366  << " SCOPE MODE digis (samples[0] = " << scope_work_digis_[regItem.index] << ") from FED id/ch "
367  << iconn->fedId() << "/" << iconn->fedCh();
368  LogTrace("SiStripRawToDigi") << ss.str();
369  }
370  } else {
371  warnings_.add("No SM digis found!");
372  }
373  }
375  warnings_.add(toString(st_ch), fmt::format("FED {0} channel {1}:", *ifed, iconn->fedCh()));
376  }
377  }
378  } // channel loop
379  } // fed loop
380 
381  // bad channels warning
382  unsigned int detIdsSize = detids.size();
383  if (edm::isDebugEnabled() && detIdsSize) {
384  std::ostringstream ss;
385  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
386  << " Problems were found in data and " << detIdsSize << " channels could not be unpacked. "
387  << "See output of FED Hardware monitoring for more information. ";
389  }
390  if ((errorThreshold_ != 0) && (detIdsSize > errorThreshold_)) {
391  edm::LogError("TooManyErrors") << "Total number of errors = " << detIdsSize;
392  }
393 
394  // update DetSetVectors
395  update(scope_mode, virgin_raw, proc_raw, zero_suppr, cm_values);
396 
397  // increment event counter
398  event_++;
399 
400  // no longer first event!
401  if (first_) {
402  first_ = false;
403  }
404 
405  // final cleanup, just in case
407  }
408 
410  RawDigis& scope_mode, RawDigis& virgin_raw, RawDigis& proc_raw, Digis& zero_suppr, RawDigis& common_mode) {
411  if (!zs_work_registry_.empty()) {
413  std::vector<edm::DetSet<SiStripDigi> > sorted_and_merged;
414  sorted_and_merged.reserve(std::min(zs_work_registry_.size(), size_t(17000)));
415 
416  bool errorInData = false;
417  std::vector<Registry>::iterator it = zs_work_registry_.begin(), it2 = it + 1, end = zs_work_registry_.end();
418  while (it < end) {
419  sorted_and_merged.push_back(edm::DetSet<SiStripDigi>(it->detid));
420  std::vector<SiStripDigi>& digis = sorted_and_merged.back().data;
421  // first count how many digis we have
422  size_t len = it->length;
423  for (it2 = it + 1; (it2 != end) && (it2->detid == it->detid); ++it2) {
424  len += it2->length;
425  }
426  // reserve memory
427  digis.reserve(len);
428  // push them in
429  for (it2 = it + 0; (it2 != end) && (it2->detid == it->detid); ++it2) {
430  digis.insert(digis.end(), &zs_work_digis_[it2->index], &zs_work_digis_[it2->index + it2->length]);
431  }
432  it = it2;
433  }
434 
435  // check sorting
436  if (!__gnu_cxx::is_sorted(sorted_and_merged.begin(), sorted_and_merged.end())) {
437  // this is an error in the code: i DID sort it already!
438  throw cms::Exception("Bug Found")
439  << "Container must be already sorted!\nat " << __FILE__ << ", line " << __LINE__ << "\n";
440  }
441 
442  std::vector<edm::DetSet<SiStripDigi> >::iterator iii = sorted_and_merged.begin();
443  std::vector<edm::DetSet<SiStripDigi> >::iterator jjj = sorted_and_merged.end();
444  for (; iii != jjj; ++iii) {
445  if (!__gnu_cxx::is_sorted(iii->begin(), iii->end())) {
446  // this might be an error in the data, if the raws from one FED are not sorted
447  iii->clear();
448  errorInData = true;
449  }
450  }
451 
452  // output error
453  if (errorInData)
454  edm::LogWarning("CorruptData")
455  << "Some modules contained corrupted ZS raw data, and have been skipped in unpacking\n";
456 
457  // make output DetSetVector
458  edm::DetSetVector<SiStripDigi> zero_suppr_dsv(sorted_and_merged, true);
459  zero_suppr.swap(zero_suppr_dsv);
460  }
461 
462  // Populate final DetSetVector container with VR data
463  if (!virgin_work_registry_.empty()) {
465 
466  std::vector<edm::DetSet<SiStripRawDigi> > sorted_and_merged;
467  sorted_and_merged.reserve(std::min(virgin_work_registry_.size(), size_t(17000)));
468 
469  bool errorInData = false;
470  std::vector<Registry>::iterator it = virgin_work_registry_.begin(), it2, end = virgin_work_registry_.end();
471  while (it < end) {
472  sorted_and_merged.push_back(edm::DetSet<SiStripRawDigi>(it->detid));
473  std::vector<SiStripRawDigi>& digis = sorted_and_merged.back().data;
474 
475  bool isDetOk = true;
476  // first count how many digis we have
477  int maxFirstStrip = it->first;
478  for (it2 = it + 1; (it2 != end) && (it2->detid == it->detid); ++it2) {
479  // duplicated APV or data corruption. DO NOT 'break' here!
480  if (it2->first <= maxFirstStrip) {
481  isDetOk = false;
482  continue;
483  }
484  maxFirstStrip = it2->first;
485  }
486  if (!isDetOk) {
487  errorInData = true;
488  it = it2;
489  continue;
490  } // skip whole det
491 
492  // make room for 256 * (max_apv_pair + 1) Raw Digis
493  digis.resize(maxFirstStrip + 256);
494  // push them in
495  for (it2 = it + 0; (it2 != end) && (it2->detid == it->detid); ++it2) {
496  // data corruption. DO NOT 'break' here
497  if (it->length != 256) {
498  isDetOk = false;
499  continue;
500  }
501  std::copy(&virgin_work_digis_[it2->index], &virgin_work_digis_[it2->index + it2->length], &digis[it2->first]);
502  }
503  if (!isDetOk) {
504  errorInData = true;
505  digis.clear();
506  it = it2;
507  continue;
508  } // skip whole det
509  it = it2;
510  }
511 
512  // output error
513  if (errorInData)
514  edm::LogWarning("CorruptData")
515  << "Some modules contained corrupted virgin raw data, and have been skipped in unpacking\n";
516 
517  // check sorting
518  if (!__gnu_cxx::is_sorted(sorted_and_merged.begin(), sorted_and_merged.end())) {
519  // this is an error in the code: i DID sort it already!
520  throw cms::Exception("Bug Found")
521  << "Container must be already sorted!\nat " << __FILE__ << ", line " << __LINE__ << "\n";
522  }
523 
524  // make output DetSetVector
525  edm::DetSetVector<SiStripRawDigi> virgin_raw_dsv(sorted_and_merged, true);
526  virgin_raw.swap(virgin_raw_dsv);
527  }
528 
529  // Populate final DetSetVector container with VR data
530  if (!proc_work_registry_.empty()) {
532 
533  std::vector<edm::DetSet<SiStripRawDigi> > sorted_and_merged;
534  sorted_and_merged.reserve(std::min(proc_work_registry_.size(), size_t(17000)));
535 
536  bool errorInData = false;
537  std::vector<Registry>::iterator it = proc_work_registry_.begin(), it2, end = proc_work_registry_.end();
538  while (it < end) {
539  sorted_and_merged.push_back(edm::DetSet<SiStripRawDigi>(it->detid));
540  std::vector<SiStripRawDigi>& digis = sorted_and_merged.back().data;
541 
542  bool isDetOk = true;
543  // first count how many digis we have
544  int maxFirstStrip = it->first;
545  for (it2 = it + 1; (it2 != end) && (it2->detid == it->detid); ++it2) {
546  // duplicated APV or data corruption. DO NOT 'break' here!
547  if (it2->first <= maxFirstStrip) {
548  isDetOk = false;
549  continue;
550  }
551  maxFirstStrip = it2->first;
552  }
553  // skip whole det
554  if (!isDetOk) {
555  errorInData = true;
556  it = it2;
557  continue;
558  }
559 
560  // make room for 256 * (max_apv_pair + 1) Raw Digis
561  digis.resize(maxFirstStrip + 256);
562  // push them in
563  for (it2 = it + 0; (it2 != end) && (it2->detid == it->detid); ++it2) {
564  // data corruption. DO NOT 'break' here
565  if (it->length != 256) {
566  isDetOk = false;
567  continue;
568  }
569  std::copy(&proc_work_digis_[it2->index], &proc_work_digis_[it2->index + it2->length], &digis[it2->first]);
570  }
571  // skip whole det
572  if (!isDetOk) {
573  errorInData = true;
574  digis.clear();
575  it = it2;
576  continue;
577  }
578  it = it2;
579  }
580 
581  // output error
582  if (errorInData)
583  edm::LogWarning("CorruptData")
584  << "Some modules contained corrupted proc raw data, and have been skipped in unpacking\n";
585 
586  // check sorting
587  if (!__gnu_cxx::is_sorted(sorted_and_merged.begin(), sorted_and_merged.end())) {
588  // this is an error in the code: i DID sort it already!
589  throw cms::Exception("Bug Found")
590  << "Container must be already sorted!\nat " << __FILE__ << ", line " << __LINE__ << "\n";
591  }
592 
593  // make output DetSetVector
594  edm::DetSetVector<SiStripRawDigi> proc_raw_dsv(sorted_and_merged, true);
595  proc_raw.swap(proc_raw_dsv);
596  }
597 
598  // Populate final DetSetVector container with SM data
599  if (!scope_work_registry_.empty()) {
601 
602  std::vector<edm::DetSet<SiStripRawDigi> > sorted_and_merged;
603  sorted_and_merged.reserve(scope_work_registry_.size());
604 
605  bool errorInData = false;
606  std::vector<Registry>::iterator it, end;
607  for (it = scope_work_registry_.begin(), end = scope_work_registry_.end(); it != end; ++it) {
608  sorted_and_merged.push_back(edm::DetSet<SiStripRawDigi>(it->detid));
609  std::vector<SiStripRawDigi>& digis = sorted_and_merged.back().data;
610  digis.insert(digis.end(), &scope_work_digis_[it->index], &scope_work_digis_[it->index + it->length]);
611 
612  if ((it + 1 != end) && (it->detid == (it + 1)->detid)) {
613  errorInData = true;
614  // let's skip *all* the detsets for that key, as we don't know which is the correct one!
615  do {
616  ++it;
617  } while ((it + 1 != end) && (it->detid == (it + 1)->detid));
618  }
619  }
620 
621  // output error
622  if (errorInData)
623  edm::LogWarning("CorruptData")
624  << "Some fed keys contained corrupted scope mode data, and have been skipped in unpacking\n";
625 
626  // check sorting
627  if (!__gnu_cxx::is_sorted(sorted_and_merged.begin(), sorted_and_merged.end())) {
628  // this is an error in the code: i DID sort it already!
629  throw cms::Exception("Bug Found")
630  << "Container must be already sorted!\nat " << __FILE__ << ", line " << __LINE__ << "\n";
631  }
632 
633  // make output DetSetVector
634  edm::DetSetVector<SiStripRawDigi> scope_mode_dsv(sorted_and_merged, true);
635  scope_mode.swap(scope_mode_dsv);
636  }
637 
638  // Populate DetSetVector with Common Mode values
639  if (extractCm_) {
640  // Populate final DetSetVector container with VR data
641  if (!cm_work_registry_.empty()) {
643 
644  std::vector<edm::DetSet<SiStripRawDigi> > sorted_and_merged;
645  sorted_and_merged.reserve(std::min(cm_work_registry_.size(), size_t(17000)));
646 
647  bool errorInData = false;
648  std::vector<Registry>::iterator it = cm_work_registry_.begin(), it2, end = cm_work_registry_.end();
649  while (it < end) {
650  sorted_and_merged.push_back(edm::DetSet<SiStripRawDigi>(it->detid));
651  std::vector<SiStripRawDigi>& digis = sorted_and_merged.back().data;
652 
653  bool isDetOk = true;
654  // first count how many digis we have
655  int maxFirstStrip = it->first;
656  for (it2 = it + 1; (it2 != end) && (it2->detid == it->detid); ++it2) {
657  // duplicated APV or data corruption. DO NOT 'break' here!
658  if (it2->first <= maxFirstStrip) {
659  isDetOk = false;
660  continue;
661  }
662  maxFirstStrip = it2->first;
663  }
664  if (!isDetOk) {
665  errorInData = true;
666  it = it2;
667  continue;
668  } // skip whole det
669 
670  // make room for 2 * (max_apv_pair + 1) Common mode values
671  digis.resize(maxFirstStrip + 2);
672  // push them in
673  for (it2 = it + 0; (it2 != end) && (it2->detid == it->detid); ++it2) {
674  // data corruption. DO NOT 'break' here
675  if (it->length != 2) {
676  isDetOk = false;
677  continue;
678  }
679  std::copy(&cm_work_digis_[it2->index], &cm_work_digis_[it2->index + it2->length], &digis[it2->first]);
680  }
681  if (!isDetOk) {
682  errorInData = true;
683  digis.clear();
684  it = it2;
685  continue;
686  } // skip whole det
687  it = it2;
688  }
689 
690  // output error
691  if (errorInData)
692  edm::LogWarning("CorruptData")
693  << "Some modules contained corrupted common mode data, and have been skipped in unpacking\n";
694 
695  // check sorting
696  if (!__gnu_cxx::is_sorted(sorted_and_merged.begin(), sorted_and_merged.end())) {
697  // this is an error in the code: i DID sort it already!
698  throw cms::Exception("Bug Found")
699  << "Container must be already sorted!\nat " << __FILE__ << ", line " << __LINE__ << "\n";
700  }
701 
702  // make output DetSetVector
703  edm::DetSetVector<SiStripRawDigi> common_mode_dsv(sorted_and_merged, true);
704  common_mode.swap(common_mode_dsv);
705  }
706  }
707  }
708 
710  // Clear working areas and registries
711 
712  localRA.update(zs_work_digis_.size());
713  zs_work_registry_.clear();
714  zs_work_digis_.clear();
715  zs_work_digis_.shrink_to_fit();
716  assert(zs_work_digis_.capacity() == 0);
717  virgin_work_registry_.clear();
718  virgin_work_digis_.clear();
719  proc_work_registry_.clear();
720  proc_work_digis_.clear();
721  scope_work_registry_.clear();
722  scope_work_digis_.clear();
723  cm_work_registry_.clear();
724  cm_work_digis_.clear();
725  }
726 
729  const uint32_t& event) {
730  // Pointer to data (recast as 32-bit words) and number of 32-bit words
731  const uint32_t* data_u32 = nullptr;
732  uint32_t size_u32 = 0;
733 
734  // Search mode
735  if (triggerFedId_ < 0) {
736  uint16_t ifed = 0;
737  while (triggerFedId_ < 0 && ifed < 1 + FEDNumbering::lastFEDId()) {
738  const FEDRawData& trigger_fed = buffers.FEDData(ifed);
739  if (trigger_fed.data() && trigger_fed.size()) {
740  const uint8_t* temp = trigger_fed.data();
741  data_u32 = reinterpret_cast<const uint32_t*>(temp) + FEDHeader::length / sizeof(uint32_t) + 1;
742  size_u32 = trigger_fed.size() / sizeof(uint32_t) - FEDHeader::length / sizeof(uint32_t) - 1;
743  const FEDTrailer fedTrailer(temp + trigger_fed.size() - FEDTrailer::length);
744  if (fedTrailer.conscheck() == 0xDEADFACE) {
745  triggerFedId_ = ifed;
746  if (edm::isDebugEnabled()) {
747  std::stringstream ss;
748  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
749  << " Search mode for 'trigger FED' activated!"
750  << " Found 'trigger FED' info with id " << triggerFedId_;
751  LogTrace("SiStripRawToDigi") << ss.str();
752  }
753  }
754  }
755  ifed++;
756  }
757  if (triggerFedId_ < 0) {
758  triggerFedId_ = 0;
759  if (edm::isDebugEnabled()) {
760  std::stringstream ss;
761  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
762  << " Search mode for 'trigger FED' activated!"
763  << " 'Trigger FED' info not found!";
765  }
766  }
767  }
768 
769  // "Trigger FED" id given in .cfg file
770  else if (triggerFedId_ > 0) {
771  const FEDRawData& trigger_fed = buffers.FEDData(triggerFedId_);
772  if (trigger_fed.data() && trigger_fed.size()) {
773  const uint8_t* temp = trigger_fed.data();
774  data_u32 = reinterpret_cast<const uint32_t*>(temp) + FEDHeader::length / sizeof(uint32_t) + 1;
775  size_u32 = trigger_fed.size() / sizeof(uint32_t) - FEDHeader::length / sizeof(uint32_t) - 1;
776  const FEDTrailer fedTrailer(temp + trigger_fed.size() - FEDTrailer::length);
777  if (fedTrailer.conscheck() != 0xDEADFACE) {
778  if (edm::isDebugEnabled()) {
779  edm::LogWarning(sistrip::mlRawToDigi_) << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
780  << " Unexpected stamp found in DAQ trailer (ie, not 0xDEADFACE)!"
781  << " Buffer appears not to contain 'trigger FED' data!";
782  }
783  triggerFedId_ = 0;
784  }
785  }
786 
787  } else {
788  triggerFedId_ = 0;
789  data_u32 = nullptr;
790  size_u32 = 0;
791  }
792 
793  // Populate summary object with commissioning information
794  if (triggerFedId_ > 0) {
795  // Some checks
796  if (!data_u32) {
797  if (edm::isDebugEnabled()) {
798  std::stringstream ss;
799  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
800  << " NULL pointer to 'trigger FED' data";
802  }
803  return;
804  }
805  if (size_u32 < sizeof(TFHeaderDescription) / sizeof(uint32_t)) {
806  if (edm::isDebugEnabled()) {
807  std::stringstream ss;
808  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
809  << " Unexpected 'Trigger FED' data size [32-bit words]: " << size_u32;
811  }
812  return;
813  }
814 
815  // Write event-specific data to event
816  const TFHeaderDescription* header = (const TFHeaderDescription*)data_u32;
817  summary.event(static_cast<uint32_t>(header->getFedEventNumber()));
818  summary.bx(static_cast<uint32_t>(header->getBunchCrossing()));
819 
820  // Write commissioning information to event
821  uint32_t hsize = sizeof(TFHeaderDescription) / sizeof(uint32_t);
822  const uint32_t* head = &data_u32[hsize];
823  summary.commissioningInfo(head, event);
824  summary.triggerFed(triggerFedId_);
825  }
826 
827  // Some debug
828  if (summary.isSet() && once_) {
829  if (edm::isDebugEnabled()) {
830  std::stringstream ss;
831  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
832  << " EventSummary built from \"trigger FED\":" << std::endl
833  << summary;
834  LogTrace("SiStripRawToDigi") << ss.str();
835  }
836  once_ = false;
837  }
838  }
839 
841  // Check size of input buffer
842  if (input.size() < 24) {
843  output.resize(input.size()); // Return UNadjusted buffer start position and size
844  memcpy(output.data(), input.data(), input.size());
845  if (edm::isDebugEnabled()) {
846  std::stringstream ss;
847  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "] "
848  << "Input FEDRawData with FED id " << fed_id << " has size " << input.size();
850  }
851  return;
852  }
853 
854  // Iterator through buffer to find DAQ header
855  bool found = false;
856  uint16_t ichar = 0;
857  while (ichar < input.size() - 16 && !found) {
858  uint16_t offset =
859  headerBytes_ < 0 ? ichar : headerBytes_; // Negative value means use "search mode" to find DAQ header
860  const uint32_t* input_u32 = reinterpret_cast<const uint32_t*>(input.data() + offset);
861  const uint32_t* fed_trailer = reinterpret_cast<const uint32_t*>(input.data() + input.size() - 8);
862 
863  // see info on FED 32-bit swapping at end-of-file
864 
865  bool old_vme_header = (input_u32[0] & 0xF0000000) == 0x50000000 && (fed_trailer[0] & 0xF0000000) == 0xA0000000 &&
866  ((fed_trailer[0] & 0x00FFFFFF) * 0x8) == (input.size() - offset);
867 
868  bool old_slink_header = (input_u32[1] & 0xF0000000) == 0x50000000 &&
869  (fed_trailer[1] & 0xF0000000) == 0xA0000000 &&
870  ((fed_trailer[1] & 0x00FFFFFF) * 0x8) == (input.size() - offset);
871 
872  bool old_slink_payload = (input_u32[3] & 0xFF000000) == 0xED000000;
873 
874  bool new_buffer_format = (input_u32[2] & 0xFF000000) == 0xC5000000;
875 
876  if (old_vme_header) {
877  // Found DAQ header at byte position 'offset'
878  found = true;
879  output.resize(input.size() - offset);
880  memcpy(output.data(), // target
881  input.data() + offset, // source
882  input.size() - offset); // nbytes
883  if (headerBytes_ < 0) {
884  if (edm::isDebugEnabled()) {
885  std::stringstream ss;
886  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
887  << " Buffer for FED id " << fed_id << " has been found at byte position " << offset << " with a size of "
888  << input.size() - offset << " bytes."
889  << " Adjust the configurable 'AppendedBytes' to " << offset;
890  LogTrace("SiStripRawToDigi") << ss.str();
891  }
892  }
893 
894  } else if (old_slink_header) {
895  if (old_slink_payload) {
896  // Found DAQ header (with MSB and LSB 32-bit words swapped) at byte position 'offset'
897  found = true;
898  output.resize(input.size() - offset);
899  uint32_t* output_u32 = reinterpret_cast<uint32_t*>(output.data());
900  uint16_t iter = offset;
901  while (iter < output.size() / sizeof(uint32_t)) {
902  output_u32[iter] = input_u32[iter + 1];
903  output_u32[iter + 1] = input_u32[iter];
904  iter += 2;
905  }
906  if (headerBytes_ < 0) {
907  if (edm::isDebugEnabled()) {
908  std::stringstream ss;
909  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
910  << " Buffer (with MSB and LSB 32-bit words swapped) for FED id " << fed_id
911  << " has been found at byte position " << offset << " with a size of " << output.size() << " bytes."
912  << " Adjust the configurable 'AppendedBytes' to " << offset;
913  LogTrace("SiStripRawToDigi") << ss.str();
914  }
915  }
916 
917  } else if (new_buffer_format) {
918  // Found DAQ header at byte position 'offset'
919  found = true;
920  output.resize(input.size() - offset);
921  memcpy(output.data(), // target
922  input.data() + offset, // source
923  input.size() - offset); // nbytes
924  if (headerBytes_ < 0) {
925  if (edm::isDebugEnabled()) {
926  std::stringstream ss;
927  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
928  << " Buffer for FED id " << fed_id << " has been found at byte position " << offset
929  << " with a size of " << input.size() - offset << " bytes."
930  << " Adjust the configurable 'AppendedBytes' to " << offset;
931  LogTrace("SiStripRawToDigi") << ss.str();
932  }
933  }
934 
935  } else {
936  headerBytes_ < 0 ? found = false : found = true;
937  }
938  } else {
939  headerBytes_ < 0 ? found = false : found = true;
940  }
941  ichar++;
942  }
943 
944  // Check size of output buffer
945  if (output.size() == 0) {
946  // Did not find DAQ header after search => return buffer with null size
947  output.resize(0); //@@ NULL SIZE
948  memcpy(output.data(), input.data(), 0); //@@ NULL SIZE
949  if (edm::isDebugEnabled()) {
950  std::stringstream ss;
951  if (headerBytes_ < 0) {
952  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
953  << " DAQ header not found within buffer for FED id: " << fed_id;
954  } else {
955  const uint32_t* input_u32 = reinterpret_cast<const uint32_t*>(input.data());
956  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
957  << " DAQ header not found at expected location for FED id: " << fed_id << std::endl
958  << " First 64-bit word of buffer is 0x" << std::hex << std::setfill('0') << std::setw(8) << input_u32[0]
959  << std::setfill('0') << std::setw(8) << input_u32[1] << std::dec << std::endl
960  << " Adjust 'AppendedBytes' configurable to '-1' to activate 'search mode'";
961  }
963  }
964 
965  } else if (output.size() < 24) { // Found DAQ header after search, but too few words
966 
967  if (edm::isDebugEnabled()) {
968  std::stringstream ss;
969  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
970  << " Unexpected buffer size! FEDRawData with FED id " << fed_id << " has size " << output.size();
972  }
973  }
974  }
975 
977  summary.event(fed.daqHeader().l1ID());
978  summary.bx(fed.daqHeader().bxID());
979 
980  // Retrieve contents of DAQ registers
981 
982  sistrip::FEDDAQEventType readout_mode = fed.daqEventType();
983  uint32_t daq1 = sistrip::invalid32_;
984  uint32_t daq2 = sistrip::invalid32_;
985 
987  const sistrip::FEDFullDebugHeader* header = nullptr;
988  header = dynamic_cast<const sistrip::FEDFullDebugHeader*>(fed.feHeader());
989  daq1 = static_cast<uint32_t>(header->daqRegister());
990  daq2 = static_cast<uint32_t>(header->daqRegister2());
991  }
992 
993  // If FED DAQ registers contain info, update (and possibly overwrite) EventSummary
994  if (daq1 != 0 && daq1 != sistrip::invalid32_) {
995  summary.triggerFed(triggerFedId_);
996  summary.fedReadoutMode(readout_mode);
997  summary.commissioningInfo(daq1, daq2);
998 
999  if (summary.isSet() && once_) {
1000  if (edm::isDebugEnabled()) {
1001  std::stringstream ss;
1002  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1003  << " EventSummary built from FED DAQ registers:" << std::endl
1004  << summary;
1005  LogTrace("SiStripRawToDigi") << ss.str();
1006  }
1007  once_ = false;
1008  }
1009  }
1010  }
1011 
1012  void RawToDigiUnpacker::dumpRawData(uint16_t fed_id, const FEDRawData& buffer, std::stringstream& ss) {
1013  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1014  << " Dump of buffer for FED id " << fed_id << std::endl
1015  << " Buffer contains " << buffer.size() << " bytes (NB: payload is byte-swapped)" << std::endl;
1016 
1017  if (false) {
1018  const uint32_t* buffer_u32 = reinterpret_cast<const uint32_t*>(buffer.data());
1019  unsigned int empty = 0;
1020 
1021  ss << "Byte-> 4 5 6 7 0 1 2 3\n";
1022  for (uint32_t i = 0; i < buffer.size() / 8; i++) {
1023  unsigned int temp0 = buffer_u32[i * 2] & sistrip::invalid32_;
1024  unsigned int temp1 = buffer_u32[i * 2 + 1] & sistrip::invalid32_;
1025  if (!temp0 && !temp1) {
1026  empty++;
1027  } else {
1028  if (empty) {
1029  ss << " [ empty words ]" << std::endl;
1030  empty = 0;
1031  }
1032  ss << std::dec << std::setfill(' ') << std::setw(6) << i * 8 << ": " << std::hex << std::setfill('0')
1033  << std::setw(8) << temp0 << std::setfill('0') << std::setw(8) << temp1 << std::dec << std::endl;
1034  }
1035  }
1036 
1037  } else {
1038  ss << " Byte | <---- Byte order ----< | Byte" << std::endl;
1039  ss << " cntr | 7 6 5 4 3 2 1 0 | cntr" << std::endl;
1040  for (uint32_t i = 0; i < buffer.size() / 8; i++) {
1041  //if ( i>=20 && ((i+4)<(buffer.size()/8)) ) { continue; }
1042  uint16_t tmp0 = buffer.data()[i * 8 + 0] & 0xFF;
1043  uint16_t tmp1 = buffer.data()[i * 8 + 1] & 0xFF;
1044  uint16_t tmp2 = buffer.data()[i * 8 + 2] & 0xFF;
1045  uint16_t tmp3 = buffer.data()[i * 8 + 3] & 0xFF;
1046  uint16_t tmp4 = buffer.data()[i * 8 + 4] & 0xFF;
1047  uint16_t tmp5 = buffer.data()[i * 8 + 5] & 0xFF;
1048  uint16_t tmp6 = buffer.data()[i * 8 + 6] & 0xFF;
1049  uint16_t tmp7 = buffer.data()[i * 8 + 7] & 0xFF;
1050  // if ( !tmp0 && !tmp1 && !tmp2 && !tmp3 &&
1051  // !tmp4 && !tmp5 && !tmp6 && !tmp7 ) { empty++; }
1052  // else {
1053  // if ( empty ) {
1054  // ss << " [.."
1055  // << std::dec << std::setfill('.') << std::setw(4) << empty
1056  // << " null words....]" << std::endl;
1057  // empty = 0;
1058  // }
1059  ss << std::dec << std::setfill(' ') << std::setw(6) << i * 8 + 7 << " : " << std::hex << std::setfill('0')
1060  << std::setw(2) << tmp7 << " " << std::setfill('0') << std::setw(2) << tmp6 << " " << std::setfill('0')
1061  << std::setw(2) << tmp5 << " " << std::setfill('0') << std::setw(2) << tmp4 << " " << std::setfill('0')
1062  << std::setw(2) << tmp3 << " " << std::setfill('0') << std::setw(2) << tmp2 << " " << std::setfill('0')
1063  << std::setw(2) << tmp1 << " " << std::setfill('0') << std::setw(2) << tmp0 << std::dec << " :"
1064  << std::setfill(' ') << std::setw(6) << i * 8 << std::endl;
1065  // }
1066  }
1067  }
1068  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1069  << " End of FED buffer";
1070  }
1071 } // namespace sistrip
1072 
1073 /*
1074 
1075 Some info on FED buffer 32-bit word swapping.
1076 
1077 Table below indicates if data are swapped relative to the "old"
1078 VME format (as originally expected by the Fed9UEvent class).
1079 
1080 -------------------------------------------
1081 | SWAPPED? | DATA FORMAT |
1082 | (wrt "OLD") | OLD (0xED) | NEW (0xC5) |
1083 | | VME | SLINK | VME | SLINK |
1084 -------------------------------------------
1085 | DAQ HEADER | N | Y | Y | Y |
1086 | TRK HEADER | N | Y | N | N |
1087 | PAYLOAD | N | Y | N | N |
1088 | DAQ TRAILER | N | Y | Y | Y |
1089 -------------------------------------------
1090 
1091 So, in code, we check in code order of bytes in DAQ header/trailer only:
1092 -> if "old_vme_header", then old format read out via vme, so do nothing.
1093 -> else if "old_slink_header", then data may be wrapped, so check additionally the TRK header:
1094 ---> if "old_slink_payload", then old format read out via slink, so swap all data;
1095 ---> else if "new_buffer_format", then new format, handled internally by Fed9UEvent, so do nothing.
1096 
1097 Pattern matching to find DAQ and tracker headers, and DAQ trailer:
1098 DAQ header, 4 bits, in field |BOE_1| with value 0x5
1099 DAQ trailer, 4 bits, in field |EOE_1| with value 0xA
1100 TRK header, 8 bits, in field |Hdr format| with value 0xED or 0xC5
1101 
1102 -------------------------------------------------------------------------------------------
1103 | SWAPPED? | DATA FORMAT |
1104 | (wrt "OLD") | OLD (0xED) | NEW (0xC5) |
1105 | | VME | SLINK | VME | SLINK |
1106 -------------------------------------------------------------------------------------------
1107 | DAQ HEADER | ........5....... | 5............... | 5............... | 5............... |
1108 | TRK HEADER | ........ED...... | ED.............. | ........C5...... | ........C5...... |
1109 | PAYLOAD | ..........EA.... | ..EA............ | ..EA............ | ............EA.. |
1110 | DAQ TRAILER | ........A....... | A............... | A............... | A............... |
1111 -------------------------------------------------------------------------------------------
1112 
1113 */
void triggerFed(const FEDRawDataCollection &, SiStripEventSummary &, const uint32_t &event)
trigger info
Log< level::Info, true > LogVerbatim
static const uint8_t PACKET_CODE_ZERO_SUPPRESSED8_BOTBOT
bool isDebugEnabled()
void update(RawDigis &scope_mode, RawDigis &virgin_raw, RawDigis &proc_raw, Digis &zero_suppr, RawDigis &common_mode)
fill DetSetVectors using registries
std::vector< Registry > proc_work_registry_
void updateEventSummary(const sistrip::FEDBuffer &, SiStripEventSummary &)
sets the SiStripEventSummary -> not yet implemented for FEDBuffer class
std::vector< SiStripDigi > zs_work_digis_
digi collections
std::vector< Registry > scope_work_registry_
StatusCode unpackZeroSuppressed(const FEDChannel &channel, OUT &&out, uint16_t stripStart, bool isNonLite, FEDReadoutMode mode, bool legacy=false, FEDLegacyReadoutMode lmode=READOUT_MODE_LEGACY_INVALID, uint8_t packetCode=0)
void cleanupWorkVectors()
method to clear registries and digi collections
static const uint32_t length
Definition: FEDTrailer.h:57
std::vector< Registry > zs_work_registry_
registries
static const uint32_t invalid32_
Definition: Constants.h:15
void locateStartOfFedBuffer(const uint16_t &fed_id, const FEDRawData &input, FEDRawData &output)
Removes any data appended prior to FED buffer and reorders 32-bit words if swapped.
static const uint32_t length
Definition: FEDHeader.h:54
const FEDFEHeader * feHeader() const
bool isScopeMode(FEDReadoutMode mode, bool legacy=false, FEDLegacyReadoutMode lmode=READOUT_MODE_LEGACY_INVALID)
static const char mlRawToDigi_[]
size_t size() const
Lenght of the data buffer in bytes.
Definition: FEDRawData.h:45
void push_back(T const &t)
Definition: EDCollection.h:60
Log< level::Error, false > LogError
assert(be >=bs)
std::string toString(fedchannelunpacker::StatusCode status)
void swap(DetSetVector &other)
sistrip classes
#define LogTrace(id)
private class to register start and end index of digis in a collection
static std::string const input
Definition: EdmProvDump.cc:50
static const uint8_t PACKET_CODE_ZERO_SUPPRESSED8_TOPBOT
static const uint8_t PACKET_CODE_ZERO_SUPPRESSED10
std::vector< SiStripRawDigi > virgin_work_digis_
bool isProcessedRaw(FEDReadoutMode mode, bool legacy=false, FEDLegacyReadoutMode lmode=READOUT_MODE_LEGACY_INVALID)
~RawToDigiUnpacker()
default constructor
boost::iterator_range< ConnsConstIter > ConnsConstIterRange
static const uint8_t PACKET_CODE_ZERO_SUPPRESSED
static void dumpRawData(uint16_t fed_id, const FEDRawData &, std::stringstream &)
dumps raw data to stdout (NB: payload is byte-swapped,headers/trailer are not).
FEDDAQEventType daqEventType() const
bool isVirginRaw(FEDReadoutMode mode, bool legacy=false, FEDLegacyReadoutMode lmode=READOUT_MODE_LEGACY_INVALID)
StatusCode unpackVirginRaw(const FEDChannel &channel, OUT &&out, uint8_t packetCode)
std::vector< SiStripRawDigi > scope_work_digis_
std::vector< SiStripRawDigi > proc_work_digis_
const FEDRawData & FEDData(int fedid) const
retrieve data for fed
void add(const std::string &message, const std::string &details="")
void reserve(size_type n)
Definition: EDCollection.h:92
std::vector< SiStripRawDigi > cm_work_digis_
StatusCode unpackScope(const FEDChannel &channel, OUT &&out)
bool isZeroSuppressed(FEDReadoutMode mode, bool legacy=false, FEDLegacyReadoutMode lmode=READOUT_MODE_LEGACY_INVALID)
static const uint16_t FEDCH_PER_FEUNIT
static const uint16_t invalid_
Definition: Constants.h:16
chan
lumi = TPaveText(lowX+0.38, lowY+0.061, lowX+0.45, lowY+0.161, "NDC") lumi.SetBorderSize( 0 ) lumi...
Contains cabling info at the device level, including DetId, APV pair numbers, hardware addresses...
bool isNonLiteZS(FEDReadoutMode mode, bool legacy=false, FEDLegacyReadoutMode lmode=READOUT_MODE_LEGACY_INVALID)
HLT enums.
size_type size() const
Definition: EDCollection.h:82
conn
Definition: getInfo.py:9
FEDBufferStatusCode preconstructCheckFEDBuffer(const FEDRawData &fedBuffer, bool allowBadBuffer=false)
const unsigned char * data() const
Return a const pointer to the beginning of the data buffer.
Definition: FEDRawData.cc:24
void createDigis(const SiStripFedCabling &, const FEDRawDataCollection &, SiStripEventSummary &, RawDigis &scope_mode, RawDigis &virgin_raw, RawDigis &proc_raw, Digis &zero_suppr, DetIdCollection &, RawDigis &common_mode)
creates digis
std::vector< Registry > cm_work_registry_
Log< level::Warning, false > LogWarning
A Digi for the silicon strip detector, containing only adc information, and suitable for storing raw ...
static constexpr int lastFEDId()
Definition: FEDNumbering.h:19
FedsConstIterRange fedIds() const
StatusCode unpackProcessedRaw(const FEDChannel &channel, OUT &&out)
std::vector< Registry > virgin_work_registry_
ConnsConstIterRange fedConnections(uint16_t fed_id) const
Definition: event.py:1
RawToDigiUnpacker()=delete
private default constructor
#define LogDebug(id)