Skip to content

Scenario Sub-Module

t3co.input_data.scenario

Scenario dataclass

Bases: object

Class object that contains all TCO parameters and performance target (range, grade, accel) information for a vehicle such that performance and TCO can be computed during optimization.

Source code in src/t3co/input_data/scenario.py
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
@dataclass
class Scenario(object):
    """
    Class object that contains all TCO parameters and performance target (range, grade, accel) information
    for a vehicle such that performance and TCO can be computed during optimization.
    """

    selection: int = None
    scenario_name: str = ""
    veh_year: int = 0
    drive_cycle: str = ""
    use_config: bool = True
    vmt: list = field(default_factory=str)
    constant_trip_distance_mi: float = 0
    vehicle_life_yr: float = 0
    discount_rate_pct_per_yr: float = 0.0

    ess_max_charging_power_kw: float = 0
    ess_cost_dol_per_kwh: float = 0
    ess_base_cost_dol: float = 0
    ess_charge_rate_kW: float = 0
    pe_mc_cost_dol_per_kw: float = 0
    pe_mc_base_cost_dol: float = 0
    fc_ice_cost_dol_per_kw: float = 0
    fc_ice_base_cost_dol: float = 0
    fc_fuelcell_cost_dol_per_kw: float = 0
    fs_cost_dol_per_kwh: float = 0
    fs_h2_cost_dol_per_kwh: float = 0
    plug_base_cost_dol: float = 0
    markup_pct: float = 0
    tax_rate_pct: float = 0
    fc_cng_ice_cost_dol_per_kw: float = 0
    fs_cng_cost_dol_per_kwh: float = 0
    vehicle_glider_cost_dol: float = 0
    gvwr_kg: float = 0
    gvwr_credit_kg: float = 0
    fuel_type: str = ""
    maint_oper_cost_dol_per_mi: List[float] = field(default_factory=float)
    vocation: str = ""
    vehicle_class: str = ""
    model_year: float = 0
    region: str = ""
    target_range_mi: float = 0
    min_speed_at_6pct_grade_in_5min_mph: float = 0
    min_speed_at_1p25pct_grade_in_5min_mph: float = 0
    max_time_0_to_60mph_at_gvwr_s: float = 0
    max_time_0_to_30mph_at_gvwr_s: float = 0
    lw_imp_curve_sel: str = ""
    eng_eff_imp_curve_sel: str = ""
    aero_drag_imp_curve_sel: str = ""

    ess_init_soc_grade: float = -1.0
    ess_init_soc_accel: float = -1.0

    soc_norm_init_for_accel_pct: float = -1
    soc_norm_init_for_grade_pct: float = -1

    fs_fueling_rate_gasoline_gpm: float = 0
    fs_fueling_rate_diesel_gpm: float = 0
    fs_fueling_rate_kg_per_min: float = 0

    purchasing_method: str = ""
    purchasing_down_payment_pct: float = 0.0
    purchasing_interest_apr_pct_per_yr: float = 0.0
    purchasing_payment_frequency_months: float = 0.0
    purchasing_term_yr: float = 0.0
    leasing_money_factor: float = 0.0
    shifts_per_year: List[float] = field(default_factory=list)

    missed_trace_correction: bool = False
    max_time_dilation: float = -1
    min_time_dilation: float = -1
    time_dilation_tol: float = -1

    skip_opt: bool = False
    knob_min_ess_kwh: float = None
    knob_max_ess_kwh: float = None
    knob_min_motor_kw: float = None
    knob_max_motor_kw: float = None
    knob_min_fc_kw: float = None
    knob_max_fc_kw: float = None
    knob_min_fs_kwh: float = None
    knob_max_fs_kwh: float = None
    constraint_c_rate: bool = False
    constraint_range: bool = False
    constraint_accel: bool = False
    constraint_grade: bool = False
    objective_tco: bool = False
    constraint_trace_miss_dist_percent_on: bool = False
    trace_miss_dist_percent: float = 0

    labor_rate_dol_per_hr: float = 0
    downtime_oppy_cost_dol_per_hr: float = 0

    activate_tco_payload_cap_cost_multiplier: bool = True
    plf_ref_veh_empty_mass_kg: float = 0
    plf_scenario_vehicle_empty_kg: float = 0
    plf_reference_vehicle_cargo_capacity_kg: float = 0
    plf_scenario_vehicle_cargo_capacity_kg: float = 0
    estimated_lost_payload_kg: float = 0

    activate_tco_fueling_dwell_time_cost: bool = True
    dlf_min_charge_time_hr: float = 0
    fdt_dwpt_fraction_power_pct: float = 0
    fdt_avg_overhead_hr_per_dwell_hr: float = 0
    fdt_frac_full_charge_bounds: List[float] = field(default_factory=float)
    fdt_num_free_dwell_trips: float = 0
    fdt_available_freetime_hr: float = 0

    fuel_prices_dol_per_gge: List[float] = field(default_factory=float)
    insurance_rates_pct_per_yr: List[float] = field(default_factory=float)

    depreciation_rates_pct_per_yr: List[float] = field(default_factory=float)
    residual_rate_pct: float = 1.0

    activate_mr_downtime_cost: bool = True
    mr_planned_downtime_hr_per_yr: float = 0
    mr_unplanned_downtime_hr_per_mi: List[float] = field(default_factory=list)
    mr_avg_tire_life_mi: float = 0
    mr_tire_replace_downtime_hr_per_event: float = 0

    fuel_prices_file: str = "./auxiliary/FuelPrices.csv"
    fuel_prices_df: pd.DataFrame = None
    plf_weight_distribution_file: str = "./auxiliary/tractorweightvars.csv"

    avg_speed_mph: float = 0.0
    msrp_total_dol: float = 0.0

    mpgge: float = 0.0
    primary_fuel_range_mi: float = 0.0

    cost_toggles_file: Union[str, Path] = gl.RESOURCES_FOLDERPATH / "cost_toggles.json"
    cost_toggles: Toggles = field(default_factory=Toggles)

    def __new__(cls, *args, **kwargs):
        """
        Creates a new instance of the Scenario class.
        """
        instance = super(Scenario, cls).__new__(cls)
        return instance

    @classmethod
    def from_config(cls, selection: int, config: Config) -> Self:
        """
        Creates a Scenario instance from the configuration.

        Args:
            selection (int): The selection index.
            config (Config): The configuration instance.

        Returns:
            Self: An instance of the Scenario class.
        """
        if config.scenario_df is not None:
            return cls.from_df(selection=selection, scenario_df=config.scenario_df)
        else:
            return cls.from_csv(selection=selection, scenario_file=config.scenario_file)

    @classmethod
    def from_csv(
        cls,
        selection: int,
        scenario_file: Union[str, Path] = gl.RESOURCES_FOLDERPATH
        / "inputs"
        / "Demo_FY22_scenario_assumptions.csv",
        config: Config = None,
    ) -> Self:
        """
        Creates a Scenario instance from a CSV file.

        Args:
            selection (int): The selection index to filter the scenario data.
            scenario_file (Union[str, Path]): Path to the scenario CSV file.

        Returns:
            Scenario: An instance of the Scenario class.
        """
        if not scenario_file.absolute():
            scenario_file = Path(config.config_filename).parent / scenario_file

        scenario_df = pd.read_csv(
            scenario_file, usecols=lambda x: x in cls.__annotations__.keys()
        )
        return cls.from_df(
            selection=selection,
            scenario_df=scenario_df,
        )

    @classmethod
    def from_df(cls, selection: int, scenario_df: pd.DataFrame) -> Self:
        """
        Creates a Scenario instance from a DataFrame.

        Args:
            selection (int): The selection index to filter the scenario data.
            scenario_df (pd.DataFrame): The scenario DataFrame.

        Returns:
            Scenario: An instance of the Scenario class.
        """
        scenario_dict = scenario_df.loc[scenario_df["selection"] == selection].to_dict(
            "records"
        )[0]

        return cls.from_dict(scenario_dict=scenario_dict)

    @classmethod
    def from_dict(cls, scenario_dict: dict) -> Self:
        """
        Creates a Scenario instance from a dictionary.

        Args:
            scenario_dict (dict): The dictionary containing scenario data.

        Returns:
            Scenario: An instance of the Scenario class.
        """
        default_scenario = cls()
        for field_name in cls.__annotations__:
            scenario_dict.setdefault(field_name, getattr(default_scenario, field_name))

        def _parse_life_year_series(
            field_name: str, fallback_value: float
        ) -> list[float]:
            raw_value = scenario_dict.get(field_name)
            if raw_value in (None, ""):
                return [fallback_value] * int(scenario_dict["vehicle_life_yr"])

            if isinstance(raw_value, str):
                parsed_value = ast.literal_eval(raw_value)
            else:
                parsed_value = raw_value

            if isinstance(parsed_value, (list, tuple)):
                return list(parsed_value)[: int(scenario_dict["vehicle_life_yr"])]

            return [parsed_value] * int(scenario_dict["vehicle_life_yr"])

        scenario_dict["vehicle_class"] = " "
        scenario_dict["vehicle_class"] = (
            scenario_dict["vehicle_class"]
            .join(scenario_dict["scenario_name"].split()[:3])
            .lower()
        )
        scenario_dict["vmt"] = _parse_life_year_series("vmt", 0.0)
        scenario_dict["shifts_per_year"] = _parse_life_year_series(
            "shifts_per_year", 0.0
        )
        scenario_dict["mr_unplanned_downtime_hr_per_mi"] = _parse_life_year_series(
            "mr_unplanned_downtime_hr_per_mi", 0.0
        )
        scenario_dict["depreciation_rates_pct_per_yr"] = _parse_life_year_series(
            "depreciation_rates_pct_per_yr", 0.0
        )
        scenario_dict["maint_oper_cost_dol_per_mi"] = _parse_life_year_series(
            "maint_oper_cost_dol_per_mi", -1.0
        )

        return cls(**handle_nan(scenario_dict))

    def override_from_config(
        self, config: Config = None, verbose: bool = False
    ) -> Self:
        """
        Overrides certain scenario fields if use_config is True and config object is not None.

        Args:
            config (Config, optional): Config object containing configuration data. Defaults to None.
            verbose (bool, optional): If True, prints the overridden fields. Defaults to False.

        Raises:
            Exception: If config file is not attached or scenario.use_config is set to False.
        """
        fields_override = [
            "vehicle_life_yr",
            "fs_fueling_rate_kg_per_min",
            "fs_fueling_rate_gasoline_gpm",
            "fs_fueling_rate_diesel_gpm",
            "lw_imp_curve_sel",
            "eng_eff_imp_curve_sel",
            "aero_drag_imp_curve_sel",
            "purchasing_method",
            "constraint_range",
            "constraint_accel",
            "constraint_grade",
            "objective_tco",
            "constraint_c_rate",
            "constraint_trace_miss_dist_percent_on",
            "activate_tco_payload_cap_cost_multiplier",
            "activate_tco_fueling_dwell_time_cost",
            "fdt_frac_full_charge_bounds",
            "activate_mr_downtime_cost",
        ]
        try:
            if config.dc_files is None:
                fields_override.append("drive_cycle")
            self.fields_overriden = []
            if self.use_config and config is not None:
                for field_select in fields_override:
                    if config.__dict__[field_select] is not None:
                        setattr(
                            self, field_select, config.__getattribute__(field_select)
                        )
                        self.fields_overriden.append(field_select)
                print(
                    f"Scenario Fields overridden from config: {self.fields_overriden}"
                ) if verbose else None

        except Exception:
            print(
                f"Error in Config file. T3COConfig either not attached or scenario.use_config set to False: {config}"
            )

        if self.purchasing_method.lower() in [
            "loan",
            "financing",
            "autoloan",
            "borrowing",
        ]:
            self.purchasing_method = "loan"
        elif self.purchasing_method.lower() in ["leasing", "renting", "lease"]:
            self.purchasing_method = "lease"
        else:
            self.purchasing_method = "cash"

        self.insurance_rates_file = config.insurance_rates_file
        self.fuel_prices_file = config.fuel_prices_file
        self.fuel_prices_df = config.fuel_prices_df
        if config.fuel_prices_region:
            self.region = config.fuel_prices_region

        if self.activate_tco_payload_cap_cost_multiplier and config:
            self.plf_weight_distribution_file = config.plf_weight_dist_file

        if config.cost_toggles is not None:
            self.cost_toggles = config.cost_toggles

        self._resolve_zipcode_region(config)

    def _resolve_zipcode_region(self, config: Config) -> None:
        """If ``self.region`` is a US zipcode and the ``eia_fuel_prices``
        toggle is enabled, resolves it to the corresponding census division
        and fetches EIA fuel prices for that region.

        If the config already resolved a zipcode (``config.fuel_prices_region``
        is set), this method is a no-op.
        """
        if config.fuel_prices_region:
            return
        if not Config._is_zipcode(self.region):
            return
        if not getattr(self, "cost_toggles", None):
            return
        if not self.cost_toggles.eia_fuel_prices:
            return

        import os
        from t3co.data_fetching.eia_client import (
            T3CO_TO_AEO_REGION_ID,
            build_fuel_prices_df_from_eia,
        )

        Config._load_dotenv()

        region_val = self.region
        if isinstance(region_val, float) and region_val == int(region_val):
            region_val = int(region_val)
        zipcode = str(region_val).strip()
        region_name = resolve_fuel_price_region_from_zipcode(zipcode)
        aeo_region_id = T3CO_TO_AEO_REGION_ID.get(region_name)
        if not aeo_region_id:
            return

        api_key = os.environ.get("T3CO_EIA_API_KEY", "")
        if not api_key:
            return

        hydrogen_fallback_df = None
        if self.fuel_prices_file:
            try:
                from t3co.utils.print_class_objects import get_path_object
                hydrogen_fallback_df = pd.read_csv(
                    get_path_object(self.fuel_prices_file)
                )
            except Exception:
                pass

        self.fuel_prices_df = build_fuel_prices_df_from_eia(
            api_key=api_key,
            aeo_year=config.eia_aeo_year or None,
            scenario=config.eia_aeo_case or None,
            hydrogen_fallback_df=hydrogen_fallback_df,
            region_ids=[aeo_region_id],
        )
        self.fuel_prices_df = self.fuel_prices_df.set_index("Fuel")
        self.region = region_name
        print(
            f"Scenario zipcode {zipcode} resolved to EIA region: {region_name}"
        )

    def get_discounted_value(self, value: float, year_number: int) -> float:
        """
        Calculates the discounted value for a given year.

        Args:
            value (float): The value to be discounted.
            year_number (int): The year number for discounting.

        Returns:
            float: The discounted value.
        """
        return value / (1 + self.discount_rate_pct_per_yr) ** (year_number)

    def delete_dataframes(self) -> None:
        """
        Deletes DataFrame attributes from the Scenario instance.
        """
        remove_df_attrs(self)

