Beispiel #1
0
def calc_def_costs(settings, totals_dict, fuel_arg):
    """

    Parameters:
        settings: The SetInputs class. \n
        totals_dict: Dictionary; provides fleet DEF consumption by vehicle.\n
        fuel_arg: String; specifies the fuel attribute to use (e.g., "Gallons" or "Gallons_withTech")

    Returns:
        The passed dictionary updated with costs associated with DEF consumption.

    """
    print('\nCalculating DEF total costs...')
    calcs = FleetTotals(totals_dict)
    prices = InputFileDict(settings.def_prices_dict)

    # get keys where fueltype=2 (Diesel since they are the only vehicles that use DEF)
    ft2_keys = [k for k, v in totals_dict.items() if v['fuelTypeID'] == 2]

    for key in ft2_keys:
        vehicle, alt, model_year, age_id, disc_rate = key
        calendar_year = model_year + age_id
        def_price = prices.get_attribute_value(calendar_year, 'DEF_USDperGal')
        gallons_def = calc_def_gallons(settings, vehicle, alt, calendar_year,
                                       model_year, totals_dict, fuel_arg)
        cost = def_price * gallons_def

        temp_dict = {
            'DEF_Gallons': gallons_def,
            'DEFCost': cost,
        }
        calcs.update_dict(key, temp_dict)

    return totals_dict
Beispiel #2
0
def tech_pkg_cost_withlearning(settings, unit, alt, cost_step, sales_arg, cumulative_sales, totals_dict):
    """

    Parameters:
        settings: The SetInputs class.\n
        unit: Tuple; represents a regclass_fueltype engine or a sourcetype_regclass_fueltype vehicle.\n
        alt: The alternative or option ID.\n
        cost_step: String; represents the model year of implementation in case standards are implemented in stages then these would represent multiple cost steps.\n
        sales_arg: String; specifies the sales attribute to use (e.g., "VPOP" or "VPOP_withTech") \n
        cumulative_sales: Numeric; represents cumulative sales of unit since cost_step. \n
        totals_dict: A dictionary containing sales (sales_arg) of units by model year.\n

    Returns:
        The package cost with learning applied for the passed unit in the given model year and associated with the given cost_step.

    """
    sales_year1 = FleetTotals(totals_dict).calc_unit_sales(unit, alt, int(cost_step), sales_arg)

    if sales_year1 == 0:
        pkg_cost_learned = 0
    else:
        try:
            rc, ft = unit
            seedvolume_factors = InputFileDict(settings.seedvol_factor_regclass_dict)
        except:
            st, rc, ft = unit
            seedvolume_factors = InputFileDict(settings.seedvol_factor_sourcetype_dict)

        seedvolume_factor = seedvolume_factors.get_attribute_value((unit, alt), 'SeedVolumeFactor')
        pkg_cost = tech_package_cost(settings, unit, alt, cost_step)

        pkg_cost_learned = pkg_cost \
                           * (((cumulative_sales + (sales_year1 * seedvolume_factor))
                               / (sales_year1 + (sales_year1 * seedvolume_factor))) ** settings.learning_rate)
    return pkg_cost_learned
