From 62c066ec113b93996c06693ddad9f3eabf086922 Mon Sep 17 00:00:00 2001 From: LesageP Date: Tue, 25 Jan 2022 23:37:00 -0500 Subject: [PATCH 1/9] Include month resolution to hurdle rates --- db/csvs_test_examples/scenarios.csv | 184 +++++++++--------- .../horizon_params.csv | 2 + .../horizon_timepoints.csv | 2 + .../period_params.csv | 2 + .../10_1horizon_1period_2months/structure.csv | 3 + .../1_transmission_hurdle_rates_1.csv | 14 +- db/db_schema.sql | 4 +- .../transmission/operations/hurdle_costs.py | 135 +++++++++---- .../inputs/transmission_hurdle_rates.tab | 16 +- .../operations/test_hurdle_costs.py | 86 ++++++-- 10 files changed, 286 insertions(+), 162 deletions(-) create mode 100644 db/csvs_test_examples/temporal/10_1horizon_1period_2months/horizon_params.csv create mode 100644 db/csvs_test_examples/temporal/10_1horizon_1period_2months/horizon_timepoints.csv create mode 100644 db/csvs_test_examples/temporal/10_1horizon_1period_2months/period_params.csv create mode 100644 db/csvs_test_examples/temporal/10_1horizon_1period_2months/structure.csv diff --git a/db/csvs_test_examples/scenarios.csv b/db/csvs_test_examples/scenarios.csv index 5b0424998..d4bf2d12f 100644 --- a/db/csvs_test_examples/scenarios.csv +++ b/db/csvs_test_examples/scenarios.csv @@ -1,93 +1,93 @@ -optional_feature_or_subscenarios,test,test_w_storage,test_w_hydro,test_new_solar,test_new_binary_solar,test_new_build_storage,test_new_build_storage_cumulative_min_max,test_new_binary_build_storage,test_no_overgen_allowed,test_no_reserves,test_variable_gen_reserves,test_new_solar_carbon_cap,test_new_solar_carbon_tax,test_ramp_up_constraints,test_ramp_up_and_down_constraints,2horizons,2horizons_w_hydro,2horizons_w_hydro_and_nuclear_binary_availability,2horizons_w_hydro_w_balancing_types,2periods,2periods_gen_lin_econ_retirement,2periods_gen_bin_econ_retirement,2periods_new_build,2periods_new_build_2zones,2periods_new_build_2zones_singleBA,2periods_new_build_2zones_transmission,2periods_new_build_2zones_transmission_w_losses,2periods_new_build_2zones_transmission_w_losses_opp_dir,2periods_new_build_2zones_new_build_transmission,2periods_new_build_cumulative_min_max,2periods_new_build_rps,2periods_new_build_rps_variable_reserves,2periods_new_build_rps_variable_reserves_subhourly_adj,2periods_new_build_rps_w_rps_eligible_storage,2periods_new_build_rps_w_rps_ineligible_storage,2periods_new_build_simple_prm,test_new_solar_carbon_cap_2zones_dont_count_tx,test_new_solar_carbon_cap_2zones_tx,single_stage_prod_cost,multi_stage_prod_cost,multi_stage_prod_cost_w_hydro,test_tx_simple,test_tx_dcopf,2periods_new_build_local_capacity,test_startup_shutdown_rates,test_no_fuels,test_variable_om_curves,test_aux_cons,2periods_new_build_rps_percent_target,single_stage_prod_cost_linked_subproblems,multi_stage_prod_cost_linked_subproblems,test_w_lf_down_percent_req,2periods_new_build_capgroups,test_markets,2periods_new_build_horizon_energy_target,2periods_new_build_period_and_horizon_energy_target,2periods_new_build_horizon_energy_target_halfyear,test_new_build_gen_var_stor_hyb,test_carbon_tax_allowance,test_min_max_build_trans,2periods_new_build_2zones_transmission_Tx1halfavail,2periods_new_build_2zones_transmission_Tx1halfavailmonthly,test_cheap_fuel_blend,test_new_solar_carbon_cap_2zones_tx_low_carbon_fuel_blend,test_cheap_fuel_blend_w_limit -of_transmission,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,,,,,,,,1,1,,,,1,1,,,,,,,,,,,,,,,,,1,1,1,,1, -of_transmission_hurdle_rates,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -of_simultaneous_flow_limits,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +optional_feature_or_subscenarios,test,test_w_storage,test_w_hydro,test_new_solar,test_new_binary_solar,test_new_build_storage,test_new_build_storage_cumulative_min_max,test_new_binary_build_storage,test_no_overgen_allowed,test_no_reserves,test_variable_gen_reserves,test_new_solar_carbon_cap,test_new_solar_carbon_tax,test_ramp_up_constraints,test_ramp_up_and_down_constraints,2horizons,2horizons_w_hydro,2horizons_w_hydro_and_nuclear_binary_availability,2horizons_w_hydro_w_balancing_types,2periods,2periods_gen_lin_econ_retirement,2periods_gen_bin_econ_retirement,2periods_new_build,2periods_new_build_2zones,2periods_new_build_2zones_singleBA,2periods_new_build_2zones_transmission,2periods_new_build_2zones_transmission_w_losses,2periods_new_build_2zones_transmission_w_losses_opp_dir,2periods_new_build_2zones_new_build_transmission,2periods_new_build_cumulative_min_max,2periods_new_build_rps,2periods_new_build_rps_variable_reserves,2periods_new_build_rps_variable_reserves_subhourly_adj,2periods_new_build_rps_w_rps_eligible_storage,2periods_new_build_rps_w_rps_ineligible_storage,2periods_new_build_simple_prm,test_new_solar_carbon_cap_2zones_dont_count_tx,test_new_solar_carbon_cap_2zones_tx,single_stage_prod_cost,multi_stage_prod_cost,multi_stage_prod_cost_w_hydro,test_tx_simple,test_tx_dcopf,2periods_new_build_local_capacity,test_startup_shutdown_rates,test_no_fuels,test_variable_om_curves,test_aux_cons,2periods_new_build_rps_percent_target,single_stage_prod_cost_linked_subproblems,multi_stage_prod_cost_linked_subproblems,test_w_lf_down_percent_req,2periods_new_build_capgroups,test_markets,2periods_new_build_horizon_energy_target,2periods_new_build_period_and_horizon_energy_target,2periods_new_build_horizon_energy_target_halfyear,test_new_build_gen_var_stor_hyb,test_carbon_tax_allowance,test_min_max_build_trans,2periods_new_build_2zones_transmission_Tx1halfavail,2periods_new_build_2zones_transmission_Tx1halfavailmonthly,test_cheap_fuel_blend,test_new_solar_carbon_cap_2zones_tx_low_carbon_fuel_blend,test_cheap_fuel_blend_w_limit,test_hurdle_rates,test_hurdle_rates_no_months +of_transmission,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,,,,,,,,1,1,,,,1,1,,,,,,,,,,,,,,,,,1,1,1,,1,,1,1 +of_transmission_hurdle_rates,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1 +of_simultaneous_flow_limits,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, of_lf_reserves_up,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,,1,1,"1 -",1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 -of_lf_reserves_down,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 -of_regulation_up,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 -of_regulation_down,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 -of_frequency_response,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -of_spinning_reserves,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -of_period_energy_target,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,1,,,,,,,,,,,,,,1,,,,,,,1,,,,,,,,, -of_horizon_energy_target,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,,,,,,,, -of_carbon_cap,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,1,1,,,,1,1,,,,,,,,,,,,,,,,,,,,,1, -of_track_carbon_imports,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,1,1,,,,,,,,,,,,,,,,,,,,,1, -of_carbon_tax,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,, -of_prm,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -of_local_capacity,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,, -of_elcc_surface,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -of_markets,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, -of_tuning,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -temporal_scenario_id,1,1,1,1,1,3,3,3,1,1,1,1,1,1,1,2,2,2,2,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,1,1,4,5,5,1,1,6,7,1,1,1,6,8,9,1,6,1,6,6,6,3,1,6,6,6,1,1,1 -load_zone_scenario_id,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,1,1,1,1,1,1,1,2,2,1,1,1,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,1,2,1 -load_scenario_id,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,2,1,1,1,1,1,1,1,2,4,1,1,1,3,1,1,1,2,1,3,3,3,1,1,2,2,2,1,1,1 -project_portfolio_scenario_id,1,2,3,4,5,6,6,7,1,1,1,4,4,1,1,1,3,3,3,1,8,9,10,11,11,12,12,12,12,10,13,13,13,14,14,10,15,15,1,1,3,16,16,10,17,1,1,1,13,1,1,1,10,1,13,13,13,18,4,12,12,12,1,15,1 -project_operational_chars_scenario_id,1,1,1,1,1,1,1,1,1,1,2,1,1,3,4,1,5,10,6,1,1,1,1,1,1,1,1,1,1,1,1,7,7,8,8,1,1,1,7,1,9,1,1,1,11,12,13,14,1,7,7,1,1,1,1,1,1,1,1,1,1,1,15,16,17 -project_availability_scenario_id,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 -project_load_zone_scenario_id,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 -project_elcc_chars_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -project_specified_capacity_scenario_id,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,1,3,3,1,1,1,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1 -project_specified_fixed_cost_scenario_id,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 -fuel_scenario_id,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 -fuel_price_scenario_id,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 -project_new_cost_scenario_id,,,,1,1,1,1,1,,,,1,1,,,,,,,,,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,,,,1,1,1,,,,,1,,,,1,,1,1,1,1,1,1,1,1,,1, -project_new_potential_scenario_id,,,,1,,,1,,,,,2,2,,,,,,,,,,,,,,,,,1,,,,,,,2,2,,,,2,2,,,,,,,,,,,,,,,,2,,,,,2, -project_new_binary_build_size_scenario_id,,,,,1,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -project_capacity_group_requirement_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,, -project_capacity_group_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,, -transmission_portfolio_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,2,,,,,,,,1,1,,,,3,3,,,,,,,,,,,,,,,,,2,1,1,,1, -transmission_load_zone_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,2,1,,,,,,,,1,1,,,,1,1,,,,,,,,,,,,,,,,,1,1,1,,1, -transmission_specified_capacity_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,,,,,,,,1,1,,,,1,1,,,,,,,,,,,,,,,,,1,1,1,,1, -transmission_availability_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,,,,,,,,1,1,,,,1,1,,,,,,,,,,,,,,,,,1,2,3,,1, -transmission_operational_chars_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,1,3,3,1,,,,,,,,1,1,,,,1,2,,,,,,,,,,,,,,,,,1,1,1,,1, -transmission_hurdle_rate_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -transmission_new_cost_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,, -transmission_new_potential_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,, -transmission_carbon_cap_zone_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,1,1,,,,,,,,,,,,,,,,,,,,,1, -transmission_simultaneous_flow_limit_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -transmission_simultaneous_flow_limit_line_group_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -lf_reserves_up_scenario_id,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 -lf_reserves_up_ba_scenario_id,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,3,3,3,3,1,1,1,4,1,1,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,1,1,1 -project_lf_reserves_up_ba_scenario_id,1,1,1,1,1,1,1,1,1,,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,4,4,5,5,1,5,5,1,1,5,5,5,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,5,1 -lf_reserves_down_scenario_id,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1 -lf_reserves_down_ba_scenario_id,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,3,3,3,3,1,1,1,4,1,1,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,1,1,1 -project_lf_reserves_down_ba_scenario_id,1,1,1,1,1,1,1,1,1,,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,4,4,5,5,1,5,5,1,1,5,5,5,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,5,1 -regulation_up_scenario_id,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 -regulation_up_ba_scenario_id,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,3,3,3,3,1,1,1,4,1,1,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,1,1,1 -project_regulation_up_ba_scenario_id,1,1,1,1,1,1,1,1,1,,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,4,4,5,5,1,5,5,1,1,5,5,5,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,5,1 -regulation_down_scenario_id,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 -regulation_down_ba_scenario_id,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,3,3,3,3,1,1,1,4,1,1,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,1,1,1 -project_regulation_down_ba_scenario_id,1,1,1,1,1,1,1,1,1,,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,4,4,5,5,1,5,5,1,1,5,5,5,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,5,1 -frequency_response_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -frequency_response_ba_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -project_frequency_response_ba_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -spinning_reserves_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -spinning_reserves_ba_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -project_spinning_reserves_ba_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -period_energy_target_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,1,,,,,,,,,,,,,,2,,,,,,,1,,,,,,,,, -horizon_energy_target_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,3,,,,,,,, -energy_target_zone_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,1,,,,,,,,,,,,,,1,,,,,,1,1,1,,,,,,,, -project_energy_target_zone_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,2,,,,,,,,,,,,,,1,,,,,,1,1,1,,,,,,,, -carbon_cap_target_scenario_id,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,1,1,,,,1,1,,,,,,,,,,,,,,,,,,,,,1, -carbon_cap_zone_scenario_id,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,1,1,,,,1,1,,,,,,,,,,,,,,,,,,,,,1, -project_carbon_cap_zone_scenario_id,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,1,1,,,,1,1,,,,,,,,,,,,,,,,,,,,,1, -carbon_tax_scenario_id,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,, -carbon_tax_zone_scenario_id,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,, -project_carbon_tax_zone_scenario_id,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,, -project_carbon_tax_allowance_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,, -prm_requirement_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -prm_zone_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -project_prm_zone_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -prm_energy_only_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -elcc_surface_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -local_capacity_requirement_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,, -local_capacity_zone_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,, -project_local_capacity_zone_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,, -project_local_capacity_chars_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,, -tuning_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -solver_options_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -market_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, -load_zone_market_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, -market_price_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, -market_volume_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, \ No newline at end of file +",1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 +of_lf_reserves_down,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 +of_regulation_up,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 +of_regulation_down,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 +of_frequency_response,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +of_spinning_reserves,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +of_period_energy_target,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,1,,,,,,,,,,,,,,1,,,,,,,1,,,,,,,,,,, +of_horizon_energy_target,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,,,,,,,,,, +of_carbon_cap,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,1,1,,,,1,1,,,,,,,,,,,,,,,,,,,,,1,,, +of_track_carbon_imports,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,1,1,,,,,,,,,,,,,,,,,,,,,1,,, +of_carbon_tax,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,, +of_prm,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +of_local_capacity,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, +of_elcc_surface,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +of_markets,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,, +of_tuning,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +temporal_scenario_id,1,1,1,1,1,3,3,3,1,1,1,1,1,1,1,2,2,2,2,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,1,1,4,5,5,1,1,6,7,1,1,1,6,8,9,1,6,1,6,6,6,3,1,6,6,6,1,1,1,10,10 +load_zone_scenario_id,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,1,1,1,1,1,1,1,2,2,1,1,1,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,1,2,1,2,2 +load_scenario_id,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,2,1,1,1,1,1,1,1,2,4,1,1,1,3,1,1,1,2,1,3,3,3,1,1,2,2,2,1,1,1,2,2 +project_portfolio_scenario_id,1,2,3,4,5,6,6,7,1,1,1,4,4,1,1,1,3,3,3,1,8,9,10,11,11,12,12,12,12,10,13,13,13,14,14,10,15,15,1,1,3,16,16,10,17,1,1,1,13,1,1,1,10,1,13,13,13,18,4,12,12,12,1,15,1,12,12 +project_operational_chars_scenario_id,1,1,1,1,1,1,1,1,1,1,2,1,1,3,4,1,5,10,6,1,1,1,1,1,1,1,1,1,1,1,1,7,7,8,8,1,1,1,7,1,9,1,1,1,11,12,13,14,1,7,7,1,1,1,1,1,1,1,1,1,1,1,15,16,17,1,1 +project_availability_scenario_id,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 +project_load_zone_scenario_id,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 +project_elcc_chars_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +project_specified_capacity_scenario_id,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,1,3,3,1,1,1,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1 +project_specified_fixed_cost_scenario_id,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 +fuel_scenario_id,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 +fuel_price_scenario_id,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 +project_new_cost_scenario_id,,,,1,1,1,1,1,,,,1,1,,,,,,,,,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,,,,1,1,1,,,,,1,,,,1,,1,1,1,1,1,1,1,1,,1,,1,1 +project_new_potential_scenario_id,,,,1,,,1,,,,,2,2,,,,,,,,,,,,,,,,,1,,,,,,,2,2,,,,2,2,,,,,,,,,,,,,,,,2,,,,,2,,, +project_new_binary_build_size_scenario_id,,,,,1,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +project_capacity_group_requirement_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,, +project_capacity_group_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,, +transmission_portfolio_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,2,,,,,,,,1,1,,,,3,3,,,,,,,,,,,,,,,,,2,1,1,,1,,1,1 +transmission_load_zone_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,2,1,,,,,,,,1,1,,,,1,1,,,,,,,,,,,,,,,,,1,1,1,,1,,1,1 +transmission_specified_capacity_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,,,,,,,,1,1,,,,1,1,,,,,,,,,,,,,,,,,1,1,1,,1,,1,1 +transmission_availability_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,,,,,,,,1,1,,,,1,1,,,,,,,,,,,,,,,,,1,2,3,,1,,1,1 +transmission_operational_chars_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,1,3,3,1,,,,,,,,1,1,,,,1,2,,,,,,,,,,,,,,,,,1,1,1,,1,,1,1 +transmission_hurdle_rate_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,2 +transmission_new_cost_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,, +transmission_new_potential_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,, +transmission_carbon_cap_zone_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,1,1,,,,,,,,,,,,,,,,,,,,,1,,, +transmission_simultaneous_flow_limit_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +transmission_simultaneous_flow_limit_line_group_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +lf_reserves_up_scenario_id,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 +lf_reserves_up_ba_scenario_id,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,3,3,3,3,1,1,1,4,1,1,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,1,1,1,3,3 +project_lf_reserves_up_ba_scenario_id,1,1,1,1,1,1,1,1,1,,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,4,4,5,5,1,5,5,1,1,5,5,5,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,5,1,1,1 +lf_reserves_down_scenario_id,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 +lf_reserves_down_ba_scenario_id,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,3,3,3,3,1,1,1,4,1,1,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,1,1,1,3,3 +project_lf_reserves_down_ba_scenario_id,1,1,1,1,1,1,1,1,1,,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,4,4,5,5,1,5,5,1,1,5,5,5,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,5,1,1,1 +regulation_up_scenario_id,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 +regulation_up_ba_scenario_id,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,3,3,3,3,1,1,1,4,1,1,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,1,1,1,3,3 +project_regulation_up_ba_scenario_id,1,1,1,1,1,1,1,1,1,,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,4,4,5,5,1,5,5,1,1,5,5,5,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,5,1,1,1 +regulation_down_scenario_id,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 +regulation_down_ba_scenario_id,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,3,3,3,3,1,1,1,4,1,1,1,1,1,1,1,1,1,1,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,1,1,1,3,3 +project_regulation_down_ba_scenario_id,1,1,1,1,1,1,1,1,1,,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,4,4,5,5,1,5,5,1,1,5,5,5,1,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,5,1,1,1 +frequency_response_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +frequency_response_ba_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +project_frequency_response_ba_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +spinning_reserves_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +spinning_reserves_ba_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +project_spinning_reserves_ba_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +period_energy_target_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,1,,,,,,,,,,,,,,2,,,,,,,1,,,,,,,,,,, +horizon_energy_target_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,3,,,,,,,,,, +energy_target_zone_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,1,,,,,,,,,,,,,,1,,,,,,1,1,1,,,,,,,,,, +project_energy_target_zone_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,2,,,,,,,,,,,,,,1,,,,,,1,1,1,,,,,,,,,, +carbon_cap_target_scenario_id,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,1,1,,,,1,1,,,,,,,,,,,,,,,,,,,,,1,,, +carbon_cap_zone_scenario_id,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,1,1,,,,1,1,,,,,,,,,,,,,,,,,,,,,1,,, +project_carbon_cap_zone_scenario_id,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,1,1,,,,1,1,,,,,,,,,,,,,,,,,,,,,1,,, +carbon_tax_scenario_id,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,, +carbon_tax_zone_scenario_id,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,, +project_carbon_tax_zone_scenario_id,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,, +project_carbon_tax_allowance_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,, +prm_requirement_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +prm_zone_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +project_prm_zone_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +prm_energy_only_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +elcc_surface_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +local_capacity_requirement_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, +local_capacity_zone_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, +project_local_capacity_zone_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, +project_local_capacity_chars_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, +tuning_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +solver_options_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +market_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,, +load_zone_market_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,, +market_price_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,, +market_volume_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,, diff --git a/db/csvs_test_examples/temporal/10_1horizon_1period_2months/horizon_params.csv b/db/csvs_test_examples/temporal/10_1horizon_1period_2months/horizon_params.csv new file mode 100644 index 000000000..35cc46b79 --- /dev/null +++ b/db/csvs_test_examples/temporal/10_1horizon_1period_2months/horizon_params.csv @@ -0,0 +1,2 @@ +subproblem_id,balancing_type_horizon,horizon,boundary +1,day,202001,circular \ No newline at end of file diff --git a/db/csvs_test_examples/temporal/10_1horizon_1period_2months/horizon_timepoints.csv b/db/csvs_test_examples/temporal/10_1horizon_1period_2months/horizon_timepoints.csv new file mode 100644 index 000000000..9a9e71718 --- /dev/null +++ b/db/csvs_test_examples/temporal/10_1horizon_1period_2months/horizon_timepoints.csv @@ -0,0 +1,2 @@ +subproblem_id,stage_id,balancing_type_horizon,horizon,tmp_start,tmp_end +1,1,day,202001,20200101,20200102 \ No newline at end of file diff --git a/db/csvs_test_examples/temporal/10_1horizon_1period_2months/period_params.csv b/db/csvs_test_examples/temporal/10_1horizon_1period_2months/period_params.csv new file mode 100644 index 000000000..269624919 --- /dev/null +++ b/db/csvs_test_examples/temporal/10_1horizon_1period_2months/period_params.csv @@ -0,0 +1,2 @@ +period,discount_factor,period_start_year,period_end_year +2020,1,2020,2021 \ No newline at end of file diff --git a/db/csvs_test_examples/temporal/10_1horizon_1period_2months/structure.csv b/db/csvs_test_examples/temporal/10_1horizon_1period_2months/structure.csv new file mode 100644 index 000000000..467fdbebb --- /dev/null +++ b/db/csvs_test_examples/temporal/10_1horizon_1period_2months/structure.csv @@ -0,0 +1,3 @@ +subproblem_id,stage_id,timepoint,period,number_of_hours_in_timepoint,timepoint_weight,previous_stage_timepoint_map,spinup_or_lookahead,linked_timepoint,month,hour_of_day,timestamp,ignore_horizon_day +1,1,20200101,2020,1,4380,,0,,1,1,2001-01-20 0:00,202001 +1,1,20200102,2020,1,4380,,0,,2,1,2001-01-20 1:00,202001 diff --git a/db/csvs_test_examples/transmission/transmission_hurdle_rates/1_transmission_hurdle_rates_1.csv b/db/csvs_test_examples/transmission/transmission_hurdle_rates/1_transmission_hurdle_rates_1.csv index b5ea76de1..b1e0a09d2 100644 --- a/db/csvs_test_examples/transmission/transmission_hurdle_rates/1_transmission_hurdle_rates_1.csv +++ b/db/csvs_test_examples/transmission/transmission_hurdle_rates/1_transmission_hurdle_rates_1.csv @@ -1,5 +1,9 @@ -transmission_line,period,hurdle_rate_positive_direction_per_mwh,hurdle_rate_negative_direction_per_mwh -Tx_1,2020,5,5 -Tx_1,2025,5,5 -Tx_new,2020,5,5 -Tx_new,2025,5,5 \ No newline at end of file +transmission_line,period,month,hurdle_rate_positive_direction_per_mwh,hurdle_rate_negative_direction_per_mwh +Tx1,2020,1,5,5 +Tx1,2025,1,5,5 +Tx_new,2020,1,5,5 +Tx_new,2025,1,5,5 +Tx1,2020,2,8,8 +Tx1,2025,2,8,8 +Tx_new,2020,2,8,8 +Tx_new,2025,2,8,8 diff --git a/db/db_schema.sql b/db/db_schema.sql index bae5e04ab..566ee36fc 100644 --- a/db/db_schema.sql +++ b/db/db_schema.sql @@ -1840,9 +1840,10 @@ CREATE TABLE inputs_transmission_hurdle_rates ( transmission_hurdle_rate_scenario_id INTEGER, transmission_line VARCHAR(64), period INTEGER, +month INTEGER, hurdle_rate_positive_direction_per_mwh FLOAT, hurdle_rate_negative_direction_per_mwh FLOAT, -PRIMARY KEY (transmission_hurdle_rate_scenario_id, transmission_line, period), +PRIMARY KEY (transmission_hurdle_rate_scenario_id, transmission_line, period, month), FOREIGN KEY (transmission_hurdle_rate_scenario_id) REFERENCES subscenarios_transmission_hurdle_rates (transmission_hurdle_rate_scenario_id) ); @@ -3409,6 +3410,7 @@ transmission_line VARCHAR(64), load_zone_from VARCHAR(64), load_zone_to VARCHAR(64), period INTEGER, +month INTEGER, subproblem_id INTEGER, stage_id INTEGER, timepoint INTEGER, diff --git a/gridpath/transmission/operations/hurdle_costs.py b/gridpath/transmission/operations/hurdle_costs.py index bfb90d05f..389e67547 100644 --- a/gridpath/transmission/operations/hurdle_costs.py +++ b/gridpath/transmission/operations/hurdle_costs.py @@ -25,6 +25,8 @@ from builtins import str import csv import os.path + +import pandas as pd from pyomo.environ import Param, Var, Constraint, NonNegativeReals, Expression, value from db.common_functions import spin_on_database_lock @@ -37,7 +39,7 @@ validate_values, validate_missing_inputs, ) - +from gridpath.auxiliary.auxiliary import cursor_to_df def add_model_components(m, d, scenario_directory, subproblem, stage): """ @@ -115,14 +117,16 @@ def add_model_components(m, d, scenario_directory, subproblem, stage): m.hurdle_rate_pos_dir_per_mwh = Param( m.TX_LINES, - m.PERIODS, # TODO: chanage to TX_OPR_PRDS? + m.PERIODS, + m.MONTHS, # TODO: chanage to TX_OPR_PRDS? within=NonNegativeReals, default=0, ) m.hurdle_rate_neg_dir_per_mwh = Param( m.TX_LINES, - m.PERIODS, # TODO: chanage to TX_OPR_PRDS? + m.PERIODS, + m.MONTHS,# TODO: chanage to TX_OPR_PRDS? within=NonNegativeReals, default=0, ) @@ -157,13 +161,13 @@ def hurdle_cost_pos_dir_rule(mod, tx, tmp): Hurdle_Cost_Pos_Dir must be non-negative, so will be 0 when Transmit_Power is negative (flow in the negative direction). """ - if mod.hurdle_rate_pos_dir_per_mwh[tx, mod.period[tmp]] == 0: + if mod.hurdle_rate_pos_dir_per_mwh[tx, mod.period[tmp], mod.month[tmp]] == 0: return Constraint.Skip else: return ( mod.Hurdle_Cost_Pos_Dir[tx, tmp] >= mod.Transmit_Power_MW[tx, tmp] - * mod.hurdle_rate_pos_dir_per_mwh[tx, mod.period[tmp]] + * mod.hurdle_rate_pos_dir_per_mwh[tx, mod.period[tmp], mod.month[tmp]] ) @@ -175,13 +179,13 @@ def hurdle_cost_neg_dir_rule(mod, tx, tmp): Hurdle_Cost_Neg_Dir must be non-negative, so will be 0 when Transmit_Power is positive (flow in the positive direction). """ - if mod.hurdle_rate_neg_dir_per_mwh[tx, mod.period[tmp]] == 0: + if mod.hurdle_rate_neg_dir_per_mwh[tx, mod.period[tmp], mod.month[tmp]] == 0: return Constraint.Skip else: return ( mod.Hurdle_Cost_Neg_Dir[tx, tmp] >= -mod.Transmit_Power_MW[tx, tmp] - * mod.hurdle_rate_neg_dir_per_mwh[tx, mod.period[tmp]] + * mod.hurdle_rate_neg_dir_per_mwh[tx, mod.period[tmp], mod.month[tmp]] ) @@ -200,23 +204,70 @@ def load_model_data(m, d, data_portal, scenario_directory, subproblem, stage): :param stage: :return: """ - data_portal.load( - filename=os.path.join( - scenario_directory, - str(subproblem), - str(stage), - "inputs", - "transmission_hurdle_rates.tab", - ), - select=( - "transmission_line", - "period", - "hurdle_rate_positive_direction_per_mwh", - "hurdle_rate_negative_direction_per_mwh", - ), - param=(m.hurdle_rate_pos_dir_per_mwh, m.hurdle_rate_neg_dir_per_mwh), + + hurdle_rate_pos_dir_per_mwh_dict = {} + hurdle_rate_neg_dir_per_mwh_dict = {} + + hrs_file = os.path.join( + scenario_directory, str(subproblem), str(stage), "inputs", "transmission_hurdle_rates.tab", + ) + # The timepoints.tab file indicates what periods have months + timepoints_file = os.path.join( + scenario_directory, str(subproblem), str(stage), "inputs", "timepoints.tab" ) + hrs_df = pd.read_csv(hrs_file, sep="\t") + timepoints_df = pd.read_csv(timepoints_file, sep="\t") + + for tx_line, hrs_df_tx_slice in hrs_df.groupby("transmission_line"): + for period, hrs_df_period_slice in hrs_df_tx_slice.groupby("period"): + expected_months = set(timepoints_df.loc[timepoints_df["period"]==period, "month"].unique()) + months = set(hrs_df_period_slice["month"].unique()) + # Hurdle rates months all 0, must apply the same hurdle rate to all months + if months == set([0]): + for month in expected_months: + hrs_df_month_slice = hrs_df_period_slice.loc[hrs_df_period_slice["month"] == 0, :] + hurdle_rate_pos_dir_per_mwh_dict.update( + { + (tx_line, period, month): hrs_df_month_slice.loc[ + :, "hurdle_rate_positive_direction_per_mwh"].values[0] + } + ) + hurdle_rate_neg_dir_per_mwh_dict.update( + { + (tx_line, period, month): hrs_df_month_slice.loc[ + :, "hurdle_rate_negative_direction_per_mwh"].values[0] + } + ) + # Hurdle rates available for all months: + elif months == expected_months: + for month in expected_months: + hrs_df_month_slice = hrs_df_period_slice.loc[hrs_df_period_slice["month"] == month, :] + hurdle_rate_pos_dir_per_mwh_dict.update( + { + (tx_line, period, month): hrs_df_month_slice.loc[ + :, "hurdle_rate_positive_direction_per_mwh"].values[0] + } + ) + hurdle_rate_neg_dir_per_mwh_dict.update( + { + (tx_line, period, month): hrs_df_month_slice.loc[ + :, "hurdle_rate_negative_direction_per_mwh"].values[0] + } + ) + # Hurdle rates months not 0 nor available for all months + else: + raise ValueError( + """Hurdle rates for period '{}' isn't specified for all + months (got {}, expected {} or 0). Set month to 0 if inputs are the + same for each month or make sure all modelled months + are included.""".format( + period, months, expected_months + ) + ) + data_portal.data()["hurdle_rate_pos_dir_per_mwh"] = hurdle_rate_pos_dir_per_mwh_dict + data_portal.data()["hurdle_rate_neg_dir_per_mwh"] = hurdle_rate_neg_dir_per_mwh_dict + def export_results(scenario_directory, subproblem, stage, m, d): """ @@ -244,6 +295,7 @@ def export_results(scenario_directory, subproblem, stage, m, d): [ "tx_line", "period", + "month", "timepoint", "timepoint_weight", "number_of_hours_in_timepoint", @@ -258,6 +310,7 @@ def export_results(scenario_directory, subproblem, stage, m, d): [ tx, m.period[tmp], + m.month[tmp], tmp, m.tmp_weight[tmp], m.hrs_in_tmp[tmp], @@ -285,21 +338,21 @@ def get_inputs_from_database(scenario_id, subscenarios, subproblem, stage, conn) stage = 1 if stage == "" else stage c = conn.cursor() hurdle_rates = c.execute( - """SELECT transmission_line, period, + """SELECT transmission_line, period, month, hurdle_rate_positive_direction_per_mwh, hurdle_rate_negative_direction_per_mwh FROM inputs_transmission_portfolios CROSS JOIN - (SELECT period - FROM inputs_temporal_periods + (SELECT period, month + FROM inputs_temporal WHERE temporal_scenario_id = {}) AS relevant_periods LEFT OUTER JOIN - (SELECT transmission_line, period, + (SELECT transmission_line, period, month, hurdle_rate_positive_direction_per_mwh, hurdle_rate_negative_direction_per_mwh FROM inputs_transmission_hurdle_rates WHERE transmission_hurdle_rate_scenario_id = {}) AS relevant_hrs - USING (transmission_line, period) + USING (transmission_line, period, month) WHERE transmission_portfolio_scenario_id = {}; """.format( subscenarios.TEMPORAL_SCENARIO_ID, @@ -307,7 +360,6 @@ def get_inputs_from_database(scenario_id, subscenarios, subproblem, stage, conn) subscenarios.TRANSMISSION_PORTFOLIO_SCENARIO_ID, ) ) - return hurdle_rates @@ -324,11 +376,9 @@ def write_model_inputs( :param conn: database connection :return: """ - hurdle_rates = get_inputs_from_database( scenario_id, subscenarios, subproblem, stage, conn ) - with open( os.path.join( scenario_directory, @@ -347,6 +397,7 @@ def write_model_inputs( [ "transmission_line", "period", + "month", "hurdle_rate_positive_direction_per_mwh", "hurdle_rate_negative_direction_per_mwh", ] @@ -394,19 +445,21 @@ def import_results_into_database( for row in reader: tx_line = row[0] period = row[1] - timepoint = row[2] - timepoint_weight = row[3] - number_of_hours_in_timepoint = row[4] - lz_from = row[5] - lz_to = row[6] - hurdle_cost_positve_direction = row[7] - hurdle_cost_negative_direction = row[8] + month = row[2] + timepoint = row[3] + timepoint_weight = row[4] + number_of_hours_in_timepoint = row[5] + lz_from = row[6] + lz_to = row[7] + hurdle_cost_positve_direction = row[8] + hurdle_cost_negative_direction = row[9] results.append( ( scenario_id, tx_line, period, + month, subproblem, stage, timepoint, @@ -420,12 +473,12 @@ def import_results_into_database( ) insert_temp_sql = """ INSERT INTO temp_results_transmission_hurdle_costs{} - (scenario_id, transmission_line, period, subproblem_id, stage_id, + (scenario_id, transmission_line, period, month, subproblem_id, stage_id, timepoint, timepoint_weight, number_of_hours_in_timepoint, load_zone_from, load_zone_to, hurdle_cost_positive_direction, hurdle_cost_negative_direction) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); """.format( scenario_id ) @@ -434,12 +487,12 @@ def import_results_into_database( # Insert sorted results into permanent results table insert_sql = """ INSERT INTO results_transmission_hurdle_costs - (scenario_id, transmission_line, period, subproblem_id, stage_id, + (scenario_id, transmission_line, period, month, subproblem_id, stage_id, timepoint, timepoint_weight, number_of_hours_in_timepoint, load_zone_from, load_zone_to, hurdle_cost_positive_direction, hurdle_cost_negative_direction) SELECT - scenario_id, transmission_line, period, subproblem_id, stage_id, + scenario_id, transmission_line, period, month, subproblem_id, stage_id, timepoint, timepoint_weight, number_of_hours_in_timepoint, load_zone_from, load_zone_to, hurdle_cost_positive_direction, hurdle_cost_negative_direction diff --git a/tests/test_data/inputs/transmission_hurdle_rates.tab b/tests/test_data/inputs/transmission_hurdle_rates.tab index e289b18de..50b17183c 100644 --- a/tests/test_data/inputs/transmission_hurdle_rates.tab +++ b/tests/test_data/inputs/transmission_hurdle_rates.tab @@ -1,5 +1,11 @@ -transmission_line period hurdle_rate_positive_direction_per_mwh hurdle_rate_negative_direction_per_mwh -Tx1 2020 1.0 1.0 -Tx1 2030 1.0 1.0 -Tx_New 2030 0.0 0.0 -Tx_New 2030 0.0 0.0 +transmission_line period month hurdle_rate_positive_direction_per_mwh hurdle_rate_negative_direction_per_mwh +Tx1 2020 5 1.5 5.1 +Tx1 2020 9 1.9 9.1 +Tx1 2020 4 1.4 4.4 +Tx1 2020 7 1.7 7.1 +Tx1 2030 5 31.5 35.1 +Tx1 2030 9 31.9 39.1 +Tx1 2030 4 31.4 34.4 +Tx1 2030 7 31.7 37.1 +Tx_New 2020 0 20.20 20.0 +Tx_New 2030 0 30.30 30.0 diff --git a/tests/transmission/operations/test_hurdle_costs.py b/tests/transmission/operations/test_hurdle_costs.py index 4da7879ed..8999eafa9 100644 --- a/tests/transmission/operations/test_hurdle_costs.py +++ b/tests/transmission/operations/test_hurdle_costs.py @@ -105,23 +105,48 @@ def test_data_loaded_correctly(self): expected_hurdle_rate_pos = OrderedDict( sorted( [ - (("Tx1", 2020), 1.0), - (("Tx1", 2030), 1.0), - (("Tx2", 2020), 0), - (("Tx2", 2030), 0), - (("Tx3", 2020), 0), - (("Tx3", 2030), 0), - (("Tx_New", 2020), 0.0), - (("Tx_New", 2030), 0.0), + (("Tx1", 2020, 5), 1.5), + (("Tx1", 2020, 9), 1.9), + (("Tx1", 2020, 4), 1.4), + (("Tx1", 2020, 7), 1.7), + (("Tx1", 2030, 5), 31.5), + (("Tx1", 2030, 9), 31.9), + (("Tx1", 2030, 4), 31.4), + (("Tx1", 2030, 7), 31.7), + (("Tx2", 2020, 5), 0), + (("Tx2", 2020, 9), 0), + (("Tx2", 2020, 4), 0), + (("Tx2", 2020, 7), 0), + (("Tx2", 2030, 5), 0), + (("Tx2", 2030, 9), 0), + (("Tx2", 2030, 4), 0), + (("Tx2", 2030, 7), 0), + (("Tx3", 2020, 5), 0), + (("Tx3", 2020, 9), 0), + (("Tx3", 2020, 4), 0), + (("Tx3", 2020, 7), 0), + (("Tx3", 2030, 5), 0), + (("Tx3", 2030, 9), 0), + (("Tx3", 2030, 4), 0), + (("Tx3", 2030, 7), 0), + (("Tx_New", 2020, 5), 20.20), + (("Tx_New", 2020, 9), 20.20), + (("Tx_New", 2020, 4), 20.20), + (("Tx_New", 2020, 7), 20.20), + (("Tx_New", 2030, 5), 30.30), + (("Tx_New", 2030, 9), 30.30), + (("Tx_New", 2030, 4), 30.30), + (("Tx_New", 2030, 7), 30.30), ] ) ) actual_hurdle_rate_pos = OrderedDict( sorted( [ - ((tx, p), instance.hurdle_rate_pos_dir_per_mwh[tx, p]) + ((tx, p, m), instance.hurdle_rate_pos_dir_per_mwh[tx, p, m]) for tx in instance.TX_LINES for p in instance.PERIODS + for m in instance.MONTHS ] ) ) @@ -131,23 +156,48 @@ def test_data_loaded_correctly(self): expected_hurdle_rate_neg = OrderedDict( sorted( [ - (("Tx1", 2020), 1.0), - (("Tx1", 2030), 1.0), - (("Tx2", 2020), 0), - (("Tx2", 2030), 0), - (("Tx3", 2020), 0), - (("Tx3", 2030), 0), - (("Tx_New", 2020), 0.0), - (("Tx_New", 2030), 0.0), + (("Tx1", 2020, 5), 5.1), + (("Tx1", 2020, 9), 9.1), + (("Tx1", 2020, 4), 4.1), + (("Tx1", 2020, 7), 7.1), + (("Tx1", 2030, 5), 35.1), + (("Tx1", 2030, 9), 39.1), + (("Tx1", 2030, 4), 34.1), + (("Tx1", 2030, 7), 37.1), + (("Tx2", 2020, 5), 0), + (("Tx2", 2020, 9), 0), + (("Tx2", 2020, 4), 0), + (("Tx2", 2020, 7), 0), + (("Tx2", 2030, 5), 0), + (("Tx2", 2030, 9), 0), + (("Tx2", 2030, 4), 0), + (("Tx2", 2030, 7), 0), + (("Tx3", 2020, 5), 0), + (("Tx3", 2020, 9), 0), + (("Tx3", 2020, 4), 0), + (("Tx3", 2020, 7), 0), + (("Tx3", 2030, 5), 0), + (("Tx3", 2030, 9), 0), + (("Tx3", 2030, 4), 0), + (("Tx3", 2030, 7), 0), + (("Tx_New", 2020, 5), 20.0), + (("Tx_New", 2020, 9), 20.0), + (("Tx_New", 2020, 4), 20.0), + (("Tx_New", 2020, 7), 20.0), + (("Tx_New", 2030, 5), 30.0), + (("Tx_New", 2030, 9), 30.0), + (("Tx_New", 2030, 4), 30.0), + (("Tx_New", 2030, 7), 30.0), ] ) ) actual_hurdle_rate_neg = OrderedDict( sorted( [ - ((tx, p), instance.hurdle_rate_neg_dir_per_mwh[tx, p]) + ((tx, p, m), instance.hurdle_rate_neg_dir_per_mwh[tx, p, m]) for tx in instance.TX_LINES for p in instance.PERIODS + for m in instance.MONTHS ] ) ) From ab61724dd7cf4854fb8afd282439f8c5b01c54da Mon Sep 17 00:00:00 2001 From: LesageP Date: Wed, 26 Jan 2022 09:21:26 -0500 Subject: [PATCH 2/9] Change month check for only expected months, not all months. --- gridpath/transmission/operations/hurdle_costs.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/gridpath/transmission/operations/hurdle_costs.py b/gridpath/transmission/operations/hurdle_costs.py index 389e67547..33ecd07dc 100644 --- a/gridpath/transmission/operations/hurdle_costs.py +++ b/gridpath/transmission/operations/hurdle_costs.py @@ -30,7 +30,6 @@ from pyomo.environ import Param, Var, Constraint, NonNegativeReals, Expression, value from db.common_functions import spin_on_database_lock -from gridpath.auxiliary.auxiliary import cursor_to_df from gridpath.auxiliary.db_interface import setup_results_import from gridpath.auxiliary.validations import ( write_validation_to_database, @@ -54,7 +53,7 @@ def add_model_components(m, d, scenario_directory, subproblem, stage): | | *Defaults to*: :code:`0` | | | | The transmission line's hurdle rate in $ per MWh for its positive | - | flows in each operational period. | + | flows in each month of each operational period. | +-------------------------------------------------------------------------+ | | :code:`hurdle_rate_neg_dir_per_mwh` | | | *Defined over*: :code:`TX_OPR_PRDS` | @@ -239,8 +238,8 @@ def load_model_data(m, d, data_portal, scenario_directory, subproblem, stage): :, "hurdle_rate_negative_direction_per_mwh"].values[0] } ) - # Hurdle rates available for all months: - elif months == expected_months: + # Hurdle rates available for all expected months: + elif all([m in months for m in expected_months]): for month in expected_months: hrs_df_month_slice = hrs_df_period_slice.loc[hrs_df_period_slice["month"] == month, :] hurdle_rate_pos_dir_per_mwh_dict.update( From 18db5a233204acbad15904dba73a3ae8a21ddfdf Mon Sep 17 00:00:00 2001 From: LesageP Date: Wed, 9 Mar 2022 21:56:25 -0500 Subject: [PATCH 3/9] Add monthly hurdle rates formatting helper --- .../transmission/operations/hurdle_costs.py | 121 +++++++++--------- 1 file changed, 59 insertions(+), 62 deletions(-) diff --git a/gridpath/transmission/operations/hurdle_costs.py b/gridpath/transmission/operations/hurdle_costs.py index 33ecd07dc..8964c982f 100644 --- a/gridpath/transmission/operations/hurdle_costs.py +++ b/gridpath/transmission/operations/hurdle_costs.py @@ -39,6 +39,7 @@ validate_missing_inputs, ) from gridpath.auxiliary.auxiliary import cursor_to_df +from gridpath.temporal.operations.timepoints import get_inputs_from_database as get_temporal_inputs_from_database def add_model_components(m, d, scenario_directory, subproblem, stage): """ @@ -191,6 +192,40 @@ def hurdle_cost_neg_dir_rule(mod, tx, tmp): # Input-Output ############################################################################### +def format_monthly_hurdle_data(hrs_df_unformatted, timepoints_df): + """ Fill monthly hurdle rates with default values where applicable + + :param hrs_df_unformatted: DataFrame with hurdle rates + :param timepoints_df: DataFrame with period and month columns + :return: + pandas.DataFrame with monthly hurdle rates for all relevant months + """ + period_months_dict = { + period: timepoints_df[timepoints_df["period"]==period]["month"].unique().tolist() + for period in timepoints_df["period"].unique() + } + hrs_df_formatted = pd.DataFrame(columns=hrs_df_unformatted.columns) + for tx_line, df_per_tx_line in hrs_df_unformatted.groupby("transmission_line"): + for period, df_per_tx_line_per_period in df_per_tx_line.groupby("period"): + months = df_per_tx_line_per_period.month.unique().tolist() + expected_months = period_months_dict[period] + if set(months) == set(expected_months): + hrs_df_formatted = pd.concat([hrs_df_formatted, df_per_tx_line_per_period], axis=0, ignore_index=True) + elif months == [0]: + df_expanded = df_per_tx_line_per_period.loc[df_per_tx_line_per_period.index.repeat(len(expected_months))] + df_expanded["month"] = expected_months + hrs_df_formatted = pd.concat([hrs_df_formatted, df_expanded], axis=0, ignore_index=True) + else: + raise ValueError( + """Hurdle rates for transmission line {} and period {} aren't specified for all relevant months + (got {}, expected {} or 0). + Set month to 0 if inputs are the same for each month + or make sure all modelled months are included.""".format( + tx_line, period, months, expected_months + ), + ) + return hrs_df_formatted + def load_model_data(m, d, data_portal, scenario_directory, subproblem, stage): """ @@ -210,59 +245,30 @@ def load_model_data(m, d, data_portal, scenario_directory, subproblem, stage): hrs_file = os.path.join( scenario_directory, str(subproblem), str(stage), "inputs", "transmission_hurdle_rates.tab", ) + hrs_df_unformatted = pd.read_csv(hrs_file, sep="\t") + # The timepoints.tab file indicates what periods have months timepoints_file = os.path.join( scenario_directory, str(subproblem), str(stage), "inputs", "timepoints.tab" ) - - hrs_df = pd.read_csv(hrs_file, sep="\t") timepoints_df = pd.read_csv(timepoints_file, sep="\t") + hrs_df = format_monthly_hurdle_data(hrs_df_unformatted, timepoints_df) + for tx_line, hrs_df_tx_slice in hrs_df.groupby("transmission_line"): for period, hrs_df_period_slice in hrs_df_tx_slice.groupby("period"): - expected_months = set(timepoints_df.loc[timepoints_df["period"]==period, "month"].unique()) - months = set(hrs_df_period_slice["month"].unique()) - # Hurdle rates months all 0, must apply the same hurdle rate to all months - if months == set([0]): - for month in expected_months: - hrs_df_month_slice = hrs_df_period_slice.loc[hrs_df_period_slice["month"] == 0, :] - hurdle_rate_pos_dir_per_mwh_dict.update( - { - (tx_line, period, month): hrs_df_month_slice.loc[ - :, "hurdle_rate_positive_direction_per_mwh"].values[0] - } - ) - hurdle_rate_neg_dir_per_mwh_dict.update( - { - (tx_line, period, month): hrs_df_month_slice.loc[ - :, "hurdle_rate_negative_direction_per_mwh"].values[0] - } - ) - # Hurdle rates available for all expected months: - elif all([m in months for m in expected_months]): - for month in expected_months: - hrs_df_month_slice = hrs_df_period_slice.loc[hrs_df_period_slice["month"] == month, :] - hurdle_rate_pos_dir_per_mwh_dict.update( - { - (tx_line, period, month): hrs_df_month_slice.loc[ - :, "hurdle_rate_positive_direction_per_mwh"].values[0] - } - ) - hurdle_rate_neg_dir_per_mwh_dict.update( - { - (tx_line, period, month): hrs_df_month_slice.loc[ - :, "hurdle_rate_negative_direction_per_mwh"].values[0] - } - ) - # Hurdle rates months not 0 nor available for all months - else: - raise ValueError( - """Hurdle rates for period '{}' isn't specified for all - months (got {}, expected {} or 0). Set month to 0 if inputs are the - same for each month or make sure all modelled months - are included.""".format( - period, months, expected_months - ) + for month, hrs_df_month_slice in hrs_df_period_slice.groupby("month"): + hurdle_rate_pos_dir_per_mwh_dict.update( + { + (tx_line, period, month): hrs_df_month_slice.loc[ + :, "hurdle_rate_positive_direction_per_mwh"].values[0] + } + ) + hurdle_rate_neg_dir_per_mwh_dict.update( + { + (tx_line, period, month): hrs_df_month_slice.loc[ + :, "hurdle_rate_negative_direction_per_mwh"].values[0] + } ) data_portal.data()["hurdle_rate_pos_dir_per_mwh"] = hurdle_rate_pos_dir_per_mwh_dict data_portal.data()["hurdle_rate_neg_dir_per_mwh"] = hurdle_rate_neg_dir_per_mwh_dict @@ -340,23 +346,10 @@ def get_inputs_from_database(scenario_id, subscenarios, subproblem, stage, conn) """SELECT transmission_line, period, month, hurdle_rate_positive_direction_per_mwh, hurdle_rate_negative_direction_per_mwh - FROM inputs_transmission_portfolios - CROSS JOIN - (SELECT period, month - FROM inputs_temporal - WHERE temporal_scenario_id = {}) AS relevant_periods - LEFT OUTER JOIN - (SELECT transmission_line, period, month, - hurdle_rate_positive_direction_per_mwh, - hurdle_rate_negative_direction_per_mwh - FROM inputs_transmission_hurdle_rates - WHERE transmission_hurdle_rate_scenario_id = {}) AS relevant_hrs - USING (transmission_line, period, month) - WHERE transmission_portfolio_scenario_id = {}; + FROM inputs_transmission_hurdle_rates + WHERE transmission_hurdle_rate_scenario_id = {}; """.format( - subscenarios.TEMPORAL_SCENARIO_ID, subscenarios.TRANSMISSION_HURDLE_RATE_SCENARIO_ID, - subscenarios.TRANSMISSION_PORTFOLIO_SCENARIO_ID, ) ) return hurdle_rates @@ -587,8 +580,12 @@ def validate_inputs(scenario_id, subscenarios, subproblem, stage, conn): hurdle_rates = get_inputs_from_database( scenario_id, subscenarios, subproblem, stage, conn ) - - df = cursor_to_df(hurdle_rates) + hrs_df_unformatted = cursor_to_df(hurdle_rates) + timepoints = get_temporal_inputs_from_database( + scenario_id, subscenarios, subproblem, stage, conn + ) + timepoints_df = cursor_to_df(timepoints) + df = format_monthly_hurdle_data(hrs_df_unformatted, timepoints_df) # Get expected dtypes expected_dtypes = get_expected_dtypes( From af1c6cd8cfa7e4c44b4fe0bc655ca4de83cc747b Mon Sep 17 00:00:00 2001 From: LesageP Date: Wed, 9 Mar 2022 21:56:42 -0500 Subject: [PATCH 4/9] Work on monthly hurdle rates test --- .../inputs/transmission_hurdle_rates.tab | 4 -- .../operations/test_hurdle_costs.py | 57 +++---------------- 2 files changed, 8 insertions(+), 53 deletions(-) diff --git a/tests/test_data/inputs/transmission_hurdle_rates.tab b/tests/test_data/inputs/transmission_hurdle_rates.tab index 50b17183c..ece737ca6 100644 --- a/tests/test_data/inputs/transmission_hurdle_rates.tab +++ b/tests/test_data/inputs/transmission_hurdle_rates.tab @@ -1,10 +1,6 @@ transmission_line period month hurdle_rate_positive_direction_per_mwh hurdle_rate_negative_direction_per_mwh Tx1 2020 5 1.5 5.1 Tx1 2020 9 1.9 9.1 -Tx1 2020 4 1.4 4.4 -Tx1 2020 7 1.7 7.1 -Tx1 2030 5 31.5 35.1 -Tx1 2030 9 31.9 39.1 Tx1 2030 4 31.4 34.4 Tx1 2030 7 31.7 37.1 Tx_New 2020 0 20.20 20.0 diff --git a/tests/transmission/operations/test_hurdle_costs.py b/tests/transmission/operations/test_hurdle_costs.py index 8999eafa9..303b60af4 100644 --- a/tests/transmission/operations/test_hurdle_costs.py +++ b/tests/transmission/operations/test_hurdle_costs.py @@ -99,47 +99,27 @@ def test_data_loaded_correctly(self): subproblem="", stage="", ) + print("actual data") + print(data.data()["hurdle_rate_pos_dir_per_mwh"]) instance = m.create_instance(data) - + print("instance.hurdle_rate_pos_dir_per_mwh.keys()") + print([k for k in instance.hurdle_rate_pos_dir_per_mwh.keys()]) # Param: hurdle_rate_pos_dir_per_mwh expected_hurdle_rate_pos = OrderedDict( sorted( [ (("Tx1", 2020, 5), 1.5), (("Tx1", 2020, 9), 1.9), - (("Tx1", 2020, 4), 1.4), - (("Tx1", 2020, 7), 1.7), - (("Tx1", 2030, 5), 31.5), - (("Tx1", 2030, 9), 31.9), (("Tx1", 2030, 4), 31.4), (("Tx1", 2030, 7), 31.7), - (("Tx2", 2020, 5), 0), - (("Tx2", 2020, 9), 0), - (("Tx2", 2020, 4), 0), - (("Tx2", 2020, 7), 0), - (("Tx2", 2030, 5), 0), - (("Tx2", 2030, 9), 0), - (("Tx2", 2030, 4), 0), - (("Tx2", 2030, 7), 0), - (("Tx3", 2020, 5), 0), - (("Tx3", 2020, 9), 0), - (("Tx3", 2020, 4), 0), - (("Tx3", 2020, 7), 0), - (("Tx3", 2030, 5), 0), - (("Tx3", 2030, 9), 0), - (("Tx3", 2030, 4), 0), - (("Tx3", 2030, 7), 0), (("Tx_New", 2020, 5), 20.20), (("Tx_New", 2020, 9), 20.20), - (("Tx_New", 2020, 4), 20.20), - (("Tx_New", 2020, 7), 20.20), - (("Tx_New", 2030, 5), 30.30), - (("Tx_New", 2030, 9), 30.30), (("Tx_New", 2030, 4), 30.30), (("Tx_New", 2030, 7), 30.30), ] ) ) + print(expected_hurdle_rate_pos) actual_hurdle_rate_pos = OrderedDict( sorted( [ @@ -147,9 +127,11 @@ def test_data_loaded_correctly(self): for tx in instance.TX_LINES for p in instance.PERIODS for m in instance.MONTHS + if (tx, p, m) in instance.hurdle_rate_pos_dir_per_mwh.keys() ] ) ) + print(actual_hurdle_rate_pos) self.assertDictEqual(expected_hurdle_rate_pos, actual_hurdle_rate_pos) # Param: hurdle_rate_neg_dir_per_mwh @@ -158,34 +140,10 @@ def test_data_loaded_correctly(self): [ (("Tx1", 2020, 5), 5.1), (("Tx1", 2020, 9), 9.1), - (("Tx1", 2020, 4), 4.1), - (("Tx1", 2020, 7), 7.1), - (("Tx1", 2030, 5), 35.1), - (("Tx1", 2030, 9), 39.1), (("Tx1", 2030, 4), 34.1), (("Tx1", 2030, 7), 37.1), - (("Tx2", 2020, 5), 0), - (("Tx2", 2020, 9), 0), - (("Tx2", 2020, 4), 0), - (("Tx2", 2020, 7), 0), - (("Tx2", 2030, 5), 0), - (("Tx2", 2030, 9), 0), - (("Tx2", 2030, 4), 0), - (("Tx2", 2030, 7), 0), - (("Tx3", 2020, 5), 0), - (("Tx3", 2020, 9), 0), - (("Tx3", 2020, 4), 0), - (("Tx3", 2020, 7), 0), - (("Tx3", 2030, 5), 0), - (("Tx3", 2030, 9), 0), - (("Tx3", 2030, 4), 0), - (("Tx3", 2030, 7), 0), (("Tx_New", 2020, 5), 20.0), (("Tx_New", 2020, 9), 20.0), - (("Tx_New", 2020, 4), 20.0), - (("Tx_New", 2020, 7), 20.0), - (("Tx_New", 2030, 5), 30.0), - (("Tx_New", 2030, 9), 30.0), (("Tx_New", 2030, 4), 30.0), (("Tx_New", 2030, 7), 30.0), ] @@ -198,6 +156,7 @@ def test_data_loaded_correctly(self): for tx in instance.TX_LINES for p in instance.PERIODS for m in instance.MONTHS + if (tx, p, m) in instance.hurdle_rate_pos_dir_per_mwh.keys() ] ) ) From 34417cfe02d1803c6b663ce47ed2d4a089402681 Mon Sep 17 00:00:00 2001 From: LesageP Date: Wed, 9 Mar 2022 22:44:09 -0500 Subject: [PATCH 5/9] Harmonized periods_months df building with fuels --- .../transmission/operations/hurdle_costs.py | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/gridpath/transmission/operations/hurdle_costs.py b/gridpath/transmission/operations/hurdle_costs.py index 8964c982f..c98856277 100644 --- a/gridpath/transmission/operations/hurdle_costs.py +++ b/gridpath/transmission/operations/hurdle_costs.py @@ -192,17 +192,17 @@ def hurdle_cost_neg_dir_rule(mod, tx, tmp): # Input-Output ############################################################################### -def format_monthly_hurdle_data(hrs_df_unformatted, timepoints_df): +def format_monthly_hurdle_data(hrs_df_unformatted, periods_months_df): """ Fill monthly hurdle rates with default values where applicable :param hrs_df_unformatted: DataFrame with hurdle rates - :param timepoints_df: DataFrame with period and month columns + :param periods_months_df: DataFrame with period and month columns :return: pandas.DataFrame with monthly hurdle rates for all relevant months """ period_months_dict = { - period: timepoints_df[timepoints_df["period"]==period]["month"].unique().tolist() - for period in timepoints_df["period"].unique() + period: periods_months_df[periods_months_df["period"]==period]["month"].unique().tolist() + for period in periods_months_df["period"].unique() } hrs_df_formatted = pd.DataFrame(columns=hrs_df_unformatted.columns) for tx_line, df_per_tx_line in hrs_df_unformatted.groupby("transmission_line"): @@ -581,11 +581,17 @@ def validate_inputs(scenario_id, subscenarios, subproblem, stage, conn): scenario_id, subscenarios, subproblem, stage, conn ) hrs_df_unformatted = cursor_to_df(hurdle_rates) - timepoints = get_temporal_inputs_from_database( - scenario_id, subscenarios, subproblem, stage, conn + periods_months = conn.execute( + """SELECT DISTINCT period, month + FROM inputs_temporal + WHERE temporal_scenario_id = {} + AND subproblem_id = {} + AND stage_id = {};""".format( + subscenarios.TEMPORAL_SCENARIO_ID, subproblem, stage + ) ) - timepoints_df = cursor_to_df(timepoints) - df = format_monthly_hurdle_data(hrs_df_unformatted, timepoints_df) + periods_months_df = cursor_to_df(periods_months) + df = format_monthly_hurdle_data(hrs_df_unformatted, periods_months_df) # Get expected dtypes expected_dtypes = get_expected_dtypes( From 3e2ec5b3f292891d42f071fc52c3fc53777a5e46 Mon Sep 17 00:00:00 2001 From: LesageP Date: Wed, 9 Mar 2022 23:02:06 -0500 Subject: [PATCH 6/9] Simplified hurdle_rates example data --- .../1_transmission_hurdle_rates_1.csv | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/db/csvs_test_examples/transmission/transmission_hurdle_rates/1_transmission_hurdle_rates_1.csv b/db/csvs_test_examples/transmission/transmission_hurdle_rates/1_transmission_hurdle_rates_1.csv index b1e0a09d2..8dcd9911a 100644 --- a/db/csvs_test_examples/transmission/transmission_hurdle_rates/1_transmission_hurdle_rates_1.csv +++ b/db/csvs_test_examples/transmission/transmission_hurdle_rates/1_transmission_hurdle_rates_1.csv @@ -1,9 +1,5 @@ transmission_line,period,month,hurdle_rate_positive_direction_per_mwh,hurdle_rate_negative_direction_per_mwh Tx1,2020,1,5,5 -Tx1,2025,1,5,5 -Tx_new,2020,1,5,5 -Tx_new,2025,1,5,5 Tx1,2020,2,8,8 -Tx1,2025,2,8,8 +Tx_new,2020,1,5,5 Tx_new,2020,2,8,8 -Tx_new,2025,2,8,8 From b494c9ca3c8bf07f89a0a6aadb8519ab4463db2a Mon Sep 17 00:00:00 2001 From: LesageP Date: Thu, 10 Mar 2022 16:46:01 -0500 Subject: [PATCH 7/9] First monthly hurdle rate example working --- db/csvs_test_examples/scenarios.csv | 6 +++--- .../1_transmission_portfolios_nonew.csv | 2 -- 2 files changed, 3 insertions(+), 5 deletions(-) delete mode 100644 db/csvs_test_examples/transmission/transmission_portfolios/1_transmission_portfolios_nonew.csv diff --git a/db/csvs_test_examples/scenarios.csv b/db/csvs_test_examples/scenarios.csv index d4bf2d12f..22af09d2c 100644 --- a/db/csvs_test_examples/scenarios.csv +++ b/db/csvs_test_examples/scenarios.csv @@ -36,14 +36,14 @@ project_new_potential_scenario_id,,,,1,,,1,,,,,2,2,,,,,,,,,,,,,,,,,1,,,,,,,2,2,, project_new_binary_build_size_scenario_id,,,,,1,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, project_capacity_group_requirement_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,, project_capacity_group_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,, -transmission_portfolio_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,2,,,,,,,,1,1,,,,3,3,,,,,,,,,,,,,,,,,2,1,1,,1,,1,1 +transmission_portfolio_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,2,,,,,,,,1,1,,,,3,3,,,,,,,,,,,,,,,,,2,1,1,,1,,4,4 transmission_load_zone_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,2,1,,,,,,,,1,1,,,,1,1,,,,,,,,,,,,,,,,,1,1,1,,1,,1,1 transmission_specified_capacity_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,,,,,,,,1,1,,,,1,1,,,,,,,,,,,,,,,,,1,1,1,,1,,1,1 transmission_availability_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,,,,,,,,1,1,,,,1,1,,,,,,,,,,,,,,,,,1,2,3,,1,,1,1 transmission_operational_chars_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,1,3,3,1,,,,,,,,1,1,,,,1,2,,,,,,,,,,,,,,,,,1,1,1,,1,,1,1 transmission_hurdle_rate_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,2 -transmission_new_cost_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,, -transmission_new_potential_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,, +transmission_new_cost_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,1,1 +transmission_new_potential_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,1,1 transmission_carbon_cap_zone_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,1,1,,,,,,,,,,,,,,,,,,,,,1,,, transmission_simultaneous_flow_limit_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, transmission_simultaneous_flow_limit_line_group_scenario_id,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, diff --git a/db/csvs_test_examples/transmission/transmission_portfolios/1_transmission_portfolios_nonew.csv b/db/csvs_test_examples/transmission/transmission_portfolios/1_transmission_portfolios_nonew.csv deleted file mode 100644 index ac0c9e6f5..000000000 --- a/db/csvs_test_examples/transmission/transmission_portfolios/1_transmission_portfolios_nonew.csv +++ /dev/null @@ -1,2 +0,0 @@ -transmission_line,capacity_type -Tx1,tx_spec \ No newline at end of file From db727e03759acda9048eab8d7460dcc050c53f76 Mon Sep 17 00:00:00 2001 From: LesageP Date: Fri, 11 Mar 2022 16:26:08 -0500 Subject: [PATCH 8/9] Fix hurdle tests --- .../operations/test_hurdle_costs.py | 195 +++++++++++++++++- 1 file changed, 184 insertions(+), 11 deletions(-) diff --git a/tests/transmission/operations/test_hurdle_costs.py b/tests/transmission/operations/test_hurdle_costs.py index 303b60af4..2cc90cba8 100644 --- a/tests/transmission/operations/test_hurdle_costs.py +++ b/tests/transmission/operations/test_hurdle_costs.py @@ -99,27 +99,111 @@ def test_data_loaded_correctly(self): subproblem="", stage="", ) - print("actual data") - print(data.data()["hurdle_rate_pos_dir_per_mwh"]) instance = m.create_instance(data) - print("instance.hurdle_rate_pos_dir_per_mwh.keys()") - print([k for k in instance.hurdle_rate_pos_dir_per_mwh.keys()]) # Param: hurdle_rate_pos_dir_per_mwh expected_hurdle_rate_pos = OrderedDict( sorted( [ + (("Tx1", 2020, 1), 0), + (("Tx1", 2020, 2), 0), + (("Tx1", 2020, 3), 0), + (("Tx1", 2020, 4), 0), (("Tx1", 2020, 5), 1.5), + (("Tx1", 2020, 6), 0), + (("Tx1", 2020, 7), 0), + (("Tx1", 2020, 8), 0), (("Tx1", 2020, 9), 1.9), + (("Tx1", 2020, 10), 0), + (("Tx1", 2020, 11), 0), + (("Tx1", 2020, 12), 0), + (("Tx1", 2030, 1), 0), + (("Tx1", 2030, 2), 0), + (("Tx1", 2030, 3), 0), (("Tx1", 2030, 4), 31.4), + (("Tx1", 2030, 5), 0), + (("Tx1", 2030, 6), 0), (("Tx1", 2030, 7), 31.7), - (("Tx_New", 2020, 5), 20.20), - (("Tx_New", 2020, 9), 20.20), - (("Tx_New", 2030, 4), 30.30), - (("Tx_New", 2030, 7), 30.30), + (("Tx1", 2030, 8), 0), + (("Tx1", 2030, 9), 0), + (("Tx1", 2030, 10), 0), + (("Tx1", 2030, 11), 0), + (("Tx1", 2030, 12), 0), + (("Tx2", 2020, 1), 0), + (("Tx2", 2020, 2), 0), + (("Tx2", 2020, 3), 0), + (("Tx2", 2020, 4), 0), + (("Tx2", 2020, 5), 0), + (("Tx2", 2020, 6), 0), + (("Tx2", 2020, 7), 0), + (("Tx2", 2020, 8), 0), + (("Tx2", 2020, 9), 0), + (("Tx2", 2020, 10), 0), + (("Tx2", 2020, 11), 0), + (("Tx2", 2020, 12), 0), + (("Tx2", 2030, 1), 0), + (("Tx2", 2030, 2), 0), + (("Tx2", 2030, 3), 0), + (("Tx2", 2030, 4), 0), + (("Tx2", 2030, 5), 0), + (("Tx2", 2030, 6), 0), + (("Tx2", 2030, 7), 0), + (("Tx2", 2030, 8), 0), + (("Tx2", 2030, 9), 0), + (("Tx2", 2030, 10), 0), + (("Tx2", 2030, 11), 0), + (("Tx2", 2030, 12), 0), + (("Tx3", 2020, 1), 0), + (("Tx3", 2020, 2), 0), + (("Tx3", 2020, 3), 0), + (("Tx3", 2020, 4), 0), + (("Tx3", 2020, 5), 0), + (("Tx3", 2020, 6), 0), + (("Tx3", 2020, 7), 0), + (("Tx3", 2020, 8), 0), + (("Tx3", 2020, 9), 0), + (("Tx3", 2020, 10), 0), + (("Tx3", 2020, 11), 0), + (("Tx3", 2020, 12), 0), + (("Tx3", 2030, 1), 0), + (("Tx3", 2030, 2), 0), + (("Tx3", 2030, 3), 0), + (("Tx3", 2030, 4), 0), + (("Tx3", 2030, 5), 0), + (("Tx3", 2030, 6), 0), + (("Tx3", 2030, 7), 0), + (("Tx3", 2030, 8), 0), + (("Tx3", 2030, 9), 0), + (("Tx3", 2030, 10), 0), + (("Tx3", 2030, 11), 0), + (("Tx3", 2030, 12), 0), + (("Tx_New", 2020, 1), 0), + (("Tx_New", 2020, 2), 0), + (("Tx_New", 2020, 3), 0), + (("Tx_New", 2020, 4), 0), + (("Tx_New", 2020, 5), 20.2), + (("Tx_New", 2020, 6), 0), + (("Tx_New", 2020, 7), 0), + (("Tx_New", 2020, 8), 0), + (("Tx_New", 2020, 9), 20.2), + (("Tx_New", 2020, 10), 0), + (("Tx_New", 2020, 11), 0), + (("Tx_New", 2020, 12), 0), + (("Tx_New", 2030, 1), 0), + (("Tx_New", 2030, 2), 0), + (("Tx_New", 2030, 3), 0), + (("Tx_New", 2030, 4), 30.3), + (("Tx_New", 2030, 5), 0), + (("Tx_New", 2030, 6), 0), + (("Tx_New", 2030, 7), 30.3), + (("Tx_New", 2030, 8), 0), + (("Tx_New", 2030, 9), 0), + (("Tx_New", 2030, 10), 0), + (("Tx_New", 2030, 11), 0), + (("Tx_New", 2030, 12), 0), ] ) ) - print(expected_hurdle_rate_pos) + actual_hurdle_rate_pos = OrderedDict( sorted( [ @@ -131,24 +215,112 @@ def test_data_loaded_correctly(self): ] ) ) - print(actual_hurdle_rate_pos) self.assertDictEqual(expected_hurdle_rate_pos, actual_hurdle_rate_pos) # Param: hurdle_rate_neg_dir_per_mwh expected_hurdle_rate_neg = OrderedDict( sorted( [ + (("Tx1", 2020, 1), 0), + (("Tx1", 2020, 2), 0), + (("Tx1", 2020, 3), 0), + (("Tx1", 2020, 4), 0), (("Tx1", 2020, 5), 5.1), + (("Tx1", 2020, 6), 0), + (("Tx1", 2020, 7), 0), + (("Tx1", 2020, 8), 0), (("Tx1", 2020, 9), 9.1), - (("Tx1", 2030, 4), 34.1), + (("Tx1", 2020, 10), 0), + (("Tx1", 2020, 11), 0), + (("Tx1", 2020, 12), 0), + (("Tx1", 2030, 1), 0), + (("Tx1", 2030, 2), 0), + (("Tx1", 2030, 3), 0), + (("Tx1", 2030, 4), 34.4), + (("Tx1", 2030, 5), 0), + (("Tx1", 2030, 6), 0), (("Tx1", 2030, 7), 37.1), + (("Tx1", 2030, 8), 0), + (("Tx1", 2030, 9), 0), + (("Tx1", 2030, 10), 0), + (("Tx1", 2030, 11), 0), + (("Tx1", 2030, 12), 0), + (("Tx2", 2020, 1), 0), + (("Tx2", 2020, 2), 0), + (("Tx2", 2020, 3), 0), + (("Tx2", 2020, 4), 0), + (("Tx2", 2020, 5), 0), + (("Tx2", 2020, 6), 0), + (("Tx2", 2020, 7), 0), + (("Tx2", 2020, 8), 0), + (("Tx2", 2020, 9), 0), + (("Tx2", 2020, 10), 0), + (("Tx2", 2020, 11), 0), + (("Tx2", 2020, 12), 0), + (("Tx2", 2030, 1), 0), + (("Tx2", 2030, 2), 0), + (("Tx2", 2030, 3), 0), + (("Tx2", 2030, 4), 0), + (("Tx2", 2030, 5), 0), + (("Tx2", 2030, 6), 0), + (("Tx2", 2030, 7), 0), + (("Tx2", 2030, 8), 0), + (("Tx2", 2030, 9), 0), + (("Tx2", 2030, 10), 0), + (("Tx2", 2030, 11), 0), + (("Tx2", 2030, 12), 0), + (("Tx3", 2020, 1), 0), + (("Tx3", 2020, 2), 0), + (("Tx3", 2020, 3), 0), + (("Tx3", 2020, 4), 0), + (("Tx3", 2020, 5), 0), + (("Tx3", 2020, 6), 0), + (("Tx3", 2020, 7), 0), + (("Tx3", 2020, 8), 0), + (("Tx3", 2020, 9), 0), + (("Tx3", 2020, 10), 0), + (("Tx3", 2020, 11), 0), + (("Tx3", 2020, 12), 0), + (("Tx3", 2030, 1), 0), + (("Tx3", 2030, 2), 0), + (("Tx3", 2030, 3), 0), + (("Tx3", 2030, 4), 0), + (("Tx3", 2030, 5), 0), + (("Tx3", 2030, 6), 0), + (("Tx3", 2030, 7), 0), + (("Tx3", 2030, 8), 0), + (("Tx3", 2030, 9), 0), + (("Tx3", 2030, 10), 0), + (("Tx3", 2030, 11), 0), + (("Tx3", 2030, 12), 0), + (("Tx_New", 2020, 1), 0), + (("Tx_New", 2020, 2), 0), + (("Tx_New", 2020, 3), 0), + (("Tx_New", 2020, 4), 0), (("Tx_New", 2020, 5), 20.0), + (("Tx_New", 2020, 6), 0), + (("Tx_New", 2020, 7), 0), + (("Tx_New", 2020, 8), 0), (("Tx_New", 2020, 9), 20.0), + (("Tx_New", 2020, 10), 0), + (("Tx_New", 2020, 11), 0), + (("Tx_New", 2020, 12), 0), + (("Tx_New", 2030, 1), 0), + (("Tx_New", 2030, 2), 0), + (("Tx_New", 2030, 3), 0), (("Tx_New", 2030, 4), 30.0), + (("Tx_New", 2030, 5), 0), + (("Tx_New", 2030, 6), 0), (("Tx_New", 2030, 7), 30.0), + (("Tx_New", 2030, 8), 0), + (("Tx_New", 2030, 9), 0), + (("Tx_New", 2030, 10), 0), + (("Tx_New", 2030, 11), 0), + (("Tx_New", 2030, 12), 0), ] ) ) + actual_hurdle_rate_neg = OrderedDict( sorted( [ @@ -160,4 +332,5 @@ def test_data_loaded_correctly(self): ] ) ) + self.assertDictEqual(expected_hurdle_rate_neg, actual_hurdle_rate_neg) From ef434390ec0190075ea72f8ea9d4929df7bde9a7 Mon Sep 17 00:00:00 2001 From: LesageP Date: Fri, 11 Mar 2022 16:29:37 -0500 Subject: [PATCH 9/9] Fix hurdle cost monthly examples --- .../transmission_hurdle_rates/2_tx_hurdle_rates_no_months.csv | 3 +++ .../4_transmission_portfolios_new_and_nonew.csv | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 db/csvs_test_examples/transmission/transmission_hurdle_rates/2_tx_hurdle_rates_no_months.csv create mode 100644 db/csvs_test_examples/transmission/transmission_portfolios/4_transmission_portfolios_new_and_nonew.csv diff --git a/db/csvs_test_examples/transmission/transmission_hurdle_rates/2_tx_hurdle_rates_no_months.csv b/db/csvs_test_examples/transmission/transmission_hurdle_rates/2_tx_hurdle_rates_no_months.csv new file mode 100644 index 000000000..59f933a1a --- /dev/null +++ b/db/csvs_test_examples/transmission/transmission_hurdle_rates/2_tx_hurdle_rates_no_months.csv @@ -0,0 +1,3 @@ +transmission_line,period,month,hurdle_rate_positive_direction_per_mwh,hurdle_rate_negative_direction_per_mwh +Tx1,2020,0,5,5 +Tx_new,2020,0,5,5 diff --git a/db/csvs_test_examples/transmission/transmission_portfolios/4_transmission_portfolios_new_and_nonew.csv b/db/csvs_test_examples/transmission/transmission_portfolios/4_transmission_portfolios_new_and_nonew.csv new file mode 100644 index 000000000..63d3abe25 --- /dev/null +++ b/db/csvs_test_examples/transmission/transmission_portfolios/4_transmission_portfolios_new_and_nonew.csv @@ -0,0 +1,3 @@ +transmission_line,capacity_type +Tx1,tx_spec +Tx_new,tx_new_lin