|
1 | 1 | from __future__ import annotations |
2 | 2 |
|
3 | | -from geophires_x.GeoPHIRESUtils import is_float, is_int |
4 | | -from geophires_x.Parameter import OutputParameter, SCHEDULE_DSL_MULTIPLIER_SYMBOL |
| 3 | +from geophires_x.Parameter import OutputParameter |
5 | 4 | from geophires_x.Units import Units, PercentUnit, TimeUnit, CurrencyUnit, CurrencyFrequencyUnit, EnergyCostUnit |
6 | 5 |
|
7 | 6 | CONSTRUCTION_CAPEX_SCHEDULE_PARAMETER_NAME = 'Construction CAPEX Schedule' |
@@ -248,90 +247,9 @@ def investment_tax_credit_output_parameter() -> OutputParameter: |
248 | 247 |
|
249 | 248 | def expand_schedule_dsl(schedule_strings: list[str | float], total_years: int) -> list[float]: |
250 | 249 | """ |
251 | | - Parse a duration-based scheduling DSL and expand it into a fixed-length time-series array. |
252 | | -
|
253 | | - Syntax: `[Value] * [Years], [Value] * [Years], ..., [Terminal Value]` |
254 | | -
|
255 | | - The terminal (last) value is repeated to fill `total_years`. A bare scalar |
256 | | - (e.g. `['2.5']`) is treated as a terminal value and broadcast across all years. |
257 | | -
|
258 | | - Examples:: |
259 | | -
|
260 | | - expand_schedule_dsl(['1.0 * 3', '0.1'], total_years=6) |
261 | | - # => [1.0, 1.0, 1.0, 0.1, 0.1, 0.1] |
262 | | -
|
263 | | - expand_schedule_dsl(['2.5'], total_years=4) |
264 | | - # => [2.5, 2.5, 2.5, 2.5] |
265 | | -
|
266 | | - :param schedule_strings: list of DSL segment strings. Each element is either |
267 | | - `"<value> * <years>"` (a run-length segment) or `"<value>"` (a scalar, |
268 | | - which becomes the terminal value when it is the last element, or a 1-year |
269 | | - segment otherwise). |
270 | | - :param total_years: The total number of years the expanded array must span |
271 | | - (typically `construction_years + plant_lifetime`). |
272 | | - :returns: A `list[float]` of length `total_years`. |
273 | | - :raises ValueError: On malformed DSL strings or when explicit segments exceed |
274 | | - `total_years`. |
| 250 | + Deprecated, call ParameterUtils.expand_schedule_dsl |
275 | 251 | """ |
276 | 252 |
|
277 | | - if total_years <= 0: |
278 | | - return [] |
279 | | - |
280 | | - if not schedule_strings: |
281 | | - return [0.0] * total_years |
282 | | - |
283 | | - segments: list[tuple[float, int | None]] = [] |
284 | | - for raw in schedule_strings: |
285 | | - raw = str(raw).strip() |
286 | | - if SCHEDULE_DSL_MULTIPLIER_SYMBOL in raw: |
287 | | - parts = raw.split(SCHEDULE_DSL_MULTIPLIER_SYMBOL) |
288 | | - if len(parts) != 2: |
289 | | - raise ValueError(f'Invalid schedule segment "{raw}": expected "<value> * <years>".') |
290 | | - |
291 | | - val_raw = parts[0].strip() |
292 | | - if not is_float(val_raw): |
293 | | - raise ValueError(f'Invalid schedule segment "{raw}": "{val_raw}" is not a float.') |
294 | | - value = float(val_raw) |
295 | | - if value < 0: |
296 | | - raise ValueError(f'Invalid schedule segment "{raw}": {val_raw} is negative.') |
297 | | - |
298 | | - years_raw = parts[1].strip() |
299 | | - if not is_int(years_raw): |
300 | | - raise ValueError(f'Invalid schedule segment "{raw}": "{years_raw}" is not an int.') |
301 | | - |
302 | | - years = int(years_raw) |
303 | | - if years < 0: |
304 | | - raise ValueError(f'Invalid schedule segment "{raw}": year count must be non-negative.') |
305 | | - segments.append((value, years)) |
306 | | - else: |
307 | | - if not is_float(raw): |
308 | | - raise ValueError(f'Invalid schedule segment "{raw}": "{raw}" is not a float.') |
309 | | - |
310 | | - value = float(raw) |
311 | | - segments.append((value, None)) |
312 | | - |
313 | | - result: list[float] = [] |
314 | | - terminal_value = 0.0 |
315 | | - |
316 | | - for idx, (value, years) in enumerate(segments): |
317 | | - is_last = idx == len(segments) - 1 |
318 | | - if years is not None: |
319 | | - result.extend([value] * years) |
320 | | - terminal_value = value |
321 | | - else: |
322 | | - if is_last: |
323 | | - terminal_value = value |
324 | | - else: |
325 | | - result.append(value) |
326 | | - terminal_value = value |
327 | | - |
328 | | - if len(result) > total_years: |
329 | | - raise ValueError( |
330 | | - f'Invalid schedule: Schedule expands to {len(result)} years ' f'which exceeds total_years={total_years}.' |
331 | | - ) |
332 | | - |
333 | | - remaining = total_years - len(result) |
334 | | - if remaining > 0: |
335 | | - result.extend([terminal_value] * remaining) |
336 | | - |
337 | | - return result |
| 253 | + from geophires_x.ParameterUtils import expand_schedule_dsl |
| 254 | + |
| 255 | + return expand_schedule_dsl(schedule_strings, total_years) |
0 commit comments