1515from __future__ import annotations
1616
1717import logging
18+ import math
1819from abc import ABC , abstractmethod
1920from collections .abc import Set
2021from dataclasses import dataclass
@@ -493,7 +494,10 @@ def from_samples(cls, samples: ComponentDataSamples) -> Self:
493494 # FIXME: We assume only one range is present
494495 # If one bound is None, we assume 0 to match the previous
495496 # behavior of v0.15, but this should eventually be fixed
496- if len (sample .bounds ) > 1 :
497+ if len (sample .bounds ) > 1 and (
498+ sample .bounds [1 ].lower != 0.0
499+ or sample .bounds [1 ].upper != 0.0
500+ ):
497501 _logger .warning (
498502 "Too many bounds found in sample, a maximum of 1 is "
499503 "supported for SOC, using only the first: %r" ,
@@ -1169,6 +1173,31 @@ def _bound_ranges_to_inclusion_exclusion(
11691173 assert_never (unexpected )
11701174
11711175
1176+ def _try_create_bounds (lower : float , upper : float , description : str ) -> list [Bounds ]:
1177+ """Safely create a bounds object, handling any exceptions gracefully.
1178+
1179+ Args:
1180+ lower: Lower bound value
1181+ upper: Upper bound value
1182+ description: Description for logging
1183+
1184+ Returns:
1185+ List containing the created Bounds object or an empty list if creation failed.
1186+ """
1187+ try :
1188+ return [Bounds (lower = lower , upper = upper )]
1189+ except ValueError as exc :
1190+ _logger .warning (
1191+ "Ignoring invalid %s bounds [%s, %s]: %s" ,
1192+ description ,
1193+ lower ,
1194+ upper ,
1195+ exc ,
1196+ stack_info = True ,
1197+ )
1198+ return []
1199+
1200+
11721201def _inclusion_exclusion_bounds_to_ranges (
11731202 inclusion_lower_bound : float ,
11741203 inclusion_upper_bound : float ,
@@ -1190,17 +1219,68 @@ def _inclusion_exclusion_bounds_to_ranges(
11901219 Returns:
11911220 A list of bounds.
11921221 """
1222+ ranges : list [Bounds ] = []
11931223 if exclusion_lower_bound == 0.0 and exclusion_upper_bound == 0.0 :
11941224 if inclusion_lower_bound == 0.0 and inclusion_upper_bound == 0.0 :
1225+ # No bounds are present at all
11951226 return []
1227+ # Only inclusion bounds are present
1228+ return _try_create_bounds (
1229+ inclusion_lower_bound , inclusion_upper_bound , "inclusion"
1230+ )
11961231
1197- ranges = [Bounds (lower = inclusion_lower_bound , upper = inclusion_upper_bound )]
1232+ if inclusion_lower_bound == 0.0 and inclusion_upper_bound == 0.0 :
1233+ # There are exclusion bounds, but no inclusion bounds, we create 2 ranges, one
1234+ # from -inf to exclusion_lower_bound and one from exclusion_upper_bound to +inf
1235+ ranges .extend (
1236+ _try_create_bounds (
1237+ float ("-inf" ), exclusion_lower_bound , "exclusion lower bound"
1238+ )
1239+ )
1240+ ranges .extend (
1241+ _try_create_bounds (
1242+ exclusion_upper_bound , float ("+inf" ), "exclusion upper bound"
1243+ )
1244+ )
11981245 return ranges
11991246
1200- assert inclusion_lower_bound != 0.0 or inclusion_upper_bound != 0.0
1247+ # First range: from inclusion_lower_bound to exclusion_lower_bound.
1248+ # If either value is NaN, skip the ordering check. Is not entirely clear what to do
1249+ # with NaN, but this is the old behavior so we are keeping it for now.
1250+ if (
1251+ math .isnan (inclusion_lower_bound )
1252+ or math .isnan (exclusion_lower_bound )
1253+ or inclusion_lower_bound <= exclusion_lower_bound
1254+ ):
1255+ ranges .extend (
1256+ _try_create_bounds (
1257+ inclusion_lower_bound , exclusion_lower_bound , "first range"
1258+ )
1259+ )
1260+ else :
1261+ _logger .warning (
1262+ "Inclusion lower bound (%s) is greater than exclusion lower bound (%s), "
1263+ "skipping this bound in the ranges" ,
1264+ inclusion_lower_bound ,
1265+ exclusion_lower_bound ,
1266+ )
1267+ # Second range: from exclusion_upper_bound to inclusion_upper_bound.
1268+ if (
1269+ math .isnan (exclusion_upper_bound )
1270+ or math .isnan (inclusion_upper_bound )
1271+ or exclusion_upper_bound <= inclusion_upper_bound
1272+ ):
1273+ ranges .extend (
1274+ _try_create_bounds (
1275+ exclusion_upper_bound , inclusion_upper_bound , "second range"
1276+ )
1277+ )
1278+ else :
1279+ _logger .warning (
1280+ "Inclusion upper bound (%s) is less than exclusion upper bound (%s), "
1281+ "no second range to add" ,
1282+ inclusion_upper_bound ,
1283+ exclusion_upper_bound ,
1284+ )
12011285
1202- ranges = [
1203- Bounds (lower = inclusion_lower_bound , upper = exclusion_lower_bound ),
1204- Bounds (lower = exclusion_upper_bound , upper = inclusion_upper_bound ),
1205- ]
12061286 return ranges
0 commit comments