From a707bedc31a46111fd32b0d0829c80b27c99a0e0 Mon Sep 17 00:00:00 2001 From: Theodor Chikin Date: Wed, 4 Mar 2026 17:57:32 +0300 Subject: [PATCH] fixed and updated frequency calibration mode. --- RFG_ADC_dataplotter.py | 121 ++++++++++++++++++++++++++++++++--------- 1 file changed, 96 insertions(+), 25 deletions(-) diff --git a/RFG_ADC_dataplotter.py b/RFG_ADC_dataplotter.py index 4bfdb7d..449c3bd 100755 --- a/RFG_ADC_dataplotter.py +++ b/RFG_ADC_dataplotter.py @@ -52,24 +52,38 @@ SweepAuxCurves = Optional[Tuple[np.ndarray, np.ndarray]] SweepPacket = Tuple[np.ndarray, SweepInfo, SweepAuxCurves] -CALIBRATION_C_BASE = np.asarray([0.0, 1.0, 0.025], dtype=np.float64) -_f0 = float(SWEEP_FREQ_MIN_GHZ) -_f1 = float(SWEEP_FREQ_MAX_GHZ) -_p0 = float(CALIBRATION_C_BASE[0] + CALIBRATION_C_BASE[1] * _f0 + CALIBRATION_C_BASE[2] * (_f0 ** 2)) -_p1 = float(CALIBRATION_C_BASE[0] + CALIBRATION_C_BASE[1] * _f1 + CALIBRATION_C_BASE[2] * (_f1 ** 2)) -if np.isfinite(_p0) and np.isfinite(_p1) and _p1 != _p0: - _cal_b = (_f1 - _f0) / (_p1 - _p0) - _cal_a = _f0 - _cal_b * _p0 - CALIBRATION_C = np.asarray( +def recalculate_calibration_c( + base_coeffs: np.ndarray, + f_min: float = SWEEP_FREQ_MIN_GHZ, + f_max: float = SWEEP_FREQ_MAX_GHZ, +) -> np.ndarray: + """Пересчитать коэффициенты так, чтобы калибровка сохраняла края диапазона свипа.""" + 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( [ - _cal_a + _cal_b * CALIBRATION_C_BASE[0], - _cal_b * CALIBRATION_C_BASE[1], - _cal_b * CALIBRATION_C_BASE[2], + shift + scale * c0, + scale * c1, + scale * c2, ], dtype=np.float64, ) -else: - CALIBRATION_C = CALIBRATION_C_BASE.copy() + + +CALIBRATION_C_BASE = np.asarray([0.0, 1.0, 0.025], dtype=np.float64) +CALIBRATION_C = recalculate_calibration_c(CALIBRATION_C_BASE) @@ -1362,6 +1376,7 @@ def main(): norm_type = str(getattr(args, "norm_type", "projector")).strip().lower() cb = None c_boxes = [] + c_values_text = None # Статусная строка (внизу окна) status_text = fig.text( @@ -1498,18 +1513,45 @@ def main(): if peak_calibrate_mode: try: - def _set_c_value(idx: int, text: str): - global CALIBRATION_C + def _refresh_c_values_text(): + if c_values_text is None: + return try: - CALIBRATION_C[idx] = float(text.strip()) + c_values_text.set_text( + "\n".join( + f"C*{idx}={float(CALIBRATION_C[idx]):.6g}" for idx in range(3) + ) + ) except Exception: pass + def _set_c_value(idx: int, text: str): + global CALIBRATION_C, CALIBRATION_C_BASE + try: + CALIBRATION_C_BASE[idx] = float(text.strip()) + CALIBRATION_C = recalculate_calibration_c(CALIBRATION_C_BASE) + except Exception: + pass + _refresh_c_values_text() + for idx, ypos in enumerate((0.36, 0.30, 0.24)): ax_c = fig.add_axes([0.92, ypos, 0.08, 0.045]) - tb = TextBox(ax_c, f"C{idx}", initial=f"{float(CALIBRATION_C[idx]):.6g}") + tb = TextBox(ax_c, f"C{idx}", initial=f"{float(CALIBRATION_C_BASE[idx]):.6g}") tb.on_submit(lambda text, i=idx: _set_c_value(i, text)) c_boxes.append(tb) + ax_c_info = fig.add_axes([0.90, 0.14, 0.10, 0.08]) + ax_c_info.axis("off") + c_values_text = ax_c_info.text( + 0.0, + 1.0, + "", + ha="left", + va="top", + fontsize=7, + family="monospace", + transform=ax_c_info.transAxes, + ) + _refresh_c_values_text() except Exception: pass @@ -2169,6 +2211,7 @@ def run_pyqtgraph(args): current_peak_width: Optional[float] = None norm_type = str(getattr(args, "norm_type", "projector")).strip().lower() c_edits = [] + c_value_labels = [] # Диапазон по Y: авто по умолчанию (поддерживает отрицательные значения) fixed_ylim: Optional[Tuple[float, float]] = None if args.ylim: @@ -2220,18 +2263,31 @@ def run_pyqtgraph(args): calib_layout = QtWidgets.QFormLayout(calib_window) calib_layout.setContentsMargins(8, 8, 8, 8) - def _apply_c_value(idx: int, edit): - global CALIBRATION_C - try: - CALIBRATION_C[idx] = float(edit.text().strip()) - except Exception: + def _refresh_c_value_labels(): + for idx, label in enumerate(c_value_labels): try: - edit.setText(f"{float(CALIBRATION_C[idx]):.6g}") + label.setText(f"{float(CALIBRATION_C[idx]):.6g}") except Exception: pass + def _apply_c_value(idx: int, edit): + global CALIBRATION_C, CALIBRATION_C_BASE + try: + CALIBRATION_C_BASE[idx] = float(edit.text().strip()) + CALIBRATION_C = recalculate_calibration_c(CALIBRATION_C_BASE) + except Exception: + try: + edit.setText(f"{float(CALIBRATION_C_BASE[idx]):.6g}") + except Exception: + pass + _refresh_c_value_labels() + + def _apply_all_c_values(): + for idx, edit in enumerate(c_edits): + _apply_c_value(idx, edit) + for idx in range(3): - edit = QtWidgets.QLineEdit(f"{float(CALIBRATION_C[idx]):.6g}") + edit = QtWidgets.QLineEdit(f"{float(CALIBRATION_C_BASE[idx]):.6g}") try: edit.setMaximumWidth(120) except Exception: @@ -2242,6 +2298,21 @@ def run_pyqtgraph(args): pass calib_layout.addRow(f"C{idx}", edit) c_edits.append(edit) + try: + update_btn = QtWidgets.QPushButton("Update") + update_btn.clicked.connect(lambda _checked=False: _apply_all_c_values()) + calib_layout.addRow(update_btn) + except Exception: + pass + try: + calib_layout.addRow(QtWidgets.QLabel("Working C"), QtWidgets.QLabel("")) + except Exception: + pass + for idx in range(3): + label = QtWidgets.QLabel(f"{float(CALIBRATION_C[idx]):.6g}") + calib_layout.addRow(f"C*{idx}", label) + c_value_labels.append(label) + _refresh_c_value_labels() try: calib_window.show() except Exception: