@mytec: feat: Phase 3.0 Architecture Refactor ✅
Major refactoring of RFCP backend: - Modular propagation models (8 models) - SharedMemoryManager for terrain data - ProcessPoolExecutor parallel processing - WebSocket progress streaming - Building filtering pipeline (351k → 15k) - 82 unit tests Performance: Standard preset 38s → 5s (7.6x speedup) Known issue: Detailed preset timeout (fix in 3.1.0)
This commit is contained in:
74
backend/app/propagation/itu_r_p1546.py
Normal file
74
backend/app/propagation/itu_r_p1546.py
Normal file
@@ -0,0 +1,74 @@
|
||||
"""
|
||||
ITU-R P.1546 model for point-to-area predictions.
|
||||
|
||||
Valid for:
|
||||
- Frequency: 30-3000 MHz
|
||||
- Distance: 1-1000 km
|
||||
- Time percentages: 1%, 10%, 50%
|
||||
|
||||
Best for: VHF/UHF broadcasting and land mobile services.
|
||||
Reference: ITU-R P.1546-6 (2019)
|
||||
"""
|
||||
|
||||
import math
|
||||
from app.propagation.base import PropagationModel, PropagationInput, PropagationOutput
|
||||
|
||||
|
||||
class ITUR_P1546Model(PropagationModel):
|
||||
"""
|
||||
Simplified P.1546 implementation.
|
||||
|
||||
Full implementation would include terrain clearance angle,
|
||||
mixed path (land/sea), and time variability.
|
||||
"""
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return "ITU-R-P.1546"
|
||||
|
||||
@property
|
||||
def frequency_range(self) -> tuple:
|
||||
return (30, 3000)
|
||||
|
||||
@property
|
||||
def distance_range(self) -> tuple:
|
||||
return (1000, 1000000) # 1-1000 km
|
||||
|
||||
def calculate(self, input: PropagationInput) -> PropagationOutput:
|
||||
f = input.frequency_mhz
|
||||
d = max(input.distance_m / 1000, 1.0) # km
|
||||
h1 = max(input.tx_height_m, 1.0)
|
||||
|
||||
# Nominal frequency bands
|
||||
if f < 100:
|
||||
f_nom = 100
|
||||
elif f < 600:
|
||||
f_nom = 600
|
||||
else:
|
||||
f_nom = 2000
|
||||
|
||||
# Basic field strength at 1 kW ERP (from curves, simplified regression)
|
||||
E_ref = 106.9 - 20 * math.log10(d) # dBuV/m at 1kW
|
||||
|
||||
# Height gain for transmitter
|
||||
delta_h1 = 20 * math.log10(h1 / 10) if h1 > 10 else 0
|
||||
|
||||
# Frequency correction
|
||||
delta_f = 20 * math.log10(f / f_nom)
|
||||
|
||||
# Convert field strength to path loss
|
||||
# L = 139.3 - E + 20*log10(f) (for 50 Ohm)
|
||||
E = E_ref + delta_h1 - delta_f
|
||||
L = 139.3 - E + 20 * math.log10(f)
|
||||
|
||||
return PropagationOutput(
|
||||
path_loss_db=L,
|
||||
model_name=self.name,
|
||||
is_los=d < 5,
|
||||
breakdown={
|
||||
"reference_field": E_ref,
|
||||
"height_gain": delta_h1,
|
||||
"frequency_correction": delta_f,
|
||||
"path_loss": L,
|
||||
},
|
||||
)
|
||||
Reference in New Issue
Block a user