FERS 0.1.0
The Flexible Extensible Radar Simulator
Loading...
Searching...
No Matches
output_metadata.h
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-only
2//
3// Copyright (c) 2026-present FERS Contributors (see AUTHORS.md).
4//
5// See the GNU GPLv2 LICENSE file in the FERS project root for more information.
6
7#pragma once
8
9#include <cstdint>
10#include <mutex>
11#include <optional>
12#include <string>
13#include <vector>
14
15#include "core/config.h"
16#include "core/output_config.h"
17#include "core/sim_id.h"
19
20namespace core
21{
22 /// Metadata for one pulsed output chunk written to HDF5.
24 {
25 unsigned chunk_index = 0; ///< Zero-based chunk index in the receiver output sequence.
26 std::string i_dataset; ///< HDF5 dataset path containing the in-phase samples.
27 std::string q_dataset; ///< HDF5 dataset path containing the quadrature samples.
28 RealType start_time = 0.0; ///< Simulation time of the first sample in seconds.
29 std::uint64_t sample_count = 0; ///< Number of samples in the chunk.
30 std::uint64_t sample_start = 0; ///< Inclusive global sample index for the chunk start.
31 std::uint64_t sample_end_exclusive = 0; ///< Exclusive global sample index for the chunk end.
32 };
33
34 /// Metadata for one contiguous streaming output segment.
36 {
37 RealType start_time = 0.0; ///< Segment start time in seconds.
38 RealType end_time = 0.0; ///< Segment end time in seconds.
39 std::uint64_t sample_count = 0; ///< Number of samples emitted for the segment.
40 std::uint64_t sample_start = 0; ///< Inclusive global sample index for the segment start.
41 std::uint64_t sample_end_exclusive = 0; ///< Exclusive global sample index for the segment end.
42 std::optional<RealType> first_chirp_start_time = std::nullopt; ///< First emitted FMCW chirp start time.
43 std::optional<std::uint64_t> emitted_chirp_count = std::nullopt; ///< Number of FMCW chirps emitted.
44 std::optional<RealType> first_triangle_start_time = std::nullopt; ///< First emitted FMCW triangle start time.
45 std::optional<std::uint64_t> emitted_triangle_count = std::nullopt; ///< Number of FMCW triangles emitted.
46 };
47
48 /// FMCW waveform metadata captured for a streaming output file.
50 {
51 std::string waveform_shape = "linear"; ///< FMCW waveform shape token: linear or triangle.
52 RealType chirp_bandwidth = 0.0; ///< Chirp bandwidth in hertz.
53 RealType chirp_duration = 0.0; ///< Active chirp duration in seconds.
54 RealType chirp_period = 0.0; ///< Chirp repetition period in seconds.
55 RealType chirp_rate = 0.0; ///< Frequency sweep rate in hertz per second.
56 RealType chirp_rate_signed = 0.0; ///< Signed frequency sweep rate in hertz per second.
57 std::string chirp_direction = "up"; ///< Frequency sweep direction token.
58 RealType start_frequency_offset = 0.0; ///< Start frequency offset relative to carrier in hertz.
59 std::optional<std::uint64_t> chirp_count = std::nullopt; ///< Optional finite chirp count.
60 std::optional<RealType> triangle_period = std::nullopt; ///< Full triangle period in seconds.
61 std::optional<std::uint64_t> triangle_count = std::nullopt; ///< Optional finite triangle count.
62 };
63
64 /// Metadata for one active FMCW transmitter schedule segment.
66 {
67 RealType start_time = 0.0; ///< Transmitter segment start time in seconds.
68 RealType end_time = 0.0; ///< Transmitter segment end time in seconds.
69 std::optional<RealType> first_chirp_start_time = std::nullopt; ///< First emitted chirp start in the segment.
70 std::optional<std::uint64_t> emitted_chirp_count = std::nullopt; ///< Number of chirps emitted in the segment.
71 std::optional<RealType> first_triangle_start_time =
72 std::nullopt; ///< First emitted triangle start in the segment.
73 std::optional<std::uint64_t> emitted_triangle_count = std::nullopt; ///< Number of triangles emitted.
74 };
75
76 /// Metadata for one FMCW illuminator represented in a streaming output file.
78 {
79 SimId transmitter_id = 0; ///< FMCW transmitter SimId.
80 std::string transmitter_name; ///< FMCW transmitter display name.
81 SimId waveform_id = 0; ///< FMCW waveform SimId.
82 std::string waveform_name; ///< FMCW waveform display name.
83 RealType carrier_frequency = 0.0; ///< Waveform carrier frequency in hertz.
84 FmcwMetadata waveform; ///< FMCW chirp parameters.
85 std::vector<FmcwSourceSegmentMetadata> segments = {}; ///< Active transmitter segments.
86 };
87
88 /// Metadata for one receiver output file.
90 {
91 SimId receiver_id = 0; ///< Receiver SimId that owns the output file.
92 std::string receiver_name; ///< Receiver display name.
93 std::string mode; ///< Output mode label, such as pulsed or streaming.
94 std::string path; ///< Filesystem path to the generated output file.
95 RealType sampling_rate = 0.0; ///< Sample rate for this output file in hertz.
96 std::uint64_t total_samples = 0; ///< Total sample count written to the file.
97 std::uint64_t sample_start = 0; ///< Inclusive global sample index for the file start.
98 std::uint64_t sample_end_exclusive = 0; ///< Exclusive global sample index for the file end.
99 std::uint64_t pulse_count = 0; ///< Number of pulses represented in the file.
100 std::uint64_t min_pulse_length_samples = 0; ///< Minimum pulse length in samples.
101 std::uint64_t max_pulse_length_samples = 0; ///< Maximum pulse length in samples.
102 bool uniform_pulse_length = true; ///< True when every pulse has the same sample length.
103 std::vector<PulseChunkMetadata> chunks = {}; ///< Pulsed output chunks written to the file.
104 std::vector<StreamingSegmentMetadata> streaming_segments = {}; ///< Streaming segments written to the file.
105 std::optional<FmcwMetadata> fmcw = std::nullopt; ///< Optional FMCW metadata for streaming outputs.
106 std::vector<FmcwSourceMetadata> fmcw_sources = {}; ///< FMCW illuminators represented in the output.
107 std::string fmcw_dechirp_mode = "none"; ///< Receiver dechirp mode for FMCW streaming outputs.
108 std::string fmcw_dechirp_reference_source = "none"; ///< Receiver dechirp reference source.
109 std::optional<SimId> fmcw_dechirp_reference_transmitter_id = std::nullopt; ///< Referenced LO transmitter ID.
110 std::optional<std::string> fmcw_dechirp_reference_transmitter_name = std::nullopt; ///< LO transmitter name.
111 std::optional<SimId> fmcw_dechirp_reference_waveform_id = std::nullopt; ///< Custom LO waveform ID.
112 std::optional<std::string> fmcw_dechirp_reference_waveform_name = std::nullopt; ///< Custom LO waveform name.
113 std::optional<FmcwMetadata> fmcw_dechirp_reference_waveform = std::nullopt; ///< Custom LO waveform parameters.
114 bool fmcw_if_decimation_enabled = false; ///< True when IF-rate resampling is used.
115 bool fmcw_if_legacy_full_rate = false; ///< True for legacy full-rate dechirped IF output.
116 std::optional<RealType> fmcw_if_requested_sample_rate = std::nullopt; ///< Requested IF ADC rate in hertz.
117 std::optional<RealType> fmcw_if_sample_rate = std::nullopt; ///< Realized IF output sample rate in hertz.
118 std::optional<RealType> fmcw_if_input_sample_rate = std::nullopt; ///< Input simulation sample rate in hertz.
119 std::optional<unsigned> fmcw_if_resample_numerator = std::nullopt; ///< Reduced rational P.
120 std::optional<unsigned> fmcw_if_resample_denominator = std::nullopt; ///< Reduced rational Q.
121 std::optional<RealType> fmcw_if_decimation_factor = std::nullopt; ///< Input/output sample-rate ratio.
122 std::optional<RealType> fmcw_if_filter_bandwidth = std::nullopt; ///< One-sided IF passband in hertz.
123 std::optional<RealType> fmcw_if_filter_transition_width = std::nullopt; ///< IF transition width in hertz.
124 std::optional<RealType> fmcw_if_filter_stopband = std::nullopt; ///< IF stopband attenuation in dB.
125 std::optional<RealType> fmcw_if_filter_group_delay_seconds = std::nullopt; ///< Total filter delay.
126 std::optional<std::uint64_t> fmcw_if_compensated_integer_delay_samples =
127 std::nullopt; ///< Integer output-delay compensation.
129 std::nullopt; ///< Fractional output-delay compensation.
130 std::optional<std::uint64_t> fmcw_if_warmup_discard_samples =
131 std::nullopt; ///< Startup outputs discarded by the sink.
132 std::optional<unsigned> fmcw_if_phase_refinement = std::nullopt; ///< Polyphase refinement factor.
133 std::optional<RealType> fmcw_if_timing_error_seconds = std::nullopt; ///< Estimated timing error.
134 std::optional<RealType> fmcw_if_phase_error_radians = std::nullopt; ///< Estimated IF edge phase error.
135 std::optional<RealType> fmcw_if_noise_variance = std::nullopt; ///< Post-resampling complex noise variance.
136 bool fmcw_if_group_delay_compensated = false; ///< True when IF output timestamps are aligned to t_start.
137 };
138
139 /// Metadata for one VITA 49.2 receiver stream.
141 {
142 SimId receiver_id = 0; ///< Receiver SimId that owns the VRT stream.
143 std::string receiver_name; ///< Receiver display name.
144 std::uint32_t stream_id = 0; ///< Allocated 32-bit VRT Stream ID.
145 std::string mode = "unknown"; ///< Receiver mode token: pulsed, cw, fmcw, or unknown.
146 RealType sample_rate = 0.0; ///< Stream sample rate in hertz.
147 RealType reference_frequency = 0.0; ///< RF reference frequency in hertz.
148 std::uint64_t packets_emitted = 0; ///< Signal data packets emitted.
149 std::uint64_t samples_emitted = 0; ///< Complex samples emitted.
150 std::uint64_t packets_dropped = 0; ///< Data packets lost to socket send failures.
151 std::uint64_t samples_dropped = 0; ///< Complex samples lost to socket send failures.
152 std::uint64_t over_range_count = 0; ///< Samples clipped by fixed full-scale scaling.
153 std::uint64_t late_packet_count = 0; ///< Packets sent after their scheduled time.
154 std::uint64_t context_packet_count = 0; ///< Context packets emitted for this stream.
155 std::optional<RealType> first_sample_time = std::nullopt; ///< First signal sample time in seconds.
156 std::optional<RealType> end_sample_time = std::nullopt; ///< Exclusive stream end sample time in seconds.
157 std::optional<Vita49Timestamp> first_timestamp = std::nullopt; ///< First VRT UTC timestamp.
158 std::optional<Vita49Timestamp> end_timestamp = std::nullopt; ///< Exclusive stream end VRT UTC timestamp.
159 };
160
161 /// Metadata for the VITA 49.2 UDP output backend.
163 {
164 std::string endpoint_host; ///< Destination host.
165 std::uint16_t endpoint_port = 0; ///< Destination UDP port.
166 std::optional<std::uint64_t> epoch_unix_nanoseconds = std::nullopt; ///< Run epoch, if already fixed.
167 RealType adc_fullscale = 0.0; ///< Fixed ADC full-scale used for int16 IQ scaling.
168 std::uint16_t max_udp_payload = 1400; ///< Maximum UDP datagram payload in bytes.
169 std::uint32_t queue_depth = 1024; ///< Bounded blocking sender queue depth in packets.
170 std::string class_id = "0xFA52530001000101"; ///< Internal placeholder VRT Class ID.
171 std::vector<Vita49StreamMetadata> streams = {}; ///< Per-receiver VRT stream metadata and stats.
172 };
173
174 /// Metadata summary for the full simulation output set.
176 {
177 unsigned schema_version = 1; ///< Metadata schema version.
178 std::string simulation_name; ///< Simulation name from the loaded scenario.
179 std::string output_directory; ///< Directory containing generated output files.
180 RealType start_time = 0.0; ///< Simulation start time in seconds.
181 RealType end_time = 0.0; ///< Simulation end time in seconds.
182 RealType sampling_rate = 0.0; ///< Output sampling rate in hertz.
183 unsigned oversample_ratio = 1; ///< Oversampling ratio used during rendering.
184 std::vector<OutputFileMetadata> files; ///< Metadata for each generated output file.
185 std::optional<Vita49OutputMetadata> vita49 = std::nullopt; ///< Optional VITA 49.2 output metadata.
186 };
187
188 /// Thread-safe collector for simulation output metadata.
190 {
191 public:
192 /// Constructs a metadata collector for the specified output directory.
193 explicit OutputMetadataCollector(std::string output_dir);
194
195 /// Adds metadata for one generated output file.
196 void addFile(OutputFileMetadata file_metadata);
197
198 /// Returns a consistent snapshot of the collected metadata.
200
201 private:
202 mutable std::mutex _mutex; ///< Mutex guarding the metadata aggregate.
203 OutputMetadata _metadata; ///< Mutable aggregate metadata collected during simulation.
204 };
205
206 /// Serializes one output-file metadata entry to JSON.
207 [[nodiscard]] std::string outputFileMetadataToJsonString(const OutputFileMetadata& metadata);
208
209 /// Serializes a full simulation output metadata snapshot to JSON.
210 [[nodiscard]] std::string outputMetadataToJsonString(const OutputMetadata& metadata);
211
212 /// Builds the static VITA metadata section from runtime output configuration.
214}
Thread-safe collector for simulation output metadata.
void addFile(OutputFileMetadata file_metadata)
Adds metadata for one generated output file.
OutputMetadata snapshot() const
Returns a consistent snapshot of the collected metadata.
Global configuration file for the project.
double RealType
Type for real numbers.
Definition config.h:27
Vita49OutputMetadata vita49MetadataFromConfig(const Vita49OutputConfig &config)
Builds the static VITA metadata section from runtime output configuration.
std::string outputFileMetadataToJsonString(const OutputFileMetadata &metadata)
Serializes one output-file metadata entry to JSON.
std::string outputMetadataToJsonString(const OutputMetadata &metadata)
Serializes a full simulation output metadata snapshot to JSON.
uint64_t SimId
64-bit Unique Simulation ID.
Definition sim_id.h:18
math::Vec3 max
FMCW waveform metadata captured for a streaming output file.
RealType chirp_period
Chirp repetition period in seconds.
std::optional< std::uint64_t > chirp_count
Optional finite chirp count.
RealType chirp_rate
Frequency sweep rate in hertz per second.
RealType chirp_duration
Active chirp duration in seconds.
RealType chirp_bandwidth
Chirp bandwidth in hertz.
std::string chirp_direction
Frequency sweep direction token.
std::string waveform_shape
FMCW waveform shape token: linear or triangle.
std::optional< std::uint64_t > triangle_count
Optional finite triangle count.
RealType start_frequency_offset
Start frequency offset relative to carrier in hertz.
std::optional< RealType > triangle_period
Full triangle period in seconds.
RealType chirp_rate_signed
Signed frequency sweep rate in hertz per second.
Metadata for one FMCW illuminator represented in a streaming output file.
std::vector< FmcwSourceSegmentMetadata > segments
Active transmitter segments.
FmcwMetadata waveform
FMCW chirp parameters.
SimId transmitter_id
FMCW transmitter SimId.
std::string transmitter_name
FMCW transmitter display name.
SimId waveform_id
FMCW waveform SimId.
std::string waveform_name
FMCW waveform display name.
RealType carrier_frequency
Waveform carrier frequency in hertz.
Metadata for one active FMCW transmitter schedule segment.
std::optional< std::uint64_t > emitted_chirp_count
Number of chirps emitted in the segment.
std::optional< std::uint64_t > emitted_triangle_count
Number of triangles emitted.
RealType start_time
Transmitter segment start time in seconds.
RealType end_time
Transmitter segment end time in seconds.
std::optional< RealType > first_triangle_start_time
First emitted triangle start in the segment.
std::optional< RealType > first_chirp_start_time
First emitted chirp start in the segment.
Metadata for one receiver output file.
std::vector< FmcwSourceMetadata > fmcw_sources
FMCW illuminators represented in the output.
std::uint64_t max_pulse_length_samples
Maximum pulse length in samples.
std::optional< RealType > fmcw_if_noise_variance
Post-resampling complex noise variance.
std::optional< RealType > fmcw_if_requested_sample_rate
Requested IF ADC rate in hertz.
std::uint64_t total_samples
Total sample count written to the file.
std::string path
Filesystem path to the generated output file.
RealType sampling_rate
Sample rate for this output file in hertz.
std::vector< PulseChunkMetadata > chunks
Pulsed output chunks written to the file.
std::optional< RealType > fmcw_if_timing_error_seconds
Estimated timing error.
std::optional< std::string > fmcw_dechirp_reference_transmitter_name
LO transmitter name.
SimId receiver_id
Receiver SimId that owns the output file.
std::uint64_t sample_start
Inclusive global sample index for the file start.
std::string fmcw_dechirp_mode
Receiver dechirp mode for FMCW streaming outputs.
std::optional< FmcwMetadata > fmcw
Optional FMCW metadata for streaming outputs.
std::uint64_t sample_end_exclusive
Exclusive global sample index for the file end.
std::uint64_t pulse_count
Number of pulses represented in the file.
bool fmcw_if_legacy_full_rate
True for legacy full-rate dechirped IF output.
std::optional< std::uint64_t > fmcw_if_compensated_integer_delay_samples
Integer output-delay compensation.
std::optional< RealType > fmcw_if_decimation_factor
Input/output sample-rate ratio.
std::optional< RealType > fmcw_if_sample_rate
Realized IF output sample rate in hertz.
std::optional< RealType > fmcw_if_compensated_fractional_delay_samples
Fractional output-delay compensation.
std::uint64_t min_pulse_length_samples
Minimum pulse length in samples.
std::optional< FmcwMetadata > fmcw_dechirp_reference_waveform
Custom LO waveform parameters.
std::optional< RealType > fmcw_if_input_sample_rate
Input simulation sample rate in hertz.
std::string receiver_name
Receiver display name.
std::optional< SimId > fmcw_dechirp_reference_transmitter_id
Referenced LO transmitter ID.
std::optional< RealType > fmcw_if_filter_bandwidth
One-sided IF passband in hertz.
std::string mode
Output mode label, such as pulsed or streaming.
std::optional< RealType > fmcw_if_filter_stopband
IF stopband attenuation in dB.
std::optional< RealType > fmcw_if_phase_error_radians
Estimated IF edge phase error.
std::optional< unsigned > fmcw_if_resample_numerator
Reduced rational P.
std::optional< std::uint64_t > fmcw_if_warmup_discard_samples
Startup outputs discarded by the sink.
bool fmcw_if_decimation_enabled
True when IF-rate resampling is used.
bool fmcw_if_group_delay_compensated
True when IF output timestamps are aligned to t_start.
std::vector< StreamingSegmentMetadata > streaming_segments
Streaming segments written to the file.
std::optional< RealType > fmcw_if_filter_transition_width
IF transition width in hertz.
std::optional< RealType > fmcw_if_filter_group_delay_seconds
Total filter delay.
std::optional< std::string > fmcw_dechirp_reference_waveform_name
Custom LO waveform name.
std::string fmcw_dechirp_reference_source
Receiver dechirp reference source.
std::optional< unsigned > fmcw_if_phase_refinement
Polyphase refinement factor.
std::optional< unsigned > fmcw_if_resample_denominator
Reduced rational Q.
std::optional< SimId > fmcw_dechirp_reference_waveform_id
Custom LO waveform ID.
bool uniform_pulse_length
True when every pulse has the same sample length.
Metadata summary for the full simulation output set.
RealType sampling_rate
Output sampling rate in hertz.
RealType end_time
Simulation end time in seconds.
std::vector< OutputFileMetadata > files
Metadata for each generated output file.
std::optional< Vita49OutputMetadata > vita49
Optional VITA 49.2 output metadata.
RealType start_time
Simulation start time in seconds.
unsigned oversample_ratio
Oversampling ratio used during rendering.
unsigned schema_version
Metadata schema version.
std::string output_directory
Directory containing generated output files.
std::string simulation_name
Simulation name from the loaded scenario.
Metadata for one pulsed output chunk written to HDF5.
std::string i_dataset
HDF5 dataset path containing the in-phase samples.
std::uint64_t sample_end_exclusive
Exclusive global sample index for the chunk end.
RealType start_time
Simulation time of the first sample in seconds.
std::string q_dataset
HDF5 dataset path containing the quadrature samples.
std::uint64_t sample_count
Number of samples in the chunk.
std::uint64_t sample_start
Inclusive global sample index for the chunk start.
unsigned chunk_index
Zero-based chunk index in the receiver output sequence.
Metadata for one contiguous streaming output segment.
RealType start_time
Segment start time in seconds.
std::optional< std::uint64_t > emitted_chirp_count
Number of FMCW chirps emitted.
std::optional< RealType > first_chirp_start_time
First emitted FMCW chirp start time.
std::uint64_t sample_start
Inclusive global sample index for the segment start.
std::uint64_t sample_count
Number of samples emitted for the segment.
std::uint64_t sample_end_exclusive
Exclusive global sample index for the segment end.
std::optional< RealType > first_triangle_start_time
First emitted FMCW triangle start time.
std::optional< std::uint64_t > emitted_triangle_count
Number of FMCW triangles emitted.
RealType end_time
Segment end time in seconds.
Metadata for the VITA 49.2 UDP output backend.
std::optional< std::uint64_t > epoch_unix_nanoseconds
Run epoch, if already fixed.
std::string class_id
Internal placeholder VRT Class ID.
std::uint16_t max_udp_payload
Maximum UDP datagram payload in bytes.
std::vector< Vita49StreamMetadata > streams
Per-receiver VRT stream metadata and stats.
std::string endpoint_host
Destination host.
RealType adc_fullscale
Fixed ADC full-scale used for int16 IQ scaling.
std::uint32_t queue_depth
Bounded blocking sender queue depth in packets.
std::uint16_t endpoint_port
Destination UDP port.
Metadata for one VITA 49.2 receiver stream.
std::optional< RealType > end_sample_time
Exclusive stream end sample time in seconds.
std::optional< Vita49Timestamp > first_timestamp
First VRT UTC timestamp.
std::uint64_t over_range_count
Samples clipped by fixed full-scale scaling.
std::string mode
Receiver mode token: pulsed, cw, fmcw, or unknown.
std::uint64_t packets_dropped
Data packets lost to socket send failures.
std::uint64_t samples_emitted
Complex samples emitted.
RealType sample_rate
Stream sample rate in hertz.
RealType reference_frequency
RF reference frequency in hertz.
std::optional< RealType > first_sample_time
First signal sample time in seconds.
std::uint64_t context_packet_count
Context packets emitted for this stream.
std::uint64_t packets_emitted
Signal data packets emitted.
std::string receiver_name
Receiver display name.
std::uint64_t samples_dropped
Complex samples lost to socket send failures.
std::uint64_t late_packet_count
Packets sent after their scheduled time.
std::uint32_t stream_id
Allocated 32-bit VRT Stream ID.
std::optional< Vita49Timestamp > end_timestamp
Exclusive stream end VRT UTC timestamp.
SimId receiver_id
Receiver SimId that owns the VRT stream.