This commit is contained in:
awe
2026-03-25 18:54:59 +03:00
parent fa4870c56c
commit 64e66933e4
14 changed files with 350 additions and 42 deletions

View File

@ -24,6 +24,21 @@ def _finite_freq_bounds(freqs: Optional[np.ndarray]) -> Optional[Tuple[float, fl
return f_min, f_max
def _coerce_sweep_array(sweep: np.ndarray) -> np.ndarray:
values = np.asarray(sweep).reshape(-1)
if np.iscomplexobj(values):
return np.asarray(values, dtype=np.complex64)
return np.asarray(values, dtype=np.float32)
def _interp_signal(x_uniform: np.ndarray, x_known: np.ndarray, y_known: np.ndarray) -> np.ndarray:
if np.iscomplexobj(y_known):
real = np.interp(x_uniform, x_known, np.asarray(y_known.real, dtype=np.float64))
imag = np.interp(x_uniform, x_known, np.asarray(y_known.imag, dtype=np.float64))
return (real + (1j * imag)).astype(np.complex64)
return np.interp(x_uniform, x_known, np.asarray(y_known, dtype=np.float64)).astype(np.float32)
def prepare_fft_segment(
sweep: np.ndarray,
freqs: Optional[np.ndarray],
@ -34,8 +49,10 @@ def prepare_fft_segment(
if take_fft <= 0:
return None
sweep_seg = np.asarray(sweep[:take_fft], dtype=np.float32)
fallback = np.nan_to_num(sweep_seg, nan=0.0).astype(np.float32, copy=False)
sweep_arr = _coerce_sweep_array(sweep)
sweep_seg = sweep_arr[:take_fft]
fallback_dtype = np.complex64 if np.iscomplexobj(sweep_seg) else np.float32
fallback = np.nan_to_num(sweep_seg, nan=0.0).astype(fallback_dtype, copy=False)
if freqs is None:
return fallback, take_fft
@ -59,7 +76,7 @@ def prepare_fft_segment(
return fallback, take_fft
x_uniform = np.linspace(float(x_unique[0]), float(x_unique[-1]), take_fft, dtype=np.float64)
resampled = np.interp(x_uniform, x_unique, y_unique).astype(np.float32)
resampled = _interp_signal(x_uniform, x_unique, y_unique)
return resampled, take_fft
@ -94,18 +111,20 @@ def build_symmetric_ifft_spectrum(
fft_seg, take_fft = prepared
if take_fft != band_len:
fft_seg = np.asarray(fft_seg[:band_len], dtype=np.float32)
fft_dtype = np.complex64 if np.iscomplexobj(fft_seg) else np.float32
fft_seg = np.asarray(fft_seg[:band_len], dtype=fft_dtype)
if fft_seg.size < band_len:
padded = np.zeros((band_len,), dtype=np.float32)
padded = np.zeros((band_len,), dtype=fft_dtype)
padded[: fft_seg.size] = fft_seg
fft_seg = padded
window = np.hanning(band_len).astype(np.float32)
band = np.nan_to_num(fft_seg, nan=0.0).astype(np.float32, copy=False) * window
band_dtype = np.complex64 if np.iscomplexobj(fft_seg) else np.float32
band = np.nan_to_num(fft_seg, nan=0.0).astype(band_dtype, copy=False) * window
spectrum = np.zeros((int(fft_len),), dtype=np.float32)
spectrum = np.zeros((int(fft_len),), dtype=band_dtype)
spectrum[pos_idx] = band
spectrum[neg_idx] = band[::-1]
spectrum[neg_idx] = np.conj(band[::-1]) if np.iscomplexobj(band) else band[::-1]
return spectrum
@ -137,16 +156,18 @@ def build_positive_only_centered_ifft_spectrum(
fft_seg, take_fft = prepared
if take_fft != band_len:
fft_seg = np.asarray(fft_seg[:band_len], dtype=np.float32)
fft_dtype = np.complex64 if np.iscomplexobj(fft_seg) else np.float32
fft_seg = np.asarray(fft_seg[:band_len], dtype=fft_dtype)
if fft_seg.size < band_len:
padded = np.zeros((band_len,), dtype=np.float32)
padded = np.zeros((band_len,), dtype=fft_dtype)
padded[: fft_seg.size] = fft_seg
fft_seg = padded
window = np.hanning(band_len).astype(np.float32)
band = np.nan_to_num(fft_seg, nan=0.0).astype(np.float32, copy=False) * window
band_dtype = np.complex64 if np.iscomplexobj(fft_seg) else np.float32
band = np.nan_to_num(fft_seg, nan=0.0).astype(band_dtype, copy=False) * window
spectrum = np.zeros((int(fft_len),), dtype=np.float32)
spectrum = np.zeros((int(fft_len),), dtype=band_dtype)
spectrum[pos_idx] = band
return spectrum
@ -168,7 +189,8 @@ def _compute_fft_mag_row_direct(
return np.full((bins,), np.nan, dtype=np.float32)
fft_seg, take_fft = prepared
fft_in = np.zeros((FFT_LEN,), dtype=np.float32)
fft_dtype = np.complex64 if np.iscomplexobj(fft_seg) else np.float32
fft_in = np.zeros((FFT_LEN,), dtype=fft_dtype)
window = np.hanning(take_fft).astype(np.float32)
fft_in[:take_fft] = fft_seg * window
spec = np.fft.ifft(fft_in)