Beispiel #3
0
def calc_fuel_costs(settings, totals_dict, fuel_arg, program):
    """

    Parameters:
        settings: The SetInputs class.\n
        totals_dict: Dictionary; provides the fleet Gallons consumed by all vehicles. \n
        fuel_arg: String; specifies the fuel attribute to use (e.g., "Gallons" or "Gallons_withTech")\n
        program: String; represents which program is being run, CAP or GHG.

    Returns:
        The passed dictionary updated to reflect fuel consumption (Gallons) adjusted to account for the fuel saved in association with ORVR.
        The dictionary is also updated to include the fuel costs associated with the gallons consumed (Gallons * $/gallon fuel).

    Note:
        Note that gallons of fuel captured are not included in the MOVES runs that serve as the input fleet data for the tool although the inventory impacts
        are included in the MOVES runs.

    """
    print('\nCalculating CAP-related fuel costs...')

    calcs = FleetTotals(totals_dict)
    prices = InputFileDict(settings.fuel_prices_dict)

    for key in totals_dict.keys():
        captured_gallons = 0
        vehicle, alt, model_year, age_id, disc_rate = key
        st, rc, ft = vehicle
        calendar_year = model_year + age_id
        fuel_price_retail = prices.get_attribute_value((calendar_year, ft), 'retail_fuel_price')
        fuel_price_pretax = prices.get_attribute_value((calendar_year, ft), 'pretax_fuel_price')
        if ft == 1:
            captured_gallons = calc_captured_gallons(settings, vehicle, alt, calendar_year, model_year, totals_dict, program)

        gallons = calcs.get_attribute_value(key, fuel_arg)
        gallons_paid_for = gallons - captured_gallons

        cost_retail = fuel_price_retail * gallons_paid_for
        cost_pretax = fuel_price_pretax * gallons_paid_for

        temp_dict = {'GallonsCaptured_byORVR': captured_gallons,
                     'FuelCost_Retail': cost_retail,
                     'FuelCost_Pretax': cost_pretax,
                     }
        calcs.update_dict(key, temp_dict)

    return totals_dict
Beispiel #4
0
def calc_estimated_age(settings, vehicle, alt, model_year, identifier, typical_vmt, estimated_ages_dict):
    """

    Parameters:
        settings: The SetInputs class.\n
        vehicle: Tuple; represents a sourcetype_regclass_fueltype vehicle.\n
        alt: Numeric; the Alternative or option ID.\n
        model_year: Numeric; the model year of the passed vehicle.\n
        identifier: String; the identifier of the age being estimated (i.e., 'Warranty' or 'Usefullife'). \n
        typical_vmt: Numeric; the typical annual VMT/vehicle over a set number of years as set via the General Inputs workbook (see calc_typical_vmt_per_year function).\n
        estimated_ages_dict: Dictionary in which to collect estimated ages to be included in the outputs for the given run.

    Returns:
        An integer representing the age at which the identifier will be reached for the passed vehicle/model year.\n
        A dictionary that tracks those ages for all vehicles.

    """
    miles_and_ages_dict = InputFileDict(settings.warranty_inputs_dict)
    if identifier == 'Usefullife': miles_and_ages_dict = InputFileDict(settings.usefullife_inputs_dict)

    st, rc, ft = vehicle
    required_age = miles_and_ages_dict.get_attribute_value(((rc, ft, 'Age'), alt), str(model_year))
    required_miles = miles_and_ages_dict.get_attribute_value(((rc, ft, 'Miles'), alt), str(model_year))
    calculated_age = round(required_miles / typical_vmt)
    estimated_age = min(required_age, calculated_age)
    estimated_ages_dict[(vehicle, alt, model_year, identifier)] = ({'vehicle': vehicle,
                                                                    'optionID': alt,
                                                                    'modelYearID': model_year,
                                                                    'identifier': identifier,
                                                                    'typical_vmt': typical_vmt,
                                                                    'required_age': required_age,
                                                                    'calculated_age': calculated_age,
                                                                    'estimated_age': estimated_age,
                                                                    })
    return estimated_age, estimated_ages_dict
Beispiel #5
0
def get_criteria_cost_factors(settings, calendar_year):
    """

    Parameters:
        settings: The SetInputs class.\n
        calendar_year: Numeric; the calendar year for which emission cost factors are needed.

    Returns:
        Six values - the PM25, NOx and SO2 emission cost factors (dollars/ton) for each of two different mortality estimates and each of two
        different discount rates.

    Note:
        Note that the BCA_General_Inputs file contains a toggle to stipulate whether to estimate emission (pollution) costs or not. This function is called
        only if that toggle is set to 'Y' (yes). The default setting is 'N' (no).

    """
    cost_factors = InputFileDict(settings.criteria_cost_factors_dict)

    cap_dr1 = settings.criteria_discount_rate_1
    cap_dr2 = settings.criteria_discount_rate_2

    pm_tailpipe_cap_dr1, pm_tailpipe_cap_dr2 = cost_factors.get_attribute_value(calendar_year, f'pm25_tailpipe_{str(cap_dr1)}_USD_per_uston'), \
                                               cost_factors.get_attribute_value(calendar_year, f'pm25_tailpipe_{str(cap_dr2)}_USD_per_uston')
    nox_tailpipe_cap_dr1, nox_tailpipe_cap_dr2 = cost_factors.get_attribute_value(calendar_year, f'nox_tailpipe_{str(cap_dr1)}_USD_per_uston'), \
                                                 cost_factors.get_attribute_value(calendar_year, f'nox_tailpipe_{str(cap_dr2)}_USD_per_uston')
    so2_tailpipe_cap_dr1, so2_tailpipe_cap_dr2 = cost_factors.get_attribute_value(calendar_year, f'so2_tailpipe_{str(cap_dr1)}_USD_per_uston'), \
                                               cost_factors.get_attribute_value(calendar_year, f'so2_tailpipe_{str(cap_dr2)}_USD_per_uston')

    return pm_tailpipe_cap_dr1, pm_tailpipe_cap_dr2, \
           nox_tailpipe_cap_dr1, nox_tailpipe_cap_dr2, \
           so2_tailpipe_cap_dr1, so2_tailpipe_cap_dr2
Beispiel #6
0
def calc_def_doserate(settings, vehicle):
    """

    Parameters:
        settings: The SetInputs class \n
        vehicle: Tuple; represents a sourcetype_regclass_fueltype vehicle.\n

    Returns:
        The DEF dose rate for the passed vehicle based on the DEF dose rate input file.

    """
    def_doserate_dict = InputFileDict(settings.def_doserate_inputs_dict)

    st, rc, ft = vehicle
    nox_std = def_doserate_dict.get_attribute_value((rc, ft), 'standard_NOx')
    nox_engine_out = def_doserate_dict.get_attribute_value((rc, ft),
                                                           'engineout_NOx')
    doserate_intercept = def_doserate_dict.get_attribute_value(
        (rc, ft), 'intercept_DEFdoserate')
    doserate_slope = def_doserate_dict.get_attribute_value((rc, ft),
                                                           'slope_DEFdoserate')
    base_doserate = (
        (nox_std - nox_engine_out) - doserate_intercept) / doserate_slope

    return base_doserate
Beispiel #7
0
def get_orvr_adjustment(settings, vehicle, alt, program):
    """
    
    Parameters:
        settings: The SetInputs class.\n
        vehicle: Tuple; represents a sourcetype_regclass_fueltype vehicle.\n
        alt: Numeric; the Alternative or option ID. \n
        program: String; represents which program is being run, CAP or GHG.

    Returns:
        A single value representing the milliliter per gram adjustment to be applied to total hydrocarbon emission reductions to
        estimate the gallons of fuel saved.

    """
    if program == 'CAP': orvr_inputs = InputFileDict(settings.orvr_inputs_dict_cap)
    else: orvr_inputs = InputFileDict(settings.orvr_inputs_dict_ghg)

    st, rc, ft = vehicle
    engine = (rc, ft)
    orvr_inputs_key = (engine, alt)
    adjustment = orvr_inputs.get_attribute_value(orvr_inputs_key, 'ml/g')

    return adjustment