__new__(*args, **kwargs)

Creates a new instance of the Scenario class.

Source code in src/t3co/input_data/scenario.py
156
157
158
159
160
161
def __new__(cls, *args, **kwargs):
    """
    Creates a new instance of the Scenario class.
    """
    instance = super(Scenario, cls).__new__(cls)
    return instance

from_config(selection, config) classmethod

Creates a Scenario instance from the configuration.

Parameters:

Name Type Description Default
selection int

The selection index.

required
config Config

The configuration instance.

required

Returns:

Name Type Description
Self Self

An instance of the Scenario class.

Source code in src/t3co/input_data/scenario.py
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
@classmethod
def from_config(cls, selection: int, config: Config) -> Self:
    """
    Creates a Scenario instance from the configuration.

    Args:
        selection (int): The selection index.
        config (Config): The configuration instance.

    Returns:
        Self: An instance of the Scenario class.
    """
    if config.scenario_df is not None:
        return cls.from_df(selection=selection, scenario_df=config.scenario_df)
    else:
        return cls.from_csv(selection=selection, scenario_file=config.scenario_file)

from_csv(selection, scenario_file=gl.RESOURCES_FOLDERPATH / 'inputs' / 'Demo_FY22_scenario_assumptions.csv', config=None) classmethod

Creates a Scenario instance from a CSV file.

Parameters:

Name Type Description Default
selection int

The selection index to filter the scenario data.

required
scenario_file Union[str, Path]

Path to the scenario CSV file.

RESOURCES_FOLDERPATH / 'inputs' / 'Demo_FY22_scenario_assumptions.csv'

Returns:

Name Type Description
Scenario Self

An instance of the Scenario class.

Source code in src/t3co/input_data/scenario.py
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
@classmethod
def from_csv(
    cls,
    selection: int,
    scenario_file: Union[str, Path] = gl.RESOURCES_FOLDERPATH
    / "inputs"
    / "Demo_FY22_scenario_assumptions.csv",
    config: Config = None,
) -> Self:
    """
    Creates a Scenario instance from a CSV file.

    Args:
        selection (int): The selection index to filter the scenario data.
        scenario_file (Union[str, Path]): Path to the scenario CSV file.

    Returns:
        Scenario: An instance of the Scenario class.
    """
    if not scenario_file.absolute():
        scenario_file = Path(config.config_filename).parent / scenario_file

    scenario_df = pd.read_csv(
        scenario_file, usecols=lambda x: x in cls.__annotations__.keys()
    )
    return cls.from_df(
        selection=selection,
        scenario_df=scenario_df,
    )

from_df(selection, scenario_df) classmethod

Creates a Scenario instance from a DataFrame.

Parameters:

Name Type Description Default
selection int

The selection index to filter the scenario data.

required
scenario_df DataFrame

The scenario DataFrame.

required

Returns:

Name Type Description
Scenario Self

An instance of the Scenario class.

Source code in src/t3co/input_data/scenario.py
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
@classmethod
def from_df(cls, selection: int, scenario_df: pd.DataFrame) -> Self:
    """
    Creates a Scenario instance from a DataFrame.

    Args:
        selection (int): The selection index to filter the scenario data.
        scenario_df (pd.DataFrame): The scenario DataFrame.

    Returns:
        Scenario: An instance of the Scenario class.
    """
    scenario_dict = scenario_df.loc[scenario_df["selection"] == selection].to_dict(
        "records"
    )[0]

    return cls.from_dict(scenario_dict=scenario_dict)

from_dict(scenario_dict) classmethod

Creates a Scenario instance from a dictionary.

Parameters:

Name Type Description Default
scenario_dict dict

The dictionary containing scenario data.

required

Returns:

Name Type Description
Scenario Self

An instance of the Scenario class.

Source code in src/t3co/input_data/scenario.py
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
@classmethod
def from_dict(cls, scenario_dict: dict) -> Self:
    """
    Creates a Scenario instance from a dictionary.

    Args:
        scenario_dict (dict): The dictionary containing scenario data.

    Returns:
        Scenario: An instance of the Scenario class.
    """
    default_scenario = cls()
    for field_name in cls.__annotations__:
        scenario_dict.setdefault(field_name, getattr(default_scenario, field_name))

    def _parse_life_year_series(
        field_name: str, fallback_value: float
    ) -> list[float]:
        raw_value = scenario_dict.get(field_name)
        if raw_value in (None, ""):
            return [fallback_value] * int(scenario_dict["vehicle_life_yr"])

        if isinstance(raw_value, str):
            parsed_value = ast.literal_eval(raw_value)
        else:
            parsed_value = raw_value

        if isinstance(parsed_value, (list, tuple)):
            return list(parsed_value)[: int(scenario_dict["vehicle_life_yr"])]

        return [parsed_value] * int(scenario_dict["vehicle_life_yr"])

    scenario_dict["vehicle_class"] = " "
    scenario_dict["vehicle_class"] = (
        scenario_dict["vehicle_class"]
        .join(scenario_dict["scenario_name"].split()[:3])
        .lower()
    )
    scenario_dict["vmt"] = _parse_life_year_series("vmt", 0.0)
    scenario_dict["shifts_per_year"] = _parse_life_year_series(
        "shifts_per_year", 0.0
    )
    scenario_dict["mr_unplanned_downtime_hr_per_mi"] = _parse_life_year_series(
        "mr_unplanned_downtime_hr_per_mi", 0.0
    )
    scenario_dict["depreciation_rates_pct_per_yr"] = _parse_life_year_series(
        "depreciation_rates_pct_per_yr", 0.0
    )
    scenario_dict["maint_oper_cost_dol_per_mi"] = _parse_life_year_series(
        "maint_oper_cost_dol_per_mi", -1.0
    )

    return cls(**handle_nan(scenario_dict))

