44 lines
1.4 KiB
Python
44 lines
1.4 KiB
Python
"""Преобразование свипа в IFFT-временной профиль (дБ)."""
|
|
|
|
from typing import Optional
|
|
|
|
import numpy as np
|
|
|
|
from rfg_adc_plotter.constants import FREQ_SPAN_GHZ, IFFT_LEN, SWEEP_LEN, ZEROS_LOW, ZEROS_MID
|
|
|
|
|
|
def build_ifft_time_axis_ns() -> np.ndarray:
|
|
"""Временная ось IFFT в наносекундах."""
|
|
return (
|
|
np.arange(IFFT_LEN, dtype=np.float64) / (FREQ_SPAN_GHZ * 1e9) * 1e9
|
|
).astype(np.float32)
|
|
|
|
|
|
def compute_ifft_db_profile(sweep: Optional[np.ndarray]) -> np.ndarray:
|
|
"""Построить IFFT-профиль свипа в дБ.
|
|
|
|
Цепочка:
|
|
raw/processed sweep -> двусторонний спектр (заполнение нулями) ->
|
|
ifftshift -> ifft -> |x| -> 20log10.
|
|
"""
|
|
bins = IFFT_LEN
|
|
if sweep is None:
|
|
return np.full((bins,), np.nan, dtype=np.float32)
|
|
|
|
s = np.asarray(sweep)
|
|
if s.size == 0:
|
|
return np.full((bins,), np.nan, dtype=np.float32)
|
|
|
|
sig = np.zeros(SWEEP_LEN, dtype=np.float32)
|
|
take = min(int(s.size), SWEEP_LEN)
|
|
seg = np.nan_to_num(s[:take], nan=0.0).astype(np.float32, copy=False)
|
|
sig[:take] = seg
|
|
|
|
data = np.zeros(IFFT_LEN, dtype=np.complex64)
|
|
data[ZEROS_LOW + ZEROS_MID :] = sig
|
|
|
|
spec = np.fft.ifftshift(data)
|
|
result = np.fft.ifft(spec)
|
|
mag = np.abs(result).astype(np.float32)
|
|
return (mag + 1e-9).astype(np.float32)
|