import numpy as np from fastapi import HTTPException from .config import MAX_COEFFICIENTS, NYQUIST_MARGIN def require_finite(value, name): if not np.isfinite(value): raise HTTPException(status_code=400, detail=f"{name} 必須是有限數值") return float(value) def validate_frequency(name, value, fs, *, below_nyquist=True): value = require_finite(value, name) if value <= 0: raise HTTPException(status_code=400, detail=f"{name} 必須大於 0") if below_nyquist and value >= (fs / 2) * NYQUIST_MARGIN: raise HTTPException(status_code=400, detail=f"{name} 必須小於 Nyquist 頻率 ({fs / 2:g} Hz)") return value def parse_coefficients(raw, name): try: values = [float(x.strip()) for x in raw.replace(",", " ").split() if x.strip()] except ValueError: raise HTTPException(status_code=400, detail=f"{name} 係數格式錯誤") return validate_coefficients(values, name) def validate_coefficients(values, name): if len(values) == 0: raise HTTPException(status_code=400, detail=f"{name} 係數不可為空") if len(values) > MAX_COEFFICIENTS: raise HTTPException(status_code=400, detail=f"{name} 係數最多 {MAX_COEFFICIENTS} 個") coeffs = np.asarray(values, dtype=float) if not np.all(np.isfinite(coeffs)): raise HTTPException(status_code=400, detail=f"{name} 係數必須都是有限數值") if name == "a" and np.isclose(coeffs[0], 0.0): raise HTTPException(status_code=400, detail="a[0] 不可為 0") return coeffs def normalize_coefficients(b_values, a_values): b_arr = validate_coefficients(b_values, "b") a_arr = validate_coefficients(a_values, "a") if not np.isclose(a_arr[0], 1.0): b_arr = b_arr / a_arr[0] a_arr = a_arr / a_arr[0] return b_arr, a_arr