Skip to content

Commit 453bccc

Browse files
RFingAdamclaude
andcommitted
Standardize parameter naming to {measurement}_{unit} convention (GH #25)
Rename parameters and local variables for consistency: - calculate_imd_from_intercept: iip_dbm -> iip_n_dbm (clarifies nth-order intercept) - calculate_interference_at_victim_quantitative: victim_sensitivity -> victim_sensitivity_dbm - analyze_system_performance: aggressor_power -> aggressor_power_dbm, victim_sensitivity -> victim_sensitivity_dbm No changes to public API (function names, return dict keys, dataclass fields). All 174 tests pass. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 433791b commit 453bccc

1 file changed

Lines changed: 47 additions & 47 deletions

File tree

rf_performance.py

Lines changed: 47 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,7 @@ def get_technology_duty_cycle(band_code: str, system_params: SystemParameters) -
702702

703703
def calculate_imd_from_intercept(
704704
p_in_dbm: float,
705-
iip_dbm: float,
705+
iip_n_dbm: float,
706706
order: int,
707707
p1db_dbm: Optional[float] = None
708708
) -> float:
@@ -722,7 +722,7 @@ def calculate_imd_from_intercept(
722722
723723
Args:
724724
p_in_dbm: Input power per tone in dBm
725-
iip_dbm: Input intercept point (IIP2, IIP3, etc.) in dBm
725+
iip_n_dbm: Input intercept point for the relevant order (IIP2, IIP3, etc.) in dBm
726726
order: IMD order (2, 3, 4, 5, 7)
727727
p1db_dbm: Optional P1dB compression point for more precise saturation clamping
728728
@@ -732,35 +732,35 @@ def calculate_imd_from_intercept(
732732
if order == 2:
733733
# IM2: beat products (f1+f2, f1-f2)
734734
# P_IM2 = 2×P_in - IIP2
735-
p_imd = 2 * p_in_dbm - iip_dbm
735+
p_imd = 2 * p_in_dbm - iip_n_dbm
736736

737737
elif order == 3:
738738
# IM3: 2f1±f2, 2f2±f1 products (most important for close-in interference)
739739
# P_IM3 = 3×P_in - 2×IIP3
740-
p_imd = 3 * p_in_dbm - 2 * iip_dbm
740+
p_imd = 3 * p_in_dbm - 2 * iip_n_dbm
741741

742742
elif order == 4:
743743
# IM4: derived from IM2 mixing, typically 15-20 dB below IM2
744-
im2_power = 2 * p_in_dbm - iip_dbm
744+
im2_power = 2 * p_in_dbm - iip_n_dbm
745745
p_imd = im2_power - 18.0 # IM4 typically 18 dB below IM2
746746

747747
elif order == 5:
748748
# IM5: 3f1±2f2, 3f2±2f1 products
749749
# P_IM5 = 5×P_in - 4×IIP5
750750
# IIP5 is typically IIP3 + 10 dB
751-
iip5_estimated = iip_dbm + 10.0
751+
iip5_estimated = iip_n_dbm + 10.0
752752
p_imd = 5 * p_in_dbm - 4 * iip5_estimated
753753

754754
elif order == 7:
755755
# IM7: 4f1±3f2, 4f2±3f1 products
756756
# P_IM7 = 7×P_in - 6×IIP7
757757
# IIP7 is typically IIP3 + 15-20 dB
758-
iip7_estimated = iip_dbm + 15.0
758+
iip7_estimated = iip_n_dbm + 15.0
759759
p_imd = 7 * p_in_dbm - 6 * iip7_estimated
760760

761761
else:
762762
# Generic higher order approximation
763-
iipn_estimated = iip_dbm + (order - 3) * 5.0
763+
iipn_estimated = iip_n_dbm + (order - 3) * 5.0
764764
p_imd = order * p_in_dbm - (order - 1) * iipn_estimated
765765

766766
# Saturation clamp: IM products cannot exceed fundamental power in compression.
@@ -1192,11 +1192,11 @@ def calculate_interference_at_victim_quantitative(interference_at_tx_dbm: float,
11921192
interference_at_victim_dbm = interference_at_tx_dbm - total_isolation_db
11931193

11941194
# Step 2: Get victim receiver parameters
1195-
victim_sensitivity = get_victim_sensitivity_quantitative(victim_band_code, system_params)
1196-
1195+
victim_sensitivity_dbm = get_victim_sensitivity_quantitative(victim_band_code, system_params)
1196+
11971197
# Step 3: Calculate receiver noise floor using proper RF methodology
11981198
thermal_noise_density_dbm_hz = system_params.thermal_noise_density_dbm_hz # -174 dBm/Hz
1199-
1199+
12001200
# Technology-specific receiver parameters
12011201
if 'GNSS' in victim_band_code.upper():
12021202
rx_bandwidth_hz = 2e6 # 2 MHz GNSS bandwidth
@@ -1216,86 +1216,86 @@ def calculate_interference_at_victim_quantitative(interference_at_tx_dbm: float,
12161216
required_cnr_db = 12.0 # WiFi SNR requirement
12171217
elif 'BLE' in victim_band_code.upper():
12181218
rx_bandwidth_hz = 1e6 # 1 MHz BLE bandwidth
1219-
noise_figure_db = system_params.noise_figure_db
1219+
noise_figure_db = system_params.noise_figure_db
12201220
required_cnr_db = 8.0 # BLE sensitivity requirement
12211221
else:
12221222
rx_bandwidth_hz = 5e6 # Default bandwidth
12231223
noise_figure_db = system_params.noise_figure_db
12241224
required_cnr_db = 10.0 # Default SNR
1225-
1225+
12261226
# Calculate receiver noise floor
12271227
thermal_noise_dbm = thermal_noise_density_dbm_hz + 10 * math.log10(rx_bandwidth_hz)
12281228
noise_floor_dbm = thermal_noise_dbm + noise_figure_db
1229-
1229+
12301230
# Step 4: Calculate interference margin (traditional approach)
1231-
interference_margin_db = victim_sensitivity - interference_at_victim_dbm
1232-
1231+
interference_margin_db = victim_sensitivity_dbm - interference_at_victim_dbm
1232+
12331233
# Step 5: Calculate professional desensitization using I/N method
12341234
if interference_at_victim_dbm <= noise_floor_dbm:
12351235
# Interference below noise floor - negligible desensitization
12361236
desensitization_db = 0.0
1237-
1237+
12381238
else:
12391239
# Professional desensitization calculation using I/N ratio
12401240
# I/N ratio in linear terms
12411241
i_over_n_linear = 10**((interference_at_victim_dbm - noise_floor_dbm) / 10.0)
1242-
1242+
12431243
# Standard RF desensitization formula: Desense = 10*log₁₀(1 + I/N)
12441244
# This represents the increase in effective noise floor due to interference
12451245
desensitization_db = 10 * math.log10(1 + i_over_n_linear)
1246-
1246+
12471247
# Alternative cross-check using direct interference impact for very strong interference
1248-
if interference_at_victim_dbm > victim_sensitivity:
1248+
if interference_at_victim_dbm > victim_sensitivity_dbm:
12491249
# Calculate how much the effective sensitivity is degraded
12501250
# Use a more realistic degradation model
1251-
excess_interference_db = interference_at_victim_dbm - victim_sensitivity
1252-
1251+
excess_interference_db = interference_at_victim_dbm - victim_sensitivity_dbm
1252+
12531253
# Apply realistic degradation scaling (not 1:1)
12541254
if 'GNSS' in victim_band_code.upper():
12551255
# GNSS is very sensitive - use more conservative scaling
12561256
sensitivity_degradation_db = excess_interference_db * 0.6 # 60% scaling
12571257
else:
12581258
# Other technologies are more robust
12591259
sensitivity_degradation_db = excess_interference_db * 0.4 # 40% scaling
1260-
1260+
12611261
# Use the larger of the two calculations but apply realistic limits
12621262
desensitization_db = max(desensitization_db, sensitivity_degradation_db)
1263-
1263+
12641264
# Apply realistic engineering limits based on technology
12651265
if 'GNSS' in victim_band_code.upper():
12661266
# GNSS: >10 dB = GPS dead zones, cap at 15 dB max for realistic analysis
12671267
desensitization_db = min(desensitization_db, 15.0)
12681268
else:
12691269
# Other technologies: cap at 30 dB max for realistic analysis
12701270
desensitization_db = min(desensitization_db, 30.0)
1271-
1271+
12721272
# Step 6: Calculate additional performance metrics
12731273
# Signal-to-interference ratio
12741274
if interference_at_victim_dbm > -200: # Valid interference level
12751275
# Assume typical desired signal at sensitivity threshold
1276-
desired_signal_dbm = victim_sensitivity + 3.0 # 3 dB above sensitivity
1276+
desired_signal_dbm = victim_sensitivity_dbm + 3.0 # 3 dB above sensitivity
12771277
sir_db = desired_signal_dbm - interference_at_victim_dbm
12781278
else:
12791279
sir_db = 999.0 # No interference
1280-
1280+
12811281
# Calculate effective sensitivity degradation
1282-
effective_sensitivity_dbm = victim_sensitivity + desensitization_db
1283-
1282+
effective_sensitivity_dbm = victim_sensitivity_dbm + desensitization_db
1283+
12841284
# Professional risk assessment based on desensitization levels and technology
12851285
_SEVERITY_TO_NAME = {5: 'Critical', 4: 'High', 3: 'Medium', 2: 'Low', 1: 'Negligible'}
12861286
risk_symbol, severity, _reason = assess_risk_severity_quantitative(
12871287
interference_power_dbm=interference_at_victim_dbm,
1288-
victim_sensitivity_dbm=victim_sensitivity,
1288+
victim_sensitivity_dbm=victim_sensitivity_dbm,
12891289
desensitization_db=desensitization_db,
12901290
victim_code=victim_band_code,
12911291
product_type='' # Not available at this call site; unused by function logic
12921292
)
12931293
risk_level = _SEVERITY_TO_NAME.get(severity, 'Negligible')
1294-
1295-
1294+
1295+
12961296
return {
12971297
'interference_at_victim_dbm': interference_at_victim_dbm,
1298-
'victim_sensitivity_dbm': victim_sensitivity,
1298+
'victim_sensitivity_dbm': victim_sensitivity_dbm,
12991299
'interference_margin_db': interference_margin_db,
13001300
'desensitization_db': desensitization_db,
13011301
'effective_sensitivity_dbm': effective_sensitivity_dbm,
@@ -1731,34 +1731,34 @@ def analyze_system_performance(interference_results: pd.DataFrame,
17311731

17321732
# Determine aggressor power based on band type
17331733
if 'LTE' in aggressors:
1734-
aggressor_power = system_params.lte_tx_power
1734+
aggressor_power_dbm = system_params.lte_tx_power
17351735
elif 'WiFi' in aggressors:
1736-
aggressor_power = system_params.wifi_tx_power
1736+
aggressor_power_dbm = system_params.wifi_tx_power
17371737
elif 'BLE' in aggressors:
1738-
aggressor_power = system_params.ble_tx_power
1738+
aggressor_power_dbm = system_params.ble_tx_power
17391739
elif 'HaLow' in aggressors:
1740-
aggressor_power = system_params.halow_tx_power
1740+
aggressor_power_dbm = system_params.halow_tx_power
17411741
else:
1742-
aggressor_power = 20.0 # Default
1743-
1742+
aggressor_power_dbm = 20.0 # Default
1743+
17441744
# Determine victim sensitivity
17451745
if 'BLE' in victims:
1746-
victim_sensitivity = system_params.ble_sensitivity
1746+
victim_sensitivity_dbm = system_params.ble_sensitivity
17471747
elif 'WiFi' in victims:
1748-
victim_sensitivity = system_params.wifi_sensitivity
1748+
victim_sensitivity_dbm = system_params.wifi_sensitivity
17491749
elif 'HaLow' in victims:
1750-
victim_sensitivity = system_params.halow_sensitivity
1750+
victim_sensitivity_dbm = system_params.halow_sensitivity
17511751
else:
1752-
victim_sensitivity = -90.0 # Default
1753-
1752+
victim_sensitivity_dbm = -90.0 # Default
1753+
17541754
# Calculate interference impact
17551755
analysis = assess_interference_level(
1756-
freq_mhz, aggressor_power, victim_sensitivity, system_params
1756+
freq_mhz, aggressor_power_dbm, victim_sensitivity_dbm, system_params
17571757
)
1758-
1758+
17591759
# Calculate IM3 power if this is an IM3 product
17601760
if 'IM3' in product_type:
1761-
im3_power = calculate_im3_power(aggressor_power, system_params.iip3_dbm)
1761+
im3_power = calculate_im3_power(aggressor_power_dbm, system_params.iip3_dbm)
17621762
analysis['im3_power_dbm'] = im3_power
17631763

17641764
# Estimate PER

0 commit comments

Comments
 (0)