Files
RadioPropagationApi/api/app/core/antenna_pattern_file.py
T
2026-06-24 07:50:00 +03:00

51 lines
1.5 KiB
Python

from __future__ import annotations
import csv
from pathlib import Path
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from app.core.antenna import AntennaPattern
def _parse_float(value: str) -> float:
return float(value.strip())
def load_pattern_file(path: str | Path) -> list[tuple[float, float, float]]:
file_path = Path(path)
if not file_path.exists():
raise FileNotFoundError(f"Antenna pattern file not found: {file_path}")
samples: list[tuple[float, float, float]] = []
with file_path.open(encoding="utf-8", newline="") as handle:
reader = csv.reader(handle)
for row in reader:
if not row or row[0].startswith("#"):
continue
if len(row) < 3:
continue
if row[0].lower() in {"azimuth_deg", "az", "azimuth"}:
continue
samples.append((_parse_float(row[0]), _parse_float(row[1]), _parse_float(row[2])))
if not samples:
raise ValueError(f"No antenna pattern samples found in {file_path}")
return samples
def gain_from_file(
pattern: AntennaPattern,
az_deg: float,
el_deg: float,
) -> float:
if not pattern.pattern_file:
raise ValueError("pattern_file is required for file patterns")
samples = load_pattern_file(pattern.pattern_file)
nearest = min(
samples,
key=lambda item: abs(item[0] - az_deg) + abs(item[1] - el_deg),
)
return pattern.gain_dbi + nearest[2]