18 #include <boost/format.hpp>
19 #include <ext/algorithm>
25 int16_t fed_buffer_dump_freq,
26 int16_t fed_event_dump_freq,
27 int16_t trigger_fed_id,
29 bool unpack_bad_channels,
30 bool mark_missing_feds,
31 const uint32_t errorThreshold)
32 : headerBytes_(appended_bytes),
33 fedBufferDumpFreq_(fed_buffer_dump_freq),
34 fedEventDumpFreq_(fed_event_dump_freq),
35 triggerFedId_(trigger_fed_id),
36 useFedKey_(using_fed_key),
37 unpackBadChannels_(unpack_bad_channels),
38 markMissingFeds_(mark_missing_feds),
42 useDaqRegister_(
false),
45 doFullCorruptBufferChecks_(
false),
46 doAPVEmulatorCheck_(
true),
47 errorThreshold_(errorThreshold),
50 LogTrace(
"SiStripRawToDigi") <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
51 <<
" Constructing object...";
55 <<
"Warning: Unpacking of bad channels enabled. Only enable this if you know what you are doing. "
62 LogTrace(
"SiStripRawToDigi") <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
63 <<
" Destructing object...";
72 maskedModules.
reserve(maskedModules.
size() + fedConnections.size());
73 for (
const auto&
conn : fedConnections) {
97 if (cabling.
fedIds().empty()) {
101 std::vector<uint16_t>
feds;
104 feds.push_back(ifed);
107 LogTrace(
"SiStripRawToDigi") <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
108 <<
" Found " <<
feds.size() <<
" FED buffers with non-zero size!";
113 bool first_fed =
true;
116 std::vector<uint16_t>::const_iterator ifed = cabling.
fedIds().begin();
117 for (; ifed != cabling.
fedIds().end(); ifed++) {
129 std::stringstream
ss;
130 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
131 <<
" Found FED id " << std::setw(4) << std::setfill(
' ') << *ifed <<
" in FEDRawDataCollection"
132 <<
" with non-zero pointer 0x" << std::hex << std::setw(8) << std::setfill(
'0')
133 << reinterpret_cast<const uint32_t*>(
input.data()) <<
std::dec <<
" and size " << std::setw(5)
134 << std::setfill(
' ') <<
input.size() <<
" chars";
142 std::stringstream
ss;
156 }
else if (!
input.size()) {
159 warnings_.
add(
"Exception caught when creating FEDBuffer object for FED",
163 maskFED(detids, conns);
167 const auto st_chan =
buffer.findChannels();
169 warnings_.
add(
"Exception caught when creating FEDBuffer object for FED",
171 maskFED(detids, conns);
176 warnings_.
add(
"Exception caught when creating FEDBuffer object for FED",
177 (
boost::format(
"id %1%: FED Buffer check fails for FED ID %1%.") % *ifed).
str());
178 maskFED(detids, conns);
182 warnings_.
add(
"Exception caught when creating FEDBuffer object for FED",
183 (
boost::format(
"id %1%: FED corrupt buffer check fails for FED ID %1%.") % *ifed).
str());
184 maskFED(detids, conns);
197 "EventSummary is not set correctly! Missing information from both \"trigger FED\" and \"DAQ registers\"!");
203 LogTrace(
"SiStripRawToDigi") <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
204 <<
" EventSummary is not valid: skipping...";
223 std::stringstream
ss;
230 std::vector<FedChannelConnection>::const_iterator iconn = conns.begin();
231 for (; iconn != conns.end(); iconn++) {
233 uint16_t
chan = iconn->fedCh();
236 if (!iconn->isConnected()) {
255 const uint32_t fed_key =
270 : iconn->apvPairNumber();
272 const auto& fedChannel =
buffer.channel(iconn->fedCh());
275 std::stringstream smode;
280 LogDebug(
"SiStripRawToDigi") <<
"Unpacking FED " << *ifed <<
" channel " << iconn->fedCh()
281 << ((!
legacy_) ?
" " :
" legacy ") <<
"data in mode " << smode.str()
282 <<
" for module " << iconn->detId() <<
" pair " << ipair;
287 const uint8_t pCode = (isNonLite ?
buffer.packetCode(
legacy_, iconn->fedCh()) : 0);
289 LogDebug(
"SiStripRawToDigi") <<
"Non-lite zero-suppressed mode. Packet code=0x" << std::hex
319 (
boost::format(
"FED %1% channel %2%:\n Request for CM median from channel with non-ZS "
320 "packet code. Packet code is %3%.") %
321 *ifed % iconn->fedCh() % pCode)
329 LogDebug(
"SiStripRawToDigi") <<
"Virgin raw packet code: 0x" << std::hex
331 << uint16_t(fedChannel.packetCode()) <<
std::dec;
360 std::stringstream
ss;
361 ss <<
"Extracted " << regItem.length
362 <<
" SCOPE MODE digis (samples[0] = " <<
scope_work_digis_[regItem.index] <<
") from FED id/ch "
363 << iconn->fedId() <<
"/" << iconn->fedCh();
378 unsigned int detIdsSize = detids.
size();
380 std::ostringstream
ss;
381 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
382 <<
" Problems were found in data and " << detIdsSize <<
" channels could not be unpacked. "
383 <<
"See output of FED Hardware monitoring for more information. ";
387 edm::LogError(
"TooManyErrors") <<
"Total number of errors = " << detIdsSize;
391 update(scope_mode, virgin_raw, proc_raw, zero_suppr, cm_values);
409 std::vector<edm::DetSet<SiStripDigi> > sorted_and_merged;
412 bool errorInData =
false;
416 std::vector<SiStripDigi>& digis = sorted_and_merged.back().data;
418 size_t len = it->length;
419 for (it2 = it + 1; (it2 !=
end) && (it2->detid == it->detid); ++it2) {
425 for (it2 = it + 0; (it2 !=
end) && (it2->detid == it->detid); ++it2) {
432 if (!__gnu_cxx::is_sorted(sorted_and_merged.begin(), sorted_and_merged.end())) {
435 <<
"Container must be already sorted!\nat " << __FILE__ <<
", line " << __LINE__ <<
"\n";
438 std::vector<edm::DetSet<SiStripDigi> >::iterator iii = sorted_and_merged.begin();
439 std::vector<edm::DetSet<SiStripDigi> >::iterator jjj = sorted_and_merged.end();
440 for (; iii != jjj; ++iii) {
441 if (!__gnu_cxx::is_sorted(iii->begin(), iii->end())) {
451 <<
"Some modules contained corrupted ZS raw data, and have been skipped in unpacking\n";
455 zero_suppr.
swap(zero_suppr_dsv);
462 std::vector<edm::DetSet<SiStripRawDigi> > sorted_and_merged;
465 bool errorInData =
false;
469 std::vector<SiStripRawDigi>& digis = sorted_and_merged.back().data;
473 int maxFirstStrip = it->first;
474 for (it2 = it + 1; (it2 !=
end) && (it2->detid == it->detid); ++it2) {
476 if (it2->first <= maxFirstStrip) {
480 maxFirstStrip = it2->first;
489 digis.resize(maxFirstStrip + 256);
491 for (it2 = it + 0; (it2 !=
end) && (it2->detid == it->detid); ++it2) {
493 if (it->length != 256) {
511 <<
"Some modules contained corrupted virgin raw data, and have been skipped in unpacking\n";
514 if (!__gnu_cxx::is_sorted(sorted_and_merged.begin(), sorted_and_merged.end())) {
517 <<
"Container must be already sorted!\nat " << __FILE__ <<
", line " << __LINE__ <<
"\n";
522 virgin_raw.
swap(virgin_raw_dsv);
529 std::vector<edm::DetSet<SiStripRawDigi> > sorted_and_merged;
532 bool errorInData =
false;
536 std::vector<SiStripRawDigi>& digis = sorted_and_merged.back().data;
540 int maxFirstStrip = it->first;
541 for (it2 = it + 1; (it2 !=
end) && (it2->detid == it->detid); ++it2) {
543 if (it2->first <= maxFirstStrip) {
547 maxFirstStrip = it2->first;
557 digis.resize(maxFirstStrip + 256);
559 for (it2 = it + 0; (it2 !=
end) && (it2->detid == it->detid); ++it2) {
561 if (it->length != 256) {
580 <<
"Some modules contained corrupted proc raw data, and have been skipped in unpacking\n";
583 if (!__gnu_cxx::is_sorted(sorted_and_merged.begin(), sorted_and_merged.end())) {
586 <<
"Container must be already sorted!\nat " << __FILE__ <<
", line " << __LINE__ <<
"\n";
591 proc_raw.
swap(proc_raw_dsv);
598 std::vector<edm::DetSet<SiStripRawDigi> > sorted_and_merged;
601 bool errorInData =
false;
602 std::vector<Registry>::iterator it,
end;
605 std::vector<SiStripRawDigi>& digis = sorted_and_merged.back().data;
608 if ((it + 1 !=
end) && (it->detid == (it + 1)->detid)) {
613 }
while ((it + 1 !=
end) && (it->detid == (it + 1)->detid));
620 <<
"Some fed keys contained corrupted scope mode data, and have been skipped in unpacking\n";
623 if (!__gnu_cxx::is_sorted(sorted_and_merged.begin(), sorted_and_merged.end())) {
626 <<
"Container must be already sorted!\nat " << __FILE__ <<
", line " << __LINE__ <<
"\n";
631 scope_mode.
swap(scope_mode_dsv);
640 std::vector<edm::DetSet<SiStripRawDigi> > sorted_and_merged;
643 bool errorInData =
false;
647 std::vector<SiStripRawDigi>& digis = sorted_and_merged.back().data;
651 int maxFirstStrip = it->first;
652 for (it2 = it + 1; (it2 !=
end) && (it2->detid == it->detid); ++it2) {
654 if (it2->first <= maxFirstStrip) {
658 maxFirstStrip = it2->first;
667 digis.resize(maxFirstStrip + 2);
669 for (it2 = it + 0; (it2 !=
end) && (it2->detid == it->detid); ++it2) {
671 if (it->length != 2) {
689 <<
"Some modules contained corrupted common mode data, and have been skipped in unpacking\n";
692 if (!__gnu_cxx::is_sorted(sorted_and_merged.begin(), sorted_and_merged.end())) {
695 <<
"Container must be already sorted!\nat " << __FILE__ <<
", line " << __LINE__ <<
"\n";
700 common_mode.
swap(common_mode_dsv);
725 const uint32_t&
event) {
727 const uint32_t* data_u32 =
nullptr;
728 uint32_t size_u32 = 0;
735 if (trigger_fed.
data() && trigger_fed.
size()) {
736 const uint8_t*
temp = trigger_fed.
data();
740 if (fedTrailer.conscheck() == 0xDEADFACE) {
743 std::stringstream
ss;
744 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
745 <<
" Search mode for 'trigger FED' activated!"
756 std::stringstream
ss;
757 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
758 <<
" Search mode for 'trigger FED' activated!"
759 <<
" 'Trigger FED' info not found!";
768 if (trigger_fed.
data() && trigger_fed.
size()) {
769 const uint8_t*
temp = trigger_fed.
data();
773 if (fedTrailer.conscheck() != 0xDEADFACE) {
776 <<
" Unexpected stamp found in DAQ trailer (ie, not 0xDEADFACE)!"
777 <<
" Buffer appears not to contain 'trigger FED' data!";
794 std::stringstream
ss;
795 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
796 <<
" NULL pointer to 'trigger FED' data";
803 std::stringstream
ss;
804 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
805 <<
" Unexpected 'Trigger FED' data size [32-bit words]: " << size_u32;
813 summary.event(static_cast<uint32_t>(
header->getFedEventNumber()));
814 summary.bx(static_cast<uint32_t>(
header->getBunchCrossing()));
818 const uint32_t* head = &data_u32[hsize];
826 std::stringstream
ss;
827 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
828 <<
" EventSummary built from \"trigger FED\":" << std::endl
838 if (
input.size() < 24) {
842 std::stringstream
ss;
843 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"] "
844 <<
"Input FEDRawData with FED id " << fed_id <<
" has size " <<
input.size();
856 const uint32_t* input_u32 = reinterpret_cast<const uint32_t*>(
input.data() +
offset);
857 const uint32_t* fed_trailer = reinterpret_cast<const uint32_t*>(
input.data() +
input.size() - 8);
861 bool old_vme_header = (input_u32[0] & 0xF0000000) == 0x50000000 && (fed_trailer[0] & 0xF0000000) == 0xA0000000 &&
862 ((fed_trailer[0] & 0x00FFFFFF) * 0x8) == (
input.size() -
offset);
864 bool old_slink_header = (input_u32[1] & 0xF0000000) == 0x50000000 &&
865 (fed_trailer[1] & 0xF0000000) == 0xA0000000 &&
866 ((fed_trailer[1] & 0x00FFFFFF) * 0x8) == (
input.size() -
offset);
868 bool old_slink_payload = (input_u32[3] & 0xFF000000) == 0xED000000;
870 bool new_buffer_format = (input_u32[2] & 0xFF000000) == 0xC5000000;
872 if (old_vme_header) {
881 std::stringstream
ss;
882 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
883 <<
" Buffer for FED id " << fed_id <<
" has been found at byte position " <<
offset <<
" with a size of "
885 <<
" Adjust the configurable 'AppendedBytes' to " <<
offset;
890 }
else if (old_slink_header) {
891 if (old_slink_payload) {
895 uint32_t* output_u32 = reinterpret_cast<uint32_t*>(
output.data());
897 while (iter <
output.size() /
sizeof(uint32_t)) {
898 output_u32[iter] = input_u32[iter + 1];
899 output_u32[iter + 1] = input_u32[iter];
904 std::stringstream
ss;
905 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
906 <<
" Buffer (with MSB and LSB 32-bit words swapped) for FED id " << fed_id
907 <<
" has been found at byte position " <<
offset <<
" with a size of " <<
output.size() <<
" bytes."
908 <<
" Adjust the configurable 'AppendedBytes' to " <<
offset;
913 }
else if (new_buffer_format) {
922 std::stringstream
ss;
923 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
924 <<
" Buffer for FED id " << fed_id <<
" has been found at byte position " <<
offset
925 <<
" with a size of " <<
input.size() -
offset <<
" bytes."
926 <<
" Adjust the configurable 'AppendedBytes' to " <<
offset;
946 std::stringstream
ss;
948 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
949 <<
" DAQ header not found within buffer for FED id: " << fed_id;
951 const uint32_t* input_u32 = reinterpret_cast<const uint32_t*>(
input.data());
952 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
953 <<
" DAQ header not found at expected location for FED id: " << fed_id << std::endl
954 <<
" First 64-bit word of buffer is 0x" << std::hex << std::setfill(
'0') << std::setw(8) << input_u32[0]
955 << std::setfill(
'0') << std::setw(8) << input_u32[1] <<
std::dec << std::endl
956 <<
" Adjust 'AppendedBytes' configurable to '-1' to activate 'search mode'";
961 }
else if (
output.size() < 24) {
964 std::stringstream
ss;
965 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
966 <<
" Unexpected buffer size! FEDRawData with FED id " << fed_id <<
" has size " <<
output.size();
984 header = dynamic_cast<const sistrip::FEDFullDebugHeader*>(fed.
feHeader());
985 daq1 = static_cast<uint32_t>(
header->daqRegister());
986 daq2 = static_cast<uint32_t>(
header->daqRegister2());
992 summary.fedReadoutMode(readout_mode);
993 summary.commissioningInfo(daq1, daq2);
997 std::stringstream
ss;
998 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
999 <<
" EventSummary built from FED DAQ registers:" << std::endl
1009 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
1010 <<
" Dump of buffer for FED id " << fed_id << std::endl
1011 <<
" Buffer contains " <<
buffer.size() <<
" bytes (NB: payload is byte-swapped)" << std::endl;
1014 const uint32_t* buffer_u32 = reinterpret_cast<const uint32_t*>(
buffer.data());
1015 unsigned int empty = 0;
1017 ss <<
"Byte-> 4 5 6 7 0 1 2 3\n";
1018 for (uint32_t
i = 0;
i <
buffer.size() / 8;
i++) {
1021 if (!temp0 && !temp1) {
1025 ss <<
" [ empty words ]" << std::endl;
1028 ss <<
std::dec << std::setfill(
' ') << std::setw(6) <<
i * 8 <<
": " << std::hex << std::setfill(
'0')
1029 << std::setw(8) << temp0 << std::setfill(
'0') << std::setw(8) << temp1 <<
std::dec << std::endl;
1034 ss <<
" Byte | <---- Byte order ----< | Byte" << std::endl;
1035 ss <<
" cntr | 7 6 5 4 3 2 1 0 | cntr" << std::endl;
1036 for (uint32_t
i = 0;
i <
buffer.size() / 8;
i++) {
1038 uint16_t tmp0 =
buffer.data()[
i * 8 + 0] & 0xFF;
1039 uint16_t tmp1 =
buffer.data()[
i * 8 + 1] & 0xFF;
1040 uint16_t tmp2 =
buffer.data()[
i * 8 + 2] & 0xFF;
1041 uint16_t tmp3 =
buffer.data()[
i * 8 + 3] & 0xFF;
1042 uint16_t tmp4 =
buffer.data()[
i * 8 + 4] & 0xFF;
1043 uint16_t tmp5 =
buffer.data()[
i * 8 + 5] & 0xFF;
1044 uint16_t tmp6 =
buffer.data()[
i * 8 + 6] & 0xFF;
1045 uint16_t tmp7 =
buffer.data()[
i * 8 + 7] & 0xFF;
1055 ss <<
std::dec << std::setfill(
' ') << std::setw(6) <<
i * 8 + 7 <<
" : " << std::hex << std::setfill(
'0')
1056 << std::setw(2) << tmp7 <<
" " << std::setfill(
'0') << std::setw(2) << tmp6 <<
" " << std::setfill(
'0')
1057 << std::setw(2) << tmp5 <<
" " << std::setfill(
'0') << std::setw(2) << tmp4 <<
" " << std::setfill(
'0')
1058 << std::setw(2) << tmp3 <<
" " << std::setfill(
'0') << std::setw(2) << tmp2 <<
" " << std::setfill(
'0')
1059 << std::setw(2) << tmp1 <<
" " << std::setfill(
'0') << std::setw(2) << tmp0 <<
std::dec <<
" :"
1060 << std::setfill(
' ') << std::setw(6) <<
i * 8 << std::endl;
1064 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
1065 <<
" End of FED buffer";