added white theme, some features to processing and saving

This commit is contained in:
Ayzen
2026-04-13 10:44:01 +03:00
parent 61685d7a4d
commit 5d2f95f959
20 changed files with 295 additions and 48 deletions
@@ -94,10 +94,23 @@ struct S11PreprocessConfig {
PreprocessAssetConfig reference{};
};
struct PreprocessNotchBandConfig {
float low_hz = 0.0F;
float high_hz = 0.0F;
};
struct PreprocessNotchConfig {
bool enabled = false;
std::vector<PreprocessNotchBandConfig> bands_hz{};
float taper_width_hz = 40'000'000.0F;
std::string taper_type = "cosine";
};
struct PreprocessConfig {
// Channel-specific preprocessing assets selected by Python GUI layer.
S21PreprocessConfig s21{};
S11PreprocessConfig s11{};
PreprocessNotchConfig notch{};
};
struct GprTxGeometry {
@@ -154,6 +154,46 @@ using Json = nlohmann::json;
return asset;
}
[[nodiscard]] auto parse_preprocess_notch(
const Json& object,
const std::string& context
) -> PreprocessNotchConfig {
PreprocessNotchConfig notch{};
notch.enabled = optional_bool(object, "enabled", false);
notch.taper_width_hz = optional_f32(object, "taper_width_hz", 40'000'000.0F);
notch.taper_type = optional_string(object, "taper_type", "cosine");
if (const auto* bands_value = optional_field(object, "bands_hz"); bands_value != nullptr) {
const auto* bands_array = as_array(*bands_value, context + ".bands_hz");
notch.bands_hz.reserve(bands_array->size());
for (const auto& band_value : *bands_array) {
const auto* band_array = as_array(band_value, context + ".bands_hz[]");
if (band_array->size() != 2U) {
throw std::runtime_error(context + ".bands_hz[] must contain exactly two numbers");
}
PreprocessNotchBandConfig band{};
band.low_hz = static_cast<float>(as_number((*band_array)[0], context + ".bands_hz[][0]"));
band.high_hz = static_cast<float>(as_number((*band_array)[1], context + ".bands_hz[][1]"));
notch.bands_hz.push_back(band);
}
}
if (notch.taper_width_hz < 0.0F) {
throw std::runtime_error(context + ".taper_width_hz must be >= 0");
}
if (notch.taper_type != "cosine" && notch.taper_type != "hard") {
throw std::runtime_error(context + ".taper_type must be 'cosine' or 'hard'");
}
for (const auto& band : notch.bands_hz) {
if (band.high_hz < band.low_hz) {
throw std::runtime_error(context + ".bands_hz[] high_hz must be >= low_hz");
}
}
return notch;
}
[[nodiscard]] auto parse_driver_mode(const std::string& value) -> DriverMode {
if (value == "mock") {
return DriverMode::Mock;
@@ -466,6 +506,10 @@ auto load_run_config(const std::string& path) -> RunConfig {
config.preprocess.s11.calibration.load =
parse_preprocess_asset(*s11_calibration_obj, "load", "preprocess.s11.calibration");
config.preprocess.s11.reference = parse_preprocess_asset(*s11_obj, "reference", "preprocess.s11");
if (const auto* notch_value = optional_field(*preprocess_obj, "notch"); notch_value != nullptr) {
config.preprocess.notch = parse_preprocess_notch(*as_object(*notch_value, "preprocess.notch"), "preprocess.notch");
}
}
if (const auto* gpr_value = optional_field(*root_obj, "gpr"); gpr_value != nullptr) {