6 #include "cetlib_except/exception.h" 12 #include <boost/asio.hpp> 52 bool swap_payload_header_bytes,
53 size_t override_uslice_size){
56 if(override_uslice_size) {
58 pl_size = override_uslice_size -
sizeof(
Header);
67 if(swap_payload_header_bytes)
103 if(current_payload_ >= (
buffer_ + pl_size))
113 data_packet_type =
type;
134 std::cerr <<
"Unknown data packet type found 0x" <<
std::hex << (
unsigned int)type <<
std::endl;
150 size_t& payload_size,
151 bool swap_payload_header_bytes,
152 size_t override_uslice_size)
const 159 if(override_uslice_size) {
161 pl_size = override_uslice_size -
sizeof(
Header);
168 while(pl_ptr < (
buffer_ + pl_size)) {
169 if(swap_payload_header_bytes)
170 *((uint32_t*)pl_ptr) = ntohl(*((uint32_t*)pl_ptr));
177 data_packet_type =
type;
202 std::cerr <<
"Unknown data packet type found 0x" <<
std::hex << (
unsigned int)type <<
std::endl;
230 std::cerr <<
"Unknown data packet type found 0x" <<
std::hex << (
unsigned int)type <<
std::endl;
238 mf::LogError(
"PennMicroSlice") <<
"Could not find payload with ID " << word_id <<
" (the data buffer has overrun)" <<
std::endl;
239 std::cerr <<
"Could not find payload with ID " << word_id <<
" (the data buffer has overrun)" <<
std::endl;
251 bool swap_payload_header_bytes,
252 size_t override_uslice_size)
const 254 throw cet::exception(
"PennMicroSlice") <<
"As of Jul-28-2015, dune::PennMicroSlice::sampleCount is deprecated";
256 n_counter_words = n_trigger_words = n_timestamp_words = n_selftest_words = n_checksum_words = 0;
261 if(override_uslice_size) {
263 pl_size = override_uslice_size -
sizeof(
Header);
270 while(pl_ptr < (
buffer_ + pl_size)) {
271 if(swap_payload_header_bytes)
272 *((uint32_t*)pl_ptr) = ntohl(*((uint32_t*)pl_ptr));
275 #ifdef __DEBUG_sampleCount__ 301 std::cerr <<
"Unknown data packet type found 0x" <<
std::hex << (
unsigned int)type <<
std::endl;
306 return n_counter_words + n_trigger_words + n_timestamp_words + n_selftest_words + n_checksum_words;
311 bool swap_payload_header_bytes,
size_t override_uslice_size)
const 314 throw cet::exception(
"PennMicroSlice") <<
"As of Jul-28-2015, dune::PennMicroSlice::sampleTimeSplit is deprecated";
318 boundary_time = boundary_time & 0xFFFFFFF;
323 if(override_uslice_size) {
325 pl_size = override_uslice_size -
sizeof(
Header);
333 while(pl_ptr < (
buffer_ + pl_size)) {
334 if(swap_payload_header_bytes)
335 *((uint32_t*)pl_ptr) = ntohl(*((uint32_t*)pl_ptr));
339 #ifdef __DEBUG_sampleTimeSplit__ 340 std::cout <<
"PennMicroSlice::sampleTimeSplit DEBUG type 0x" <<
std::hex << (
unsigned int)type <<
" timestamp " <<
std::dec << timestamp <<
std::endl;
343 if(timestamp > boundary_time) {
348 remaining_size = (
buffer_ + pl_size) - pl_ptr;
372 std::cerr <<
"Unknown data packet type found 0x" <<
std::hex << (
unsigned int)type <<
std::endl;
394 bool swap_payload_header_bytes,
size_t override_uslice_size)
const 396 throw cet::exception(
"PennMicroSlice") <<
"As of Jul-28-2015, dune::PennMicroSlice::sampleTimeSplitAndCount is deprecated";
398 n_words_b = n_counter_words_b = n_trigger_words_b = n_timestamp_words_b = n_selftest_words_b = n_checksum_words_b = 0;
399 n_words_a = n_counter_words_a = n_trigger_words_a = n_timestamp_words_a = n_selftest_words_a = n_checksum_words_a = 0;
401 uint8_t* remaining_data_ptr =
nullptr;
402 bool is_before =
true;
407 if(override_uslice_size) {
409 pl_size = override_uslice_size -
sizeof(
Header);
417 while(pl_ptr < (
buffer_ + pl_size)) {
418 if(swap_payload_header_bytes)
419 *((uint32_t*)pl_ptr) = ntohl(*((uint32_t*)pl_ptr));
423 #ifdef __DEBUG_sampleTimeSplitAndCount__ 424 std::cout <<
"PennMicroSlice::sampleTimeSplitAndCount DEBUG type 0x" <<
std::hex << (
unsigned int)type <<
" timestamp " <<
std::dec << timestamp <<
std::endl;
427 if(is_before && (timestamp > boundary_time)) {
432 remaining_size = (
buffer_ + pl_size) - pl_ptr;
433 remaining_data_ptr = pl_ptr;
456 n_timestamp_words_b++;
458 n_timestamp_words_a++;
463 n_selftest_words_b++;
465 n_selftest_words_a++;
470 n_checksum_words_b++;
472 n_checksum_words_a++;
476 std::cerr <<
"Unknown data packet type found 0x" <<
std::hex << (
unsigned int)type
482 n_words_b = n_counter_words_b + n_trigger_words_b + n_timestamp_words_b + n_selftest_words_b + n_checksum_words_b;
483 n_words_a = n_counter_words_a + n_trigger_words_a + n_timestamp_words_a + n_selftest_words_a + n_checksum_words_a;
484 #ifdef __DEBUG_sampleTimeSplitAndCount__ 485 std::cout <<
"PennMicroSlice::sampleTimeSplitAndCount DEBUG returning with remaining size " << remaining_size <<
" for boundary_time " << boundary_time
487 <<
"PennMicroSlice::sampleTimeSplitAndCount DEBUG returning with: " 488 <<
" Payloads before " << n_words_b <<
" = " << n_counter_words_b <<
" + " << n_trigger_words_b
489 <<
" + " << n_timestamp_words_b <<
" + " << n_selftest_words_b <<
" + " << n_checksum_words_b
490 <<
" Payloads after " << n_words_a <<
" = " << n_counter_words_a <<
" + " << n_trigger_words_a
491 <<
" + " << n_timestamp_words_a <<
" + " << n_selftest_words_a <<
" + " << n_checksum_words_a
494 return remaining_data_ptr;
507 uint64_t overlap_time,
size_t& overlap_size, uint8_t*& overlap_data_ptr,
527 bool swap_payload_header_bytes,
size_t override_uslice_size)
const 530 n_words_b = n_counter_words_b = n_trigger_words_b = n_timestamp_words_b = n_selftest_words_b = n_checksum_words_b = 0;
532 n_words_a = n_counter_words_a = n_trigger_words_a = n_timestamp_words_a = n_selftest_words_a = n_checksum_words_a = 0;
535 overlap_size = remaining_size = 0;
537 uint8_t* remaining_data_ptr =
nullptr;
538 overlap_data_ptr =
nullptr;
539 bool is_before_boundary =
true, is_before_overlap =
true, is_in_overlap =
false;
546 if(override_uslice_size) {
548 pl_size = override_uslice_size -
sizeof(
Header);
555 #ifdef __DEBUG_sampleTimeSplitAndCountTwice__ 556 mf::LogInfo(
"PennMicroSlice") <<
"Dumping the received microslice with " << pl_size <<
" bytes.";
560 uint8_t* aux_ptr = pl_ptr;
565 mf::LogError(
"PennMicroSlice") <<
"Last word in the microslice is not a checksum :" << std::bitset<3>(payload_header->
data_packet_type);
575 uint64_t microslice_boundary = pl_ts->nova_timestamp;
577 uint64_t frame_timestamp = 0;
580 while(pl_ptr < (
buffer_ + pl_size)) {
581 #ifdef __DEBUG_sampleTimeSplitAndCountTwice__ 583 mf::LogInfo(
"PennMicroSlice") <<
"PennMicroSlice::sampleTimeSplitAndCountTwice DEBUG microslice_boundary = " << microslice_boundary;
584 mf::LogInfo(
"PennMicroSlice") <<
"PennMicroSlice::sampleTimeSplitAndCountTwice DEBUG pointers." 585 <<
" Payload " << (
unsigned int*)pl_ptr
586 <<
"\tOverlap " << (
unsigned int*)overlap_data_ptr
587 <<
"\tRemaining " << (
unsigned int*)remaining_data_ptr;
591 if(swap_payload_header_bytes) {
592 *((uint32_t*)pl_ptr) = ntohl(*((uint32_t*)pl_ptr));
604 }
else if ((microslice_boundary & 0x7FFFFFF) == timestamp) {
605 frame_timestamp = microslice_boundary;
606 }
else if ((microslice_boundary & 0x7FFFFFF) > timestamp) {
607 frame_timestamp = microslice_boundary - ((microslice_boundary & 0x7FFFFFF) - timestamp);
611 frame_timestamp = microslice_boundary - ((microslice_boundary & 0x7FFFFFF) + (0x7FFFFFF - timestamp));
614 #ifdef __DEBUG_sampleTimeSplitAndCountTwice__ 615 mf::LogInfo(
"PennMicroSlice") <<
"PennMicroSlice::sampleTimeSplitAndCountTwice DEBUG >> frame_timestamp : " << frame_timestamp <<
" type " << std::bitset<3>(
type);
623 mf::LogInfo(
"PennMicroSlice") <<
"Sample type: counter : [" << std::bitset<3>(
type) <<
"]";
629 mf::LogInfo(
"PennMicroSlice") <<
"Sample type: trigger : [" << std::bitset<3>(
type) <<
"]";
635 mf::LogInfo(
"PennMicroSlice") <<
"Sample type: checksum : [" << std::bitset<3>(
type) <<
"]";
638 mf::LogInfo(
"PennMicroSlice") <<
"Sample type: timestamp : [" << std::bitset<3>(
type) <<
"]";
644 mf::LogInfo(
"PennMicroSlice") <<
"Sample type: WARNING : [" << std::bitset<3>(
type) <<
"]";
650 mf::LogError(
"PennMicroSlice") <<
"Unexpected header type...something is going to fail [" << std::bitset<3>(
type) <<
"]";
662 if (is_before_boundary && (frame_timestamp > boundary_time)) {
663 remaining_size = (
buffer_ + pl_size) - pl_ptr;
664 remaining_data_ptr = pl_ptr;
665 is_before_boundary =
false;
666 is_before_overlap =
false;
667 is_in_overlap =
false;
671 overlap_size -= remaining_size;
673 }
else if (is_before_overlap & (frame_timestamp > overlap_time)) {
674 overlap_size = (
buffer_ + pl_size) - pl_ptr;
675 overlap_data_ptr = pl_ptr;
676 is_in_overlap =
true;
677 is_before_overlap =
false;
747 if(is_before_boundary)
756 if(is_before_boundary)
765 if(is_before_boundary)
766 n_timestamp_words_b++;
768 n_timestamp_words_a++;
770 n_timestamp_words_o++;
782 mf::LogWarning(
"PennMicroSlice") <<
"The DMA timed out. Possible data loss after this point.";
break;
784 mf::LogWarning(
"PennMicroSlice") <<
"Unknown data type received.";
break;
786 mf::LogWarning(
"PennMicroSlice") <<
"FIFO reached half full state. Stop run recommended.";
789 mf::LogError(
"PennMicroSlice") <<
"FIFO reached full state. Data after this point is unreliable.";
794 if(is_before_boundary)
795 n_selftest_words_b++;
797 n_selftest_words_a++;
799 n_selftest_words_o++;
804 if(is_before_boundary)
805 n_checksum_words_b++;
807 n_checksum_words_a++;
809 n_checksum_words_o++;
816 checksum = *(
reinterpret_cast<uint16_t*
>(pl_ptr) );
824 std::cerr <<
"Unknown data packet type found 0x" <<
std::hex << (
unsigned int)type
830 n_words_b = n_counter_words_b + n_trigger_words_b + n_timestamp_words_b + n_selftest_words_b + n_checksum_words_b;
831 n_words_a = n_counter_words_a + n_trigger_words_a + n_timestamp_words_a + n_selftest_words_a + n_checksum_words_a;
832 n_words_o = n_counter_words_o + n_trigger_words_o + n_timestamp_words_o + n_selftest_words_o + n_checksum_words_o;
833 #ifdef __DEBUG_sampleTimeSplitAndCountTwice__ 834 mf::LogInfo(
"PennMicroSlice") <<
"PennMicroSlice::sampleTimeSplitAndCountTwice DEBUG returning with:" 835 <<
" remaining size " << remaining_size <<
" for boundary_time " << boundary_time
836 <<
" overlap size " << overlap_size <<
" for overlap_time " << overlap_time;
838 mf::LogInfo(
"PennMicroSlice") <<
"PennMicroSlice::sampleTimeSplitAndCountTwice DEBUG returning with: " 839 <<
" Payloads before " << n_words_b <<
" = " << n_counter_words_b <<
" + " << n_trigger_words_b
840 <<
" + " << n_timestamp_words_b <<
" + " << n_selftest_words_b <<
" + " << n_checksum_words_b
841 <<
" Payloads after " << n_words_a <<
" = " << n_counter_words_a <<
" + " << n_trigger_words_a
842 <<
" + " << n_timestamp_words_a <<
" + " << n_selftest_words_a <<
" + " << n_checksum_words_a
843 <<
" Overlap payloads " << n_words_o <<
" = " << n_counter_words_o <<
" + " << n_trigger_words_o
844 <<
" + " << n_timestamp_words_o <<
" + " << n_selftest_words_o <<
" + " << n_checksum_words_o ;
846 return remaining_data_ptr;
852 return reinterpret_cast_checked<uint32_t*>(
buffer_);
858 return reinterpret_cast_checked<Header const *>(
buffer_);
static microslice_size_t const payload_size_trigger
static microslice_size_t const payload_size_timestamp
static const Warning_Word::warning_type_t WarnFIFOHalfFull
static const Payload_Header::data_packet_type_t DataTypeWarning
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
static microslice_size_t const payload_size_checksum
Header::sequence_id_t sequence_id() const
uint8_t * get_payload(uint32_t word_id, Payload_Header::data_packet_type_t &data_packet_type, Payload_Header::short_nova_timestamp_t &short_nova_timestamp, size_t &size, bool swap_payload_header_bytes, size_t override_uslice_size=0) const
static const uint64_t ROLLOVER_HIGH_VALUE
QTextStream & hex(QTextStream &s)
void display_bits(void *memstart, size_t nbytes, std::string sourcename)
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
static const Payload_Header::data_packet_type_t DataTypeTimestamp
sample_count_t sampleCount(sample_count_t &n_counter_words, sample_count_t &n_trigger_words, sample_count_t &n_timestamp_words, sample_count_t &n_selftest_words, sample_count_t &n_checksum_words, bool swap_payload_header_bytes, size_t override_uslice_size=0) const
static microslice_size_t const payload_size_counter
Header const * header_() const
uint8_t * current_payload_
static const Warning_Word::warning_type_t WarnUnknownDataType
PennMicroSlice(uint8_t *address)
Header::block_size_t microslice_size_t
dune::PennMicroSlice::microslice_size_t size() const
static const Payload_Header::data_packet_type_t DataTypeChecksum
Header::format_version_t format_version() const
warning_type_t warning_type
uint32_t current_word_id_
QTextStream & dec(QTextStream &s)
uint8_t * sampleTimeSplitAndCountTwice(uint64_t boundary_time, size_t &remaining_size, uint64_t overlap_time, size_t &overlap_size, uint8_t *&overlap_data_ptr, sample_count_t &n_words_b, sample_count_t &n_counter_words_b, sample_count_t &n_trigger_words_b, sample_count_t &n_timestamp_words_b, sample_count_t &n_selftest_words_b, sample_count_t &n_checksum_words_b, sample_count_t &n_words_a, sample_count_t &n_counter_words_a, sample_count_t &n_trigger_words_a, sample_count_t &n_timestamp_words_a, sample_count_t &n_selftest_words_a, sample_count_t &n_checksum_words_a, sample_count_t &n_words_o, sample_count_t &n_counter_words_o, sample_count_t &n_trigger_words_o, sample_count_t &n_timestamp_words_o, sample_count_t &n_selftest_words_o, sample_count_t &n_checksum_words_o, uint32_t &checksum, bool swap_payload_header_bytes, size_t override_uslice_size=0) const
static const Payload_Header::data_packet_type_t DataTypeTrigger
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
Header::block_size_t block_size() const
uint32_t const * data_() const
static const Warning_Word::warning_type_t WarnTimeout
static const Warning_Word::warning_type_t WarnFIFOFull
uint8_t * get_next_payload(uint32_t &word_id, Payload_Header::data_packet_type_t &data_packet_type, Payload_Header::short_nova_timestamp_t &short_nova_timestamp, size_t &size, bool swap_payload_header_bytes, size_t override_uslice_size=0)
static const uint32_t ROLLOVER_LOW_VALUE
static microslice_size_t const payload_size_warning
cet::coded_exception< error, detail::translate > exception
static const Payload_Header::data_packet_type_t DataTypeCounter
QTextStream & endl(QTextStream &s)
uint8_t * sampleTimeSplit(uint64_t boundary_time, size_t &remaining_size, bool swap_payload_header_bytes, size_t override_uslice_size=0) const
uint8_t * sampleTimeSplitAndCount(uint64_t boundary_time, size_t &remaining_size, sample_count_t &n_words_b, sample_count_t &n_counter_words_b, sample_count_t &n_trigger_words_b, sample_count_t &n_timestamp_words_b, sample_count_t &n_selftest_words_b, sample_count_t &n_checksum_words_b, sample_count_t &n_words_a, sample_count_t &n_counter_words_a, sample_count_t &n_trigger_words_a, sample_count_t &n_timestamp_words_a, sample_count_t &n_selftest_words_a, sample_count_t &n_checksum_words_a, bool swap_payload_header_bytes, size_t override_uslice_size=0) const