voltage range
This commit is contained in:
@ -74,7 +74,17 @@ def build_parser() -> argparse.ArgumentParser:
|
|||||||
"8-байтный бинарный протокол: либо legacy старт "
|
"8-байтный бинарный протокол: либо legacy старт "
|
||||||
"0xFFFF,0xFFFF,0xFFFF,(CH<<8)|0x0A и точки step,uint32(hi16,lo16),0x000A, "
|
"0xFFFF,0xFFFF,0xFFFF,(CH<<8)|0x0A и точки step,uint32(hi16,lo16),0x000A, "
|
||||||
"либо tty CH1/CH2 поток из kamil_adc в формате 0x000A,step,ch1_i16,ch2_i16. "
|
"либо tty CH1/CH2 поток из kamil_adc в формате 0x000A,step,ch1_i16,ch2_i16. "
|
||||||
"Для tty CH1/CH2: сырая кривая = ch1^2+ch2^2, FFT вход = ch1+i*ch2"
|
"Для tty CH1/CH2: после парсинга int16 переводятся в В, "
|
||||||
|
"сырая кривая = ch1^2+ch2^2 (В^2), FFT вход = ch1+i*ch2 (В)"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--tty-range-v",
|
||||||
|
type=float,
|
||||||
|
default=5.0,
|
||||||
|
help=(
|
||||||
|
"Полный диапазон для пересчета tty int16 в напряжение ±V "
|
||||||
|
"(только для --bin CH1/CH2, по умолчанию 5.0)"
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
|
|||||||
@ -61,6 +61,10 @@ DEFAULT_MAIN_WINDOW_WIDTH = 1200
|
|||||||
DEFAULT_MAIN_WINDOW_HEIGHT = 680
|
DEFAULT_MAIN_WINDOW_HEIGHT = 680
|
||||||
MIN_MAIN_WINDOW_WIDTH = 640
|
MIN_MAIN_WINDOW_WIDTH = 640
|
||||||
MIN_MAIN_WINDOW_HEIGHT = 420
|
MIN_MAIN_WINDOW_HEIGHT = 420
|
||||||
|
TTY_CODE_SCALE_DENOM = 32767.0
|
||||||
|
TTY_RANGE_DEFAULT_V = 5.0
|
||||||
|
TTY_RANGE_MIN_V = 1e-6
|
||||||
|
TTY_RANGE_MAX_V = 1_000_000.0
|
||||||
|
|
||||||
|
|
||||||
def sanitize_curve_data_for_display(
|
def sanitize_curve_data_for_display(
|
||||||
@ -489,6 +493,28 @@ def compute_aux_phase_curve(aux_curves: SweepAuxCurves) -> Optional[np.ndarray]:
|
|||||||
return phase
|
return phase
|
||||||
|
|
||||||
|
|
||||||
|
def sanitize_tty_voltage_range(range_v: float, default: float = TTY_RANGE_DEFAULT_V) -> float:
|
||||||
|
"""Return a finite positive full-scale voltage range for tty int16 conversion."""
|
||||||
|
try:
|
||||||
|
value = float(range_v)
|
||||||
|
except Exception:
|
||||||
|
value = float(default)
|
||||||
|
if not np.isfinite(value):
|
||||||
|
value = float(default)
|
||||||
|
return float(np.clip(abs(value), TTY_RANGE_MIN_V, TTY_RANGE_MAX_V))
|
||||||
|
|
||||||
|
|
||||||
|
def convert_tty_i16_to_voltage(codes: np.ndarray, range_v: float) -> np.ndarray:
|
||||||
|
"""Convert signed tty int16 code array to clipped voltage values in ``[-range_v, +range_v]``."""
|
||||||
|
code_arr = np.asarray(codes, dtype=np.float32).reshape(-1)
|
||||||
|
if code_arr.size <= 0:
|
||||||
|
return np.zeros((0,), dtype=np.float32)
|
||||||
|
range_abs_v = sanitize_tty_voltage_range(range_v)
|
||||||
|
scale_v = range_abs_v / float(TTY_CODE_SCALE_DENOM)
|
||||||
|
volt = code_arr * np.float32(scale_v)
|
||||||
|
return np.clip(volt, -range_abs_v, range_abs_v).astype(np.float32, copy=False)
|
||||||
|
|
||||||
|
|
||||||
def decimate_curve_for_display(
|
def decimate_curve_for_display(
|
||||||
xs: Optional[np.ndarray],
|
xs: Optional[np.ndarray],
|
||||||
ys: Optional[np.ndarray],
|
ys: Optional[np.ndarray],
|
||||||
@ -606,6 +632,7 @@ def run_pyqtgraph(args) -> None:
|
|||||||
peak_calibrate_mode = bool(getattr(args, "calibrate", False))
|
peak_calibrate_mode = bool(getattr(args, "calibrate", False))
|
||||||
peak_search_enabled = bool(getattr(args, "peak_search", False))
|
peak_search_enabled = bool(getattr(args, "peak_search", False))
|
||||||
bin_mode = bool(getattr(args, "bin_mode", False))
|
bin_mode = bool(getattr(args, "bin_mode", False))
|
||||||
|
tty_range_v = sanitize_tty_voltage_range(getattr(args, "tty_range_v", TTY_RANGE_DEFAULT_V))
|
||||||
complex_ascii_mode = bool(getattr(args, "parser_complex_ascii", False))
|
complex_ascii_mode = bool(getattr(args, "parser_complex_ascii", False))
|
||||||
complex_sweep_mode = bool(
|
complex_sweep_mode = bool(
|
||||||
bin_mode
|
bin_mode
|
||||||
@ -695,7 +722,7 @@ def run_pyqtgraph(args) -> None:
|
|||||||
p_line_aux_vb = pg.ViewBox()
|
p_line_aux_vb = pg.ViewBox()
|
||||||
try:
|
try:
|
||||||
p_line.showAxis("right")
|
p_line.showAxis("right")
|
||||||
p_line.getAxis("right").setLabel("CH1/CH2")
|
p_line.getAxis("right").setLabel("CH1/CH2, В")
|
||||||
p_line.scene().addItem(p_line_aux_vb)
|
p_line.scene().addItem(p_line_aux_vb)
|
||||||
p_line.getAxis("right").linkToView(p_line_aux_vb)
|
p_line.getAxis("right").linkToView(p_line_aux_vb)
|
||||||
p_line_aux_vb.setXLink(p_line)
|
p_line_aux_vb.setXLink(p_line)
|
||||||
@ -718,7 +745,7 @@ def run_pyqtgraph(args) -> None:
|
|||||||
p_line.setLabel("left", "Y")
|
p_line.setLabel("left", "Y")
|
||||||
if bin_iq_power_mode:
|
if bin_iq_power_mode:
|
||||||
try:
|
try:
|
||||||
p_line.setLabel("left", "CH1^2 + CH2^2")
|
p_line.setLabel("left", "CH1^2 + CH2^2, В^2")
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
ch_text = pg.TextItem("", anchor=(1, 1))
|
ch_text = pg.TextItem("", anchor=(1, 1))
|
||||||
@ -790,7 +817,7 @@ def run_pyqtgraph(args) -> None:
|
|||||||
try:
|
try:
|
||||||
if bin_iq_power_mode:
|
if bin_iq_power_mode:
|
||||||
p_fft.setTitle("FFT: CH1 + i*CH2")
|
p_fft.setTitle("FFT: CH1 + i*CH2")
|
||||||
p_line.setTitle("Сырые CH1/CH2 и CH1^2 + CH2^2")
|
p_line.setTitle("Сырые CH1/CH2 (В) и CH1^2 + CH2^2 (В^2)")
|
||||||
else:
|
else:
|
||||||
p_fft.setTitle("FFT: Re / Im / Abs")
|
p_fft.setTitle("FFT: Re / Im / Abs")
|
||||||
p_line.setTitle("Сырые данные до FFT")
|
p_line.setTitle("Сырые данные до FFT")
|
||||||
@ -820,7 +847,7 @@ def run_pyqtgraph(args) -> None:
|
|||||||
curve_complex_calib_real = p_complex_calib.plot(pen=pg.mkPen((80, 120, 255), width=1))
|
curve_complex_calib_real = p_complex_calib.plot(pen=pg.mkPen((80, 120, 255), width=1))
|
||||||
curve_complex_calib_imag = p_complex_calib.plot(pen=pg.mkPen((120, 200, 120), width=1))
|
curve_complex_calib_imag = p_complex_calib.plot(pen=pg.mkPen((120, 200, 120), width=1))
|
||||||
p_complex_calib.setLabel("bottom", "ГГц")
|
p_complex_calib.setLabel("bottom", "ГГц")
|
||||||
p_complex_calib.setLabel("left", "Амплитуда")
|
p_complex_calib.setLabel("left", "В" if bin_iq_power_mode else "Амплитуда")
|
||||||
try:
|
try:
|
||||||
p_complex_calib.setXLink(p_line)
|
p_complex_calib.setXLink(p_line)
|
||||||
p_complex_calib.setVisible(bool(complex_sweep_mode))
|
p_complex_calib.setVisible(bool(complex_sweep_mode))
|
||||||
@ -945,10 +972,28 @@ def run_pyqtgraph(args) -> None:
|
|||||||
background_buttons_row.addWidget(background_save_btn)
|
background_buttons_row.addWidget(background_save_btn)
|
||||||
background_buttons_row.addWidget(background_load_btn)
|
background_buttons_row.addWidget(background_load_btn)
|
||||||
background_group_layout.addLayout(background_buttons_row)
|
background_group_layout.addLayout(background_buttons_row)
|
||||||
|
tty_range_group = QtWidgets.QGroupBox("TTY диапазон")
|
||||||
|
tty_range_layout = QtWidgets.QFormLayout(tty_range_group)
|
||||||
|
tty_range_layout.setContentsMargins(6, 6, 6, 6)
|
||||||
|
tty_range_layout.setSpacing(6)
|
||||||
|
tty_range_spin = QtWidgets.QDoubleSpinBox()
|
||||||
|
tty_range_spin.setDecimals(6)
|
||||||
|
tty_range_spin.setRange(TTY_RANGE_MIN_V, TTY_RANGE_MAX_V)
|
||||||
|
tty_range_spin.setSingleStep(0.1)
|
||||||
|
try:
|
||||||
|
tty_range_spin.setSuffix(" V")
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
tty_range_spin.setValue(tty_range_v)
|
||||||
|
tty_range_layout.addRow("±V", tty_range_spin)
|
||||||
|
try:
|
||||||
|
tty_range_group.setEnabled(bool(bin_iq_power_mode))
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
parsed_data_cb = QtWidgets.QCheckBox("данные после парсинга")
|
parsed_data_cb = QtWidgets.QCheckBox("данные после парсинга")
|
||||||
if complex_sweep_mode:
|
if complex_sweep_mode:
|
||||||
try:
|
try:
|
||||||
parsed_data_cb.setText("Сырые CH1/CH2" if bin_iq_power_mode else "Сырые Re/Im")
|
parsed_data_cb.setText("Сырые CH1/CH2 (В)" if bin_iq_power_mode else "Сырые Re/Im")
|
||||||
parsed_data_cb.setChecked(True)
|
parsed_data_cb.setChecked(True)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
@ -978,6 +1023,7 @@ def run_pyqtgraph(args) -> None:
|
|||||||
settings_layout.addWidget(range_group)
|
settings_layout.addWidget(range_group)
|
||||||
settings_layout.addWidget(calib_group)
|
settings_layout.addWidget(calib_group)
|
||||||
settings_layout.addWidget(complex_calib_group)
|
settings_layout.addWidget(complex_calib_group)
|
||||||
|
settings_layout.addWidget(tty_range_group)
|
||||||
settings_layout.addWidget(parsed_data_cb)
|
settings_layout.addWidget(parsed_data_cb)
|
||||||
settings_layout.addWidget(background_group)
|
settings_layout.addWidget(background_group)
|
||||||
settings_layout.addWidget(fft_mode_label)
|
settings_layout.addWidget(fft_mode_label)
|
||||||
@ -1005,6 +1051,7 @@ def run_pyqtgraph(args) -> None:
|
|||||||
status_dirty = True
|
status_dirty = True
|
||||||
calibration_toggle_in_progress = False
|
calibration_toggle_in_progress = False
|
||||||
range_change_in_progress = False
|
range_change_in_progress = False
|
||||||
|
tty_range_change_in_progress = False
|
||||||
debug_event_counts: Dict[str, int] = {}
|
debug_event_counts: Dict[str, int] = {}
|
||||||
last_queue_backlog = 0
|
last_queue_backlog = 0
|
||||||
last_backlog_skipped = 0
|
last_backlog_skipped = 0
|
||||||
@ -1164,6 +1211,27 @@ def run_pyqtgraph(args) -> None:
|
|||||||
path = ""
|
path = ""
|
||||||
return path or "fft_background.npy"
|
return path or "fft_background.npy"
|
||||||
|
|
||||||
|
def rebuild_tty_voltage_curves_from_codes() -> bool:
|
||||||
|
if (not bin_iq_power_mode) or runtime.full_current_aux_curves_codes is None:
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
code_1, code_2 = runtime.full_current_aux_curves_codes
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
code_1_arr = np.asarray(code_1, dtype=np.float32).reshape(-1)
|
||||||
|
code_2_arr = np.asarray(code_2, dtype=np.float32).reshape(-1)
|
||||||
|
width = min(code_1_arr.size, code_2_arr.size)
|
||||||
|
if width <= 0:
|
||||||
|
return False
|
||||||
|
ch_1_v = convert_tty_i16_to_voltage(code_1_arr[:width], tty_range_v)
|
||||||
|
ch_2_v = convert_tty_i16_to_voltage(code_2_arr[:width], tty_range_v)
|
||||||
|
runtime.full_current_aux_curves = (ch_1_v, ch_2_v)
|
||||||
|
runtime.full_current_fft_source = ch_1_v.astype(np.complex64) + (1j * ch_2_v.astype(np.complex64))
|
||||||
|
ch_1_v_f64 = ch_1_v.astype(np.float64, copy=False)
|
||||||
|
ch_2_v_f64 = ch_2_v.astype(np.float64, copy=False)
|
||||||
|
runtime.full_current_sweep_raw = np.asarray((ch_1_v_f64 * ch_1_v_f64) + (ch_2_v_f64 * ch_2_v_f64), dtype=np.float32)
|
||||||
|
return True
|
||||||
|
|
||||||
def reset_background_state(*, clear_profile: bool = True) -> None:
|
def reset_background_state(*, clear_profile: bool = True) -> None:
|
||||||
runtime.background_buffer.reset()
|
runtime.background_buffer.reset()
|
||||||
if clear_profile:
|
if clear_profile:
|
||||||
@ -1435,6 +1503,33 @@ def run_pyqtgraph(args) -> None:
|
|||||||
set_status_note(f"диапазон: {new_min:.6g}..{new_max:.6g} GHz")
|
set_status_note(f"диапазон: {new_min:.6g}..{new_max:.6g} GHz")
|
||||||
runtime.mark_dirty()
|
runtime.mark_dirty()
|
||||||
|
|
||||||
|
def set_tty_range() -> None:
|
||||||
|
nonlocal tty_range_v, tty_range_change_in_progress
|
||||||
|
if tty_range_change_in_progress:
|
||||||
|
return
|
||||||
|
if not bin_iq_power_mode:
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
requested_v = float(tty_range_spin.value())
|
||||||
|
except Exception:
|
||||||
|
requested_v = tty_range_v
|
||||||
|
new_range_v = sanitize_tty_voltage_range(requested_v, default=tty_range_v)
|
||||||
|
if np.isclose(new_range_v, tty_range_v, rtol=0.0, atol=1e-12):
|
||||||
|
return
|
||||||
|
tty_range_v = new_range_v
|
||||||
|
tty_range_change_in_progress = True
|
||||||
|
try:
|
||||||
|
tty_range_spin.setValue(tty_range_v)
|
||||||
|
finally:
|
||||||
|
tty_range_change_in_progress = False
|
||||||
|
if rebuild_tty_voltage_curves_from_codes():
|
||||||
|
reset_background_state(clear_profile=True)
|
||||||
|
refresh_current_window(push_to_ring=True, reset_ring=True)
|
||||||
|
set_status_note(f"tty диапазон: ±{tty_range_v:.6g} В")
|
||||||
|
else:
|
||||||
|
set_status_note(f"tty диапазон: ±{tty_range_v:.6g} В (ожидание данных)")
|
||||||
|
runtime.mark_dirty()
|
||||||
|
|
||||||
def pick_calib_file() -> None:
|
def pick_calib_file() -> None:
|
||||||
start_path = get_calib_file_path()
|
start_path = get_calib_file_path()
|
||||||
try:
|
try:
|
||||||
@ -1687,6 +1782,7 @@ def run_pyqtgraph(args) -> None:
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
restore_range_controls()
|
restore_range_controls()
|
||||||
|
set_tty_range()
|
||||||
set_calib_enabled()
|
set_calib_enabled()
|
||||||
set_complex_calib_enabled()
|
set_complex_calib_enabled()
|
||||||
set_parsed_data_enabled()
|
set_parsed_data_enabled()
|
||||||
@ -1698,6 +1794,7 @@ def run_pyqtgraph(args) -> None:
|
|||||||
try:
|
try:
|
||||||
range_min_spin.valueChanged.connect(lambda _v: set_working_range())
|
range_min_spin.valueChanged.connect(lambda _v: set_working_range())
|
||||||
range_max_spin.valueChanged.connect(lambda _v: set_working_range())
|
range_max_spin.valueChanged.connect(lambda _v: set_working_range())
|
||||||
|
tty_range_spin.valueChanged.connect(lambda _v: set_tty_range())
|
||||||
calib_cb.stateChanged.connect(lambda _v: set_calib_enabled())
|
calib_cb.stateChanged.connect(lambda _v: set_calib_enabled())
|
||||||
complex_calib_cb.stateChanged.connect(lambda _v: set_complex_calib_enabled())
|
complex_calib_cb.stateChanged.connect(lambda _v: set_complex_calib_enabled())
|
||||||
parsed_data_cb.stateChanged.connect(lambda _v: set_parsed_data_enabled())
|
parsed_data_cb.stateChanged.connect(lambda _v: set_parsed_data_enabled())
|
||||||
@ -1935,6 +2032,7 @@ def run_pyqtgraph(args) -> None:
|
|||||||
)
|
)
|
||||||
base_freqs = np.linspace(SWEEP_FREQ_MIN_GHZ, SWEEP_FREQ_MAX_GHZ, sweep.size, dtype=np.float64)
|
base_freqs = np.linspace(SWEEP_FREQ_MIN_GHZ, SWEEP_FREQ_MAX_GHZ, sweep.size, dtype=np.float64)
|
||||||
runtime.full_current_aux_curves = None
|
runtime.full_current_aux_curves = None
|
||||||
|
runtime.full_current_aux_curves_codes = None
|
||||||
runtime.full_current_fft_source = None
|
runtime.full_current_fft_source = None
|
||||||
if complex_sweep_mode and aux_curves is not None:
|
if complex_sweep_mode and aux_curves is not None:
|
||||||
try:
|
try:
|
||||||
@ -1944,21 +2042,20 @@ def run_pyqtgraph(args) -> None:
|
|||||||
runtime.full_current_freqs = np.asarray(calibrated_aux_1_payload["F"], dtype=np.float64)
|
runtime.full_current_freqs = np.asarray(calibrated_aux_1_payload["F"], dtype=np.float64)
|
||||||
calibrated_aux_1 = np.asarray(calibrated_aux_1_payload["I"], dtype=np.float32)
|
calibrated_aux_1 = np.asarray(calibrated_aux_1_payload["I"], dtype=np.float32)
|
||||||
calibrated_aux_2 = np.asarray(calibrated_aux_2, dtype=np.float32)
|
calibrated_aux_2 = np.asarray(calibrated_aux_2, dtype=np.float32)
|
||||||
|
if bin_iq_power_mode:
|
||||||
|
runtime.full_current_aux_curves_codes = (calibrated_aux_1, calibrated_aux_2)
|
||||||
|
if not rebuild_tty_voltage_curves_from_codes():
|
||||||
|
runtime.full_current_aux_curves = None
|
||||||
|
runtime.full_current_fft_source = None
|
||||||
|
else:
|
||||||
runtime.full_current_aux_curves = (calibrated_aux_1, calibrated_aux_2)
|
runtime.full_current_aux_curves = (calibrated_aux_1, calibrated_aux_2)
|
||||||
runtime.full_current_fft_source = (
|
runtime.full_current_fft_source = (
|
||||||
calibrated_aux_1.astype(np.complex64) + (1j * calibrated_aux_2.astype(np.complex64))
|
calibrated_aux_1.astype(np.complex64) + (1j * calibrated_aux_2.astype(np.complex64))
|
||||||
)
|
)
|
||||||
if bin_iq_power_mode:
|
|
||||||
aux_1_f64 = calibrated_aux_1.astype(np.float64, copy=False)
|
|
||||||
aux_2_f64 = calibrated_aux_2.astype(np.float64, copy=False)
|
|
||||||
runtime.full_current_sweep_raw = np.asarray(
|
|
||||||
(aux_1_f64 * aux_1_f64) + (aux_2_f64 * aux_2_f64),
|
|
||||||
dtype=np.float32,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
runtime.full_current_sweep_raw = np.abs(runtime.full_current_fft_source).astype(np.float32)
|
runtime.full_current_sweep_raw = np.abs(runtime.full_current_fft_source).astype(np.float32)
|
||||||
except Exception:
|
except Exception:
|
||||||
runtime.full_current_aux_curves = None
|
runtime.full_current_aux_curves = None
|
||||||
|
runtime.full_current_aux_curves_codes = None
|
||||||
runtime.full_current_fft_source = None
|
runtime.full_current_fft_source = None
|
||||||
|
|
||||||
if runtime.full_current_fft_source is None:
|
if runtime.full_current_fft_source is None:
|
||||||
@ -1976,12 +2073,16 @@ def run_pyqtgraph(args) -> None:
|
|||||||
aux_1, aux_2 = aux_curves
|
aux_1, aux_2 = aux_curves
|
||||||
calibrated_aux_1 = calibrate_freqs({"F": base_freqs, "I": aux_1})["I"]
|
calibrated_aux_1 = calibrate_freqs({"F": base_freqs, "I": aux_1})["I"]
|
||||||
calibrated_aux_2 = calibrate_freqs({"F": base_freqs, "I": aux_2})["I"]
|
calibrated_aux_2 = calibrate_freqs({"F": base_freqs, "I": aux_2})["I"]
|
||||||
runtime.full_current_aux_curves = (
|
calibrated_aux_1_arr = np.asarray(calibrated_aux_1, dtype=np.float32)
|
||||||
np.asarray(calibrated_aux_1, dtype=np.float32),
|
calibrated_aux_2_arr = np.asarray(calibrated_aux_2, dtype=np.float32)
|
||||||
np.asarray(calibrated_aux_2, dtype=np.float32),
|
if bin_iq_power_mode:
|
||||||
)
|
runtime.full_current_aux_curves_codes = (calibrated_aux_1_arr, calibrated_aux_2_arr)
|
||||||
|
rebuild_tty_voltage_curves_from_codes()
|
||||||
|
else:
|
||||||
|
runtime.full_current_aux_curves = (calibrated_aux_1_arr, calibrated_aux_2_arr)
|
||||||
except Exception:
|
except Exception:
|
||||||
runtime.full_current_aux_curves = None
|
runtime.full_current_aux_curves = None
|
||||||
|
runtime.full_current_aux_curves_codes = None
|
||||||
runtime.current_info = info
|
runtime.current_info = info
|
||||||
refresh_current_window(push_to_ring=True)
|
refresh_current_window(push_to_ring=True)
|
||||||
processed_frames += 1
|
processed_frames += 1
|
||||||
|
|||||||
@ -36,7 +36,7 @@ def tty_ch_pair_to_sweep(ch_1: int, ch_2: int) -> float:
|
|||||||
"""Reduce a raw CH1/CH2 TTY point to power-like scalar ``ch1^2 + ch2^2``."""
|
"""Reduce a raw CH1/CH2 TTY point to power-like scalar ``ch1^2 + ch2^2``."""
|
||||||
ch_1_i = int(ch_1)
|
ch_1_i = int(ch_1)
|
||||||
ch_2_i = int(ch_2)
|
ch_2_i = int(ch_2)
|
||||||
return float(((ch_1_i * ch_1_i) + (ch_2_i * ch_2_i))**0.5)
|
return float((ch_1_i * ch_1_i) + (ch_2_i * ch_2_i))
|
||||||
|
|
||||||
|
|
||||||
class AsciiSweepParser:
|
class AsciiSweepParser:
|
||||||
|
|||||||
@ -22,6 +22,7 @@ class RuntimeState:
|
|||||||
full_current_sweep_raw: Optional[np.ndarray] = None
|
full_current_sweep_raw: Optional[np.ndarray] = None
|
||||||
full_current_fft_source: Optional[np.ndarray] = None
|
full_current_fft_source: Optional[np.ndarray] = None
|
||||||
full_current_aux_curves: SweepAuxCurves = None
|
full_current_aux_curves: SweepAuxCurves = None
|
||||||
|
full_current_aux_curves_codes: SweepAuxCurves = None
|
||||||
current_freqs: Optional[np.ndarray] = None
|
current_freqs: Optional[np.ndarray] = None
|
||||||
current_distances: Optional[np.ndarray] = None
|
current_distances: Optional[np.ndarray] = None
|
||||||
current_sweep_raw: Optional[np.ndarray] = None
|
current_sweep_raw: Optional[np.ndarray] = None
|
||||||
|
|||||||
@ -26,10 +26,12 @@ class CliTests(unittest.TestCase):
|
|||||||
args = build_parser().parse_args(["/dev/null"])
|
args = build_parser().parse_args(["/dev/null"])
|
||||||
self.assertFalse(args.logscale)
|
self.assertFalse(args.logscale)
|
||||||
self.assertFalse(args.opengl)
|
self.assertFalse(args.opengl)
|
||||||
|
self.assertAlmostEqual(float(args.tty_range_v), 5.0, places=6)
|
||||||
|
|
||||||
args_log = build_parser().parse_args(["/dev/null", "--logscale", "--opengl"])
|
args_log = build_parser().parse_args(["/dev/null", "--logscale", "--opengl", "--tty-range-v", "2.5"])
|
||||||
self.assertTrue(args_log.logscale)
|
self.assertTrue(args_log.logscale)
|
||||||
self.assertTrue(args_log.opengl)
|
self.assertTrue(args_log.opengl)
|
||||||
|
self.assertAlmostEqual(float(args_log.tty_range_v), 2.5, places=6)
|
||||||
|
|
||||||
def test_wrapper_help_works(self):
|
def test_wrapper_help_works(self):
|
||||||
proc = _run("RFG_ADC_dataplotter.py", "--help")
|
proc = _run("RFG_ADC_dataplotter.py", "--help")
|
||||||
|
|||||||
@ -14,6 +14,7 @@ from rfg_adc_plotter.gui.pyqtgraph_backend import (
|
|||||||
coalesce_packets_for_ui,
|
coalesce_packets_for_ui,
|
||||||
compute_background_subtracted_bscan_levels,
|
compute_background_subtracted_bscan_levels,
|
||||||
compute_aux_phase_curve,
|
compute_aux_phase_curve,
|
||||||
|
convert_tty_i16_to_voltage,
|
||||||
decimate_curve_for_display,
|
decimate_curve_for_display,
|
||||||
resolve_axis_bounds,
|
resolve_axis_bounds,
|
||||||
resolve_heavy_refresh_stride,
|
resolve_heavy_refresh_stride,
|
||||||
@ -62,6 +63,17 @@ from rfg_adc_plotter.processing.peaks import find_peak_width_markers, find_top_p
|
|||||||
|
|
||||||
|
|
||||||
class ProcessingTests(unittest.TestCase):
|
class ProcessingTests(unittest.TestCase):
|
||||||
|
def test_convert_tty_i16_to_voltage_maps_and_clips_full_range(self):
|
||||||
|
codes = np.asarray([-32768.0, -16384.0, 0.0, 16384.0, 32767.0], dtype=np.float32)
|
||||||
|
volts = convert_tty_i16_to_voltage(codes, 5.0)
|
||||||
|
|
||||||
|
self.assertEqual(volts.shape, codes.shape)
|
||||||
|
self.assertAlmostEqual(float(volts[0]), -5.0, places=6)
|
||||||
|
self.assertAlmostEqual(float(volts[2]), 0.0, places=6)
|
||||||
|
self.assertAlmostEqual(float(volts[-1]), 5.0, places=6)
|
||||||
|
self.assertTrue(np.all(volts >= -5.0))
|
||||||
|
self.assertTrue(np.all(volts <= 5.0))
|
||||||
|
|
||||||
def test_recalculate_calibration_preserves_requested_edges(self):
|
def test_recalculate_calibration_preserves_requested_edges(self):
|
||||||
coeffs = recalculate_calibration_c(np.asarray([0.0, 1.0, 0.025], dtype=np.float64), 3.3, 14.3)
|
coeffs = recalculate_calibration_c(np.asarray([0.0, 1.0, 0.025], dtype=np.float64), 3.3, 14.3)
|
||||||
y0 = coeffs[0] + coeffs[1] * 3.3 + coeffs[2] * (3.3 ** 2)
|
y0 = coeffs[0] + coeffs[1] * 3.3 + coeffs[2] * (3.3 ** 2)
|
||||||
|
|||||||
Reference in New Issue
Block a user