Refactor radar system
This commit is contained in:
+3
@@ -16,6 +16,9 @@ struct ChannelTrace {
|
||||
std::vector<ipc::Complex32> samples{};
|
||||
};
|
||||
|
||||
void validate_channel_trace_layout(const ChannelTrace& trace, const std::string& label, const ipc::ComboKey& combo);
|
||||
[[nodiscard]] auto frequency_axes_match(std::span<const float> left, std::span<const float> right) -> bool;
|
||||
|
||||
class S21CalibrationBundle {
|
||||
public:
|
||||
void load(const std::string& path);
|
||||
|
||||
+23
-10
@@ -12,6 +12,7 @@
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "calibrator_interface.hpp"
|
||||
@@ -59,6 +60,8 @@ void validate_raw_trace_layout(const ipc::SweepTraceBlock& trace, const std::str
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void validate_channel_trace_layout(
|
||||
const ChannelTrace& trace,
|
||||
const std::string& trace_label,
|
||||
@@ -69,6 +72,12 @@ void validate_channel_trace_layout(
|
||||
trace_label + " frequency/channel vector size mismatch for combo " + combo_to_string(combo)
|
||||
);
|
||||
}
|
||||
for (std::size_t i = 0; i < trace.samples.size(); ++i) {
|
||||
if (!std::isfinite(trace.frequency_hz[i]) || !std::isfinite(trace.samples[i].re)
|
||||
|| !std::isfinite(trace.samples[i].im)) {
|
||||
throw std::runtime_error(trace_label + " contains non-finite values for combo " + combo_to_string(combo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] auto frequency_axes_match(std::span<const float> left, std::span<const float> right) -> bool {
|
||||
@@ -77,6 +86,9 @@ void validate_channel_trace_layout(
|
||||
}
|
||||
|
||||
for (std::size_t index = 0; index < left.size(); ++index) {
|
||||
if (!std::isfinite(left[index]) || !std::isfinite(right[index])) {
|
||||
return false;
|
||||
}
|
||||
const auto delta = std::fabs(left[index] - right[index]);
|
||||
const auto scale = std::max(std::fabs(left[index]), std::fabs(right[index]));
|
||||
const auto tolerance = std::max(kFrequencyAbsoluteTolerance, scale * kFrequencyRelativeTolerance);
|
||||
@@ -87,6 +99,8 @@ void validate_channel_trace_layout(
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void ensure_frequency_axis_match(
|
||||
std::span<const float> expected,
|
||||
std::span<const float> actual,
|
||||
@@ -122,6 +136,9 @@ void ensure_frequency_axis_match(
|
||||
const std::string& bundle_label
|
||||
) -> ChannelTrace {
|
||||
validate_raw_trace_layout(trace, bundle_label + " trace");
|
||||
if (trace.frequency_hz.empty()) {
|
||||
throw std::runtime_error(bundle_label + " trace contains no frequency samples");
|
||||
}
|
||||
|
||||
ChannelTrace channel_trace{};
|
||||
channel_trace.frequency_hz = trace.frequency_hz;
|
||||
@@ -275,8 +292,6 @@ void ensure_combo_coverage(
|
||||
} // namespace
|
||||
|
||||
void S21CalibrationBundle::load(const std::string& path) {
|
||||
traces_by_combo_.clear();
|
||||
|
||||
if (path.empty()) {
|
||||
throw std::runtime_error("S21 calibration bundle path must not be empty");
|
||||
}
|
||||
@@ -311,8 +326,6 @@ auto S21CalibrationBundle::resolve(const ipc::ComboKey& combo) const -> const Ch
|
||||
}
|
||||
|
||||
void S21ReferenceBundle::load(const std::string& path) {
|
||||
traces_by_combo_.clear();
|
||||
|
||||
if (path.empty()) {
|
||||
throw std::runtime_error("S21 reference bundle path must not be empty");
|
||||
}
|
||||
@@ -337,9 +350,8 @@ void S11CalibrationBundle::load(
|
||||
const std::string& short_path,
|
||||
const std::string& load_path
|
||||
) {
|
||||
coefficients_by_combo_.clear();
|
||||
|
||||
if (open_path.empty() && short_path.empty() && load_path.empty()) {
|
||||
coefficients_by_combo_.clear();
|
||||
// #38: S11 calibration disabled because no OSL paths were provided; surface it instead of silently skipping.
|
||||
std::cerr << "S11 calibration: no open/short/load bundle paths provided; reflection correction disabled\n";
|
||||
return;
|
||||
@@ -357,13 +369,15 @@ void S11CalibrationBundle::load(
|
||||
ensure_combo_coverage(short_traces, open_traces, "S11 short calibration", "S11 open calibration");
|
||||
ensure_combo_coverage(load_traces, open_traces, "S11 load calibration", "S11 open calibration");
|
||||
|
||||
coefficients_by_combo_.reserve(open_traces.size());
|
||||
decltype(coefficients_by_combo_) coefficients;
|
||||
coefficients.reserve(open_traces.size());
|
||||
for (const auto& [combo, open_trace] : open_traces) {
|
||||
coefficients_by_combo_.insert_or_assign(
|
||||
coefficients.insert_or_assign(
|
||||
combo,
|
||||
solve_osl_coefficients(combo, open_trace, short_traces.at(combo), load_traces.at(combo))
|
||||
);
|
||||
}
|
||||
coefficients_by_combo_ = std::move(coefficients);
|
||||
}
|
||||
|
||||
auto S11CalibrationBundle::is_enabled() const noexcept -> bool {
|
||||
@@ -422,9 +436,8 @@ auto S11CalibrationBundle::resolve(const ipc::ComboKey& combo) const -> const Co
|
||||
}
|
||||
|
||||
void S11ReferenceBundle::load(const std::string& path) {
|
||||
traces_by_combo_.clear();
|
||||
|
||||
if (path.empty()) {
|
||||
traces_by_combo_.clear();
|
||||
// #38: S11 reference disabled because no path was provided; surface it instead of silently skipping.
|
||||
std::cerr << "S11 reference: no bundle path provided; reference normalization disabled\n";
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user