Beispiel #8
0
    def __init__(self):
        """

        The SetInputs class establishes the input files to use and other input settings set in the BCA_Inputs file and needed within the tool.

        """
        set_paths = SetPaths()

        self.start_time = time.time()
        self.start_time_readable = datetime.now().strftime('%Y%m%d-%H%M%S')
        print(f'\nHD BCA tool version: {bca_tool_code.__version__}')
        print(f'\nStart date and time:  {self.start_time_readable}')
        print("\nReading input files...")

        self.start_time_read = time.time()
        self.input_files_df = gen_fxns.read_input_files(
            set_paths.path_inputs,
            'Input_Files.csv',
            usecols=lambda x: 'Notes' not in x,
            index_col=0)
        self.input_files_dict = self.input_files_df.to_dict('index')

        self.bca_inputs = gen_fxns.read_input_files(
            set_paths.path_inputs,
            self.input_files_dict['bca_inputs']['UserEntry.csv'],
            usecols=lambda x: 'Notes' not in x,
            index_col=0)
        self.regclass_costs = gen_fxns.read_input_files(
            set_paths.path_inputs,
            self.input_files_dict['regclass_costs']['UserEntry.csv'],
            usecols=lambda x: 'Notes' not in x)
        self.sourcetype_costs = gen_fxns.read_input_files(
            set_paths.path_inputs,
            self.input_files_dict['sourcetype_costs']['UserEntry.csv'],
            usecols=lambda x: 'Notes' not in x)
        self.regclass_learningscalers = gen_fxns.read_input_files(
            set_paths.path_inputs,
            self.input_files_dict['regclass_learningscalers']['UserEntry.csv'],
            usecols=lambda x: 'Notes' not in x)
        self.sourcetype_learningscalers = gen_fxns.read_input_files(
            set_paths.path_inputs,
            self.input_files_dict['sourcetype_learningscalers']
            ['UserEntry.csv'],
            usecols=lambda x: 'Notes' not in x)
        self.markups_regclass = gen_fxns.read_input_files(
            set_paths.path_inputs,
            self.input_files_dict['markups_regclass']['UserEntry.csv'],
            usecols=lambda x: 'Notes' not in x)
        self.markups_sourcetype = gen_fxns.read_input_files(
            set_paths.path_inputs,
            self.input_files_dict['markups_sourcetype']['UserEntry.csv'],
            usecols=lambda x: 'Notes' not in x)
        self.warranty_inputs = gen_fxns.read_input_files(
            set_paths.path_inputs,
            self.input_files_dict['warranty_inputs']['UserEntry.csv'],
            usecols=lambda x: 'Notes' not in x)
        self.usefullife_inputs = gen_fxns.read_input_files(
            set_paths.path_inputs,
            self.input_files_dict['usefullife_inputs']['UserEntry.csv'],
            usecols=lambda x: 'Notes' not in x)
        self.moves_cap = gen_fxns.read_input_files(
            set_paths.path_inputs,
            self.input_files_dict['moves_cap']['UserEntry.csv'],
            usecols=lambda x: 'Notes' not in x)
        self.moves_ghg = gen_fxns.read_input_files(
            set_paths.path_inputs,
            self.input_files_dict['moves_ghg']['UserEntry.csv'],
            usecols=lambda x: 'Notes' not in x)
        self.moves_adjustments_cap = gen_fxns.read_input_files(
            set_paths.path_inputs,
            self.input_files_dict['moves_adjustments_cap']['UserEntry.csv'],
            usecols=lambda x: 'Notes' not in x)
        self.moves_adjustments_ghg = gen_fxns.read_input_files(
            set_paths.path_inputs,
            self.input_files_dict['moves_adjustments_ghg']['UserEntry.csv'],
            usecols=lambda x: 'Notes' not in x)
        self.options_cap = gen_fxns.read_input_files(
            set_paths.path_inputs,
            self.input_files_dict['options_cap']['UserEntry.csv'],
            usecols=lambda x: 'Notes' not in x,
            index_col=0)
        self.options_ghg = gen_fxns.read_input_files(
            set_paths.path_inputs,
            self.input_files_dict['options_ghg']['UserEntry.csv'],
            usecols=lambda x: 'Notes' not in x,
            index_col=0)
        self.options_cap_dict = self.options_cap.to_dict('index')
        self.options_ghg_dict = self.options_ghg.to_dict('index')
        self.def_doserate_inputs = gen_fxns.read_input_files(
            set_paths.path_inputs,
            self.input_files_dict['def_doserate_inputs']['UserEntry.csv'],
            usecols=lambda x: 'Notes' not in x)
        self.def_prices = gen_fxns.read_input_files(
            set_paths.path_inputs,
            self.input_files_dict['def_prices']['UserEntry.csv'],
            usecols=lambda x: 'Notes' not in x)
        self.orvr_fuelchanges_cap = gen_fxns.read_input_files(
            set_paths.path_inputs,
            self.input_files_dict['orvr_fuelchanges_cap']['UserEntry.csv'],
            usecols=lambda x: 'Notes' not in x)
        self.orvr_fuelchanges_ghg = gen_fxns.read_input_files(
            set_paths.path_inputs,
            self.input_files_dict['orvr_fuelchanges_ghg']['UserEntry.csv'],
            usecols=lambda x: 'Notes' not in x)
        self.repair_and_maintenance = gen_fxns.read_input_files(
            set_paths.path_inputs,
            self.input_files_dict['repair_and_maintenance']['UserEntry.csv'],
            usecols=lambda x: 'Notes' not in x,
            index_col=0)
        self.unit_conversions = gen_fxns.read_input_files(
            set_paths.path_inputs,
            self.input_files_dict['unit_conversions']['UserEntry.csv'],
            usecols=lambda x: 'Notes' not in x,
            index_col=0)

        self.fuel_prices_file = gen_fxns.read_input_files(
            set_paths.path_inputs,
            self.input_files_dict['fuel_prices_file']['UserEntry.csv'],
            skiprows=4,
            reset_index=True)
        self.deflators_file = gen_fxns.read_input_files(
            set_paths.path_inputs,
            self.input_files_dict['deflators_file']['UserEntry.csv'],
            skiprows=4,
            reset_index=True)

        self.input_files_pathlist = SetPaths().input_files_pathlist(
            self.input_files_df)

        self.elapsed_time_read = time.time() - self.start_time_read

        # set some year data
        self.moves_cap.insert(
            self.moves_cap.columns.get_loc('modelYearID') + 1, 'ageID',
            self.moves_cap['yearID'] - self.moves_cap['modelYearID'])
        self.moves_ghg.insert(
            self.moves_ghg.columns.get_loc('modelYearID') + 1, 'ageID',
            self.moves_ghg['yearID'] - self.moves_ghg['modelYearID'])
        self.year_min = self.moves_cap.loc[
            self.moves_cap['ageID'] == 0, 'yearID'].min(
            )  # this will work for both calendar year and model year
        self.year_max = self.moves_cap['yearID'].max(
        )  # this is the last calendar year included
        self.model_year_max = self.moves_cap.loc[
            self.moves_cap['ageID'] == 0, 'modelYearID'].max(
            )  # calendar years could extend beyond the last model year included
        self.years = range(self.year_min, self.year_max + 1)
        self.model_years = range(self.year_min, self.model_year_max + 1)

        # parse values from the input files
        self.calc_cap_value = self.bca_inputs.at['calculate_cap_costs',
                                                 'UserEntry']
        self.calc_ghg_value = self.bca_inputs.at['calculate_ghg_costs',
                                                 'UserEntry']
        self.calc_cap_pollution_effects_value = self.bca_inputs.at[
            'calculate_cap_pollution_effects', 'UserEntry']
        self.calc_ghg_pollution_effects_value = self.bca_inputs.at[
            'calculate_ghg_pollution_effects', 'UserEntry']

        self.dollar_basis_analysis = pd.to_numeric(
            self.bca_inputs.at['dollar_basis_analysis', 'UserEntry'])
        self.no_action_alt = pd.to_numeric(self.bca_inputs.at['no_action_alt',
                                                              'UserEntry'])
        self.aeo_case = self.bca_inputs.at['aeo_fuel_price_case', 'UserEntry']
        self.discount_to_yearID = pd.to_numeric(
            self.bca_inputs.at['discount_to_yearID', 'UserEntry'])
        self.costs_start = self.bca_inputs.at['costs_start', 'UserEntry']
        self.learning_rate = pd.to_numeric(self.bca_inputs.at['learning_rate',
                                                              'UserEntry'])

        self.warranty_vmt_share = pd.to_numeric(
            self.bca_inputs.at['warranty_vmt_share', 'UserEntry'])
        self.r_and_d_vmt_share = pd.to_numeric(
            self.bca_inputs.at['r_and_d_vmt_share', 'UserEntry'])
        self.indirect_cost_scaling_metric = self.bca_inputs.at[
            'scale_indirect_costs_by', 'UserEntry']
        self.def_gallons_per_ton_nox_reduction = pd.to_numeric(
            self.bca_inputs.at['def_gallons_per_ton_nox_reduction',
                               'UserEntry'])
        self.max_age_included = pd.to_numeric(
            self.bca_inputs.at['weighted_operating_cost_thru_ageID',
                               'UserEntry'])
        self.social_discount_rate_1 = pd.to_numeric(
            self.bca_inputs.at['social_discount_rate_1', 'UserEntry'])
        self.social_discount_rate_2 = pd.to_numeric(
            self.bca_inputs.at['social_discount_rate_2', 'UserEntry'])
        self.criteria_discount_rate_1 = pd.to_numeric(
            self.bca_inputs.at['criteria_discount_rate_1', 'UserEntry'])
        self.criteria_discount_rate_2 = pd.to_numeric(
            self.bca_inputs.at['criteria_discount_rate_2', 'UserEntry'])

        self.grams_per_short_ton = self.unit_conversions.at[
            'grams_per_short_ton', 'UserEntry']
        self.gallons_per_ml = self.unit_conversions.at['gallons_per_ml',
                                                       'UserEntry']

        self.calc_cap = True if self.calc_cap_value == 'Y' else None
        self.calc_ghg = True if self.calc_ghg_value == 'Y' else None
        self.calc_cap_pollution_effects = True if self.calc_cap_pollution_effects_value == 'Y' else None
        self.calc_ghg_pollution_effects = True if self.calc_ghg_pollution_effects_value == 'Y' else None

        # now adjust some things as needed
        if 'Alternative' in self.moves_cap.columns.tolist():
            self.moves_cap.rename(columns={'Alternative': 'optionID'},
                                  inplace=True)
        if 'Alternative' in self.moves_ghg.columns.tolist():
            self.moves_ghg.rename(columns={'Alternative': 'optionID'},
                                  inplace=True)
        self.number_alts_cap = len(self.options_cap['OptionName'].unique())
        self.number_alts_ghg = len(self.options_ghg['OptionName'].unique())

        # get the fuel price inputs and usd basis for the analysis
        self.fuel_prices_obj = GetFuelPrices(self.fuel_prices_file,
                                             self.aeo_case, 'full name',
                                             'Motor Gasoline', 'Diesel')
        print(self.fuel_prices_obj)
        self.fuel_prices = self.fuel_prices_obj.get_prices()
        # self.dollar_basis_analysis = self.fuel_prices_obj.aeo_dollars()

        # generate a dictionary of gdp deflators, calc adjustment values and apply adjustment values to cost inputs
        self.deflators_obj = GetDeflators(self.deflators_file, 'Unnamed: 1',
                                          'Gross domestic product')
        self.gdp_deflators = self.deflators_obj.calc_adjustment_factors(
            self.dollar_basis_analysis)
        self.cost_steps_regclass = [
            col for col in self.regclass_costs.columns if '20' in col
        ]
        self.cost_steps_sourcetype = [
            col for col in self.sourcetype_costs.columns if '20' in col
        ]
        gen_fxns.convert_dollars_to_analysis_basis(
            self.regclass_costs, self.gdp_deflators,
            self.dollar_basis_analysis,
            [step for step in self.cost_steps_regclass])
        gen_fxns.convert_dollars_to_analysis_basis(
            self.sourcetype_costs, self.gdp_deflators,
            self.dollar_basis_analysis,
            [step for step in self.cost_steps_sourcetype])
        gen_fxns.convert_dollars_to_analysis_basis(self.def_prices,
                                                   self.gdp_deflators,
                                                   self.dollar_basis_analysis,
                                                   'DEF_USDperGal')
        gen_fxns.convert_dollars_to_analysis_basis(self.repair_and_maintenance,
                                                   self.gdp_deflators,
                                                   self.dollar_basis_analysis,
                                                   'Value')
        gen_fxns.convert_dollars_to_analysis_basis(self.fuel_prices,
                                                   self.gdp_deflators,
                                                   self.dollar_basis_analysis,
                                                   'retail_fuel_price',
                                                   'pretax_fuel_price')

        # create any DataFrames and dictionaries and lists that are useful as part of settings (used throughout project)
        self.moves_adjustments_cap_dict, self.moves_adjustments_ghg_dict = dict(
        ), dict()
        self.seedvol_factor_regclass_dict, self.seedvol_factor_sourcetype_dict = dict(
        ), dict()
        self.markup_inputs_regclass_dict, self.markup_inputs_sourcetype_dict = dict(
        ), dict()
        self.orvr_inputs_dict_cap, self.orvr_inputs_dict_ghg, self.fuel_prices_dict = dict(
        ), dict(), dict()
        self.def_doserate_inputs_dict, self.def_prices_dict = dict(), dict()
        self.required_miles_and_ages_dict, self.criteria_cost_factors_dict = dict(
        ), dict()
        self.warranty_inputs_dict, self.usefullife_inputs_dict = dict(), dict()

        self.moves_adjustments_cap_dict = InputFileDict(self.moves_adjustments_cap_dict)\
            .create_project_dict(self.moves_adjustments_cap, 'sourceTypeID', 'regClassID', 'fuelTypeID', 'optionID')
        self.moves_adjustments_ghg_dict = InputFileDict(self.moves_adjustments_ghg_dict)\
            .create_project_dict(self.moves_adjustments_ghg, 'sourceTypeID', 'regClassID', 'fuelTypeID', 'optionID')

        self.seedvol_factor_regclass_dict = InputFileDict(self.seedvol_factor_regclass_dict)\
            .create_project_dict(self.regclass_learningscalers, 'regClassID', 'fuelTypeID', 'optionID')
        self.seedvol_factor_sourcetype_dict = InputFileDict(self.seedvol_factor_sourcetype_dict)\
            .create_project_dict(self.sourcetype_learningscalers, 'sourceTypeID', 'regClassID', 'fuelTypeID', 'optionID')

        self.markup_inputs_regclass_dict = InputFileDict(self.markup_inputs_regclass_dict)\
            .create_project_dict(self.markups_regclass, 'fuelTypeID', 'Markup_Factor', 'optionID')
        self.markup_inputs_sourcetype_dict = InputFileDict(self.markup_inputs_sourcetype_dict)\
            .create_project_dict(self.markups_regclass, 'fuelTypeID', 'Markup_Factor', 'optionID')

        self.orvr_inputs_dict_cap = InputFileDict(self.orvr_inputs_dict_cap)\
            .create_project_dict(self.orvr_fuelchanges_cap, 'regClassID', 'fuelTypeID', 'optionID')
        self.orvr_inputs_dict_ghg = InputFileDict(self.orvr_inputs_dict_ghg) \
            .create_project_dict(self.orvr_fuelchanges_ghg, 'regClassID', 'fuelTypeID', 'optionID')
        self.fuel_prices_dict = InputFileDict(self.fuel_prices_dict)\
            .create_project_dict(self.fuel_prices, 'yearID', 'fuelTypeID')

        self.def_doserate_inputs_dict = InputFileDict(self.def_doserate_inputs_dict)\
            .create_project_dict(self.def_doserate_inputs, 'regClassID', 'fuelTypeID')
        self.def_prices_dict = InputFileDict(self.def_prices_dict)\
            .create_project_dict(self.def_prices, 'yearID')

        self.warranty_inputs_dict = InputFileDict(self.warranty_inputs_dict)\
            .create_project_dict(self.warranty_inputs, 'regClassID', 'fuelTypeID', 'period', 'optionID')
        self.usefullife_inputs_dict = InputFileDict(self.usefullife_inputs_dict) \
            .create_project_dict(self.usefullife_inputs, 'regClassID', 'fuelTypeID', 'period', 'optionID')
        self.repair_inputs_dict = self.repair_and_maintenance.to_dict('index')

        self.markup_factors_unique_names = [
            arg for arg in self.markups_regclass['Markup_Factor'].unique()
        ]
        self.markup_factors_sourcetype = [
            arg for arg in self.markups_sourcetype['Markup_Factor'].unique()
        ]

        # read criteria cost factors if needed
        if self.calc_cap_pollution_effects:
            self.criteria_cost_factors = gen_fxns.read_input_files(
                set_paths.path_inputs,
                self.input_files_dict['criteria_emission_costs']
                ['UserEntry.csv'], lambda x: 'Notes' not in x)
            self.criteria_cost_factors_dict = InputFileDict(self.criteria_cost_factors_dict)\
                .create_project_dict(self.criteria_cost_factors, 'yearID')

        if self.calc_ghg_pollution_effects:
            print(
                '\nWARNING: The tool is not configured to calculate GHG effects at this time.'
            )

        self.row_header_for_fleet_files = [
            'yearID',
            'modelYearID',
            'ageID',
            'optionID',
            'OptionName',
            'sourceTypeID',
            'sourceTypeName',
            'regClassID',
            'regClassName',
            'fuelTypeID',
            'fuelTypeName',
            'DiscountRate',
        ]
        self.row_header_for_annual_summary_files = [
            'yearID', 'optionID', 'OptionName', 'DiscountRate'
        ]
