LCOV - code coverage report
Current view: top level - hdf5libs/test/apps - HDF5LIBS_TestDumpRecord.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 316 0
Test Date: 2025-12-21 13:07:08 Functions: 0.0 % 8 0

            Line data    Source code
       1              : /**
       2              :  * @file HDF5TestDumpRecord.cpp
       3              :  *
       4              :  * Demo of HDF5 file reader for TPC fragments: this example demonstrates
       5              :  * simple 'record-dump' functionality.
       6              :  *
       7              :  * This is part of the DUNE DAQ Software Suite, copyright 2020.
       8              :  * Licensing/copyright details are in the COPYING file that you should have
       9              :  * received with this code.
      10              :  */
      11              : 
      12              : #include "hdf5libs/HDF5RawDataFile.hpp"
      13              : 
      14              : #include "daqdataformats/Fragment.hpp"
      15              : #include "detdataformats/DetID.hpp"
      16              : #include "detdataformats/HSIFrame.hpp"
      17              : #include "logging/Logging.hpp"
      18              : #include "trgdataformats/TriggerObjectOverlay.hpp"
      19              : 
      20              : #include <bitset>
      21              : #include <fstream>
      22              : #include <iostream>
      23              : #include <sstream>
      24              : #include <string>
      25              : #include <time.h>
      26              : #include <unistd.h>
      27              : 
      28              : using namespace dunedaq::hdf5libs;
      29              : using namespace dunedaq::daqdataformats;
      30              : using namespace dunedaq::detdataformats;
      31              : using namespace dunedaq::trgdataformats;
      32              : 
      33              : void
      34            0 : print_usage(const char* appname)
      35              : {
      36            0 :   std::cout << "Usage: " << appname
      37            0 :             << " [-t] [-n <number of TRs to print>] [-s <number of TRs to skip>] <input_file_name>" << std::endl;
      38            0 :   std::cout << "Where a negative number of TRs to skip counts backward from the end of the file." << std::endl;
      39            0 :   std::cout << "And the \'-t\' option causes human-readable times to be printed for selected timestamp values."
      40            0 :             << std::endl;
      41            0 : }
      42              : 
      43              : std::string
      44            0 : get_calendar_time_string(timestamp_t timestamp)
      45              : {
      46            0 :   time_t epoch_sec = timestamp / 62500000;
      47            0 :   tm* gmtm = gmtime(&epoch_sec);
      48            0 :   std::string time_string = asctime(gmtm);
      49            0 :   time_string.pop_back(); // removing trailing newline
      50            0 :   size_t fractional_part = double(timestamp % 62500000) * 10000.0 / 625.0;
      51            0 :   if (fractional_part != 0 && time_string.length() > 6) {
      52            0 :     std::string year_string = time_string.substr(time_string.length() - 4);
      53            0 :     time_string = time_string.substr(0, time_string.length() - 5);
      54            0 :     std::ostringstream oss;
      55            0 :     oss << time_string << "." << std::setw(9) << std::setfill('0') << fractional_part << " " << year_string;
      56            0 :     time_string = oss.str();
      57            0 :   }
      58            0 :   return time_string;
      59            0 : }
      60              : 
      61              : int
      62            0 : main(int argc, char** argv)
      63              : {
      64            0 :   int number_of_trs_to_print = 0x0ffffff;
      65            0 :   int number_of_trs_to_skip = 0;
      66            0 :   bool print_calendar_time = false;
      67            0 :   signed char opt;
      68            0 :   while ((opt = getopt(argc, argv, "hn:s:t")) != -1) {
      69            0 :     switch (opt) {
      70            0 :       case 'h':
      71            0 :         print_usage(argv[0]);
      72              :         return 1;
      73            0 :       case 'n':
      74            0 :         number_of_trs_to_print = atoi(optarg);
      75            0 :         break;
      76            0 :       case 's':
      77            0 :         number_of_trs_to_skip = atoi(optarg);
      78            0 :         break;
      79              :       case 't':
      80              :         print_calendar_time = true;
      81              :         break;
      82            0 :       default: /* '?' */
      83            0 :         print_usage(argv[0]);
      84              :         return 1;
      85              :     }
      86              :   }
      87              : 
      88            0 :   argc -= (optind - 1);
      89            0 :   argv += (optind - 1);
      90            0 :   if (argc != 2) {
      91            0 :     print_usage(argv[0]);
      92            0 :     return 1;
      93              :   }
      94              : 
      95            0 :   const std::string ifile_name = std::string(argv[1]);
      96              : 
      97              :   // open our file reading
      98            0 :   HDF5RawDataFile h5_raw_data_file(ifile_name);
      99            0 :   std::ostringstream ss;
     100              : 
     101            0 :   ss << "\nFile name: " << h5_raw_data_file.get_file_name();
     102            0 :   ss << "\n\tRecorded size: " << h5_raw_data_file.get_recorded_size();
     103            0 :   size_t uncompressed_raw_data_size = h5_raw_data_file.get_attribute_if_exists<size_t>("uncompressed_raw_data_size", h5_raw_data_file.get_recorded_size());
     104            0 :   ss << "\n\tUncompressed raw data size: " << uncompressed_raw_data_size;
     105              : 
     106            0 :   auto record_type = h5_raw_data_file.get_record_type();
     107            0 :   ss << "\nRecord type = " << record_type;
     108              : 
     109            0 :   TLOG() << ss.str();
     110            0 :   ss.str("");
     111              : 
     112              :   // get some file attributes
     113            0 :   auto run_number = h5_raw_data_file.get_attribute<unsigned int>("run_number");
     114            0 :   auto file_index = h5_raw_data_file.get_attribute<unsigned int>("file_index");
     115            0 :   auto app_name = h5_raw_data_file.get_attribute<std::string>("application_name");
     116            0 :   auto compression_level = h5_raw_data_file.get_attribute_if_exists<unsigned>("compression_level", 0);
     117              : 
     118            0 :   ss << "\n\tRun number: " << run_number;
     119            0 :   ss << "\n\tFile index: " << file_index;
     120            0 :   if (h5_raw_data_file.get_file_layout().get_version() >= 6) {
     121            0 :     auto creation_timestamp = h5_raw_data_file.get_attribute<size_t>("creation_timestamp");
     122            0 :     ss << "\n\tCreation timestamp: " << creation_timestamp;
     123              :   } else {
     124            0 :     auto creation_timestamp = h5_raw_data_file.get_attribute<std::string>("creation_timestamp");
     125            0 :     ss << "\n\tCreation timestamp: " << creation_timestamp;
     126            0 :   }
     127            0 :   ss << "\n\tWriter app name: " << app_name;
     128            0 :   ss << "\n\tCompression level: " << compression_level;
     129              : 
     130            0 :   TLOG() << ss.str();
     131            0 :   ss.str("");
     132              : 
     133            0 :   auto records = h5_raw_data_file.get_all_record_ids();
     134            0 :   ss << "\nNumber of records: " << records.size();
     135            0 :   if (records.empty()) {
     136            0 :     ss << "\n\nNO TRIGGER RECORDS FOUND";
     137            0 :     TLOG() << ss.str();
     138            0 :     return 0;
     139              :   }
     140            0 :   auto first_rec = *(records.begin());
     141            0 :   auto last_rec = *(std::next(records.begin(), records.size() - 1));
     142              : 
     143            0 :   ss << "\n\tFirst record: " << first_rec.first << "," << first_rec.second;
     144            0 :   ss << "\n\tLast record: " << last_rec.first << "," << last_rec.second;
     145              : 
     146            0 :   TLOG() << ss.str();
     147            0 :   ss.str("");
     148              : 
     149            0 :   if (number_of_trs_to_skip < 0) {
     150            0 :     number_of_trs_to_skip += records.size();
     151              :   }
     152            0 :   int tr_count = 0;
     153            0 :   int trs_printed = 0;
     154              : 
     155            0 :   for (auto const& record_id : records) {
     156            0 :     ++tr_count;
     157            0 :     if (number_of_trs_to_skip > 0 && tr_count <= number_of_trs_to_skip) {
     158            0 :       continue;
     159              :     }
     160              : 
     161            0 :     if (trs_printed >= number_of_trs_to_print) {
     162              :       break;
     163              :     }
     164              : 
     165            0 :     if (h5_raw_data_file.is_timeslice_type()) {
     166            0 :       auto tsh_ptr = h5_raw_data_file.get_tsh_ptr(record_id);
     167            0 :       ss << "\n\tTimeSliceHeader: " << *tsh_ptr;
     168            0 :     } else {
     169            0 :       auto trh_ptr = h5_raw_data_file.get_trh_ptr(record_id);
     170            0 :       if (trh_ptr->get_header().version != TriggerRecordHeaderData::s_trigger_record_header_version) {
     171            0 :         std::cout << std::endl;
     172            0 :         std::cout << "ERROR: The specified data file was written with a version of the DUNE-DAQ software that "
     173            0 :                   << "used a different version" << std::endl
     174              :                   << "       of the TriggerRecordHeader "
     175            0 :                   << "than this application (built with the current version of the software) is expecting."
     176            0 :                   << std::endl;
     177            0 :         std::cout << "Please use a version of the software that is compatible with the data file." << std::endl;
     178            0 :         std::cout << "(Expected TRH version " << TriggerRecordHeaderData::s_trigger_record_header_version
     179            0 :                   << " and found version " << trh_ptr->get_header().version << ".)" << std::endl;
     180            0 :         std::exit(1);
     181              :       }
     182            0 :       ss << "\n\tTriggerRecordHeader: " << trh_ptr->get_header();
     183            0 :       if (print_calendar_time) {
     184            0 :         std::string trigger_timestamp_string = get_calendar_time_string(trh_ptr->get_header().trigger_timestamp);
     185            0 :         ss << "\n\t\t"
     186            0 :            << "Trigger timestamp corresponds to UTC " << trigger_timestamp_string;
     187            0 :       }
     188            0 :     }
     189            0 :     TLOG() << ss.str();
     190            0 :     ss.str("");
     191            0 :     bool first_frag = true;
     192            0 :     std::set<SourceID> frag_sid_list = h5_raw_data_file.get_fragment_source_ids(record_id);
     193            0 :     for (auto const& source_id : frag_sid_list) {
     194            0 :       if (first_frag) {
     195              :         first_frag = false;
     196              :       } else {
     197            0 :         ss << "\n";
     198              :       }
     199            0 :       auto frag_ptr = h5_raw_data_file.get_frag_ptr(record_id, source_id);
     200            0 :       ss << "\t" << fragment_type_to_string(frag_ptr->get_fragment_type()) << " fragment with SourceID "
     201            0 :          << frag_ptr->get_element_id().to_string() << " from subdetector "
     202            0 :          << DetID::subdetector_to_string(static_cast<DetID::Subdetector>(frag_ptr->get_detector_id()))
     203            0 :          << " has size = " << frag_ptr->get_size() << " -----";
     204            0 :       if (h5_raw_data_file.is_trigger_record_type()) {
     205            0 :         try {
     206            0 :           auto trh_ptr = h5_raw_data_file.get_trh_ptr(record_id);
     207            0 :           ComponentRequest cr = trh_ptr->get_component_for_source_id(frag_ptr->get_element_id());
     208            0 :           int64_t begin_diff = cr.window_begin;
     209            0 :           begin_diff -= trh_ptr->get_trigger_timestamp();
     210            0 :           int64_t end_diff = cr.window_end;
     211            0 :           end_diff -= trh_ptr->get_trigger_timestamp();
     212            0 :           ss << "\n\t\t"
     213            0 :              << "Readout window begin = " << begin_diff << ", end = " << end_diff
     214            0 :              << " (relative to the trigger_timestamp)";
     215            0 :           if (print_calendar_time) {
     216            0 :             std::string window_begin_string = get_calendar_time_string(cr.window_begin);
     217            0 :             std::string window_end_string = get_calendar_time_string(cr.window_end);
     218            0 :             ss << "\n\t\t\t"
     219            0 :                << "Readout window times corresponds to UTC " << window_begin_string << " and " << window_end_string;
     220            0 :           }
     221            0 :         } catch (std::exception const& excpt) {
     222            0 :           ss << "\n\t\t"
     223            0 :              << "Unable to determine readout window, exception was \"" << excpt.what() << "\"";
     224            0 :         }
     225              :       }
     226            0 :       if (h5_raw_data_file.is_timeslice_type()) {
     227            0 :         ss << "\n\t\tFragment window begin time = " << frag_ptr->get_window_begin()
     228            0 :            << ", window end time = " << frag_ptr->get_window_end();
     229            0 :         if (print_calendar_time) {
     230            0 :           std::string window_begin_string = get_calendar_time_string(frag_ptr->get_window_begin());
     231            0 :           std::string window_end_string = get_calendar_time_string(frag_ptr->get_window_end());
     232            0 :           ss << "\n\t\t\t"
     233            0 :              << "Fragment window times corresponds to UTC " << window_begin_string << " and " << window_end_string;
     234            0 :         }
     235              :       }
     236            0 :       if (frag_ptr->get_element_id().subsystem == SourceID::Subsystem::kDetectorReadout) {
     237            0 :         ss << "\n\t\t"
     238            0 :            << "It may contain data from the following detector components:";
     239            0 :         std::vector<uint64_t> geo_id_list = h5_raw_data_file.get_geo_ids_for_source_id(record_id, source_id);
     240            0 :         for (auto const& geo_id : geo_id_list) {
     241              :           // FIXME
     242              :           // GeoInfo = HardwareMapService::parse_geo_id(geo_id);
     243            0 :           uint16_t det_id = geo_id & 0xffff;
     244            0 :           uint16_t crate_id = (geo_id >> 16) & 0xffff;
     245            0 :           uint16_t slot_id = (geo_id >> 32) & 0xffff;
     246            0 :           uint16_t link_id = (geo_id >> 48) & 0xffff;
     247            0 :           ss << "\n\t\t\t"
     248            0 :              << "subdetector " << DetID::subdetector_to_string(static_cast<DetID::Subdetector>(det_id)) << " ("
     249            0 :              << det_id << ")"
     250            0 :              << ", crate " << crate_id << ", slot " << slot_id << ", link " << link_id;
     251              :         }
     252            0 :       }
     253            0 :       if (frag_ptr->get_data_size() == 0) {
     254            0 :         ss << "\n\t\t"
     255            0 :            << "*** Empty fragment! Moving to next fragment. ***";
     256            0 :         continue;
     257              :       }
     258            0 :       if (frag_ptr->get_fragment_type() == FragmentType::kTriggerCandidate) {
     259            0 :         size_t payload_size = frag_ptr->get_size() - sizeof(FragmentHeader);
     260            0 :         size_t offset = 0;
     261            0 :         int number_of_TCs = 0;
     262            0 :         int number_of_referenced_TAs = 0;
     263            0 :         while ((offset + sizeof(TriggerCandidateData)) < payload_size) {
     264            0 :           ++number_of_TCs;
     265            0 :           TriggerCandidate* tmp_tcptr =
     266            0 :             reinterpret_cast<TriggerCandidate*>(offset + reinterpret_cast<uint8_t*>(frag_ptr->get_data()));
     267            0 :           offset += sizeof(TriggerCandidateData) + sizeof(tmp_tcptr->n_inputs);
     268            0 :           offset += (tmp_tcptr->n_inputs * sizeof(TriggerActivityData));
     269            0 :           number_of_referenced_TAs += tmp_tcptr->n_inputs;
     270              :         }
     271            0 :         TriggerCandidate* tcptr = static_cast<TriggerCandidate*>(frag_ptr->get_data());
     272            0 :         ss << "\n\t\t"
     273            0 :            << "Number of TCs in this fragment=" << number_of_TCs
     274            0 :            << ", overall number of referenced TAs=" << number_of_referenced_TAs
     275            0 :            << ", size of TC data=" << (sizeof(TriggerCandidateData) + sizeof(tcptr->n_inputs));
     276            0 :         ss << "\n\t\t"
     277            0 :            << "First TC type = " << get_trigger_candidate_type_names()[tcptr->data.type] << " ("
     278            0 :            << static_cast<int>(tcptr->data.type) << "), TC algorithm = " << static_cast<int>(tcptr->data.algorithm)
     279            0 :            << ", number of TAs = " << tcptr->n_inputs;
     280            0 :         ss << "\n\t\t"
     281            0 :            << "First TC start time=" << tcptr->data.time_start << ", end time=" << tcptr->data.time_end
     282            0 :            << ", and candidate time=" << tcptr->data.time_candidate;
     283            0 :         if (number_of_TCs >= 2) {
     284            0 :           offset = sizeof(TriggerCandidateData) + sizeof(tcptr->n_inputs);
     285            0 :           offset += (tcptr->n_inputs * sizeof(TriggerActivityData));
     286            0 :           TriggerCandidate* tmp_tcptr =
     287            0 :             reinterpret_cast<TriggerCandidate*>(offset+reinterpret_cast<uint8_t*>(frag_ptr->get_data()));
     288            0 :           ss << "\n\t\t" << "Second TC type = " << get_trigger_candidate_type_names()[tmp_tcptr->data.type]
     289            0 :              << " (" << static_cast<int>(tmp_tcptr->data.type) << "), TC algorithm = "
     290            0 :              << static_cast<int>(tmp_tcptr->data.algorithm) << ", number of TAs = " << tmp_tcptr->n_inputs;
     291            0 :           ss << "\n\t\t" << "Second TC start time=" << tmp_tcptr->data.time_start << ", end time=" << tmp_tcptr->data.time_end
     292            0 :              << ", and candidate time=" << tmp_tcptr->data.time_candidate;
     293              :         }
     294              :       }
     295            0 :       if (frag_ptr->get_fragment_type() == FragmentType::kTriggerActivity) {
     296            0 :         size_t payload_size = frag_ptr->get_size() - sizeof(FragmentHeader);
     297            0 :         size_t offset = 0;
     298            0 :         int number_of_TAs = 0;
     299            0 :         int number_of_referenced_TPs = 0;
     300            0 :         while ((offset + sizeof(TriggerActivityData)) < payload_size) {
     301            0 :           ++number_of_TAs;
     302            0 :           TriggerActivity* tmp_taptr =
     303            0 :             reinterpret_cast<TriggerActivity*>(offset + reinterpret_cast<uint8_t*>(frag_ptr->get_data()));
     304            0 :           offset += sizeof(TriggerActivityData) + sizeof(tmp_taptr->n_inputs);
     305            0 :           offset += (tmp_taptr->n_inputs * sizeof(TriggerPrimitive));
     306            0 :           number_of_referenced_TPs += tmp_taptr->n_inputs;
     307              :         }
     308            0 :         TriggerActivity* taptr = static_cast<TriggerActivity*>(frag_ptr->get_data());
     309            0 :         ss << "\n\t\t"
     310            0 :            << "Number of TAs in this fragment=" << number_of_TAs
     311            0 :            << ", overall number of referenced TPs=" << number_of_referenced_TPs
     312            0 :            << ", size of TA data=" << (sizeof(TriggerActivityData) + sizeof(taptr->n_inputs));
     313            0 :         ss << "\n\t\t"
     314            0 :            << "First TA type = " << static_cast<int>(taptr->data.type)
     315            0 :            << ", TA algorithm = " << static_cast<int>(taptr->data.algorithm) << ", number of TPs = " << taptr->n_inputs;
     316            0 :         ss << "\n\t\t"
     317            0 :            << "First TA start time=" << taptr->data.time_start << ", end time=" << taptr->data.time_end
     318            0 :            << ", and activity time=" << taptr->data.time_activity;
     319            0 :         if (number_of_TAs >= 2) {
     320            0 :           offset = sizeof(TriggerActivityData) + sizeof(taptr->n_inputs);
     321            0 :           offset += (taptr->n_inputs * sizeof(TriggerPrimitive));
     322            0 :           TriggerActivity* tmp_taptr =
     323            0 :             reinterpret_cast<TriggerActivity*>(offset+reinterpret_cast<uint8_t*>(frag_ptr->get_data()));
     324            0 :           ss << "\n\t\t" << "Second TA type = " << static_cast<int>(tmp_taptr->data.type) << ", TA algorithm = "
     325            0 :              << static_cast<int>(tmp_taptr->data.algorithm) << ", number of TPs = " << tmp_taptr->n_inputs;
     326            0 :           ss << "\n\t\t" << "Second TA start time=" << tmp_taptr->data.time_start << ", end time=" << tmp_taptr->data.time_end
     327            0 :              << ", and activity time=" << tmp_taptr->data.time_activity;
     328              :         }
     329              :       }
     330            0 :       if (frag_ptr->get_fragment_type() == FragmentType::kTriggerPrimitive) {
     331            0 :         TriggerPrimitive* tpptr = static_cast<TriggerPrimitive*>(frag_ptr->get_data());
     332            0 :         if (tpptr->version != TriggerPrimitive::s_trigger_primitive_version) {
     333            0 :           std::cout << std::endl;
     334            0 :           std::cout << "ERROR: The specified data file was written with a version of the DUNE-DAQ software that "
     335            0 :                     << std::endl
     336            0 :                     << "       used a different version of the TriggerPrimitive data structure than this "
     337            0 :                     << std::endl
     338            0 :                     << "       application (built with the current version of the software) is expecting."
     339            0 :                     << std::endl;
     340            0 :           std::cout << "Please use a version of the software that is compatible with the data file." << std::endl;
     341            0 :           std::cout << "(Expected TP version " << static_cast<int>(TriggerPrimitive::s_trigger_primitive_version)
     342            0 :                     << " and found version " << tpptr->version << ".)" << std::endl;
     343            0 :           std::exit(1);
     344              :         }
     345            0 :         ss << "\n\t\t"
     346            0 :            << "Number of TPs in this fragment="
     347            0 :            << ((frag_ptr->get_size() - sizeof(FragmentHeader)) / sizeof(TriggerPrimitive))
     348            0 :            << ", size of TP data structure=" << sizeof(TriggerPrimitive)
     349            0 :            << ", size of Fragment Header=" << sizeof(FragmentHeader);
     350            0 :         ss << "\n\t\t"
     351            0 :            << "First TP flag = " << static_cast<int>(tpptr->flag)
     352            0 :            << ", TP detid = " << static_cast<int>(tpptr->detid);
     353            0 :         ss << "\n\t\t"
     354            0 :            << "First TP start time=" << tpptr->time_start << ", samples to peak=" << tpptr->samples_to_peak
     355            0 :            << ", and samples over threshold=" << tpptr->samples_over_threshold;
     356            0 :         if (print_calendar_time) {
     357            0 :           std::string time_string = get_calendar_time_string(tpptr->time_start);
     358            0 :           ss << "\n\t\t\t"
     359            0 :              << "First TP start time corresponds to UTC " << time_string;
     360            0 :         }
     361              :       }
     362            0 :       if (frag_ptr->get_fragment_type() == FragmentType::kHardwareSignal) {
     363            0 :         HSIFrame* hsi_ptr = static_cast<HSIFrame*>(frag_ptr->get_data());
     364            0 :         ss << "\n\t\t"
     365            0 :            << "Detector ID = " << hsi_ptr->detector_id << ", Crate = " << hsi_ptr->crate << ", Slot = " << hsi_ptr->slot
     366            0 :            << ", Link = " << hsi_ptr->link;
     367            0 :         ss << ",\n\t\t"
     368            0 :            << "Sequence = " << hsi_ptr->sequence << ", Trigger = " << hsi_ptr->trigger
     369            0 :            << ", Version = " << hsi_ptr->version;
     370            0 :         ss << ",\n\t\t"
     371            0 :            << "Timestamp = " << hsi_ptr->get_timestamp();
     372              : 
     373              :         // Finding the bit positions for input_low and input_high
     374            0 :         uint32_t bit_pos, bit_sniff;
     375            0 :         uint32_t input_low = hsi_ptr->input_low;
     376            0 :         std::bitset<32> low_bits{ input_low };
     377            0 :         size_t num_bits = low_bits.count();
     378            0 :         ss << ",\n\t\t"
     379            0 :            << "Input Low Bitmap = " << input_low;
     380            0 :         if (input_low != 0) { // Skip printing the positions if the value is 0.
     381            0 :           ss << ", Input Low Bit Positions = ";
     382              :           bit_sniff = 1;
     383            0 :           for (bit_pos = 0; bit_pos < 32 && num_bits > 0; bit_pos++) {
     384            0 :             if (input_low & bit_sniff) {
     385            0 :               if (num_bits == 1)
     386            0 :                 ss << bit_pos;
     387              :               else
     388            0 :                 ss << bit_pos << ", ";
     389            0 :               num_bits--;
     390              :             }
     391            0 :             bit_sniff = bit_sniff << 1;
     392              :           }
     393              :         }
     394              : 
     395            0 :         uint32_t input_high = hsi_ptr->input_high;
     396            0 :         std::bitset<32> high_bits{ input_high };
     397            0 :         num_bits = high_bits.count();
     398            0 :         ss << ",\n\t\t"
     399            0 :            << "Input High Bitmap = " << input_high;
     400            0 :         if (input_high != 0) {
     401            0 :           ss << ", Input High Bit Positions = ";
     402              :           bit_sniff = 1;
     403            0 :           for (bit_pos = 0; bit_pos < 32 && num_bits > 0; bit_pos++) {
     404            0 :             if (input_high & bit_sniff) {
     405            0 :               if (num_bits == 1)
     406            0 :                 ss << bit_pos;
     407              :               else
     408            0 :                 ss << bit_pos << ", ";
     409            0 :               num_bits--;
     410              :             }
     411            0 :             bit_sniff = bit_sniff << 1;
     412              :           }
     413              :         }
     414            0 :         ss << "."; // Finishes the HSI section.
     415              :       }
     416            0 :     }
     417            0 :     std::cout << ss.str() << std::endl;
     418            0 :     ss.str("");
     419              : 
     420            0 :     ++trs_printed;
     421            0 :   }
     422              : 
     423            0 :   return 0;
     424              : } // NOLINT
        

Generated by: LCOV version 2.0-1