override_from_config(config=None, verbose=False)

Overrides certain scenario fields if use_config is True and config object is not None.

Parameters:

Name Type Description Default
config Config

Config object containing configuration data. Defaults to None.

None
verbose bool

If True, prints the overridden fields. Defaults to False.

False

Raises:

Type Description
Exception

If config file is not attached or scenario.use_config is set to False.

Source code in src/t3co/input_data/scenario.py
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
def override_from_config(
    self, config: Config = None, verbose: bool = False
) -> Self:
    """
    Overrides certain scenario fields if use_config is True and config object is not None.

    Args:
        config (Config, optional): Config object containing configuration data. Defaults to None.
        verbose (bool, optional): If True, prints the overridden fields. Defaults to False.

    Raises:
        Exception: If config file is not attached or scenario.use_config is set to False.
    """
    fields_override = [
        "vehicle_life_yr",
        "fs_fueling_rate_kg_per_min",
        "fs_fueling_rate_gasoline_gpm",
        "fs_fueling_rate_diesel_gpm",
        "lw_imp_curve_sel",
        "eng_eff_imp_curve_sel",
        "aero_drag_imp_curve_sel",
        "purchasing_method",
        "constraint_range",
        "constraint_accel",
        "constraint_grade",
        "objective_tco",
        "constraint_c_rate",
        "constraint_trace_miss_dist_percent_on",
        "activate_tco_payload_cap_cost_multiplier",
        "activate_tco_fueling_dwell_time_cost",
        "fdt_frac_full_charge_bounds",
        "activate_mr_downtime_cost",
    ]
    try:
        if config.dc_files is None:
            fields_override.append("drive_cycle")
        self.fields_overriden = []
        if self.use_config and config is not None:
            for field_select in fields_override:
                if config.__dict__[field_select] is not None:
                    setattr(
                        self, field_select, config.__getattribute__(field_select)
                    )
                    self.fields_overriden.append(field_select)
            print(
                f"Scenario Fields overridden from config: {self.fields_overriden}"
            ) if verbose else None

    except Exception:
        print(
            f"Error in Config file. T3COConfig either not attached or scenario.use_config set to False: {config}"
        )

    if self.purchasing_method.lower() in [
        "loan",
        "financing",
        "autoloan",
        "borrowing",
    ]:
        self.purchasing_method = "loan"
    elif self.purchasing_method.lower() in ["leasing", "renting", "lease"]:
        self.purchasing_method = "lease"
    else:
        self.purchasing_method = "cash"

    self.insurance_rates_file = config.insurance_rates_file
    self.fuel_prices_file = config.fuel_prices_file
    self.fuel_prices_df = config.fuel_prices_df
    if config.fuel_prices_region:
        self.region = config.fuel_prices_region

    if self.activate_tco_payload_cap_cost_multiplier and config:
        self.plf_weight_distribution_file = config.plf_weight_dist_file

    if config.cost_toggles is not None:
        self.cost_toggles = config.cost_toggles

    self._resolve_zipcode_region(config)

get_discounted_value(value, year_number)

Calculates the discounted value for a given year.

Parameters:

Name Type Description Default
value float

The value to be discounted.

required
year_number int

The year number for discounting.

required

Returns:

Name Type Description
float float

The discounted value.

Source code in src/t3co/input_data/scenario.py
422
423
424
425
426
427
428
429
430
431
432
433
def get_discounted_value(self, value: float, year_number: int) -> float:
    """
    Calculates the discounted value for a given year.

    Args:
        value (float): The value to be discounted.
        year_number (int): The year number for discounting.

    Returns:
        float: The discounted value.
    """
    return value / (1 + self.discount_rate_pct_per_yr) ** (year_number)

delete_dataframes()

Deletes DataFrame attributes from the Scenario instance.

Source code in src/t3co/input_data/scenario.py
435
436
437
438
439
def delete_dataframes(self) -> None:
    """
    Deletes DataFrame attributes from the Scenario instance.
    """
    remove_df_attrs(self)