@@ -702,7 +702,7 @@ def get_technology_duty_cycle(band_code: str, system_params: SystemParameters) -
702702
703703def 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