From b43b6264112dc3dc75aab24b05b7ac3e1a09f334 Mon Sep 17 00:00:00 2001 From: P-A Loizeau <p.-a.loizeau@gsi.de> Date: Fri, 29 Nov 2024 18:31:09 +0100 Subject: [PATCH] Bugfix and Improve TS and MS Printout formaters - Fix missing own header include for CbmFormatTsPrintout in the source file - Replace std::endl with plain newline - Add method to print a microslice descriptor help (dump description) - Catch more low probablility error/crash cases (TS with no comp, Comps with no MS, ...) - Add possibility to dump the MS for only a selected System ID type (default = all as before) - Add possibility to dump only the first M microslices in each component for each TS (default = all as before) --- .../flestools/CbmFormatMsHeaderPrintout.cxx | 37 ++++-- .../flestools/CbmFormatMsHeaderPrintout.h | 2 + .../utils/flestools/CbmFormatTsPrintout.cxx | 108 +++++++++++------- .../utils/flestools/CbmFormatTsPrintout.h | 7 +- 4 files changed, 101 insertions(+), 53 deletions(-) diff --git a/core/base/utils/flestools/CbmFormatMsHeaderPrintout.cxx b/core/base/utils/flestools/CbmFormatMsHeaderPrintout.cxx index 153af59dee..2ce7081a1f 100644 --- a/core/base/utils/flestools/CbmFormatMsHeaderPrintout.cxx +++ b/core/base/utils/flestools/CbmFormatMsHeaderPrintout.cxx @@ -7,26 +7,41 @@ std::string FormatMsHeaderPrintout(const fles::MicrosliceDescriptor& msDescriptor) { std::stringstream ss; - ss << "hi hv eqid flag si sv idx/start crc size offset" << std::endl + ss << "hi hv eqid flag si sv idx/start crc size offset" + << "\n" << std::hex << std::setfill('0') << std::setw(2) << static_cast<unsigned int>(msDescriptor.hdr_id) << " " << std::setw(2) << static_cast<unsigned int>(msDescriptor.hdr_ver) << " " << std::setw(4) << msDescriptor.eq_id << " " << std::setw(4) << msDescriptor.flags << " " << std::setw(2) << static_cast<unsigned int>(msDescriptor.sys_id) << " " << std::setw(2) << static_cast<unsigned int>(msDescriptor.sys_ver) << " " << std::setw(16) << msDescriptor.idx << " " << std::setw(8) << msDescriptor.crc << " " << std::setw(8) << msDescriptor.size << " " << std::setw(16) - << msDescriptor.offset << std::dec << std::setfill(' '); + << msDescriptor.offset; + return ss.str(); +} + +std::string FormatMsHeaderHelp() +{ + std::stringstream ss; + ss << " Description of the microslice header format:\n" + << "==> hdr_id = Header format identifier (0xDD) \n" + << "| ==> hdr_ver = Header format version (0x01) \n" + << "| | ==> eq_id = Equipment identifier \n" + << "| | | ==> flags = Status and error flags \n" + << "| | | | ==> sys_id = Subsystem identifier \n" + << "| | | | | ==> sys_ver = Subsystem format/version \n" + << "| | | | | | ==> idx = Microslice index / start time \n" + << "| | | | | | | \n" + << "hi hv eqid flag si sv idx/start crc size offset \n" + << "dd 01 3001 0000 30 03 180c1f234b1b6000 00000000 00000008 0000000000000080\n" + << " | | | \n" + << " crc = CRC-32C of data content <== | | \n" + << " (Castagnoli polynomial) | | \n" + << " size = Content size (bytes) <== | \n" + << " offset = Offset in event buffer (bytes) <== \n"; return ss.str(); } std::ostream& operator<<(std::ostream& os, const fles::MicrosliceDescriptor& msDescriptor) { - char cPrevFill = os.fill('0'); - return os << "hi hv eqid flag si sv idx/start crc size offset" << std::endl - << std::hex << std::setfill('0') << std::setw(2) << static_cast<unsigned int>(msDescriptor.hdr_id) << " " - << std::setw(2) << static_cast<unsigned int>(msDescriptor.hdr_ver) << " " << std::setw(4) - << msDescriptor.eq_id << " " << std::setw(4) << msDescriptor.flags << " " << std::setw(2) - << static_cast<unsigned int>(msDescriptor.sys_id) << " " << std::setw(2) - << static_cast<unsigned int>(msDescriptor.sys_ver) << " " << std::setw(16) << msDescriptor.idx << " " - << std::setw(8) << msDescriptor.crc << " " << std::setw(8) << msDescriptor.size << " " << std::setw(16) - << msDescriptor.offset << std::dec << std::setfill(cPrevFill); + return os << FormatMsHeaderPrintout(msDescriptor); } diff --git a/core/base/utils/flestools/CbmFormatMsHeaderPrintout.h b/core/base/utils/flestools/CbmFormatMsHeaderPrintout.h index 66cedb8699..0f750005ff 100644 --- a/core/base/utils/flestools/CbmFormatMsHeaderPrintout.h +++ b/core/base/utils/flestools/CbmFormatMsHeaderPrintout.h @@ -32,6 +32,8 @@ std::string FormatMsHeaderPrintout(const fles::MicrosliceDescriptor& msDescriptor); +std::string FormatMsHeaderHelp(); + std::ostream& operator<<(std::ostream& os, const fles::MicrosliceDescriptor& msDescriptor); #endif // CbmFormatMsHeaderPrintout_H diff --git a/core/base/utils/flestools/CbmFormatTsPrintout.cxx b/core/base/utils/flestools/CbmFormatTsPrintout.cxx index e0da34c5fc..4fc696399c 100644 --- a/core/base/utils/flestools/CbmFormatTsPrintout.cxx +++ b/core/base/utils/flestools/CbmFormatTsPrintout.cxx @@ -2,6 +2,8 @@ SPDX-License-Identifier: GPL-3.0-only Authors: Pierre-Alain Loizeau [committer] */ +#include "CbmFormatTsPrintout.h" + #include "CbmFormatMsBufferPrintout.h" #include "CbmFormatMsHeaderPrintout.h" @@ -46,72 +48,96 @@ std::string FormatTsHeaderPrintout(const fles::Timeslice& ts) else { ss << std::setw(3) << min_overlap; } // else of if( min_overlap != max_overlap ) - ss << " overlap) = " << std::setw(9) << total_num_microslices << std::endl; + ss << " overlap) = " << std::setw(9) << total_num_microslices << "\n"; ss << "\tmicroslice size min/avg/max: " << std::setw(6) << min_microslice_size << " / " << std::fixed << std::setprecision(0) << std::setw(6) << (static_cast<double>(total_microslice_size) / total_num_microslices) // << std::defaultfloat // commented out as not included in GCC 4.9.2 => restore defaults, probably not needed << std::setprecision(6) // restore defaults, probably not needed - << " / " << std::setw(6) << max_microslice_size << " bytes" << std::endl; + << " / " << std::setw(6) << max_microslice_size << " bytes" + << "\n"; } // if( 0 != nbComps ) + else { + ss << " = " << std::setw(9) << total_num_microslices << "\n"; + } return ss.str(); } -std::string FormatTsPrintout(const fles::Timeslice& ts) +std::string FormatTsContentPrintout(const fles::Timeslice& ts, std::underlying_type_t<fles::Subsystem> selSysId, + size_t nbMsPerComp) { std::stringstream ss; - ss << FormatTsHeaderPrintout(ts); size_t nbComps = ts.num_components(); if (0 != nbComps) { size_t nbMicroslicesCore = ts.num_core_microslices(); size_t nbMicroslicesOverlap = ts.num_microslices(0) - ts.num_core_microslices(); - - for (size_t compIdx = 0; compIdx < nbComps; ++compIdx) { - ss << "Core Microslices for component " << std::setw(3) << compIdx << std::endl; - for (size_t msIdx = 0; msIdx < nbMicroslicesCore; ++msIdx) { - ss << ts.descriptor(compIdx, msIdx) << std::endl; - ss << FormatMsBufferPrintout(ts, compIdx, msIdx); - ss << "----------------------------------------------" << std::endl; - } // for( size_t msIdx = 0; msIdx < nbMicroslicesCore; ++msIdx ) - ss << "Overlap Microslices for component " << std::setw(3) << compIdx << std::endl; - for (size_t msIdx = 0; msIdx < nbMicroslicesOverlap; ++msIdx) { - ss << ts.descriptor(compIdx, msIdx + nbMicroslicesCore) << std::endl; - ss << FormatMsBufferPrintout(ts, compIdx, msIdx + nbMicroslicesCore); - ss << "----------------------------------------------" << std::endl; - } // for( size_t msIdx = 0; msIdx < nbMicroslicesOverlap; ++msIdx ) - } // for( size_t comp = 0; comp < nbComps; ++comp ) + size_t nbCoreMsToLoop = nbMicroslicesCore; + size_t nbOverMsToLoop = nbMicroslicesOverlap; + if (nbMsPerComp < nbMicroslicesCore) { + nbCoreMsToLoop = nbMsPerComp; + nbOverMsToLoop = 0; + } // if (nbMsPerComp < nbMicroslicesCore) + else if (nbMsPerComp < nbMicroslicesCore + nbMicroslicesOverlap) { + nbOverMsToLoop = nbMicroslicesOverlap - (nbMsPerComp - nbMicroslicesCore); + } // else if (nbMsPerComp < nbMicroslicesCore + nbMicroslicesOverlap) + + if (0 < nbMicroslicesCore) { + for (size_t compIdx = 0; compIdx < nbComps; ++compIdx) { + if (0 < nbMicroslicesCore && 0x00 != selSysId && ts.descriptor(compIdx, 0).sys_id != selSysId) { + // FIXME: define "reserved/undefined" system ID somewhere (best in flesnet microslice descriptor header) + continue; + } // if (0 < nbMicroslicesCore && 0x00 != selSysId && ts.descriptor(compIdx, 0).sys_id != selSysId) + // FIXME: Need safe accessor with range check for the cast, to be done in flesnet side + ss << "Component " << std::setw(3) << compIdx << ", Subsystem " + << fles::to_string(static_cast<fles::Subsystem>(ts.descriptor(compIdx, 0).sys_id)) << "\n"; + if (0 < nbCoreMsToLoop) { + ss << "Core Microslices for component " << std::setw(3) << compIdx << " (" + << fles::to_string(static_cast<fles::Subsystem>(ts.descriptor(compIdx, 0).sys_id)) << ")" + << "\n"; + for (size_t msIdx = 0; msIdx < nbCoreMsToLoop; ++msIdx) { + ss << ts.descriptor(compIdx, msIdx) << "\n"; + ss << FormatMsBufferPrintout(ts, compIdx, msIdx); + ss << "----------------------------------------------" + << "\n"; + } // for( size_t msIdx = 0; msIdx < nbOverMsToLoop; ++msIdx ) + } // if (0 < nbCoreMsToLoop ) + if (0 < nbOverMsToLoop) { + ss << "Overlap Microslices for component " << std::setw(3) << compIdx << " (" + << fles::to_string(static_cast<fles::Subsystem>(ts.descriptor(compIdx, 0).sys_id)) << ")" + << "\n"; + for (size_t msIdx = 0; msIdx < nbOverMsToLoop; ++msIdx) { + ss << ts.descriptor(compIdx, msIdx + nbMicroslicesCore) << "\n"; + ss << FormatMsBufferPrintout(ts, compIdx, msIdx + nbMicroslicesCore); + ss << "----------------------------------------------" + << "\n"; + } // for( size_t msIdx = 0; msIdx < nbOverMsToLoop; ++msIdx ) + } // if (0 < nbOverMsToLoop ) + ss << "++++++++++++++++++++++++++++++++++++++++++++++" + << "\n"; + } // for( size_t comp = 0; comp < nbComps; ++comp ) + } // if (0 < nbMicroslicesCore) ) } // if( 0 != nbComps ) - ss << "**********************************************" << std::endl; + ss << "**********************************************" + << "\n"; + + return ss.str(); +} +std::string FormatTsPrintout(const fles::Timeslice& ts, std::underlying_type_t<fles::Subsystem> selSysId, + size_t nbMsPerComp) +{ + std::stringstream ss; + ss << FormatTsHeaderPrintout(ts); + ss << FormatTsContentPrintout(ts, selSysId, nbMsPerComp); return ss.str(); } std::ostream& operator<<(std::ostream& os, const fles::Timeslice& ts) { os << FormatTsHeaderPrintout(ts); - - size_t nbComps = ts.num_components(); - size_t nbMicroslicesCore = ts.num_core_microslices(); - size_t nbMicroslicesOverlap = ts.num_microslices(0) - ts.num_core_microslices(); - - for (size_t compIdx = 0; compIdx < nbComps; ++compIdx) { - os << "Core Microslices for component " << std::setw(3) << compIdx << std::endl; - for (size_t msIdx = 0; msIdx < nbMicroslicesCore; ++msIdx) { - os << ts.descriptor(compIdx, msIdx) << std::endl; - os << FormatMsBufferPrintout(ts, compIdx, msIdx); - os << "----------------------------------------------" << std::endl; - } // for( size_t msIdx = 0; msIdx < nbMicroslicesCore; ++msIdx ) - os << "Overlap Microslices for component " << std::setw(3) << compIdx << std::endl; - for (size_t msIdx = 0; msIdx < nbMicroslicesOverlap; ++msIdx) { - os << ts.descriptor(compIdx, msIdx + nbMicroslicesCore) << std::endl; - os << FormatMsBufferPrintout(ts, compIdx, msIdx + nbMicroslicesCore); - os << "----------------------------------------------" << std::endl; - } // for( size_t msIdx = 0; msIdx < nbMicroslicesOverlap; ++msIdx ) - } // for( size_t comp = 0; comp < nbComps; ++comp ) - os << "**********************************************" << std::endl; - + os << FormatTsContentPrintout(ts); return os; } diff --git a/core/base/utils/flestools/CbmFormatTsPrintout.h b/core/base/utils/flestools/CbmFormatTsPrintout.h index 8ae3e34e4d..33c947266d 100644 --- a/core/base/utils/flestools/CbmFormatTsPrintout.h +++ b/core/base/utils/flestools/CbmFormatTsPrintout.h @@ -14,6 +14,7 @@ #include "Timeslice.hpp" +#include <cstdint> // For SIZE_MAX #include <iomanip> #include <iostream> #include <sstream> @@ -24,7 +25,11 @@ std::string FormatTsHeaderPrintout(const fles::Timeslice& ts); -std::string FormatTsPrintout(const fles::Timeslice& ts); +std::string FormatTsContentPrintout(const fles::Timeslice& ts, std::underlying_type_t<fles::Subsystem> selSysId = 0x00, + size_t nbMsPerComp = SIZE_MAX); + +std::string FormatTsPrintout(const fles::Timeslice& ts, std::underlying_type_t<fles::Subsystem> SelSysId = 0x00, + size_t nbMsPerComp = SIZE_MAX); std::ostream& operator<<(std::ostream& os, const fles::Timeslice& ts); -- GitLab