4 #include <ext/algorithm>
6 #include <fmt/format.h>
28 int16_t fed_buffer_dump_freq,
29 int16_t fed_event_dump_freq,
30 int16_t trigger_fed_id,
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),
45 useDaqRegister_(
false),
48 doFullCorruptBufferChecks_(
false),
49 doAPVEmulatorCheck_(
true),
50 errorThreshold_(errorThreshold),
53 LogTrace(
"SiStripRawToDigi") <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
54 <<
" Constructing object...";
58 <<
"Warning: Unpacking of bad channels enabled. Only enable this if you know what you are doing. "
65 LogTrace(
"SiStripRawToDigi") <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
66 <<
" Destructing object...";
75 maskedModules.
reserve(maskedModules.
size() + fedConnections.size());
76 for (
const auto&
conn : fedConnections) {
100 if (cabling.
fedIds().empty()) {
104 std::vector<uint16_t>
feds;
107 feds.push_back(ifed);
110 LogTrace(
"SiStripRawToDigi") <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
111 <<
" Found " <<
feds.size() <<
" FED buffers with non-zero size!";
116 bool first_fed =
true;
119 std::vector<uint16_t>::const_iterator ifed = cabling.
fedIds().begin();
120 for (; ifed != cabling.
fedIds().end(); ifed++) {
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";
145 std::stringstream
ss;
159 }
else if (!
input.size()) {
162 warnings_.
add(
"Exception caught when creating FEDBuffer object for FED",
166 maskFED(detids, conns);
170 const auto st_chan =
buffer.findChannels();
172 warnings_.
add(
"Exception caught when creating FEDBuffer object for FED",
174 maskFED(detids, conns);
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);
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);
200 "EventSummary is not set correctly! Missing information from both \"trigger FED\" and \"DAQ registers\"!");
206 LogTrace(
"SiStripRawToDigi") <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
207 <<
" EventSummary is not valid: skipping...";
226 std::stringstream
ss;
233 std::vector<FedChannelConnection>::const_iterator iconn = conns.begin();
234 for (; iconn != conns.end(); iconn++) {
236 uint16_t
chan = iconn->fedCh();
239 if (!iconn->isConnected()) {
258 const uint32_t fed_key =
273 : iconn->apvPairNumber();
275 const auto& fedChannel =
buffer.channel(iconn->fedCh());
278 std::stringstream smode;
283 LogDebug(
"SiStripRawToDigi") <<
"Unpacking FED " << *ifed <<
" channel " << iconn->fedCh()
284 << ((!
legacy_) ?
" " :
" legacy ") <<
"data in mode " << smode.str()
285 <<
" for module " << iconn->detId() <<
" pair " << ipair;
290 const uint8_t pCode = (isNonLite ?
buffer.packetCode(
legacy_, iconn->fedCh()) : 0);
292 LogDebug(
"SiStripRawToDigi") <<
"Non-lite zero-suppressed mode. Packet code=0x" << std::hex
299 fmt::format(
"FED {0} channel {1}", *ifed, iconn->fedCh()));
322 fmt::format(
"FED {0} channel {1}:\n Request for CM median from channel with non-ZS "
323 "packet code. Packet code is {2}.",
333 LogDebug(
"SiStripRawToDigi") <<
"Virgin raw packet code: 0x" << std::hex
335 << uint16_t(fedChannel.packetCode()) <<
std::dec;
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();
382 unsigned int detIdsSize = detids.
size();
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. ";
391 edm::LogError(
"TooManyErrors") <<
"Total number of errors = " << detIdsSize;
395 update(scope_mode, virgin_raw, proc_raw, zero_suppr, cm_values);
413 std::vector<edm::DetSet<SiStripDigi> > sorted_and_merged;
416 bool errorInData =
false;
420 std::vector<SiStripDigi>& digis = sorted_and_merged.back().data;
422 size_t len = it->length;
423 for (it2 = it + 1; (it2 !=
end) && (it2->detid == it->detid); ++it2) {
429 for (it2 = it + 0; (it2 !=
end) && (it2->detid == it->detid); ++it2) {
436 if (!__gnu_cxx::is_sorted(sorted_and_merged.begin(), sorted_and_merged.end())) {
439 <<
"Container must be already sorted!\nat " << __FILE__ <<
", line " << __LINE__ <<
"\n";
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())) {
455 <<
"Some modules contained corrupted ZS raw data, and have been skipped in unpacking\n";
459 zero_suppr.
swap(zero_suppr_dsv);
466 std::vector<edm::DetSet<SiStripRawDigi> > sorted_and_merged;
469 bool errorInData =
false;
473 std::vector<SiStripRawDigi>& digis = sorted_and_merged.back().data;
477 int maxFirstStrip = it->first;
478 for (it2 = it + 1; (it2 !=
end) && (it2->detid == it->detid); ++it2) {
480 if (it2->first <= maxFirstStrip) {
484 maxFirstStrip = it2->first;
493 digis.resize(maxFirstStrip + 256);
495 for (it2 = it + 0; (it2 !=
end) && (it2->detid == it->detid); ++it2) {
497 if (it->length != 256) {
515 <<
"Some modules contained corrupted virgin raw data, and have been skipped in unpacking\n";
518 if (!__gnu_cxx::is_sorted(sorted_and_merged.begin(), sorted_and_merged.end())) {
521 <<
"Container must be already sorted!\nat " << __FILE__ <<
", line " << __LINE__ <<
"\n";
526 virgin_raw.
swap(virgin_raw_dsv);
533 std::vector<edm::DetSet<SiStripRawDigi> > sorted_and_merged;
536 bool errorInData =
false;
540 std::vector<SiStripRawDigi>& digis = sorted_and_merged.back().data;
544 int maxFirstStrip = it->first;
545 for (it2 = it + 1; (it2 !=
end) && (it2->detid == it->detid); ++it2) {
547 if (it2->first <= maxFirstStrip) {
551 maxFirstStrip = it2->first;
561 digis.resize(maxFirstStrip + 256);
563 for (it2 = it + 0; (it2 !=
end) && (it2->detid == it->detid); ++it2) {
565 if (it->length != 256) {
584 <<
"Some modules contained corrupted proc raw data, and have been skipped in unpacking\n";
587 if (!__gnu_cxx::is_sorted(sorted_and_merged.begin(), sorted_and_merged.end())) {
590 <<
"Container must be already sorted!\nat " << __FILE__ <<
", line " << __LINE__ <<
"\n";
595 proc_raw.
swap(proc_raw_dsv);
602 std::vector<edm::DetSet<SiStripRawDigi> > sorted_and_merged;
605 bool errorInData =
false;
606 std::vector<Registry>::iterator it,
end;
609 std::vector<SiStripRawDigi>& digis = sorted_and_merged.back().data;
612 if ((it + 1 !=
end) && (it->detid == (it + 1)->detid)) {
617 }
while ((it + 1 !=
end) && (it->detid == (it + 1)->detid));
624 <<
"Some fed keys contained corrupted scope mode data, and have been skipped in unpacking\n";
627 if (!__gnu_cxx::is_sorted(sorted_and_merged.begin(), sorted_and_merged.end())) {
630 <<
"Container must be already sorted!\nat " << __FILE__ <<
", line " << __LINE__ <<
"\n";
635 scope_mode.
swap(scope_mode_dsv);
644 std::vector<edm::DetSet<SiStripRawDigi> > sorted_and_merged;
647 bool errorInData =
false;
651 std::vector<SiStripRawDigi>& digis = sorted_and_merged.back().data;
655 int maxFirstStrip = it->first;
656 for (it2 = it + 1; (it2 !=
end) && (it2->detid == it->detid); ++it2) {
658 if (it2->first <= maxFirstStrip) {
662 maxFirstStrip = it2->first;
671 digis.resize(maxFirstStrip + 2);
673 for (it2 = it + 0; (it2 !=
end) && (it2->detid == it->detid); ++it2) {
675 if (it->length != 2) {
693 <<
"Some modules contained corrupted common mode data, and have been skipped in unpacking\n";
696 if (!__gnu_cxx::is_sorted(sorted_and_merged.begin(), sorted_and_merged.end())) {
699 <<
"Container must be already sorted!\nat " << __FILE__ <<
", line " << __LINE__ <<
"\n";
704 common_mode.
swap(common_mode_dsv);
729 const uint32_t&
event) {
731 const uint32_t* data_u32 =
nullptr;
732 uint32_t size_u32 = 0;
739 if (trigger_fed.
data() && trigger_fed.
size()) {
740 const uint8_t*
temp = trigger_fed.
data();
744 if (fedTrailer.conscheck() == 0xDEADFACE) {
747 std::stringstream
ss;
748 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
749 <<
" Search mode for 'trigger FED' activated!"
760 std::stringstream
ss;
761 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
762 <<
" Search mode for 'trigger FED' activated!"
763 <<
" 'Trigger FED' info not found!";
772 if (trigger_fed.
data() && trigger_fed.
size()) {
773 const uint8_t*
temp = trigger_fed.
data();
777 if (fedTrailer.conscheck() != 0xDEADFACE) {
780 <<
" Unexpected stamp found in DAQ trailer (ie, not 0xDEADFACE)!"
781 <<
" Buffer appears not to contain 'trigger FED' data!";
798 std::stringstream
ss;
799 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
800 <<
" NULL pointer to 'trigger FED' data";
807 std::stringstream
ss;
808 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
809 <<
" Unexpected 'Trigger FED' data size [32-bit words]: " << size_u32;
817 summary.event(static_cast<uint32_t>(
header->getFedEventNumber()));
818 summary.bx(static_cast<uint32_t>(
header->getBunchCrossing()));
822 const uint32_t* head = &data_u32[hsize];
830 std::stringstream
ss;
831 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
832 <<
" EventSummary built from \"trigger FED\":" << std::endl
842 if (
input.size() < 24) {
846 std::stringstream
ss;
847 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"] "
848 <<
"Input FEDRawData with FED id " << fed_id <<
" has size " <<
input.size();
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);
865 bool old_vme_header = (input_u32[0] & 0xF0000000) == 0x50000000 && (fed_trailer[0] & 0xF0000000) == 0xA0000000 &&
866 ((fed_trailer[0] & 0x00FFFFFF) * 0x8) == (
input.size() -
offset);
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);
872 bool old_slink_payload = (input_u32[3] & 0xFF000000) == 0xED000000;
874 bool new_buffer_format = (input_u32[2] & 0xFF000000) == 0xC5000000;
876 if (old_vme_header) {
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 "
889 <<
" Adjust the configurable 'AppendedBytes' to " <<
offset;
894 }
else if (old_slink_header) {
895 if (old_slink_payload) {
899 uint32_t* output_u32 = reinterpret_cast<uint32_t*>(
output.data());
901 while (iter <
output.size() /
sizeof(uint32_t)) {
902 output_u32[iter] = input_u32[iter + 1];
903 output_u32[iter + 1] = input_u32[iter];
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;
917 }
else if (new_buffer_format) {
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;
950 std::stringstream
ss;
952 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
953 <<
" DAQ header not found within buffer for FED id: " << fed_id;
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'";
965 }
else if (
output.size() < 24) {
968 std::stringstream
ss;
969 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
970 <<
" Unexpected buffer size! FEDRawData with FED id " << fed_id <<
" has size " <<
output.size();
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());
996 summary.fedReadoutMode(readout_mode);
997 summary.commissioningInfo(daq1, daq2);
1001 std::stringstream
ss;
1002 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
1003 <<
" EventSummary built from FED DAQ registers:" << std::endl
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;
1018 const uint32_t* buffer_u32 = reinterpret_cast<const uint32_t*>(
buffer.data());
1019 unsigned int empty = 0;
1021 ss <<
"Byte-> 4 5 6 7 0 1 2 3\n";
1022 for (uint32_t
i = 0;
i <
buffer.size() / 8;
i++) {
1025 if (!temp0 && !temp1) {
1029 ss <<
" [ empty words ]" << std::endl;
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;
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++) {
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;
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;
1068 ss <<
"[sistrip::RawToDigiUnpacker::" << __func__ <<
"]"
1069 <<
" End of FED buffer";