new
This commit is contained in:
81
rfg_adc_plotter/processing/calibration.py
Normal file
81
rfg_adc_plotter/processing/calibration.py
Normal file
@ -0,0 +1,81 @@
|
||||
"""Frequency-axis calibration helpers."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, Mapping
|
||||
|
||||
import numpy as np
|
||||
|
||||
from rfg_adc_plotter.constants import SWEEP_FREQ_MAX_GHZ, SWEEP_FREQ_MIN_GHZ
|
||||
from rfg_adc_plotter.types import SweepData
|
||||
|
||||
|
||||
def recalculate_calibration_c(
|
||||
base_coeffs: np.ndarray,
|
||||
f_min: float = SWEEP_FREQ_MIN_GHZ,
|
||||
f_max: float = SWEEP_FREQ_MAX_GHZ,
|
||||
) -> np.ndarray:
|
||||
"""Recalculate coefficients while preserving sweep edges."""
|
||||
coeffs = np.asarray(base_coeffs, dtype=np.float64).reshape(-1)
|
||||
if coeffs.size < 3:
|
||||
out = np.zeros((3,), dtype=np.float64)
|
||||
out[: coeffs.size] = coeffs
|
||||
coeffs = out
|
||||
c0, c1, c2 = float(coeffs[0]), float(coeffs[1]), float(coeffs[2])
|
||||
x0 = float(f_min)
|
||||
x1 = float(f_max)
|
||||
y0 = c0 + c1 * x0 + c2 * (x0 ** 2)
|
||||
y1 = c0 + c1 * x1 + c2 * (x1 ** 2)
|
||||
if not (np.isfinite(y0) and np.isfinite(y1)) or y1 == y0:
|
||||
return np.asarray([c0, c1, c2], dtype=np.float64)
|
||||
scale = (x1 - x0) / (y1 - y0)
|
||||
shift = x0 - scale * y0
|
||||
return np.asarray(
|
||||
[
|
||||
shift + scale * c0,
|
||||
scale * c1,
|
||||
scale * c2,
|
||||
],
|
||||
dtype=np.float64,
|
||||
)
|
||||
|
||||
|
||||
CALIBRATION_C_BASE = np.asarray([0.0, 1.0, 0.025], dtype=np.float64)
|
||||
CALIBRATION_C = recalculate_calibration_c(CALIBRATION_C_BASE)
|
||||
|
||||
|
||||
def get_calibration_base() -> np.ndarray:
|
||||
return np.asarray(CALIBRATION_C_BASE, dtype=np.float64).copy()
|
||||
|
||||
|
||||
def get_calibration_coeffs() -> np.ndarray:
|
||||
return np.asarray(CALIBRATION_C, dtype=np.float64).copy()
|
||||
|
||||
|
||||
def set_calibration_base_value(index: int, value: float) -> np.ndarray:
|
||||
"""Update one base coefficient and recalculate the working coefficients."""
|
||||
global CALIBRATION_C
|
||||
CALIBRATION_C_BASE[int(index)] = float(value)
|
||||
CALIBRATION_C = recalculate_calibration_c(CALIBRATION_C_BASE)
|
||||
return get_calibration_coeffs()
|
||||
|
||||
|
||||
def calibrate_freqs(sweep: Mapping[str, Any]) -> SweepData:
|
||||
"""Return a sweep copy with calibrated and resampled frequency axis."""
|
||||
freqs = np.asarray(sweep["F"], dtype=np.float64).copy()
|
||||
values = np.asarray(sweep["I"], dtype=np.float64).copy()
|
||||
coeffs = np.asarray(CALIBRATION_C, dtype=np.float64)
|
||||
if freqs.size > 0:
|
||||
freqs = coeffs[0] + coeffs[1] * freqs + coeffs[2] * (freqs * freqs)
|
||||
|
||||
if freqs.size >= 2:
|
||||
freqs_cal = np.linspace(float(freqs[0]), float(freqs[-1]), freqs.size, dtype=np.float64)
|
||||
values_cal = np.interp(freqs_cal, freqs, values).astype(np.float64)
|
||||
else:
|
||||
freqs_cal = freqs.copy()
|
||||
values_cal = values.copy()
|
||||
|
||||
return {
|
||||
"F": freqs_cal,
|
||||
"I": values_cal,
|
||||
}
|
||||
Reference in New Issue
Block a user