Beispiel #9
0
def calc_project_markup_value(settings, unit, alt, markup_factor_name,
                              model_year):
    """

    This function calculates the project markup value for the markup_factor (Warranty, RnD, Other, Profit) passed.

    Parameters:
        settings: The SetInputs classs.\n
        unit:  Tuple; represents a regclass_fueltype engine or a sourcetype_regclass_fueltype vehicle.\n
        alt: Numeric; The Alternative or option ID.\n
        markup_factor_name: String; represents the name of the project markup factor value to return (warranty, r and d, other, etc.).\n
        model_year: Numeric; the model year of the passed unit.

    Returns:
        A single markup factor value to be used in the project having been adjusted in accordance with the proposed warranty and useful life
        changes and the Absolute/Relative scaling entries.

    Note:
        The project markup factor differs from the input markup factors by scaling where that scaling is done based on the "Absolute" or "Relative"
        entries in the input file and by the scaling metric (Miles or Age) entries of the warranty/useful life input files. Whether Miles or Age is used is set
        via the BCA_General_Inputs file.

    """
    try:
        rc, ft = unit
        markups_dict = InputFileDict(settings.markup_inputs_regclass_dict)
    except:
        st, rc, ft = unit
        markups_dict = InputFileDict(settings.markup_inputs_sourcetype_dict)

    markups_dict_key = (ft, markup_factor_name), alt
    scaling_metric = settings.indirect_cost_scaling_metric  # scaling metric will be 'Miles' or 'Age'
    input_markup_value, scaler, scaled_by, num_years = markups_dict.get_attribute_value(markups_dict_key, 'Value'), \
                                                       markups_dict.get_attribute_value(markups_dict_key, 'Scaler'), \
                                                       markups_dict.get_attribute_value(markups_dict_key, 'Scaled_by'), \
                                                       markups_dict.get_attribute_value(markups_dict_key, 'NumberOfYears')

    numerator, denominator = 1, 1

    # remember that warranty and useful life provisions are by regclass, not sourcetype
    scaling_dict_key = ((rc, ft, scaling_metric), alt)
    if scaled_by == 'Warranty':
        scaling_dict = InputFileDict(settings.warranty_inputs_dict)
        numerator = scaling_dict.get_attribute_value(scaling_dict_key,
                                                     f'{model_year}')
    elif scaled_by == 'Usefullife':
        scaling_dict = InputFileDict(settings.usefullife_inputs_dict)
        numerator = scaling_dict.get_attribute_value(scaling_dict_key,
                                                     f'{model_year}')
    else:
        pass

    if scaler == 'Absolute':
        denominator = scaling_dict.get_attribute_value(scaling_dict_key,
                                                       '2024')
    elif scaler == 'Relative':
        denominator = scaling_dict.get_attribute_value(
            scaling_dict_key, str(int(model_year) - int(num_years)))
    else:
        pass

    project_markup_value = input_markup_value * (numerator / denominator)

    return project_markup_value