From 2e3d144481a14ad139b4b674b6216aa2e067336c Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Wed, 17 Jun 2026 15:46:19 -0600 Subject: [PATCH 01/28] use float32 for all parameters in inputs.h5; move more input parameters to inputs.h5 --- inputs/financials/retire_penalty.csv | 3 +- .../plant_characteristics/min_retire_age.csv | 3 +- inputs/techs/tech_resourceclass.csv | 2 +- inputs/waterclimate/water_with_cons_rate.csv | 2 +- reeds/core/setup/b_inputs.gms | 38 ------------------- reeds/input_processing/copy_files.py | 2 +- reeds/input_processing/runfiles.csv | 9 ++--- reeds/io.py | 1 + 8 files changed, 12 insertions(+), 48 deletions(-) diff --git a/inputs/financials/retire_penalty.csv b/inputs/financials/retire_penalty.csv index 22907f488..dfb5d566c 100644 --- a/inputs/financials/retire_penalty.csv +++ b/inputs/financials/retire_penalty.csv @@ -1,3 +1,4 @@ +allt,fraction 2010,1 2011,1 2012,1 @@ -38,4 +39,4 @@ 2047,0.5 2048,0.5 2049,0.5 -2050,0.5 \ No newline at end of file +2050,0.5 diff --git a/inputs/plant_characteristics/min_retire_age.csv b/inputs/plant_characteristics/min_retire_age.csv index 10df5b74f..331af7f09 100644 --- a/inputs/plant_characteristics/min_retire_age.csv +++ b/inputs/plant_characteristics/min_retire_age.csv @@ -1,3 +1,4 @@ +i,years biopower,20 coal-IGCC,20 coal-new,20 @@ -10,4 +11,4 @@ Gas-CT,20 Gas-CT_aero,20 Nuclear,20 Nuclear-SMR,20 -o-g-s,20 \ No newline at end of file +o-g-s,20 diff --git a/inputs/techs/tech_resourceclass.csv b/inputs/techs/tech_resourceclass.csv index 648981deb..511170f25 100644 --- a/inputs/techs/tech_resourceclass.csv +++ b/inputs/techs/tech_resourceclass.csv @@ -1,4 +1,4 @@ -*i,resourceclass +i,resourceclass csp1_1,1 csp1_2,2 csp1_3,3 diff --git a/inputs/waterclimate/water_with_cons_rate.csv b/inputs/waterclimate/water_with_cons_rate.csv index b362fa04d..9580a37bc 100644 --- a/inputs/waterclimate/water_with_cons_rate.csv +++ b/inputs/waterclimate/water_with_cons_rate.csv @@ -1,4 +1,4 @@ -*i,ctt,w,value +i,ctt,w,gal/MWh Hydro,n,with,1 Gas-CT,n,with,1 Gas-CT_aero,n,with,1 diff --git a/reeds/core/setup/b_inputs.gms b/reeds/core/setup/b_inputs.gms index 90d45c9d6..cd2047f8d 100644 --- a/reeds/core/setup/b_inputs.gms +++ b/reeds/core/setup/b_inputs.gms @@ -639,14 +639,6 @@ $endif.naris parameter resourceclassnum(resourceclass) "numeric value for resource class" ; resourceclassnum(resourceclass) = resourceclass.val ; -set tech_resourceclass(i,resourceclass) "map from CSP/DUPV techs to resource classes" -/ -$offlisting -$ondelim -$include inputs_case%ds%tech_resourceclass.csv -$offdelim -$onlisting -/ ; * There are 12 CSP resource classes by default. If Sw_NumCSPclasses < 12, we ban the * CSP techs with resource class > Sw_NumCSPclasses if(Sw_NumCSPclasses < 12, @@ -805,18 +797,6 @@ tg_i("csp",i)$[(csp1(i) or csp2(i) or csp3(i) or csp4(i))$Sw_WaterMain] = yes ; storage_interday(i)$(Sw_InterDayLinkage = 0) = no ; -$onempty -parameter water_with_cons_rate(i,ctt,w) "--gal/MWh-- technology specific-cooling tech based water withdrawal and consumption data" -/ -$offlisting -$ondelim -$include inputs_case%ds%water_with_cons_rate.csv -$offdelim -$onlisting -/ -; -$offempty - $onempty * Water requirement if all filling takes place in 1 year and minimum reservoir level is 15% of max volume table water_req_psh(r,rscbin) "--Mgal/MW/yr-- required water for PSH during construction to fill reservoir" @@ -872,28 +852,10 @@ sccapcosttech(i)$[hydro(i) or psh(i) or dr_shed(i)] = yes ; retiretech(i,v,r,t) = no ; inv_cond(i,v,r,t,tt) = no ; -parameter min_retire_age(i) "minimum retirement age by technology" -/ -$offlisting -$ondelim -$include inputs_case%ds%min_retire_age.csv -$offdelim -$onlisting -/ ; - min_retire_age(i)$[i_water_cooling(i)$Sw_WaterMain] = sum{ii$ctt_i_ii(i,ii), min_retire_age(ii) } ; * if GSw_Clean_Air_Act is enabled, there is no minimum retire age for coal plants min_retire_age(i)$[coal(i)$Sw_Clean_Air_Act] = no ; -parameter retire_penalty(allt) "--fraction-- penalty for retiring a power plant expressed as a fraction of FOM" -/ -$offlisting -$ondelim -$include inputs_case%ds%retire_penalty.csv -$offdelim -$onlisting - / ; - *include non-numeraire CSPs and then exclude numeraire CSPs in ii dimension of *prescriptivelink0(pcat,ii) set when Sw_WaterMain is ON diff --git a/reeds/input_processing/copy_files.py b/reeds/input_processing/copy_files.py index 5a74bdfaf..a00f6cc80 100644 --- a/reeds/input_processing/copy_files.py +++ b/reeds/input_processing/copy_files.py @@ -901,7 +901,7 @@ def write_non_region_file( df.to_csv(os.path.join(dir_dst, 'co2_site_char.csv'), index=False) else: - if str(row.GAMStype).lower() == 'set': + if str(row.GAMStype).lower() in ['set', 'parameter']: reeds.io.write_csv_to_inputs_h5( filepath=row.full_filepath, case=case, diff --git a/reeds/input_processing/runfiles.csv b/reeds/input_processing/runfiles.csv index 6ca5b1998..de4541557 100644 --- a/reeds/input_processing/runfiles.csv +++ b/reeds/input_processing/runfiles.csv @@ -102,7 +102,6 @@ growth_bin_size_mult.csv,inputs/growth_constraints/growth_bin_size_mult.csv,1,ig growth_limit_absolute.csv,inputs/growth_constraints/growth_limit_absolute.csv,1,ignore,ignore,,,,,0,,,,,, growth_penalty.csv,inputs/growth_constraints/growth_penalty.csv,1,ignore,ignore,,,,,0,,,,,, h2_ba_share.csv,inputs/consume/h2_demand_county_share.csv,int(sw.GSw_H2) != 0,sum,ignore,*r,t,,0,0,,,,,, -gwp.csv,inputs/emission_constraints/gwp.csv,1,ignore,ignore,,,,,0,,1,parameter,gwp,, h2_leakage_rate.csv,inputs/emission_constraints/h2_leakage_rate.csv,1,ignore,ignore,,,,,0,,,,,, h2_exogenous_demand.csv,inputs/consume/h2_exogenous_demand.csv,int(sw.GSw_H2) != 0,ignore,ignore,,p,,1,0,,,,,, h2_st.csv,inputs/sets/h2_st.csv,1,ignore,ignore,,,,,,,,set,h2_st,investments needed to store and transport H2, @@ -139,7 +138,7 @@ maxdailycf.csv,inputs/plant_characteristics/maxdailycf.csv,int(sw.GSw_MaxDailyCF mcs_distributions.yaml,inputs/userinput/mcs_distributions_{MCS_dist}.yaml,int(sw.MCS_runs) != 0,ignore,ignore,,,,,,,,,,, mex_growth_rate.csv,inputs/load/mex_growth_rate.csv,1,ignore,ignore,,,,0,,,,,,, minCF.csv,inputs/plant_characteristics/minCF.csv,int(sw.GSw_MinCF) != 0,ignore,ignore,,,,,0,,,,,, -min_retire_age.csv,inputs/plant_characteristics/min_retire_age.csv,1,ignore,ignore,,,,,0,,,,,, +min_retire_age.csv,inputs/plant_characteristics/min_retire_age.csv,1,ignore,ignore,,,,,0,,,parameter,,minimum retirement age by technology, mingen_fixed.csv,inputs/plant_characteristics/mingen_fixed.csv,int(sw.GSw_MingenFixed) != 0,ignore,ignore,,,*i,,0,,,,,, minloadfrac0.csv,inputs/plant_characteristics/minloadfrac0.csv,(int(sw.GSw_Mingen) != 0) or (int(sw.GSw_MinLoading) != 0),ignore,ignore,,,,,0,,,,,, modeled_regions.csv,inputs/userinput/modeled_regions.csv,1,ignore,ignore,,,,,,,,,,, @@ -214,7 +213,7 @@ recstyle.csv,inputs/state_policies/recstyle.csv,int(sw.GSw_StateRPS) != 0,ignore rectable.csv,inputs/state_policies/rectable.csv,int(sw.GSw_StateRPS) != 0,ignore,ignore,st_st,st,,,0,,,,,, regional_cap_cost_diff.csv,inputs/financials/reg_cap_cost_diff_{reg_cap_cost_diff_suffix}.csv,1,mean,ignore,r,wide,,1,0,,,,,,precursor data to reg_cap_cost_diff.csv resourceclass.csv,inputs/sets/resourceclass.csv,1,ignore,ignore,,,,,,,,set,resourceclass,renewable resource classes, -retire_penalty.csv,inputs/financials/retire_penalty.csv,1,ignore,ignore,,,,,0,,,,,, +retire_penalty.csv,inputs/financials/retire_penalty.csv,1,ignore,ignore,,,,,0,,,parameter,,--fraction-- penalty for retiring a power plant expressed as a fraction of FOM, rev_paths.csv,inputs/supply_curve/rev_paths.csv,1,ignore,ignore,,,,,0,,,,,, rggi_states.csv,inputs/emission_constraints/rggi_states.csv,int(sw.GSw_RGGI) != 0,ignore,ignore,*st,,,,0,,,,,, rggicon.csv,inputs/emission_constraints/rggicon.csv,int(sw.GSw_RGGI) != 0,ignore,ignore,,,,0,,,,,,, @@ -234,7 +233,7 @@ supplycurve_wind-ons.csv,inputs/supply_curve/supplycurve_wind-ons-{GSw_SitingWin wst_surface.csv,inputs/sets/wst_surface.csv,1,ignore,ignore,,,,,0,,,set,wst_surface,surface water types where access is based on consumption not withdrawal, tc_phaseout_schedule.csv,inputs/financials/tc_phaseout_schedule_{GSw_TCPhaseout_schedule}.csv,int(sw.GSw_TCPhaseout) != 0,ignore,ignore,,,,,0,,,,,, tech-subset-table.csv,inputs/tech-subset-table.csv,1,ignore,ignore,,,,,0,,,,,, -tech_resourceclass.csv,inputs/techs/tech_resourceclass.csv,1,ignore,ignore,,,,,0,,,,,, +tech_resourceclass.csv,inputs/techs/tech_resourceclass.csv,1,ignore,ignore,,,,,0,,,set,,map from CSP/DUPV techs to resource classes, techs.csv,inputs/techs/techs_{techs_suffix}.csv,1,ignore,ignore,,,,,0,,,,,, techs_banned.csv,inputs/state_policies/techs_banned.yaml,1,ignore,ignore,wide,i,,,0,,,,,, techs_banned_ces.csv,inputs/state_policies/techs_banned_ces.csv,int(sw.GSw_StateRPS) != 0,ignore,ignore,wide_st,i,,,0,,,,,, @@ -263,7 +262,7 @@ uranium_price.csv,inputs/fuelprices/uranium_{uraniumscen}.csv,1,ignore,ignore,,, var_map.csv,inputs/valuestreams/var_map.csv,1,ignore,ignore,,,,,0,,,,,, wat_access_cap_cost.csv,inputs/waterclimate/wat_access_cap_cost.csv,int(sw.GSw_WaterMain) != 0,sc_cat,geosize,r,*wst,,0,0,value,,,,, water_req_psh_10h_1_51.csv,inputs/waterclimate/water_req_psh_10h_1_51.csv,(int(sw.GSw_PSHwatercon) != 0) and (int(sw.GSw_WaterMain) != 0),sum,geosize,r,wide,,1,0,,,,,,not yet ready for county-level disaggregation -water_with_cons_rate.csv,inputs/waterclimate/water_with_cons_rate.csv,int(sw.GSw_WaterMain) != 0,ignore,ignore,,,,,0,,,,,, +water_with_cons_rate.csv,inputs/waterclimate/water_with_cons_rate.csv,int(sw.GSw_WaterMain) != 0,ignore,ignore,,,,,0,,,parameter,,--gal/MWh-- technology specific-cooling tech based water withdrawal and consumption data, windows.csv,inputs/userinput/windows_{windows_suffix}.csv,1,ignore,ignore,,,,,0,,,,,, wst_climate.csv,inputs/sets/wst_climate.csv,1,ignore,ignore,,,,,0,,,set,wst_climate,, yearafter.csv,inputs/sets/yearafter.csv,1,ignore,ignore,,,,,,,,set,yearafter,set to loop over for the final year calculation, diff --git a/reeds/io.py b/reeds/io.py index 4c13b5212..471ce10ce 100644 --- a/reeds/io.py +++ b/reeds/io.py @@ -1764,6 +1764,7 @@ def write_to_inputs_h5( ## should contain the data as floats; all the other columns are treated as indices if gamstype == 'parameter': dfwrite.columns = dfwrite.columns.tolist()[:-1] + ['Value'] + dfwrite['Value'] = dfwrite['Value'].astype(np.float32) ### Write record to h5 file calling_file = Path(inspect.stack()[-1][1]).name attrs = {'gamstype': gamstype.lower(), 'written_by': calling_file} From 2060be554c9709d53f78b993377ad64184e88f98 Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Fri, 26 Jun 2026 16:32:16 -0600 Subject: [PATCH 02/28] add inputs.h5 support to copy_files.write_region_indexed_file(); move some more inputs to inputs.h5 --- inputs/plant_characteristics/maxdailycf.csv | 1 + inputs/plant_characteristics/minCF.csv | 1 + .../years_until_endogenous.csv | 188 ++++++++++++++++-- inputs/state_policies/acp_disallowed.csv | 2 +- inputs/state_policies/forced_retirements.csv | 2 +- inputs/state_policies/nuclear_subsidies.csv | 2 +- inputs/storage/storage_duration.csv | 1 + reeds/core/setup/b_inputs.gms | 81 -------- reeds/input_processing/WriteHintage.py | 13 +- reeds/input_processing/copy_files.py | 37 +++- reeds/input_processing/recf.py | 3 +- reeds/input_processing/runfiles.csv | 12 +- reeds/input_processing/writecapdat.py | 7 +- reeds/io.py | 6 +- runreeds.py | 2 +- 15 files changed, 225 insertions(+), 133 deletions(-) diff --git a/inputs/plant_characteristics/maxdailycf.csv b/inputs/plant_characteristics/maxdailycf.csv index 1a70a7088..b40876235 100644 --- a/inputs/plant_characteristics/maxdailycf.csv +++ b/inputs/plant_characteristics/maxdailycf.csv @@ -1,2 +1,3 @@ +i,fraction dr_shed_1,0.167 dr_shed_2,0.167 diff --git a/inputs/plant_characteristics/minCF.csv b/inputs/plant_characteristics/minCF.csv index 9f91c5b0a..8cf16f350 100644 --- a/inputs/plant_characteristics/minCF.csv +++ b/inputs/plant_characteristics/minCF.csv @@ -1,3 +1,4 @@ +i,fraction beccs_mod,0.06 beccs_max,0.06 biopower,0.06 diff --git a/inputs/plant_characteristics/years_until_endogenous.csv b/inputs/plant_characteristics/years_until_endogenous.csv index e6c02d297..6fe684e71 100644 --- a/inputs/plant_characteristics/years_until_endogenous.csv +++ b/inputs/plant_characteristics/years_until_endogenous.csv @@ -1,4 +1,4 @@ -tech,years_from_now +i,years_from_now battery_li,0 biopower,2 beccs_mod,4 @@ -6,21 +6,95 @@ beccs_max,4 can-imports,500 coal-CCS_mod,4 coal-CCS_max,4 -coal-CCS-F1*coal-CCS-F3,4 +coal-CCS-F1,4 +coal-CCS-F2,4 +coal-CCS-F3,4 Coal-IGCC,2 coal-new,2 CoalOldScr,500 CoalOldUns,500 CofireNew,2 CofireOld,500 -csp1_1*csp1_12,3 -csp2_1*csp2_12,3 -csp3_1*csp3_12,3 -csp4_1*csp4_12,3 -dr_shed_1*dr_shed_2,0 -evmc_storage_1*evmc_storage_10,0 -evmc_shape_1*evmc_shape_10,0 -egs_allkm_1*egs_allkm_10,8 +csp1_1,3 +csp1_2,3 +csp1_3,3 +csp1_4,3 +csp1_5,3 +csp1_6,3 +csp1_7,3 +csp1_8,3 +csp1_9,3 +csp1_10,3 +csp1_11,3 +csp1_12,3 +csp2_1,3 +csp2_2,3 +csp2_3,3 +csp2_4,3 +csp2_5,3 +csp2_6,3 +csp2_7,3 +csp2_8,3 +csp2_9,3 +csp2_10,3 +csp2_11,3 +csp2_12,3 +csp3_1,3 +csp3_2,3 +csp3_3,3 +csp3_4,3 +csp3_5,3 +csp3_6,3 +csp3_7,3 +csp3_8,3 +csp3_9,3 +csp3_10,3 +csp3_11,3 +csp3_12,3 +csp4_1,3 +csp4_2,3 +csp4_3,3 +csp4_4,3 +csp4_5,3 +csp4_6,3 +csp4_7,3 +csp4_8,3 +csp4_9,3 +csp4_10,3 +csp4_11,3 +csp4_12,3 +dr_shed_1,0 +dr_shed_2,0 +evmc_storage_1,0 +evmc_storage_2,0 +evmc_storage_3,0 +evmc_storage_4,0 +evmc_storage_5,0 +evmc_storage_6,0 +evmc_storage_7,0 +evmc_storage_8,0 +evmc_storage_9,0 +evmc_storage_10,0 +evmc_shape_1,0 +evmc_shape_2,0 +evmc_shape_3,0 +evmc_shape_4,0 +evmc_shape_5,0 +evmc_shape_6,0 +evmc_shape_7,0 +evmc_shape_8,0 +evmc_shape_9,0 +evmc_shape_10,0 +egs_allkm_1,8 +egs_allkm_2,8 +egs_allkm_3,8 +egs_allkm_4,8 +egs_allkm_5,8 +egs_allkm_6,8 +egs_allkm_7,8 +egs_allkm_8,8 +egs_allkm_9,8 +egs_allkm_10,8 distpv,0 Gas-CC,0 Gas-CC_H_1x1,0 @@ -31,17 +105,55 @@ Gas-CC_H_1x1-CCS_mod,4 Gas-CC_H_1x1-CCS_max,4 Gas-CC_H_2x1-CCS_mod,4 Gas-CC_H_2x1-CCS_max,4 -Gas-CC-CCS-F1*Gas-CC-CCS-F3,4 +Gas-CC-CCS-F1,4 +Gas-CC-CCS-F2,4 +Gas-CC-CCS-F3,4 Gas-CT,0 Gas-CT_aero,0 H2-CT,3 H2-CC,3 ng-fuel-cell,10 -geohydro_allkm_1*geohydro_allkm_10,2 +geohydro_allkm_1,2 +geohydro_allkm_2,2 +geohydro_allkm_3,2 +geohydro_allkm_4,2 +geohydro_allkm_5,2 +geohydro_allkm_6,2 +geohydro_allkm_7,2 +geohydro_allkm_8,2 +geohydro_allkm_9,2 +geohydro_allkm_10,2 geothermal,2 -pvb1_1*pvb1_10,0 -pvb2_1*pvb2_10,0 -pvb3_1*pvb3_10,0 +pvb1_1,0 +pvb1_2,0 +pvb1_3,0 +pvb1_4,0 +pvb1_5,0 +pvb1_6,0 +pvb1_7,0 +pvb1_8,0 +pvb1_9,0 +pvb1_10,0 +pvb2_1,0 +pvb2_2,0 +pvb2_3,0 +pvb2_4,0 +pvb2_5,0 +pvb2_6,0 +pvb2_7,0 +pvb2_8,0 +pvb2_9,0 +pvb2_10,0 +pvb3_1,0 +pvb3_2,0 +pvb3_3,0 +pvb3_4,0 +pvb3_5,0 +pvb3_6,0 +pvb3_7,0 +pvb3_8,0 +pvb3_9,0 +pvb3_10,0 hydD,2 hydED,2 hydEND,2 @@ -54,17 +166,53 @@ hydSND,2 hydUD,2 hydUND,2 lfill-gas,500 -egs_nearfield_1*egs_nearfield_10,2 +egs_nearfield_1,2 +egs_nearfield_2,2 +egs_nearfield_3,2 +egs_nearfield_2,2 +egs_nearfield_5,2 +egs_nearfield_6,2 +egs_nearfield_7,2 +egs_nearfield_8,2 +egs_nearfield_9,2 +egs_nearfield_10,2 Nuclear,8 Nuclear-SMR,8 o-g-s,500 pumped-hydro,3 pumped-hydro-flex,3 -upv_1*upv_10,0 -wind-ofs_1*wind-ofs_10,4 -wind-ons_1*wind-ons_10,0 +upv_1,0 +upv_2,0 +upv_3,0 +upv_4,0 +upv_5,0 +upv_6,0 +upv_7,0 +upv_8,0 +upv_9,0 +upv_10,0 +wind-ofs_1,4 +wind-ofs_2,4 +wind-ofs_3,4 +wind-ofs_4,4 +wind-ofs_5,4 +wind-ofs_6,4 +wind-ofs_7,4 +wind-ofs_8,4 +wind-ofs_9,4 +wind-ofs_10,4 +wind-ons_1,0 +wind-ons_2,0 +wind-ons_3,0 +wind-ons_4,0 +wind-ons_5,0 +wind-ons_6,0 +wind-ons_7,0 +wind-ons_8,0 +wind-ons_9,0 +wind-ons_10,0 electrolyzer,0 smr,0 smr_ccs,0 dac,3 -dac_gas,3 \ No newline at end of file +dac_gas,3 diff --git a/inputs/state_policies/acp_disallowed.csv b/inputs/state_policies/acp_disallowed.csv index 011b6bff9..495de1e6c 100644 --- a/inputs/state_policies/acp_disallowed.csv +++ b/inputs/state_policies/acp_disallowed.csv @@ -1,2 +1,2 @@ -*st,RPSCat,val +st,RPSCat,val NY,CES,1 diff --git a/inputs/state_policies/forced_retirements.csv b/inputs/state_policies/forced_retirements.csv index 39803fbc8..dfa4356bc 100644 --- a/inputs/state_policies/forced_retirements.csv +++ b/inputs/state_policies/forced_retirements.csv @@ -1,4 +1,4 @@ -*i,st,t +i,st,t CoalOldScr,IL,2045 CoalOldScr,NY,2040 CoalOldScr,VA,2024 diff --git a/inputs/state_policies/nuclear_subsidies.csv b/inputs/state_policies/nuclear_subsidies.csv index 567532f06..74f485c9c 100644 --- a/inputs/state_policies/nuclear_subsidies.csv +++ b/inputs/state_policies/nuclear_subsidies.csv @@ -1,4 +1,4 @@ -*st,year +st,year CT,2030 IL,2028 NJ,2026 diff --git a/inputs/storage/storage_duration.csv b/inputs/storage/storage_duration.csv index 12fb2e13f..df26e566b 100644 --- a/inputs/storage/storage_duration.csv +++ b/inputs/storage/storage_duration.csv @@ -1,3 +1,4 @@ +i,hours pumped-hydro,12 pumped-hydro-flex,12 csp1_1,14 diff --git a/reeds/core/setup/b_inputs.gms b/reeds/core/setup/b_inputs.gms index cd2047f8d..f16c0d020 100644 --- a/reeds/core/setup/b_inputs.gms +++ b/reeds/core/setup/b_inputs.gms @@ -1181,15 +1181,6 @@ pvf_onm_undisc(t)$pvf_capital(t) = pvf_onm(t) / pvf_capital(t) ; *========================================== * Note that some techs have a dummy firstyear of 2500 -parameter firstyear(i) "first year where new investment is allowed" -/ -$offlisting -$ondelim -$include inputs_case%ds%firstyear.csv -$offdelim -$onlisting -/ ; - *---Add first year that capacity can be built: firstyear(i)$[(firstyear(i) < firstyear_min)$firstyear(i)] = firstyear_min ; @@ -1232,16 +1223,6 @@ stfeas(st)$[sum{r$r_st(r,st), 1 }] = yes ; * -- existing capacity -- *========================== -*Begin loading of capacity data -parameter poi_cap_init(r) "--MW-- initial (pre-2010) capacity of all types" -/ -$offlisting -$ondelim -$include inputs_case%ds%poi_cap_init.csv -$offdelim -$onlisting -/ ; - *created by reeds/input_processing/writecapdat.py table capnonrsc(i,r,*) "--MW-- raw power capacity data for non-RSC tech" $offlisting @@ -1356,17 +1337,6 @@ $onlisting ; $offempty -$onempty -parameter forced_retirements(i,st) "--integer-- year in which to force retirements of certain techs by state" -/ -$offlisting -$ondelim -$include inputs_case%ds%forced_retirements.csv -$offdelim -$onlisting -/ ; -$offempty - set forced_retire(i,r,t) ; forced_retire(i,r,t)$[sum{st$r_st(r,st), (yeart(t)>=forced_retirements(i,st))$forced_retirements(i,st) }] = yes ; @@ -2618,18 +2588,6 @@ $offdelim $onlisting ; -$onempty -parameter acp_disallowed(st,RPSCat) "--integer-- Indication for whether ACP purchases are disallowed (1) or allowed (0)." -/ -$offlisting -$ondelim -$include inputs_case%ds%acp_disallowed.csv -$offdelim -$onlisting -/ -; -$offempty - RecStates(RPSCat,st,t)$[RecPerc(RPSCat,st,t) or sum{ast, rectable(ast,st) }] = yes ; *If both states have an RPS for the RPSCat and if they're allowed to trade, they can trade @@ -5210,15 +5168,6 @@ resourcescaler(i)$csp(i) = CSP_SM(i) / csp_sm_baseline ; * For PSH, tech-specific storage duration sets a default value. * Then when when GSw_HydroPSHDurData = 1, * region- and vintage-specific durations are defined where data exists. -parameter storage_duration(i) "--hours-- storage duration by tech" -/ -$offlisting -$ondelim -$include inputs_case%ds%storage_duration.csv -$offdelim -$onlisting -/ ; - $onempty scalar psh_sc_duration "--hours-- PSH storage duration corresponding to selected supply curve" / @@ -5305,15 +5254,6 @@ cost_vom(i,v,r,t)$[storage(i)$valgen(i,v,r,t)$(not cost_vom(i,v,r,t))] = storage parameter minCF(i,t) "--fraction-- minimum annual capacity factor for each tech fleet, applied to (i,r)" maxdailycf(i,t) "--fraction-- maximum daily capacity factor" ; -* 6% for H2-CT and H2-CC is based on unpublished PLEXOS runs of 100% RE scenarios performed in summer 2019 -parameter minCF_input(i) "--fraction-- minimum annual capacity factor for each tech fleet, applied to (i,r)" -/ -$offlisting -$ondelim -$include inputs_case%ds%minCF.csv -$offdelim -$onlisting -/ ; minCF(i,t) = minCF_input(i) ; minCF(i,t)$[i_water_cooling(i)$Sw_WaterMain] = sum{ii$ctt_i_ii(i,ii), minCF(ii,t) } ; minCF(i,t)$upgrade(i) = sum{ii$upgrade_to(i,ii), minCF(ii,t) } ; @@ -5321,15 +5261,6 @@ minCF(i,t)$upgrade(i) = sum{ii$upgrade_to(i,ii), minCF(ii,t) } ; * adjust fleet mincf for nuclear when using flexible nuclear minCF(i,t)$[nuclear(i)$Sw_NukeFlex] = minCF_nuclear_flex ; -parameter maxdailycf_input(i) "--fraction-- maximum daily capacity factor for a technology" -/ -$offlisting -$ondelim -$include inputs_case%ds%maxdailycf.csv -$offdelim -$onlisting -/ ; - maxdailycf(i,t) = maxdailycf_input(i) ; maxdailycf(i,t)$[i_water_cooling(i)$Sw_WaterMain] = sum{ii$ctt_i_ii(i,ii), maxdailycf(ii,t) } ; maxdailycf(i,t)$upgrade(i) = sum{ii$upgrade_to(i,ii), maxdailycf(ii,t) } ; @@ -5619,18 +5550,6 @@ retiretech(i,v,r,t)$[(Sw_Retire=5)$nuclear(i)$(yeart(t)<=2030)] = no ; *several states have subsidies for nuclear power, so do not allow nuclear to retire in these states *before the year specified (see https://www.eia.gov/todayinenergy/detail.php?id=41534) *Note that Ohio has since repealed their nuclear subsidy, so is no longer included -$onempty -parameter nuclear_subsidies(st) '--year-- the year a nuclear subsidy ends in a given state' -/ -$offlisting -$ondelim -$include inputs_case%ds%nuclear_subsidies.csv -$offdelim -$onlisting -/ -; -$offempty - retiretech(i,initv,r,t)$[(yeart(t) < sum{st$r_st(r,st), nuclear_subsidies(st) })$valcap(i,initv,r,t)$nuclear(i)] = no ; * if Sw_NukeNoRetire is enabled, don't allow nuclear to retire through Sw_NukeNoRetireYear diff --git a/reeds/input_processing/WriteHintage.py b/reeds/input_processing/WriteHintage.py index 755993d10..3e68ccf73 100644 --- a/reeds/input_processing/WriteHintage.py +++ b/reeds/input_processing/WriteHintage.py @@ -297,9 +297,9 @@ def main(reeds_path, inputs_case): print('Starting WriteHintage.py') # #%% Settings for testing - # reeds_path = os.path.expanduser('~/github/ReEDS') + # reeds_path = reeds.io.reeds_path # inputs_case = os.path.join( - # reeds_path,'runs','v20231027_yamM0_Z45_h_d_365_transreg_z69_core','inputs_case') + # reeds_path,'runs','v20260626_inputsM1_Pacific','inputs_case') #%% Inputs from switches sw = reeds.io.get_switches(inputs_case) @@ -547,10 +547,11 @@ def main(reeds_path, inputs_case): #%%############################################################################ # -- Get forced retirement dataframe and merge onto output dataframe -- # ############################################################################### - forced_retire = pd.read_csv( - os.path.join(inputs_case, 'forced_retirements.csv'), - header=0, names=['tech','st','retire_year']) - + forced_retire = ( + reeds.io.read_input(inputs_case, 'forced_retirements') + .astype({'Value':int}) + .rename(columns={'i':'tech', 'Value':'retire_year'}) + ) # Forced retirements are at the state level, so use hierarchy to get the regions state2r = ( pd.read_csv( diff --git a/reeds/input_processing/copy_files.py b/reeds/input_processing/copy_files.py index a00f6cc80..3d02f717b 100644 --- a/reeds/input_processing/copy_files.py +++ b/reeds/input_processing/copy_files.py @@ -906,8 +906,8 @@ def write_non_region_file( filepath=row.full_filepath, case=case, gamstype=row.GAMStype.lower(), + name=(None if isinstance(row.GAMSname, float) else row.GAMSname), comment=(row.comment if isinstance(row.comment, str) else ''), - overwrite=True, ) else: shutil.copy(row.full_filepath, os.path.join(dir_dst, row.filename)) @@ -1067,7 +1067,7 @@ def map_and_aggregate( def write_region_indexed_file( df, - dir_dst, + inputs_case, source_deflator_map, sw, region_file_entry, @@ -1103,7 +1103,7 @@ def write_region_indexed_file( #---- Write data to dir_dst (inputs_case) folder ---- if filetype_out == 'h5': - reeds.io.write_profile_to_h5(df, filename, dir_dst) + reeds.io.write_profile_to_h5(df, filename, inputs_case) else: # Special cases: These files' values need to be adjusted to copy filepath = region_file_entry['filepath'] @@ -1125,7 +1125,23 @@ def write_region_indexed_file( case _: pass - df.to_csv(os.path.join(dir_dst,filename), index=False) + if str(region_file_entry.GAMStype).lower() in ['set', 'parameter']: + reeds.io.write_to_inputs_h5( + df, + key=( + Path(region_file_entry.filename).stem + if isinstance(region_file_entry.GAMSname, float) + else region_file_entry.GAMSname + ), + case=reeds.io.standardize_case(inputs_case), + gamstype=region_file_entry.GAMStype.lower(), + comment=( + region_file_entry.comment + if isinstance(region_file_entry.comment, str) else '' + ), + ) + else: + df.to_csv(os.path.join(inputs_case, filename), index=False) def write_region_indexed_files( @@ -1219,17 +1235,20 @@ def write_miscellaneous_files( )[sw['GSw_H2LeakageScen']].rename_axis('*i').round(5).to_csv( os.path.join(inputs_case,'h2_leakage_rate.csv')) - # Add this_year to years_until_endogenous to generate the tech-specific firstyear.csv file + # Add this_year to years_until_endogenous to generate the tech-specific firstyear parameter scalars = reeds.io.get_scalars(full=True) - ( + firstyear = ( pd.read_csv( # years_until_endogenous created using function write_non_region_files os.path.join(inputs_case, 'years_until_endogenous.csv'), index_col=0, ).squeeze(1) + int(scalars.loc['this_year','value']) - ).rename_axis('*i').rename('t').to_csv(os.path.join(inputs_case, 'firstyear.csv')) - + ) + reeds.io.write_to_inputs_h5( + firstyear, 'firstyear', inputs_case, gamstype='parameter', + comment='first year where new investment is allowed', + ) ### Single column from input table ### @@ -1578,7 +1597,7 @@ def main(reeds_path, inputs_case): # #%% Settings for testing ### # reeds_path = reeds.io.reeds_path - # inputs_case = os.path.join(reeds_path,'runs','v20260522_transcostM0_OR_water','inputs_case') + # inputs_case = os.path.join(reeds_path,'runs','v20260626_inputsM0_Pacific','inputs_case') # ---- Set up logger ---- diff --git a/reeds/input_processing/recf.py b/reeds/input_processing/recf.py index 40204f8d9..8ee7964e2 100644 --- a/reeds/input_processing/recf.py +++ b/reeds/input_processing/recf.py @@ -483,8 +483,7 @@ def main(reeds_path, inputs_case): ### Get solar multiples sms = {tech: scalars[f'csp_sm_{tech.strip("csp")}'] for tech in csptechs} ### Get storage durations - storage_duration = pd.read_csv( - os.path.join(inputs_case,'storage_duration.csv'), header=None, index_col=0).squeeze(1) + storage_duration = reeds.io.read_input(inputs_case, 'storage_duration').set_index('i').squeeze(1) ## All CSP resource classes have the same duration for a given tech, so just take the first one durations = {tech: storage_duration[f'csp{tech.strip("csp")}_1'] for tech in csptechs} ### Run the dispatch simulation for modeled regions diff --git a/reeds/input_processing/runfiles.csv b/reeds/input_processing/runfiles.csv index de4541557..f5b188755 100644 --- a/reeds/input_processing/runfiles.csv +++ b/reeds/input_processing/runfiles.csv @@ -13,7 +13,7 @@ quarter.csv,inputs/sets/quarter.csv,1,ignore,ignore,,,,,,,1,set,quarter,original month.csv,inputs/sets/month.csv,1,ignore,ignore,,,,,,,1,set,month,calendar months in a year, RPSCat.csv,inputs/sets/RPSCat.csv,1,ignore,ignore,,,,,,,,set,RPSCat,RPS constraint categories including clean energy standards, aclike.csv,inputs/sets/aclike.csv,1,ignore,ignore,,,,,0,,,set,aclike,AC transmission capacity types, -acp_disallowed.csv,inputs/state_policies/acp_disallowed.csv,int(sw.GSw_StateRPS) != 0,ignore,ignore,*st,"RPSCat,val",,,0,,,,,, +acp_disallowed.csv,inputs/state_policies/acp_disallowed.csv,int(sw.GSw_StateRPS) != 0,ignore,ignore,st,"RPSCat,val",,,0,,,parameter,,--integer-- Indication for whether ACP purchases are disallowed (1) or allowed (0), acp_prices.csv,inputs/state_policies/acp_prices.csv,int(sw.GSw_StateRPS) != 0,ignore,ignore,st,st,,1,0,,,,,, allt.csv,inputs/sets/allt.csv,1,ignore,ignore,,,,,,,,set,allt,all potential years, alpha.csv,inputs/fuelprices/alpha_{ngscen}.csv,1,ignore,ignore,wide_cendiv,t,,1,0,,,,,, @@ -88,7 +88,7 @@ financials_tech.csv,inputs/financials/financials_tech_{financials_tech_suffix}.c financials_transmission.csv,inputs/financials/financials_transmission_{financials_trans_suffix}.csv,1,ignore,ignore,,,,,0,,,,,, years_until_endogenous.csv,inputs/plant_characteristics/years_until_endogenous.csv,1,ignore,ignore,,,,,0,,,,,, flex_type.csv,inputs/sets/flex_type.csv,1,ignore,ignore,,,,,,,,set,flex_type,demand flexibility types, -forced_retirements.csv,inputs/state_policies/forced_retirements.csv,1,ignore,ignore,st,"*i,t",,0,0,,,,,, +forced_retirements.csv,inputs/state_policies/forced_retirements.csv,1,ignore,ignore,st,"i,t",,0,0,,,parameter,,--integer-- year in which to force retirements of certain techs by state, fuel2tech.csv,inputs/sets/fuel2tech.csv,1,ignore,ignore,,,,,0,,,set,fuel2tech,mapping between fuel types and generations, fuelbin.csv,inputs/sets/fuelbin.csv,1,ignore,ignore,,,,,,,,set,fuelbin,gas usage bracket, futurefiles.csv,inputs/userinput/futurefiles.csv,1,ignore,ignore,,,,,0,,,,,, @@ -134,10 +134,10 @@ lcclike.csv,inputs/sets/lcclike.csv,1,ignore,ignore,,,,,0,,,set,lcclike,transmis load_multiplier.csv,inputs/load/demand_{demandscen}.csv,1,ignore,ignore,,,,,0,,,,,, loadsite_annual.csv,inputs/load/loadsite_{GSw_LoadSiteTrajectory}.csv,float(sw.GSw_LoadSiteCF) > 0,ignore,ignore,*loadsitereg,t,,,0,,,,,, maxage.csv,inputs/plant_characteristics/maxage.csv,1,ignore,ignore,,,,,0,,,,,, -maxdailycf.csv,inputs/plant_characteristics/maxdailycf.csv,int(sw.GSw_MaxDailyCF) != 0,ignore,ignore,,,,,0,,,,,, +maxdailycf.csv,inputs/plant_characteristics/maxdailycf.csv,int(sw.GSw_MaxDailyCF) != 0,ignore,ignore,,,,,0,,,parameter,maxdailycf_input,--fraction-- maximum daily capacity factor for a technology, mcs_distributions.yaml,inputs/userinput/mcs_distributions_{MCS_dist}.yaml,int(sw.MCS_runs) != 0,ignore,ignore,,,,,,,,,,, mex_growth_rate.csv,inputs/load/mex_growth_rate.csv,1,ignore,ignore,,,,0,,,,,,, -minCF.csv,inputs/plant_characteristics/minCF.csv,int(sw.GSw_MinCF) != 0,ignore,ignore,,,,,0,,,,,, +minCF.csv,inputs/plant_characteristics/minCF.csv,int(sw.GSw_MinCF) != 0,ignore,ignore,,,,,0,,,parameter,minCF_input,"--fraction-- minimum annual capacity factor for each tech fleet, applied to (i,r)",6% for H2-CT and H2-CC is based on unpublished PLEXOS runs of 100% RE scenarios performed in summer 2019 min_retire_age.csv,inputs/plant_characteristics/min_retire_age.csv,1,ignore,ignore,,,,,0,,,parameter,,minimum retirement age by technology, mingen_fixed.csv,inputs/plant_characteristics/mingen_fixed.csv,int(sw.GSw_MingenFixed) != 0,ignore,ignore,,,*i,,0,,,,,, minloadfrac0.csv,inputs/plant_characteristics/minloadfrac0.csv,(int(sw.GSw_Mingen) != 0) or (int(sw.GSw_MinLoading) != 0),ignore,ignore,,,,,0,,,,,, @@ -154,7 +154,7 @@ ng_demand_tot.csv,inputs/fuelprices/ng_tot_demand_{ngscen}.csv,1,ignore,ignore,w noretire.csv,inputs/sets/noretire.csv,1,ignore,ignore,,,,,0,,,set,noretire,technologies that will never be retired, notvsc.csv,inputs/sets/notvsc.csv,1,ignore,ignore,,,,,0,,,set,notvsc,transmission capacity types that are not VSC, nuclear_energy_communities.csv,inputs/financials/nuclear_energy_communities.csv,1,ignore,ignore,,,,,0,,,,,,region aggregation and filtering is handled in copy_files -nuclear_subsidies.csv,inputs/state_policies/nuclear_subsidies.csv,1,ignore,ignore,*st,year,,0,0,,,,,, +nuclear_subsidies.csv,inputs/state_policies/nuclear_subsidies.csv,1,ignore,ignore,st,year,,0,0,,,parameter,,--year-- the year a nuclear subsidy ends in a given state, objective_function_params.yaml,tests/objective_function_params.yaml,1,ignore,ignore,,,,,,,,,,, offshore_req.csv,inputs/state_policies/offshore_req_{GSw_OfsWindForceScen}.csv,(int(sw.GSw_StateRPS) != 0) and (int(sw.GSw_OfsWind) != 0),ignore,ignore,st,,,1,0,,,,,, ofstype.csv,inputs/sets/ofstype.csv,1,ignore,ignore,,,,,,,,set,ofstype,offshore types used in offshore requirement constraint (eq_RPS_OFSWind), @@ -222,7 +222,7 @@ sc_cat.csv,inputs/sets/sc_cat.csv,1,ignore,ignore,,,,,0,,,set,sc_cat,supply curv scalars.csv,inputs/scalars.csv,1,ignore,ignore,,,,,0,,1,,,, startcost.csv,inputs/plant_characteristics/startcost.csv,int(sw.GSw_StartCost) != 0,ignore,ignore,,,*i,,0,,,,,, state_cap.csv,inputs/emission_constraints/state_cap.csv,int(sw.GSw_StateCap) != 0,ignore,ignore,*st,t,,0,0,,,,,, -storage_duration.csv,inputs/storage/storage_duration.csv,int(sw.GSw_Storage) != 0,ignore,ignore,,,,,0,,,,,, +storage_duration.csv,inputs/storage/storage_duration.csv,int(sw.GSw_Storage) != 0,ignore,ignore,,,,,0,,,parameter,,--hours-- storage duration by tech, storage_mandates.csv,inputs/state_policies/storage_mandates.csv,int(sw.GSw_BatteryMandate) != 0,ignore,ignore,*st,t,,0,0,,,,,, stressperiods_user.csv,inputs/temporal/stressperiods_{GSw_PRM_StressModel}.csv,sw.GSw_PRM_StressModel == 'user*',ignore,ignore,,,,,,,,,,, supply_chain_adjust.csv,inputs/financials/supply_chain_adjust.csv,1,ignore,ignore,,,,,0,,,,,, diff --git a/reeds/input_processing/writecapdat.py b/reeds/input_processing/writecapdat.py index fd49d5941..c55ee7dc7 100644 --- a/reeds/input_processing/writecapdat.py +++ b/reeds/input_processing/writecapdat.py @@ -306,7 +306,6 @@ def main(reeds_path, inputs_case, agglevel, regions): poi_cap_init = gdb_use.loc[(gdb_use[Sw_onlineyearcol] < startyear) & (gdb_use['RetireYear'] > startyear) ].groupby('r').summer_power_capacity_MW.sum().rename('MW').round(3) - poi_cap_init.index = poi_cap_init.index.rename('*r') #%%###################################### # -- non-RSC Existing Capacity -- # @@ -489,9 +488,7 @@ def main(reeds_path, inputs_case, agglevel, regions): print('Gathering SMR Existing Capacity...') # Grab the first year for smr because that is when new capacity can begin to be built (for # smr, smr_ccs and electrolyzers) - firstyear = pd.read_csv( - os.path.join(inputs_case,'firstyear.csv'), - ).rename(columns={'*i':'i'}).set_index('i').squeeze(1) + firstyear = reeds.io.read_input(inputs_case, 'firstyear').set_index('i').squeeze(1) h2_prod_first_year = firstyear['smr'] # Get exogenous H2 demand h2_exogenous_demand = ( @@ -802,6 +799,7 @@ def main(reeds_path, inputs_case, agglevel, regions): } comments = { 'pcat': 'prescribed capacity categories', + 'poi_cap_init': '--MW-- initial (pre-2010) capacity of all types', } return files_out, comments @@ -902,6 +900,7 @@ def main(reeds_path, inputs_case, agglevel, regions): } gamstype = { 'pcat': 'set', + 'poi_cap_init': 'parameter', } for key, df in data.items(): if gamstype.get(key, False): diff --git a/reeds/io.py b/reeds/io.py index 471ce10ce..6d2993bd3 100644 --- a/reeds/io.py +++ b/reeds/io.py @@ -1787,6 +1787,7 @@ def write_csv_to_inputs_h5( filepath:str|Path, case:str|Path, gamstype:Literal['set','parameter'], + name:str|None=None, comment:str='', **kwargs, ): @@ -1795,7 +1796,10 @@ def write_csv_to_inputs_h5( and write it to inputs.h5 """ df = pd.read_csv(filepath, dtype=str, header=None) - key = Path(filepath).stem + if isinstance(name, str): + if not len(name): + name = None + key = (Path(filepath).stem if name is None else name) if df.shape[1] == 1: ## Subsets have a header column beginning with '*'; ## primary sets do not have a header diff --git a/runreeds.py b/runreeds.py index e06286228..0d5fe8f72 100644 --- a/runreeds.py +++ b/runreeds.py @@ -913,7 +913,7 @@ def setupEnvironment( f'Specified single={single} but available cases are:\n' + '\n> '.join([c for c in df_cases.columns]) ) - raise KeyError(err) + raise ValueError(err) df_cases = df_cases[single.split(',')].copy() casenames = single.split(',') From 0e612ee20d28f119c5455acdc64c051e25b36119 Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Fri, 26 Jun 2026 16:32:53 -0600 Subject: [PATCH 03/28] io.write_to_h5(): turn overwrite on by default --- reeds/input_processing/copy_files.py | 8 +------- reeds/io.py | 3 ++- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/reeds/input_processing/copy_files.py b/reeds/input_processing/copy_files.py index 3d02f717b..dcb74a794 100644 --- a/reeds/input_processing/copy_files.py +++ b/reeds/input_processing/copy_files.py @@ -181,7 +181,6 @@ def get_regions_and_agglevel( reeds_path, inputs_case, save_regions_and_agglevel=True, - overwrite=False, ): """ Create a regional mapping to help filter for specific regions and aggregation levels. @@ -360,7 +359,6 @@ def get_regions_and_agglevel( reeds.io.write_to_inputs_h5( itlgrp, 'itlgrp', inputs_case, gamstype='set', comment='zone for additional interface transfer limit constraint', - overwrite=overwrite, ) # Drop any substate region columns as these will no longer be needed @@ -389,14 +387,12 @@ def get_regions_and_agglevel( df = pd.Series(hier_sub[level].unique()) reeds.io.write_to_inputs_h5( df, level, inputs_case, gamstype='set', comment=comment, - overwrite=overwrite, ) # Use a modified version of val_st that includes 'voluntary' reeds.io.write_to_inputs_h5( pd.Series(val_st), 'st', inputs_case, gamstype='set', comment="state (or special 'voluntary' entry for corporate procurements)", - overwrite=overwrite, ) # Rename columns and save as hierarchy.csv @@ -410,7 +406,6 @@ def get_regions_and_agglevel( offshore = hier_sub.loc[hier_sub.offshore == 1, 'r'] reeds.io.write_to_inputs_h5( offshore, 'offshore', inputs_case, gamstype='set', comment='offshore zones', - overwrite=overwrite, ) levels = [i for i in hier_sub if i != 'offshore'] @@ -421,8 +416,7 @@ def get_regions_and_agglevel( # Export region files if save_regions_and_agglevel: reeds.io.write_to_inputs_h5( - pd.Series(val_r), 'r', inputs_case, gamstype='set', - comment='regions', overwrite=overwrite, + pd.Series(val_r), 'r', inputs_case, gamstype='set', comment='regions', ) regions_and_agglevel = { diff --git a/reeds/io.py b/reeds/io.py index 6d2993bd3..cc98730dc 100644 --- a/reeds/io.py +++ b/reeds/io.py @@ -1661,7 +1661,7 @@ def write_to_h5( key, filepath, attrs={}, - overwrite=False, + overwrite=True, compression='gzip', compression_opts=4, **kwargs, @@ -1671,6 +1671,7 @@ def write_to_h5( if key in list(f): if overwrite: del f[key] + print(f'{key} was already used in {filepath} but is being overwritten') else: raise ValueError(f'{key} is already used in {filepath}') From c1c66a284e42bd6d29bec8a07a900fe16a3b142c Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Fri, 26 Jun 2026 16:33:34 -0600 Subject: [PATCH 04/28] plots.rainbowmapper(): move cmap for large number of traces to kwarg --- reeds/plots.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/reeds/plots.py b/reeds/plots.py index 617998b9a..f13e3151c 100644 --- a/reeds/plots.py +++ b/reeds/plots.py @@ -113,7 +113,13 @@ def df2gdf(dfin, crs='ESRI:102008', lat=None, lon=None): ### Sequential color dict -def rainbowmapper(iterable, colormap=None, explicitcolors=False, categorical=False): +def rainbowmapper( + iterable, + colormap=None, + explicitcolors=False, + categorical=False, + cmap_large=plt.cm.turbo, +): categoricalrainbow = [ plt.cm.tab20(i) for i in [10,11,6,7,2,3,12,13,16,17,4,5,18,19,0,1,8,9,14,15,] ] @@ -147,7 +153,7 @@ def rainbowmapper(iterable, colormap=None, explicitcolors=False, categorical=Fal elif categorical: colors = categoricalrainbow * (len(iterable)//20 + 1) else: - colors=[plt.cm.rainbow(i) for i in np.linspace(0,1,len(iterable))] + colors=[cmap_large(i) for i in np.linspace(0,1,len(iterable))] out = dict(zip(iterable, colors)) if explicitcolors: explicit = { From c69b1095fcae1b5cf411d2e0580e84d90765956b Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Thu, 2 Jul 2026 14:11:00 -0600 Subject: [PATCH 05/28] reshape some waterclimate inputs to long --- inputs/waterclimate/cost_cap_mult.csv | 150 +++++++++++++++++++------ inputs/waterclimate/cost_vom_mult.csv | 150 +++++++++++++++++++------ inputs/waterclimate/heat_rate_mult.csv | 146 ++++++++++++++++++------ reeds/core/setup/b_inputs.gms | 24 ---- reeds/input_processing/runfiles.csv | 6 +- 5 files changed, 339 insertions(+), 137 deletions(-) diff --git a/inputs/waterclimate/cost_cap_mult.csv b/inputs/waterclimate/cost_cap_mult.csv index 038f86579..aea2c0541 100644 --- a/inputs/waterclimate/cost_cap_mult.csv +++ b/inputs/waterclimate/cost_cap_mult.csv @@ -1,37 +1,113 @@ -,o,r,d,p,n -Hydro,0,0,0,0,1 -gas-CT,0,0,0,0,1 -gas-CT_aero,0,0,0,0,1 -gas-CC,0.978,1,1.102,0.978,0 -gas-CC_h_1x1,0.978,1,1.102,0.978,0 -gas-CC_h_2x1,0.978,1,1.102,0.978,0 -Gas-CC-CCS_mod,0.981,1,1.075,0,0 -Gas-CC-CCS_max,0.981,1,1.075,0,0 -Gas-CC_H_1x1-CCS_mod,0.981,1,1.075,0,0 -Gas-CC_H_1x1-CCS_max,0.981,1,1.075,0,0 -Gas-CC_H_2x1-CCS_mod,0.981,1,1.075,0,0 -Gas-CC_H_2x1-CCS_max,0.981,1,1.075,0,0 -Gas-CC-CCS-F1,0.981,1,1.075,0,0 -Gas-CC-CCS-F2,0.981,1,1.075,0,0 -Gas-CC-CCS-F3,0.981,1,1.075,0,0 -CoalOldScr,0.981,1,1.045,0.981,0 -CoalOldUns,0.981,1,1.045,0.981,0 -coal-new,0.981,1,1.045,0.981,0 -coal-IGCC,0.988,1,1.033,0.988,0 -coal-CCS_mod,0.982,1,1.031,0,0 -coal-CCS_max,0.982,1,1.031,0,0 -coal-CCS-F1,0.982,1,1.031,0,0 -coal-CCS-F2,0.982,1,1.031,0,0 -coal-CCS-F3,0.982,1,1.031,0,0 -o-g-s,0.981,1,1.045,0.981,1 -nuclear,0.981,1,1.045,0.981,0 -nuclear-SMR,0.981,1,1.045,0.981,0 -geothermal,0,0,0,0,1 -biopower,0.981,1,1.045,0.981,0 -beccs_mod,0.981,1,1.045,0.981,0 -beccs_max,0.981,1,1.045,0.981,0 -CofireOld,0.981,1,1.045,0.981,0 -CofireNew,0.981,1,1.045,0.981,0 -lfill-gas,0,0,0,0,1 -distpv,0,0,0,0,1 -csp1_1,0.9048,0.9524,1,0,0 +i,ctt,fraction +Hydro,n,1.0 +gas-CT,n,1.0 +gas-CT_aero,n,1.0 +gas-CC,o,0.978 +gas-CC,r,1.0 +gas-CC,d,1.102 +gas-CC,p,0.978 +gas-CC_h_1x1,o,0.978 +gas-CC_h_1x1,r,1.0 +gas-CC_h_1x1,d,1.102 +gas-CC_h_1x1,p,0.978 +gas-CC_h_2x1,o,0.978 +gas-CC_h_2x1,r,1.0 +gas-CC_h_2x1,d,1.102 +gas-CC_h_2x1,p,0.978 +Gas-CC-CCS_mod,o,0.981 +Gas-CC-CCS_mod,r,1.0 +Gas-CC-CCS_mod,d,1.075 +Gas-CC-CCS_max,o,0.981 +Gas-CC-CCS_max,r,1.0 +Gas-CC-CCS_max,d,1.075 +Gas-CC_H_1x1-CCS_mod,o,0.981 +Gas-CC_H_1x1-CCS_mod,r,1.0 +Gas-CC_H_1x1-CCS_mod,d,1.075 +Gas-CC_H_1x1-CCS_max,o,0.981 +Gas-CC_H_1x1-CCS_max,r,1.0 +Gas-CC_H_1x1-CCS_max,d,1.075 +Gas-CC_H_2x1-CCS_mod,o,0.981 +Gas-CC_H_2x1-CCS_mod,r,1.0 +Gas-CC_H_2x1-CCS_mod,d,1.075 +Gas-CC_H_2x1-CCS_max,o,0.981 +Gas-CC_H_2x1-CCS_max,r,1.0 +Gas-CC_H_2x1-CCS_max,d,1.075 +Gas-CC-CCS-F1,o,0.981 +Gas-CC-CCS-F1,r,1.0 +Gas-CC-CCS-F1,d,1.075 +Gas-CC-CCS-F2,o,0.981 +Gas-CC-CCS-F2,r,1.0 +Gas-CC-CCS-F2,d,1.075 +Gas-CC-CCS-F3,o,0.981 +Gas-CC-CCS-F3,r,1.0 +Gas-CC-CCS-F3,d,1.075 +CoalOldScr,o,0.981 +CoalOldScr,r,1.0 +CoalOldScr,d,1.045 +CoalOldScr,p,0.981 +CoalOldUns,o,0.981 +CoalOldUns,r,1.0 +CoalOldUns,d,1.045 +CoalOldUns,p,0.981 +coal-new,o,0.981 +coal-new,r,1.0 +coal-new,d,1.045 +coal-new,p,0.981 +coal-IGCC,o,0.988 +coal-IGCC,r,1.0 +coal-IGCC,d,1.033 +coal-IGCC,p,0.988 +coal-CCS_mod,o,0.982 +coal-CCS_mod,r,1.0 +coal-CCS_mod,d,1.031 +coal-CCS_max,o,0.982 +coal-CCS_max,r,1.0 +coal-CCS_max,d,1.031 +coal-CCS-F1,o,0.982 +coal-CCS-F1,r,1.0 +coal-CCS-F1,d,1.031 +coal-CCS-F2,o,0.982 +coal-CCS-F2,r,1.0 +coal-CCS-F2,d,1.031 +coal-CCS-F3,o,0.982 +coal-CCS-F3,r,1.0 +coal-CCS-F3,d,1.031 +o-g-s,o,0.981 +o-g-s,r,1.0 +o-g-s,d,1.045 +o-g-s,p,0.981 +o-g-s,n,1.0 +nuclear,o,0.981 +nuclear,r,1.0 +nuclear,d,1.045 +nuclear,p,0.981 +nuclear-SMR,o,0.981 +nuclear-SMR,r,1.0 +nuclear-SMR,d,1.045 +nuclear-SMR,p,0.981 +geothermal,n,1.0 +biopower,o,0.981 +biopower,r,1.0 +biopower,d,1.045 +biopower,p,0.981 +beccs_mod,o,0.981 +beccs_mod,r,1.0 +beccs_mod,d,1.045 +beccs_mod,p,0.981 +beccs_max,o,0.981 +beccs_max,r,1.0 +beccs_max,d,1.045 +beccs_max,p,0.981 +CofireOld,o,0.981 +CofireOld,r,1.0 +CofireOld,d,1.045 +CofireOld,p,0.981 +CofireNew,o,0.981 +CofireNew,r,1.0 +CofireNew,d,1.045 +CofireNew,p,0.981 +lfill-gas,n,1.0 +distpv,n,1.0 +csp1_1,o,0.905 +csp1_1,r,0.952 +csp1_1,d,1.0 diff --git a/inputs/waterclimate/cost_vom_mult.csv b/inputs/waterclimate/cost_vom_mult.csv index cfb2c2c30..901caab6a 100644 --- a/inputs/waterclimate/cost_vom_mult.csv +++ b/inputs/waterclimate/cost_vom_mult.csv @@ -1,37 +1,113 @@ -,o,r,d,p,n -Hydro,0,0,0,0,1 -gas-CT,0,0,0,0,1 -gas-CT_aero,0,0,0,0,1 -gas-CC,0.9957,1,1.021,0.9957,0 -gas-CC_h_1x1,0.9957,1,1.021,0.9957,0 -gas-CC_h_2x1,0.9957,1,1.021,0.9957,0 -Gas-CC-CCS_mod,0.9774,1,1.107,0,0 -Gas-CC-CCS_max,0.9774,1,1.107,0,0 -Gas-CC_H_1x1-CCS_mod,0.9774,1,1.107,0,0 -Gas-CC_H_1x1-CCS_max,0.9774,1,1.107,0,0 -Gas-CC_H_2x1-CCS_mod,0.9774,1,1.107,0,0 -Gas-CC_H_2x1-CCS_max,0.9774,1,1.107,0,0 -Gas-CC-CCS-F1,0.9774,1,1.107,0,0 -Gas-CC-CCS-F2,0.9774,1,1.107,0,0 -Gas-CC-CCS-F3,0.9774,1,1.107,0,0 -CoalOldScr,0.9893,1,1.051,0.9893,0 -CoalOldUns,0.9893,1,1.051,0.9893,0 -coal-new,0.9893,1,1.051,0.9893,0 -coal-IGCC,0.9957,1,1.021,0.9957,0 -coal-CCS_mod,0.9929,1,1.034,0,0 -coal-CCS_max,0.9929,1,1.034,0,0 -coal-CCS-F1,0.9929,1,1.034,0,0 -coal-CCS-F2,0.9929,1,1.034,0,0 -coal-CCS-F3,0.9929,1,1.034,0,0 -o-g-s,0.9893,1,1.051,0.9893,1 -nuclear,0.9893,1,1.051,0.9893,0 -nuclear-SMR,0.9893,1,1.051,0.9893,0 -geothermal,0,0,0,0,1 -biopower,0.9893,1,1.051,0.9893,0 -beccs_mod,0.9893,1,1.051,0.9893,0 -beccs_max,0.9893,1,1.051,0.9893,0 -CofireOld,0.9893,1,1.051,0.9893,0 -CofireNew,0.9893,1,1.051,0.9893,0 -lfill-gas,0,0,0,0,1 -distpv,0,0,0,0,1 -csp1_1,0.9048,0.9524,1,0,0 +i,ctt,fraction +Hydro,n,1.0 +gas-CT,n,1.0 +gas-CT_aero,n,1.0 +gas-CC,o,0.996 +gas-CC,r,1.0 +gas-CC,d,1.021 +gas-CC,p,0.996 +gas-CC_h_1x1,o,0.996 +gas-CC_h_1x1,r,1.0 +gas-CC_h_1x1,d,1.021 +gas-CC_h_1x1,p,0.996 +gas-CC_h_2x1,o,0.996 +gas-CC_h_2x1,r,1.0 +gas-CC_h_2x1,d,1.021 +gas-CC_h_2x1,p,0.996 +Gas-CC-CCS_mod,o,0.977 +Gas-CC-CCS_mod,r,1.0 +Gas-CC-CCS_mod,d,1.107 +Gas-CC-CCS_max,o,0.977 +Gas-CC-CCS_max,r,1.0 +Gas-CC-CCS_max,d,1.107 +Gas-CC_H_1x1-CCS_mod,o,0.977 +Gas-CC_H_1x1-CCS_mod,r,1.0 +Gas-CC_H_1x1-CCS_mod,d,1.107 +Gas-CC_H_1x1-CCS_max,o,0.977 +Gas-CC_H_1x1-CCS_max,r,1.0 +Gas-CC_H_1x1-CCS_max,d,1.107 +Gas-CC_H_2x1-CCS_mod,o,0.977 +Gas-CC_H_2x1-CCS_mod,r,1.0 +Gas-CC_H_2x1-CCS_mod,d,1.107 +Gas-CC_H_2x1-CCS_max,o,0.977 +Gas-CC_H_2x1-CCS_max,r,1.0 +Gas-CC_H_2x1-CCS_max,d,1.107 +Gas-CC-CCS-F1,o,0.977 +Gas-CC-CCS-F1,r,1.0 +Gas-CC-CCS-F1,d,1.107 +Gas-CC-CCS-F2,o,0.977 +Gas-CC-CCS-F2,r,1.0 +Gas-CC-CCS-F2,d,1.107 +Gas-CC-CCS-F3,o,0.977 +Gas-CC-CCS-F3,r,1.0 +Gas-CC-CCS-F3,d,1.107 +CoalOldScr,o,0.989 +CoalOldScr,r,1.0 +CoalOldScr,d,1.051 +CoalOldScr,p,0.989 +CoalOldUns,o,0.989 +CoalOldUns,r,1.0 +CoalOldUns,d,1.051 +CoalOldUns,p,0.989 +coal-new,o,0.989 +coal-new,r,1.0 +coal-new,d,1.051 +coal-new,p,0.989 +coal-IGCC,o,0.996 +coal-IGCC,r,1.0 +coal-IGCC,d,1.021 +coal-IGCC,p,0.996 +coal-CCS_mod,o,0.993 +coal-CCS_mod,r,1.0 +coal-CCS_mod,d,1.034 +coal-CCS_max,o,0.993 +coal-CCS_max,r,1.0 +coal-CCS_max,d,1.034 +coal-CCS-F1,o,0.993 +coal-CCS-F1,r,1.0 +coal-CCS-F1,d,1.034 +coal-CCS-F2,o,0.993 +coal-CCS-F2,r,1.0 +coal-CCS-F2,d,1.034 +coal-CCS-F3,o,0.993 +coal-CCS-F3,r,1.0 +coal-CCS-F3,d,1.034 +o-g-s,o,0.989 +o-g-s,r,1.0 +o-g-s,d,1.051 +o-g-s,p,0.989 +o-g-s,n,1.0 +nuclear,o,0.989 +nuclear,r,1.0 +nuclear,d,1.051 +nuclear,p,0.989 +nuclear-SMR,o,0.989 +nuclear-SMR,r,1.0 +nuclear-SMR,d,1.051 +nuclear-SMR,p,0.989 +geothermal,n,1.0 +biopower,o,0.989 +biopower,r,1.0 +biopower,d,1.051 +biopower,p,0.989 +beccs_mod,o,0.989 +beccs_mod,r,1.0 +beccs_mod,d,1.051 +beccs_mod,p,0.989 +beccs_max,o,0.989 +beccs_max,r,1.0 +beccs_max,d,1.051 +beccs_max,p,0.989 +CofireOld,o,0.989 +CofireOld,r,1.0 +CofireOld,d,1.051 +CofireOld,p,0.989 +CofireNew,o,0.989 +CofireNew,r,1.0 +CofireNew,d,1.051 +CofireNew,p,0.989 +lfill-gas,n,1.0 +distpv,n,1.0 +csp1_1,o,0.905 +csp1_1,r,0.952 +csp1_1,d,1.0 diff --git a/inputs/waterclimate/heat_rate_mult.csv b/inputs/waterclimate/heat_rate_mult.csv index 2be23bf1f..488343e2f 100644 --- a/inputs/waterclimate/heat_rate_mult.csv +++ b/inputs/waterclimate/heat_rate_mult.csv @@ -1,36 +1,110 @@ -,o,r,d,p,n -Hydro,0,0,0,0,1 -gas-CT,0,0,0,0,1 -gas-CT_aero,0,0,0,0,1 -gas-CC,0.978,1,1.102,0.978,0 -gas-CC_h_1x1,0.978,1,1.102,0.978,0 -gas-CC_h_2x1,0.978,1,1.102,0.978,0 -Gas-CC-CCS_mod,0.981,1,1.075,0,0 -Gas-CC-CCS_max,0.981,1,1.075,0,0 -Gas-CC_H_1x1-CCS_mod,0.981,1,1.075,0,0 -Gas-CC_H_1x1-CCS_max,0.981,1,1.075,0,0 -Gas-CC_H_2x1-CCS_mod,0.981,1,1.075,0,0 -Gas-CC_H_2x1-CCS_max,0.981,1,1.075,0,0 -Gas-CC-CCS-F1,0.981,1,1.075,0,0 -Gas-CC-CCS-F2,0.981,1,1.075,0,0 -Gas-CC-CCS-F3,0.981,1,1.075,0,0 -CoalOldScr,0.981,1,1.045,0.981,0 -CoalOldUns,0.981,1,1.045,0.981,0 -coal-new,0.981,1,1.045,0.981,0 -coal-IGCC,0.988,1,1.033,0.988,0 -coal-CCS_mod,0.982,1,1.031,0,0 -coal-CCS_max,0.982,1,1.031,0,0 -coal-CCS-F1,0.982,1,1.031,0,0 -coal-CCS-F2,0.982,1,1.031,0,0 -coal-CCS-F3,0.982,1,1.031,0,0 -o-g-s,0.981,1,1.045,0.981,1 -nuclear,0.981,1,1.045,0.981,0 -nuclear-SMR,0.981,1,1.045,0.981,0 -geothermal,0,0,0,0,1 -biopower,0.981,1,1.045,0.981,0 -beccs_mod,0.981,1,1.045,0.981,0 -beccs_max,0.981,1,1.045,0.981,0 -CofireOld,0.981,1,1.045,0.981,0 -CofireNew,0.981,1,1.045,0.981,0 -lfill-gas,0,0,0,0,1 -distpv,0,0,0,0,1 +i,ctt,fraction +Hydro,n,1.0 +gas-CT,n,1.0 +gas-CT_aero,n,1.0 +gas-CC,o,0.978 +gas-CC,r,1.0 +gas-CC,d,1.102 +gas-CC,p,0.978 +gas-CC_h_1x1,o,0.978 +gas-CC_h_1x1,r,1.0 +gas-CC_h_1x1,d,1.102 +gas-CC_h_1x1,p,0.978 +gas-CC_h_2x1,o,0.978 +gas-CC_h_2x1,r,1.0 +gas-CC_h_2x1,d,1.102 +gas-CC_h_2x1,p,0.978 +Gas-CC-CCS_mod,o,0.981 +Gas-CC-CCS_mod,r,1.0 +Gas-CC-CCS_mod,d,1.075 +Gas-CC-CCS_max,o,0.981 +Gas-CC-CCS_max,r,1.0 +Gas-CC-CCS_max,d,1.075 +Gas-CC_H_1x1-CCS_mod,o,0.981 +Gas-CC_H_1x1-CCS_mod,r,1.0 +Gas-CC_H_1x1-CCS_mod,d,1.075 +Gas-CC_H_1x1-CCS_max,o,0.981 +Gas-CC_H_1x1-CCS_max,r,1.0 +Gas-CC_H_1x1-CCS_max,d,1.075 +Gas-CC_H_2x1-CCS_mod,o,0.981 +Gas-CC_H_2x1-CCS_mod,r,1.0 +Gas-CC_H_2x1-CCS_mod,d,1.075 +Gas-CC_H_2x1-CCS_max,o,0.981 +Gas-CC_H_2x1-CCS_max,r,1.0 +Gas-CC_H_2x1-CCS_max,d,1.075 +Gas-CC-CCS-F1,o,0.981 +Gas-CC-CCS-F1,r,1.0 +Gas-CC-CCS-F1,d,1.075 +Gas-CC-CCS-F2,o,0.981 +Gas-CC-CCS-F2,r,1.0 +Gas-CC-CCS-F2,d,1.075 +Gas-CC-CCS-F3,o,0.981 +Gas-CC-CCS-F3,r,1.0 +Gas-CC-CCS-F3,d,1.075 +CoalOldScr,o,0.981 +CoalOldScr,r,1.0 +CoalOldScr,d,1.045 +CoalOldScr,p,0.981 +CoalOldUns,o,0.981 +CoalOldUns,r,1.0 +CoalOldUns,d,1.045 +CoalOldUns,p,0.981 +coal-new,o,0.981 +coal-new,r,1.0 +coal-new,d,1.045 +coal-new,p,0.981 +coal-IGCC,o,0.988 +coal-IGCC,r,1.0 +coal-IGCC,d,1.033 +coal-IGCC,p,0.988 +coal-CCS_mod,o,0.982 +coal-CCS_mod,r,1.0 +coal-CCS_mod,d,1.031 +coal-CCS_max,o,0.982 +coal-CCS_max,r,1.0 +coal-CCS_max,d,1.031 +coal-CCS-F1,o,0.982 +coal-CCS-F1,r,1.0 +coal-CCS-F1,d,1.031 +coal-CCS-F2,o,0.982 +coal-CCS-F2,r,1.0 +coal-CCS-F2,d,1.031 +coal-CCS-F3,o,0.982 +coal-CCS-F3,r,1.0 +coal-CCS-F3,d,1.031 +o-g-s,o,0.981 +o-g-s,r,1.0 +o-g-s,d,1.045 +o-g-s,p,0.981 +o-g-s,n,1.0 +nuclear,o,0.981 +nuclear,r,1.0 +nuclear,d,1.045 +nuclear,p,0.981 +nuclear-SMR,o,0.981 +nuclear-SMR,r,1.0 +nuclear-SMR,d,1.045 +nuclear-SMR,p,0.981 +geothermal,n,1.0 +biopower,o,0.981 +biopower,r,1.0 +biopower,d,1.045 +biopower,p,0.981 +beccs_mod,o,0.981 +beccs_mod,r,1.0 +beccs_mod,d,1.045 +beccs_mod,p,0.981 +beccs_max,o,0.981 +beccs_max,r,1.0 +beccs_max,d,1.045 +beccs_max,p,0.981 +CofireOld,o,0.981 +CofireOld,r,1.0 +CofireOld,d,1.045 +CofireOld,p,0.981 +CofireNew,o,0.981 +CofireNew,r,1.0 +CofireNew,d,1.045 +CofireNew,p,0.981 +lfill-gas,n,1.0 +distpv,n,1.0 diff --git a/reeds/core/setup/b_inputs.gms b/reeds/core/setup/b_inputs.gms index f16c0d020..bb095a6af 100644 --- a/reeds/core/setup/b_inputs.gms +++ b/reeds/core/setup/b_inputs.gms @@ -213,30 +213,6 @@ set i_numeraire(i) "numeraire techs that need cooling" ; *or will have numeraire techs otherwise. i_numeraire(ii)$sum{(wst,ctt,i)$i_ii_ctt_wst(i,ii,ctt,wst), 1 } = yes ; -table ctt_hr_mult(i,ctt) "heatrate multipliers to differentiate cooling technology types" -$offlisting -$ondelim -$include inputs_case%ds%heat_rate_mult.csv -$offdelim -$onlisting -; - -table ctt_cc_mult(i,ctt) "capital cost multipliers to differentiate cooling technology types" -$offlisting -$ondelim -$include inputs_case%ds%cost_cap_mult.csv -$offdelim -$onlisting -; - -table ctt_cost_vom_mult(i,ctt) "VOM cost multipliers to differentiate cooling technology types" -$offlisting -$ondelim -$include inputs_case%ds%cost_vom_mult.csv -$offdelim -$onlisting -; - set *technology-specific subsets battery(i) "battery storage technologies", diff --git a/reeds/input_processing/runfiles.csv b/reeds/input_processing/runfiles.csv index c63e7cd62..5c7683bee 100644 --- a/reeds/input_processing/runfiles.csv +++ b/reeds/input_processing/runfiles.csv @@ -41,12 +41,12 @@ construction_schedules.csv,inputs/financials/construction_schedules_{constructio construction_times.csv,inputs/financials/construction_times_{construction_times_suffix}.csv,1,ignore,ignore,,,,,0,,,,,, consume_char.csv,inputs/consume/consume_char_{GSw_H2_Inputs}.csv,int(sw.GSw_H2) != 0,ignore,ignore,,"*i,t,parameter",,0,0,,,,,, consumecat.csv,inputs/sets/consumecat.csv,1,ignore,ignore,,,,,,,,set,consumecat,categories for consuming facility characteristics, -cost_cap_mult.csv,inputs/waterclimate/cost_cap_mult.csv,int(sw.GSw_WaterMain) != 0,ignore,ignore,,,,,0,,,,,, +cost_cap_mult.csv,inputs/waterclimate/cost_cap_mult.csv,int(sw.GSw_WaterMain) != 0,ignore,ignore,,,,,0,,,parameter,ctt_cc_mult,capital cost multipliers to differentiate cooling technology types, cost_hurdle_country.csv,inputs/transmission/cost_hurdle_country.csv,1,ignore,ignore,*country,,,,0,,,,,, cost_hurdle_intra.csv,inputs/transmission/cost_hurdle_intra.csv,1,ignore,ignore,,t,,,0,,,,,, cost_opres_default.csv,inputs/plant_characteristics/cost_opres_default.csv,int(sw.GSw_OpRes) != 0,ignore,ignore,,,,,0,,,,,, cost_opres_market.csv,inputs/plant_characteristics/cost_opres_market.csv,int(sw.GSw_OpRes) != 0,ignore,ignore,,,,,0,,,,,, -cost_vom_mult.csv,inputs/waterclimate/cost_vom_mult.csv,int(sw.GSw_WaterMain) != 0,ignore,ignore,,,,,0,,,,,, +cost_vom_mult.csv,inputs/waterclimate/cost_vom_mult.csv,int(sw.GSw_WaterMain) != 0,ignore,ignore,,,,,0,,,parameter,ctt_cost_vom_mult,VOM cost multipliers to differentiate cooling technology types, csapr_cat.csv,inputs/sets/csapr_cat.csv,1,ignore,ignore,,,,,,,,set,csapr_cat,CSAPR regulation categories, csapr_group.csv,inputs/sets/csapr_group.csv,1,ignore,ignore,,,,,,,,set,csapr_group,CSAPR trading group, csapr_group1_ex.csv,inputs/emission_constraints/csapr_group1_ex.csv,int(sw.GSw_CSAPR) != 0,ignore,ignore,*st,,,,0,,,,,, @@ -108,7 +108,7 @@ h2_st.csv,inputs/sets/h2_st.csv,1,ignore,ignore,,,,,,,,set,h2_st,investments nee h2_stor.csv,inputs/sets/h2_stor.csv,1,ignore,ignore,,,,,0,,,set,h2_stor,H2 storage options, h2_transport_and_storage_costs.csv,inputs/consume/h2_transport_and_storage_costs.csv,int(sw.GSw_H2) != 0,ignore,ignore,,,,,,,,,,, heat_rate_adj.csv,inputs/plant_characteristics/heat_rate_adj.csv,1,ignore,ignore,,,,,0,,,,,, -heat_rate_mult.csv,inputs/waterclimate/heat_rate_mult.csv,int(sw.GSw_WaterMain) != 0,ignore,ignore,,,,,0,,,,,, +heat_rate_mult.csv,inputs/waterclimate/heat_rate_mult.csv,int(sw.GSw_WaterMain) != 0,ignore,ignore,,,,,0,,,parameter,ctt_hr_mult,heatrate multipliers to differentiate cooling technology types, heat_rate_penalty_spin.csv,inputs/plant_characteristics/heat_rate_penalty_spin.csv,1,ignore,ignore,,,,,0,,,,,, hintage_char.csv,inputs/sets/hintage_char.csv,1,ignore,ignore,,,,,,,,set,hintage_char,characteristics available in hintage_data, hyd_add_upg_cap.csv,inputs/supply_curve/hyd_add_upg_cap.csv,int(sw.GSw_HydroCapEnerUpgradeType) == 2,sum,hydroexist,r,"i,rscbin,wide",,1,0,,,,,, From 7c8c3bf8ef13af886d75995670ed48eb49d3eb7a Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Thu, 2 Jul 2026 16:03:21 -0600 Subject: [PATCH 06/28] move transmission.py outputs to inputs.h5; disaggregate co2_site_char table into individual parameters --- inputs/ctus/dollaryear.csv | 2 + inputs/userinput/futurefiles.csv | 2 - reeds/core/setup/b_inputs.gms | 241 +------------------------ reeds/core/setup/d_objective.gms | 2 +- reeds/core/setup/e_solveprep.gms | 2 +- reeds/core/terminus/report.gms | 2 +- reeds/input_processing/copy_files.py | 6 - reeds/input_processing/runfiles.csv | 1 - reeds/input_processing/transmission.py | 103 ++++++++--- reeds/io.py | 9 + 10 files changed, 92 insertions(+), 278 deletions(-) create mode 100644 inputs/ctus/dollaryear.csv diff --git a/inputs/ctus/dollaryear.csv b/inputs/ctus/dollaryear.csv new file mode 100644 index 000000000..b791af075 --- /dev/null +++ b/inputs/ctus/dollaryear.csv @@ -0,0 +1,2 @@ +filename,US_dollar_year +co2_site_char.csv,2018 diff --git a/inputs/userinput/futurefiles.csv b/inputs/userinput/futurefiles.csv index 4baf63009..3c8abcc30 100644 --- a/inputs/userinput/futurefiles.csv +++ b/inputs/userinput/futurefiles.csv @@ -363,7 +363,6 @@ pvf_onm_int.csv,.csv,1,None,*t,None,0,0,linear_10,0,None,done (but double-check quarter.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, r_cendiv.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, r_county.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, -r_cs_distance_mi.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, r_cs.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, r_rr_adj.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, ramprate.csv,.csv,1,None,9999,None,9999,0,constant,None,None,done,constant @@ -475,7 +474,6 @@ upgrade_mult_mid.csv,.csv,0,None,wide,dummy,1,0,linear_5,0,None,new, upgradelink_water.csv,.csv,1,None,9999,None,9999,0,constant,None,None,done,constant uranium_price.csv,.csv,0,None,year,None,0,0,linear_5,0,None,new, va_ng_crf_penalty.csv,.csv,0,None,0,None,0,None,constant,None,None,done,constant -val_cs.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, val_r_all.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, var_map.csv,.csv,1,None,9999,None,9999,0,constant,None,None,done,constant w.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, diff --git a/reeds/core/setup/b_inputs.gms b/reeds/core/setup/b_inputs.gms index bb095a6af..781e08c5e 100644 --- a/reeds/core/setup/b_inputs.gms +++ b/reeds/core/setup/b_inputs.gms @@ -72,16 +72,6 @@ $include inputs_case%ds%scalars.txt * --- Set Declarations --- *========================== -* written by copy_files.py -$onempty -set cs(*) "carbon storage sites" -/ -$offlisting -$include inputs_case%ds%val_cs.csv -$onlisting -/ ; -$offempty - * Written by h5_to_gdx.py $include autocode%ds%b_declare_sets.gms $include autocode%ds%b_declare_parameters.gms @@ -2815,43 +2805,6 @@ trtypemax(trtype)$[(Sw_TransCapMaxTypes=1)] = yes ; trtypemax(trtype)$[(Sw_TransCapMaxTypes=2)$sameas(trtype,'VSC')] = yes ; trtypemax(trtype)$[(Sw_TransCapMaxTypes=3)$(not sameas(trtype,'AC'))] = yes ; -* --- initial transmission capacity --- -* transmission capacity input data are defined in both directions for each region-to-region pair -* Written by transmission.py -$onempty -parameter trancap_init_energy(r,rr,trtype) "--MW-- initial transmission capacity for energy trading" -/ -$offlisting -$ondelim -$include inputs_case%ds%trancap_init_energy.csv -$offdelim -$onlisting -/ ; - -parameter trancap_init_prm(r,rr,trtype) "--MW-- initial transmission capacity for capacity (PRM) trading" -/ -$offlisting -$ondelim -$include inputs_case%ds%trancap_init_prm.csv -$offdelim -$onlisting -/ ; -$offempty - -* --- future transmission capacity --- -* Transmission additions are defined in one direction for each region-to-region pair with the lowest region number listed first -* Written by transmission.py -$onempty -parameter trancap_fut(r,rr,trancap_fut_cat,trtype,allt) "--MW-- potential future transmission capacity by type (one direction)" -/ -$offlisting -$ondelim -$include inputs_case%ds%trancap_fut.csv -$offdelim -$onlisting -/ ; -$offempty - * --- exogenously specified transmission capacity --- * Transmission additions are defined in one direction for each region-to-region pair with the lowest region number listed first parameter invtran_exog(r,rr,trtype,t) "--MW-- exogenous transmission capacity investment (one direction)" ; @@ -2956,18 +2909,6 @@ $endif.oprestradelevel Scalar opres_mult "multiplier on opres flow in transmission constraint" ; opres_mult = Sw_OpResTradeMult; -* Interfaces are collections of routes with an additional constraint on total flows -$onempty -parameter trancap_init_transgroup(transgrp,transgrpp,trtype) "--MW-- initial upper limit on interface AC flows" -/ -$offlisting -$ondelim -$include inputs_case%ds%trancap_init_transgroup.csv -$offdelim -$onlisting -/ ; -$offempty - $onempty parameter trancap_init_itlgrp(itlgrp,itlgrpp,trtype) "--MW-- initial upper limit on interface flows between itlgrps" / @@ -3007,64 +2948,6 @@ routes_itlgrp(itlgrp,itlgrpp,r,rr)$[ $(not sameas(r,rr)) $[not((sameas(itlgrp,r)) AND (sameas(itlgrpp,rr)))] ] = yes ; -* --- transmission cost --- - -* Transmission line capex cost (generated from reV tables) -* Written by transmission.py -$onempty -parameter tsc_binwidth(r,rr,tscbin) "--$-- investment bin widths for transmission interfaces" -/ -$offlisting -$ondelim -$include inputs_case%ds%tsc_binwidth.csv -$offdelim -$onlisting -/ ; - -parameter tsc_forward(r,rr,tscbin) "--$/MW-- transmission upgrade cost for forward direction" -/ -$offlisting -$ondelim -$include inputs_case%ds%tsc_forward.csv -$offdelim -$onlisting -/ ; - -parameter tsc_reverse(r,rr,tscbin) "--$/MW-- transmission upgrade cost for reverse direction" -/ -$offlisting -$ondelim -$include inputs_case%ds%tsc_reverse.csv -$offdelim -$onlisting -/ ; - -parameter transmission_cost_nonac(r,rr,trtype) "--$/MW-- expansion cost for DC interfaces (only lines; converters handled separately)" -/ -$offlisting -$ondelim -$include inputs_case%ds%transmission_cost_nonac.csv -$offdelim -$onlisting -/ ; - -* Scale transmission line costs by Sw_TransCostMult (for sensitivity analysis) -tsc_binwidth(r,rr,tscbin) = tsc_binwidth(r,rr,tscbin) * Sw_TransCostMult ; -tsc_forward(r,rr,tscbin) = tsc_forward(r,rr,tscbin) * Sw_TransCostMult ; -tsc_reverse(r,rr,tscbin) = tsc_reverse(r,rr,tscbin) * Sw_TransCostMult ; -transmission_cost_nonac(r,rr,trtype) = transmission_cost_nonac(r,rr,trtype) * Sw_TransCostMult ; - -* Transmission line FOM cost -* Written by transmission.py -parameter transmission_line_fom(r,rr,trtype) "--$/MW/year-- fixed O&M cost of transmission lines" -/ -$offlisting -$ondelim -$include inputs_case%ds%transmission_line_fom.csv -$offdelim -$onlisting -/ ; -$offempty parameter cost_hurdle(r,rr,allt) "--$ per MWh-- cost for transmission hurdle rate" ; parameter cost_hurdle_regiongrp1(r,rr,allt) "--$ per MWh-- cost for transmission hurdle rate between regiongrp1" ; @@ -3082,28 +2965,6 @@ $onlisting $offempty * Assign hurdle rates to chosen GSw_TransHurdLevel -$onempty -parameter cost_hurdle_rate1(allt) "--$ per MWh-- raw data cost for transmission hurdle rate for regiongrp1" -/ -$offlisting -$ondelim -$include inputs_case%ds%cost_hurdle_rate1.csv -$offdelim -$onlisting -/ ; -$offempty - -$onempty -parameter cost_hurdle_rate2(allt) "--$ per MWh-- raw data cost for transmission hurdle rate for regiongrp2" -/ -$offlisting -$ondelim -$include inputs_case%ds%cost_hurdle_rate2.csv -$offdelim -$onlisting -/ ; -$offempty - * define hurdle rates across international lines * first determine whether the regions are of different countries.. cost_hurdle_regiongrp1(r,rr,t)$[sum{country$r_country(r,country),ord(country) } @@ -3154,36 +3015,6 @@ $endif.hurdlelevel_regiongrp2 * The final hurdle cost is the higher cost among regiongrp1 and regiongrp2, and hurdle_rate_floor cost_hurdle(r,rr,t)$[sum{trtype, routes(r,rr,trtype,t) }] = max{cost_hurdle_regiongrp1(r,rr,t),cost_hurdle_regiongrp2(r,rr,t), hurdle_rate_floor} ; -* --- transmission distance --- - -* The distance for a transmission interface is calculated in reV using the same "least-cost-path" -* algorithm and cost tables as for wind and solar spur lines. -* Distances are more representative of new greenfield lines than existing lines. -* Written by transmission.py -$onempty -parameter distance(r,rr,trtype) "--miles-- distance between BAs by line type" -/ -$offlisting -$ondelim -$include inputs_case%ds%transmission_miles.csv -$offdelim -$onlisting -/ ; - - -* --- transmission losses --- -* Written by transmission.py -parameter tranloss(r,rr,trtype) "--fraction-- transmission loss between r and rr" -/ -$offlisting -$ondelim -$include inputs_case%ds%tranloss.csv -$offdelim -$onlisting -/ ; -$offempty - - * --- VSC HVDC macrogrid --- set val_converter(r,t) "BAs where VSC converter investment is allowed" ; val_converter(r,t) = no ; @@ -3302,16 +3133,6 @@ ccseason_cap_frac_delta(i,v,r,ccseason,t)$[conv(i)$sameas(ccseason,'hot')] = * -- Consume technologies specification -- *============================================ -$onempty -set routes_adjacent(r,rr) "all pairs of adjacent land-based BAs" -/ -$offlisting -$ondelim -$include inputs_case%ds%routes_adjacent.csv -$offdelim -$onlisting -/ ; -$offempty * Remove offshore zones routes_adjacent(r,rr)$(offshore(r) or offshore(rr)) = no ; @@ -3525,17 +3346,6 @@ $offdelim $onlisting / ; -$onempty -parameter pipeline_cost_mult(r,rr) "--fraction-- cost multiplier for H2 pipelines (will be added to 1)" -/ -$offlisting -$ondelim -$include inputs_case%ds%pipeline_cost_mult.csv -$offdelim -$onlisting -/ ; -$offempty - * here computing capital and FOM costs as $/metric ton-hour for all possible routes * including capital cost multipliers, which are different for pipelines and compressors * note that pipeline distance is between BA centroids @@ -4327,15 +4137,6 @@ $onlisting / ; $onempty -parameter firm_import_limit(nercr,allt) "--fraction-- limit on net firm imports into NERC regions" -/ -$offlisting -$ondelim -$include inputs_case%ds%firm_import_limit.csv -$offdelim -$onlisting -/ ; - parameter peakload_nercr(nercr,allt) "--MW-- Peak exogenous demand across all weather years by NERC region" / $offlisting @@ -5772,37 +5573,14 @@ m_rsc_dat_init(r,i,rscbin)$m_rsc_dat(r,i,rscbin,"cap") = m_rsc_dat(r,i,rscbin,"c *======================================== * -- CO2 Capture and Storage Network -- *======================================== -$onempty set csfeas(cs) "carbon storage sites with available capacity" - r_cs(r,cs) "mapping from BA to carbon storage sites" -/ -$offlisting -$ondelim -$include inputs_case%ds%r_cs.csv -$offdelim -$onlisting -/ , co2_routes(r,rr) "set of available inter-ba co2 trade relationships" ; -parameter co2_storage_limit(cs) "--metric tons-- total cumulative storage capacity per carbon storage site", - co2_injection_limit(cs) "--metric tons/hr-- co2 site injection rate upper bound", - cost_co2_pipeline_cap(r,rr,t) "--$2004/(metric ton-mi/hr)-- capital costs associated with investing in co2 pipeline infrastructure", +parameter cost_co2_pipeline_cap(r,rr,t) "--$2004/(metric ton-mi/hr)-- capital costs associated with investing in co2 pipeline infrastructure", cost_co2_pipeline_fom(r,rr,t) "--$2004/((metric ton-mi/hr)-yr)-- FO&M costs associated with maintaining co2 pipeline infrastructure", - cost_co2_stor_bec(cs,t) "--$2004/metric ton-- breakeven cost for storing carbon - CF determined by GSw_CO2_BEC", cost_co2_spurline_cap(r,cs,t) "--$2004/(metric ton-mi/hr)-- capital costs associated with investing in spur lines to injection sites", - cost_co2_spurline_fom(r,cs,t) "--2004/((metric ton-mi/hr)-yr)-- FO&M costs associated with maintaining co2 spurline infrastructure", - r_cs_distance(r,cs) "--mi-- euclidean distance between BA transmission endpoints and storage formations" -/ -$offlisting -$offdigit -$ondelim -$include inputs_case%ds%r_cs_distance_mi.csv -$offdelim -$ondigit -$onlisting -/ + cost_co2_spurline_fom(r,cs,t) "--2004/((metric ton-mi/hr)-yr)-- FO&M costs associated with maintaining co2 spurline infrastructure" ; -$offempty * Assign spurline costs cost_co2_spurline_cap(r,cs,t)$[r_cs(r,cs)$tmodel_new(t)] = Sw_CO2_spurline_cost * r_cs_distance(r,cs) ; @@ -5813,19 +5591,6 @@ cost_co2_pipeline_fom(r,rr,t)$[routes_adjacent(r,rr)$tmodel_new(t)] = Sw_CO2_pip co2_routes(r,rr)$[routes_adjacent(r,rr)$pipeline_distance(r,rr)] = yes ; -$onempty -table co2_char(cs,*) "co2 site characteristics including injection rate limit, total storage limit, and break even cost" -$ondelim -$include inputs_case%ds%co2_site_char.csv -$offdelim -; -$offempty - -*note that original units Mton == 'million tons' -co2_storage_limit(cs) = 1e6 * co2_char(cs,"max_stor_cap") ; -co2_injection_limit(cs) = co2_char(cs,"max_inj_rate") ; -cost_co2_stor_bec(cs,t) = co2_char(cs,"bec_%GSw_CO2_BEC%"); - * only want to consider storage sites that have both available capacity and injection limits csfeas(cs)$[co2_storage_limit(cs)$co2_injection_limit(cs)] = yes ; * only want to consider r_cs pairs which have available capacity @@ -5835,7 +5600,7 @@ cost_co2_spurline_fom(r,cs,t)$[r_cs(r,cs)$tmodel_new(t)] = Sw_CO2_spurline_fom * cost_co2_pipeline_cap(r,rr,t) = %GSw_CO2_CostAdj% * cost_co2_pipeline_cap(r,rr,t); cost_co2_pipeline_fom(r,rr,t) = %GSw_CO2_CostAdj% * cost_co2_pipeline_fom(r,rr,t); -cost_co2_stor_bec(cs,t) = %GSw_CO2_CostAdj% * cost_co2_stor_bec(cs,t) ; +cost_co2_stor_bec(cs) = %GSw_CO2_CostAdj% * cost_co2_stor_bec(cs) ; cost_co2_spurline_fom(r,cs,t) = %GSw_CO2_CostAdj% * cost_co2_spurline_fom(r,cs,t) ; cost_co2_spurline_cap(r,cs,t) = %GSw_CO2_CostAdj% * cost_co2_spurline_cap(r,cs,t) ; diff --git a/reeds/core/setup/d_objective.gms b/reeds/core/setup/d_objective.gms index fae5e5cae..f9f1dcec4 100644 --- a/reeds/core/setup/d_objective.gms +++ b/reeds/core/setup/d_objective.gms @@ -340,7 +340,7 @@ eq_Objfn_op(t)$tmodel(t).. CO2_SPURLINE_INV(r,cs,tt) } }$[Sw_CO2_Detail$(yeart(t)>=co2_detail_startyr)] * --- CO2 injection break even costs - + sum{(r,cs,h)$r_cs(r,cs), hours(h) * CO2_STORED(r,cs,h,t) * cost_co2_stor_bec(cs,t) }$[Sw_CO2_Detail$(yeart(t)>=co2_detail_startyr)] + + sum{(r,cs,h)$r_cs(r,cs), hours(h) * CO2_STORED(r,cs,h,t) * cost_co2_stor_bec(cs) }$[Sw_CO2_Detail$(yeart(t)>=co2_detail_startyr)] * --- Tax credit for CO2 stored --- * note conversion to 12-year CRF given length of CO2 captured incentive payments diff --git a/reeds/core/setup/e_solveprep.gms b/reeds/core/setup/e_solveprep.gms index 326d0d629..c59c463e2 100644 --- a/reeds/core/setup/e_solveprep.gms +++ b/reeds/core/setup/e_solveprep.gms @@ -64,7 +64,7 @@ cost_co2_pipeline_fom(r,rr,t) =round(cost_co2_pipeline_fom(r,rr,t),2) ; cost_co2_pipeline_cap(r,rr,t) =round(cost_co2_pipeline_cap(r,rr,t),2) ; cost_co2_spurline_fom(r,cs,t) = round(cost_co2_spurline_fom(r,cs,t),2) ; cost_co2_spurline_cap(r,cs,t) = round(cost_co2_spurline_cap(r,cs,t),2) ; -cost_co2_stor_bec(cs,t) = round(cost_co2_stor_bec(cs,t),2) ; +cost_co2_stor_bec(cs) = round(cost_co2_stor_bec(cs),2) ; cost_fom(i,v,r,t)$cost_fom(i,v,r,t) = round(cost_fom(i,v,r,t),2) ; cost_fom_energy(i,v,r,t)$cost_fom_energy(i,v,r,t) = round(cost_fom_energy(i,v,r,t),2) ; cost_h2_storage_cap(h2_stor,t) = round(cost_h2_storage_cap(h2_stor,t), 2) ; diff --git a/reeds/core/terminus/report.gms b/reeds/core/terminus/report.gms index 33ff1c967..bb2489465 100644 --- a/reeds/core/terminus/report.gms +++ b/reeds/core/terminus/report.gms @@ -1558,7 +1558,7 @@ systemcost_ba("inv_h2_storage",r,t)$[tmodel_new(t)$(Sw_H2 = 2)] = *=============== systemcost_ba("op_co2_storage",r,t)$[tmodel_new(t)$Sw_CO2_Detail] = - + sum{(h,cs)$r_cs(r,cs), hours(h) * CO2_STORED.l(r,cs,h,t) * cost_co2_stor_bec(cs,t) } + + sum{(h,cs)$r_cs(r,cs), hours(h) * CO2_STORED.l(r,cs,h,t) * cost_co2_stor_bec(cs) } ; * here following same logic of transmission pipelines diff --git a/reeds/input_processing/copy_files.py b/reeds/input_processing/copy_files.py index f12da4f67..4a65c16a1 100644 --- a/reeds/input_processing/copy_files.py +++ b/reeds/input_processing/copy_files.py @@ -708,12 +708,6 @@ def write_non_region_file( e_df.columns = ['r', 'percentage_energy_communities'] e_df.to_csv(os.path.join(dir_dst, row.filename),index=False) - - elif row.filename == 'co2_site_char.csv': - # Adjust for inflation - df = pd.read_csv(row.full_filepath) - df[f"bec_{sw['GSw_CO2_BEC']}"] *= source_deflator_map[row.filepath] - df.to_csv(os.path.join(dir_dst, 'co2_site_char.csv'), index=False) else: if str(row.GAMStype).lower() in ['set', 'parameter']: diff --git a/reeds/input_processing/runfiles.csv b/reeds/input_processing/runfiles.csv index 5c7683bee..4307b2e1c 100644 --- a/reeds/input_processing/runfiles.csv +++ b/reeds/input_processing/runfiles.csv @@ -35,7 +35,6 @@ cd_beta0.csv,inputs/fuelprices/cd_beta0.csv,1,ignore,ignore,*cendiv,,,,0,,,,,, cd_beta0_allsector.csv,inputs/fuelprices/cd_beta0_allsector.csv,1,ignore,ignore,*cendiv,,,,0,,,,,, ces_fraction.csv,inputs/state_policies/ces_fraction.csv,int(sw.GSw_StateRPS) != 0,ignore,ignore,st,st,,1,0,,,,,, climate_param.csv,inputs/sets/climate_param.csv,1,ignore,ignore,,,,,,,,set,climate_param,parameters defined in climate_heuristics_finalyear, -co2_site_char.csv,inputs/ctus/co2_site_char.csv,1,ignore,ignore,,,,0,,,,,,, coal_price.csv,inputs/fuelprices/coal_{coalscen}.csv,1,ignore,ignore,wide_cendiv,year,,1,0,,,,,, construction_schedules.csv,inputs/financials/construction_schedules_{construction_schedules_suffix}.csv,1,ignore,ignore,,,,1,0,,,,,, construction_times.csv,inputs/financials/construction_times_{construction_times_suffix}.csv,1,ignore,ignore,,,,,0,,,,,, diff --git a/reeds/input_processing/transmission.py b/reeds/input_processing/transmission.py index 7de08db37..634aaf380 100644 --- a/reeds/input_processing/transmission.py +++ b/reeds/input_processing/transmission.py @@ -228,15 +228,15 @@ def get_trancap_fut(case): planned_capacity = pd.concat([planned_capacity, offshore_links]) trancap_fut = ( planned_capacity.reset_index() - .rename(columns={'year_online':'t', 'certain':'status'}) + .rename(columns={'year_online':'t', 'certain':'trancap_fut_cat'}) .astype({'t':int}) ## '0' is used as a filler value in the t column for firstyear_trans, ## so we replace it whenever we load a transmission_capacity_future file. .replace({ 't': {0: int(scalars['firstyear_trans_longterm'])}, - 'status': {0:'possible', 1:'certain'} + 'trancap_fut_cat': {0:'possible', 1:'certain'} }) - [['r', 'rr', 'status', 'trtype', 't', 'MW']] + [['r', 'rr', 'trancap_fut_cat', 'trtype', 't', 'MW']] .astype({'t':int}).round(3) ) @@ -292,9 +292,10 @@ def get_firm_import_limit(case): .reindex(allyears).interpolate('linear').bfill().ffill() .loc[solveyears] .unstack('t').rename('fraction') + .reset_index().rename(columns={'t':'allt'}) ) - return firm_import_limit.reset_index() + return firm_import_limit def get_trancap_init(case, interface_params, level='r'): @@ -618,6 +619,31 @@ def calculate_co2_storage_routes(dfzones, max_miles=200): return routes_cs +def get_co2_site_char(case): + """CO2 storage site characteristics""" + sw = reeds.io.get_switches(case) + fdir = Path(reeds.io.reeds_path, 'inputs', 'ctus') + co2_site_char = pd.read_csv(Path(fdir, 'co2_site_char.csv'), index_col='cs') + ## Convert from Mton = million tons to tons + co2_site_char['max_stor_cap'] *= 1e6 + ## Deflate break even cost (BEC) + dollaryear = pd.read_csv(Path(fdir, 'dollaryear.csv'), index_col='filename').squeeze(1) + inflatable = reeds.io.get_inflatable() + deflator = inflatable[dollaryear['co2_site_char.csv'], int(sw.dollar_year)] + co2_site_char['cost_co2_stor_bec'] = co2_site_char[f'bec_{sw.GSw_CO2_BEC}'] * deflator + ## Rename for GAMS and downselect to sites in modeled regions + rename = { + 'max_inj_rate': 'co2_injection_limit', + 'max_stor_cap': 'co2_storage_limit', + } + co2_site_char = ( + co2_site_char + .rename(columns=rename) + [['co2_injection_limit', 'co2_storage_limit', 'cost_co2_stor_bec']] + ) + return co2_site_char + + def check_nonac_costs(trancap_fut, trancap_init_energy, transmission_cost_nonac): """Make sure every non-AC transmission route has a cost""" routecols = ['r', 'rr', 'trtype'] @@ -644,20 +670,25 @@ def check_nonac_costs(trancap_fut, trancap_init_energy, transmission_cost_nonac) #%% Main function def main(case): #%% Calculate parameters + sw = reeds.io.get_switches(case) outputs = {} outputs['firm_import_limit'] = get_firm_import_limit(case) interface_params = get_interface_params(case) - outputs['transmission_miles'] = interface_params[['r','rr','trtype','miles']].round(3) + outputs['distance'] = interface_params[['r','rr','trtype','miles']].round(3) outputs['tranloss'] = interface_params[['r','rr','trtype','loss']].round(5) outputs['transmission_line_fom'] = get_transmission_fom(case, interface_params).reset_index() outputs['trancap_fut'] = get_trancap_fut(case) - outputs['transmission_cost_nonac'] = get_transmission_cost_nonac(case, interface_params) + outputs['transmission_cost_nonac'] = ( + get_transmission_cost_nonac(case, interface_params) + .set_index(['r','rr','trtype']).squeeze(1) + * float(sw.GSw_TransCostMult) + ).reset_index() ## A few downstream processes expect a single distance for each zone pair; ## keep the longest outputs['transmission_distance'] = ( - outputs['transmission_miles'].drop(columns='trtype') + outputs['distance'].drop(columns='trtype') .sort_values('miles', ascending=False).drop_duplicates(['r','rr'], keep='first') .sort_values(['r','rr']) ) @@ -702,9 +733,9 @@ def main(case): } for col, label in labels.items(): outputs[f'tsc_{label}'] = ( - transmission_cost_ac[['r','rr','tscbin',col]] - .round(2) - ) + transmission_cost_ac.set_index(['r','rr','tscbin'])[col] + * float(sw.GSw_TransCostMult) + ).round(2).reset_index() outputs['tscbin'] = transmission_cost_ac.tscbin.drop_duplicates().rename() ## Write transmission_cost_ac for R2X outputs['transmission_cost_ac'] = transmission_cost_ac @@ -720,18 +751,17 @@ def main(case): ### CO2 storage sites routes_cs = calculate_co2_storage_routes(case) outputs['r_cs'] = routes_cs[['r', 'cs']] - outputs['r_cs_distance_mi'] = routes_cs[['r', 'cs', 'miles']] + outputs['r_cs_distance'] = routes_cs[['r', 'cs', 'miles']] # Determine sites that have valid routes to model regions val_cs = pd.Series(routes_cs['cs'].unique()) - outputs['val_cs'] = val_cs + outputs['cs'] = val_cs - # Subset CO2 site characteristics data to valid sites - co2_site_char = pd.read_csv(Path(reeds.io.reeds_path, 'inputs', 'ctus', 'co2_site_char.csv')) - outputs['co2_site_char'] = co2_site_char.loc[co2_site_char['cs'].isin(val_cs)] + co2_site_char = get_co2_site_char(case).loc[val_cs] + for col in co2_site_char: + outputs[col] = co2_site_char[col].reset_index() #%% Downselect to active regions - table = {'co2_site_char': True} hierarchy = reeds.io.get_hierarchy(case).reset_index() for key, df in outputs.items(): columns = df.columns if isinstance(df, pd.DataFrame) else [] @@ -741,12 +771,6 @@ def main(case): df = df.loc[df[level].isin(hierarchy[level])] if levell in columns: df = df.loc[df[levell].isin(hierarchy[level])] - ### Add '*' to the beginning so GAMS reads the header as a comment - if not table.get(key, False): - if isinstance(df, pd.DataFrame): - df = df.rename(columns={df.columns[0]: '*'+str(df.columns[0])}) - else: - df = df.rename('*'+df.name) if df.name else df outputs[key] = df #%% Write the outputs @@ -754,13 +778,36 @@ def main(case): 'val_cs': False, 'tscbin': False, } - inputs_h5 = { - 'tscbin': ('set', 'transmission upgrade supply curve bins'), + sets = ['tscbin', 'routes_adjacent', 'r_cs', 'cs'] + comment = { + 'co2_injection_limit': '--metric tons/hr-- co2 site injection rate upper bound', + 'co2_storage_limit': '--metric tons-- total cumulative storage capacity per carbon storage site', + 'cost_co2_stor_bec': '--$/metric ton-- breakeven cost for storing carbon - CF determined by GSw_CO2_BEC', + 'cost_hurdle_rate1': '--$ per MWh-- raw data cost for transmission hurdle rate for regiongrp1', + 'cost_hurdle_rate2': '--$ per MWh-- raw data cost for transmission hurdle rate for regiongrp2', + 'cs': 'CO2 storage sites', + 'distance': '--miles-- distance between BAs by line type', + 'firm_import_limit': '--fraction-- limit on net firm imports into NERC regions', + 'pipeline_cost_mult': '--fraction-- cost multiplier for H2 pipelines (will be added to 1)', + 'r_cs_distance': '--mi-- euclidean distance between BA transmission endpoints and storage formations', + 'r_cs': 'mapping from BA to carbon storage sites', + 'routes_adjacent': 'all pairs of adjacent land-based BAs', + 'trancap_fut': '--MW-- potential future transmission capacity by type (one direction)', + 'trancap_init_energy': '--MW-- initial transmission capacity for energy trading (both directions)', + 'trancap_init_prm': '--MW-- initial transmission capacity for capacity (PRM) trading (both directions)', + 'trancap_init_transgroup': '--MW-- initial upper limit on interface AC flows', + 'tranloss': '--fraction-- transmission loss between r and rr', + 'transmission_cost_nonac': '--$/MW-- expansion cost for DC interfaces (only lines; converters handled separately)', + 'transmission_line_fom': '--$/MW-year-- fixed O&M cost of transmission lines', + 'tsc_binwidth': '--$-- investment bin widths for transmission interfaces', + 'tsc_forward': '--$/MW-- transmission upgrade cost for forward direction', + 'tsc_reverse': '--$/MW-- transmission upgrade cost for reverse direction', + 'tscbin': 'transmission upgrade supply curve bins', } for key, df in outputs.items(): - if key in inputs_h5: - gamstype, comment = inputs_h5[key] - reeds.io.write_to_inputs_h5(df, key, case, gamstype=gamstype, comment=comment) + if key in comment: + gamstype = 'set' if key in sets else 'parameter' + reeds.io.write_to_inputs_h5(df, key, case, gamstype=gamstype, comment=comment[key]) else: df.to_csv( Path(case, 'inputs_case', f'{key}.csv'), @@ -782,7 +829,7 @@ def main(case): case = Path(args.inputs_case).parent # #%% Settings for testing ### - # case = str(Path(reeds.io.reeds_path, 'runs', 'v20260601_transcostM1_USA_faster')) + # case = str(Path(reeds.io.reeds_path, 'runs', 'v22060702_inputsM0_github_Pacific')) #%% Set up logger log = reeds.log.makelog(scriptname=__file__, logpath=Path(case, 'gamslog.txt')) diff --git a/reeds/io.py b/reeds/io.py index 728bb892c..a07679fda 100644 --- a/reeds/io.py +++ b/reeds/io.py @@ -1647,6 +1647,15 @@ def assemble_prescribed_builds(filepath, case=None, **kwargs): ### Write files +def gamsify_header(df): + """Add '*' to the beginning so GAMS reads the header as a comment""" + if isinstance(df, pd.DataFrame): + df = df.rename(columns={df.columns[0]: '*'+str(df.columns[0])}) + else: + df = df.rename('*'+df.name) if df.name else df + return df + + def get_dtype(col, df=None): if col.lower() == "value": return np.float32 From 471ae98bed4ba97aa31a12ad7a5bc37c1ed2930f Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Fri, 3 Jul 2026 07:04:52 -0600 Subject: [PATCH 07/28] fix co2_site_char index --- reeds/input_processing/transmission.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reeds/input_processing/transmission.py b/reeds/input_processing/transmission.py index 634aaf380..93c2a5b40 100644 --- a/reeds/input_processing/transmission.py +++ b/reeds/input_processing/transmission.py @@ -757,7 +757,7 @@ def main(case): val_cs = pd.Series(routes_cs['cs'].unique()) outputs['cs'] = val_cs - co2_site_char = get_co2_site_char(case).loc[val_cs] + co2_site_char = get_co2_site_char(case).reindex(val_cs).dropna().rename_axis('cs') for col in co2_site_char: outputs[col] = co2_site_char[col].reset_index() @@ -829,7 +829,7 @@ def main(case): case = Path(args.inputs_case).parent # #%% Settings for testing ### - # case = str(Path(reeds.io.reeds_path, 'runs', 'v22060702_inputsM0_github_Pacific')) + # case = str(Path(reeds.io.reeds_path, 'runs', 'v22060702_inputsM0_github_Everything')) #%% Set up logger log = reeds.log.makelog(scriptname=__file__, logpath=Path(case, 'gamslog.txt')) From 61ada4259ae7403c471e23e55c625fbf466d52b9 Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Tue, 7 Jul 2026 08:31:29 -0600 Subject: [PATCH 08/28] move outputs of calc_financial_inputs.py to inputs.h5 --- postprocessing/bokehpivot/reeds_bokeh.py | 5 +- reeds/core/setup/b_inputs.gms | 155 +----------------- reeds/core/solve/1_tc_phaseout.py | 7 +- reeds/financials.py | 17 +- .../input_processing/calc_financial_inputs.py | 118 ++++++++----- 5 files changed, 93 insertions(+), 209 deletions(-) diff --git a/postprocessing/bokehpivot/reeds_bokeh.py b/postprocessing/bokehpivot/reeds_bokeh.py index 40f6c69ad..4cac1da2c 100644 --- a/postprocessing/bokehpivot/reeds_bokeh.py +++ b/postprocessing/bokehpivot/reeds_bokeh.py @@ -356,7 +356,10 @@ def get_src(scen, src): except FileNotFoundError: df_src = read_input(scen['path'], src['name'], low_memory=False, **kwargs) else: - df_src = read_output(scen['path'], filepath) + if 'inputs_case' in filepath: + df_src = read_input(scen['path'], filepath) + else: + df_src = read_output(scen['path'], filepath) if 'transpose' in src and src['transpose'] is True: df_src = df_src.T if 'columns' in src: diff --git a/reeds/core/setup/b_inputs.gms b/reeds/core/setup/b_inputs.gms index 781e08c5e..9045411e9 100644 --- a/reeds/core/setup/b_inputs.gms +++ b/reeds/core/setup/b_inputs.gms @@ -1051,81 +1051,12 @@ one_newv(i)$sum{(v,t)$[not sameas(v,"new1")], ivt(i,v,t) } = no ; *--- basic parameter declarations --- *===================================== -parameter crf(t) "--unitless-- capital recovery factor" -/ -$offlisting -$ondelim -$include inputs_case%ds%crf.csv -$offdelim -$onlisting -/, - crf_co2_incentive(t) "--unitless-- capital recovery factor using a 12-year economic lifetime" -/ -$offlisting -$ondelim -$include inputs_case%ds%crf_co2_incentive.csv -$offdelim -$onlisting -/, - - crf_h2_incentive(t) "--unitless-- capital recovery factor using a 10-year economic lifetime" -/ -$offlisting -$ondelim -$include inputs_case%ds%crf_h2_incentive.csv -$offdelim -$onlisting -/, - -* pvf_capital and pvf_onm here are for intertemporal mode. These parameters -* are overwritten for sequential mode in e_solveprep.gms. - pvf_capital(t) "--unitless-- present value factor for overnight capital costs" -/ -$offlisting -$ondelim -$include inputs_case%ds%pvf_cap.csv -$offdelim -$onlisting -/, - pvf_onm(t)"--unitless-- present value factor of operations and maintenance costs" -/ -$offlisting -$ondelim -$include inputs_case%ds%pvf_onm_int.csv -$offdelim -$onlisting -/, +parameter tc_phaseout_mult(i,v,t) "--unitless-- multiplier that reduces the value of the PTC and ITC after the phaseout trigger has been hit", tc_phaseout_mult_t(i,t) "--unitless-- a single year's multiplier of tc_phaseout_mult", tc_phaseout_mult_t_load(i,t) "--unitless-- a single year's multiplier of tc_phaseout_mult", co2_captured_incentive(i,v,r,allt) "--$/tco2 stored-- incentive on CO2 captured dependent on technology" - co2_captured_incentive_in(i,v,allt) "--$/tco2 stored-- incentive on CO2 captured dependent on technology" -/ -$offlisting -$ondelim -$include inputs_case%ds%co2_capture_incentive.csv -$offdelim -$onlisting -/, - h2_ptc(i,v,r,allt) "--2004$/kg h2 produced -- incentive on hydrogen production by electrolyzers which purchase Energy Attribute Credits" - h2_ptc_in(i,v,allt) "--2004$/kg h2 produced -- incentive on hydrogen production by electrolyzers which purchase Energy Attribute Credits, this parameter is used to build h2_ptc" -/ -$offlisting -$ondelim -$include inputs_case%ds%h2_ptc.csv -$offdelim -$onlisting -/, - - ptc_value_scaled(i,v,allt) "--$/MWh-- value of the PTC incorporating adjustments for monetization costs, tax grossup benefits, and the difference between ptc duration and reeds evaluation period" -/ -$offlisting -$ondelim -$include inputs_case%ds%ptc_value_scaled.csv -$offdelim -$onlisting -/, pvf_onm_undisc(t) "--unitless-- undiscounted present value factor of operations and maintenance costs" ; @@ -4151,90 +4082,6 @@ $offempty * =========================================================================== * Regional and temporal capital cost multipliers * =========================================================================== -* Load scenario-specific capital cost multiplier components - -parameter ccmult(i,allt) "construction cost multiplier" -/ -$offlisting -$ondelim -$include inputs_case%ds%ccmult.csv -$offdelim -$onlisting -/ ; - -parameter tax_rate(allt) "all-in tax rate" -/ -$offlisting -$ondelim -$include inputs_case%ds%tax_rate.csv -$offdelim -$onlisting -/ ; - -parameter itc_frac_monetized(i,allt) "fractional value of the ITC, after adjusting for the costs of monetization" -/ -$offlisting -$ondelim -$include inputs_case%ds%itc_frac_monetized.csv -$offdelim -$onlisting -/ ; - -$onempty -parameter itc_energy_comm_bonus(i,r) "energy community tax credit bonus factor" -/ -$offlisting -$ondelim -$include inputs_case%ds%itc_energy_comm_bonus.csv -$offdelim -$onlisting -/ ; -$offempty - -parameter pv_frac_of_depreciation(i,allt) "present value of depreciation, expressed as a fraction of the capital cost of the investment" -/ -$offlisting -$ondelim -$include inputs_case%ds%pv_frac_of_depreciation.csv -$offdelim -$onlisting -/ ; - -parameter degradation_adj(i,allt) "adjustment to reflect degradation over the lifetime of an asset" -/ -$offlisting -$ondelim -$include inputs_case%ds%degradation_adj.csv -$offdelim -$onlisting -/ ; - -parameter financing_risk_mult(i,allt) "multiplier to reflect higher financing costs for riskier assets" -/ -$offlisting -$ondelim -$include inputs_case%ds%financing_risk_mult.csv -$offdelim -$onlisting -/ ; - -parameter reg_cap_cost_diff(i,r) "regional capital cost difference [fraction] (note that wind-ons and upv have separate multiplers in the supply curve cost)" -/ -$offlisting -$ondelim -$include inputs_case%ds%reg_cap_cost_diff.csv -$offdelim -$onlisting -/ ; - -parameter eval_period_adj_mult(i,allt) "adjustment multiplier for the capital costs of techs with non-standard evaluation periods" -/ -$offlisting -$ondelim -$include inputs_case%ds%eval_period_adj_mult.csv -$offdelim -$onlisting -/ ; eval_period_adj_mult(i,t)$[i_water_cooling(i)$Sw_WaterMain] = sum{ii$ctt_i_ii(i,ii), eval_period_adj_mult(ii,t) } ; diff --git a/reeds/core/solve/1_tc_phaseout.py b/reeds/core/solve/1_tc_phaseout.py index 66454f473..9383f2d7c 100644 --- a/reeds/core/solve/1_tc_phaseout.py +++ b/reeds/core/solve/1_tc_phaseout.py @@ -68,9 +68,10 @@ def calc_tc_phaseout_mult(year, case, use_historical=use_historical): # Note that even though we can specify incentive-level safe harbors in the inputs, we are # calculating the single phaseout mult with the maximum safe harbor. This is an expedient for # lack of time to create a phaseout for each incentive. - safe_harbors = pd.read_csv( - os.path.join(case, 'inputs_case', 'safe_harbor.csv') - ).rename(columns={'*i':'i', 't':'t_online'}) + safe_harbors = ( + reeds.io.read_input(case, 'safe_harbor') + .rename(columns={'t':'t_online', 'Value':'safe_harbor'}) + ) const_times = pd.read_csv( os.path.join(case, 'inputs_case', 'construction_times.csv')) diff --git a/reeds/financials.py b/reeds/financials.py index 64bd60172..0241fc26d 100644 --- a/reeds/financials.py +++ b/reeds/financials.py @@ -744,7 +744,9 @@ def adjust_ptc_values(df_ivt): return df_ivt -def inv_param_exporter(df, modeled_years, parameter, indices, file_name, output_dir): +def inv_param_exporter( + df, modeled_years, parameter, indices, file_name, inputs_case, units='', comment='', +): ''' General exporter for investment parameters, to be used in the GAMS model. @@ -776,15 +778,6 @@ def inv_param_exporter(df, modeled_years, parameter, indices, file_name, output_ sys.exit() df_param[parameter] = np.round(df_param[parameter], 6) - ### Add '*' to first column name so GAMS reads it as a comment - df_param = df_param.rename( - columns={c: (f'*{c}' if not i else c) for i, c in enumerate(df_param.columns)} + reeds.io.write_to_inputs_h5( + df_param, file_name, inputs_case, gamstype='parameter', units=units, comment=comment, ) - df_param.to_csv(os.path.join(output_dir, f'{file_name}.csv'), index=False, header=True) - - -def param_exporter(df, parameter, file_name, output_dir): - """Export parameters""" - ### Add '*' to first column name so GAMS reads it as a comment - df = df.rename(columns={c: (f'*{c}' if not i else c) for i, c in enumerate(df.columns)}) - df.round(5).to_csv(os.path.join(output_dir, f'{file_name}.csv'), index=False, header=True) diff --git a/reeds/input_processing/calc_financial_inputs.py b/reeds/input_processing/calc_financial_inputs.py index f2611a52d..14ad0cbec 100644 --- a/reeds/input_processing/calc_financial_inputs.py +++ b/reeds/input_processing/calc_financial_inputs.py @@ -391,59 +391,88 @@ def calc_financial_inputs(inputs_case): #%% Write the scenario-specific output files # Write out the components of the financial multiplier + df_ivt['allt'] = df_ivt['t'] reeds.financials.inv_param_exporter( - df_ivt, modeled_years, 'CCmult', ['i', 't'], - 'ccmult', inputs_case) + df_ivt, modeled_years, 'CCmult', ['i', 'allt'], 'ccmult', inputs_case, + units='fraction', comment='construction cost multiplier', + ) + reeds.financials.inv_param_exporter( + df_ivt, modeled_years, 'tax_rate', ['allt'], 'tax_rate', inputs_case, + units='fraction', comment='all-in tax rate', + ) reeds.financials.inv_param_exporter( - df_ivt, modeled_years, 'tax_rate', ['t'], - 'tax_rate', inputs_case) + df_ivt, modeled_years, 'itc_frac_monetized', ['i', 'allt'], 'itc_frac_monetized', inputs_case, + units='fraction', + comment='fractional value of the ITC, after adjusting for the costs of monetization', + ) reeds.financials.inv_param_exporter( - df_ivt, modeled_years, 'itc_frac_monetized', ['i', 't'], - 'itc_frac_monetized', inputs_case) + df_ivt, modeled_years, 'PV_fraction_of_depreciation', + ['i', 'allt'], 'pv_frac_of_depreciation', inputs_case, + units='fraction', + comment='present value of depreciation, expressed as a fraction of the capital cost of the investment', + ) reeds.financials.inv_param_exporter( - df_ivt, modeled_years, 'PV_fraction_of_depreciation', ['i', 't'], - 'pv_frac_of_depreciation', inputs_case) + df_ivt, modeled_years, 'Degradation_Adj', ['i', 'allt'], 'degradation_adj', inputs_case, + units='fraction', comment='adjustment to reflect degradation over the lifetime of an asset', + ) reeds.financials.inv_param_exporter( - df_ivt, modeled_years, 'Degradation_Adj', ['i', 't'], - 'degradation_adj', inputs_case) + df_ivt, modeled_years, 'financing_risk_mult', ['i', 'allt'], 'financing_risk_mult', inputs_case, + units='fraction', comment='multiplier to reflect higher financing costs for riskier assets', + ) reeds.financials.inv_param_exporter( - df_ivt, modeled_years, 'financing_risk_mult', ['i', 't'], - 'financing_risk_mult', inputs_case) + reg_cap_cost_diff, None, 'reg_cap_cost_diff', ['i', 'r'], 'reg_cap_cost_diff', inputs_case, + units='fraction', + comment='regional capital cost difference (wind and PV have separate multiplers in the supply curve cost)', + ) reeds.financials.inv_param_exporter( - reg_cap_cost_diff, None, 'reg_cap_cost_diff', ['i', 'r'], - 'reg_cap_cost_diff', inputs_case) - + df_ivt, modeled_years, 'pvf_capital', ['t'], 'pvf_capital', inputs_case, + units='fraction', comment='present value factor for overnight capital costs', + ) + # Write out the energy community itc bonus - reeds.financials.param_exporter( + reeds.io.write_to_inputs_h5( e_df[['i','r','itc_energy_comm_bonus']], - 'itc_energy_comm_bonus', 'itc_energy_comm_bonus', inputs_case + 'itc_energy_comm_bonus', inputs_case, gamstype='parameter', + comment='energy community tax credit bonus factor', ) # Write out the adjustment multiplier for non-standard evaluation periods - reeds.financials.param_exporter( - df_ivt[['i', 't', 'eval_period_adj_mult']], - 'eval_period_adj_mult', 'eval_period_adj_mult', inputs_case) + reeds.io.write_to_inputs_h5( + df_ivt[['i', 't', 'eval_period_adj_mult']].rename(columns={'t':'allt'}), + 'eval_period_adj_mult', inputs_case, gamstype='parameter', + comment='adjustment multiplier for the capital costs of techs with non-standard evaluation periods', + ) # Write out the safe harbor window for each tech, for determining # the tax credit phaseout schedules - reeds.financials.param_exporter( - df_ivt[['i', 't', 'safe_harbor']], - 'safe_harbor', 'safe_harbor', inputs_case) + reeds.io.write_to_inputs_h5( + df_ivt[['i', 't', 'safe_harbor']], + 'safe_harbor', inputs_case, gamstype='parameter', + ) # Write out the carbon capture incentive values - reeds.financials.param_exporter( - co2_capture_value[['i', 'v', 't', 'co2_capture_value_monetized']], - 'co2_capture_value_monetized', 'co2_capture_incentive', inputs_case) + reeds.io.write_to_inputs_h5( + co2_capture_value[['i', 'v', 't', 'co2_capture_value_monetized']].rename(columns={'t':'allt'}), + 'co2_captured_incentive_in', inputs_case, gamstype='parameter', units='$/tCO2 stored', + comment='incentive on CO2 captured dependent on technology', + ) # Write out the H2 production incentive values - reeds.financials.param_exporter( - h2_ptc_value[['i', 'v', 't', 'h2_ptc_value_monetized']], - 'h2_ptc_value_monetized', 'h2_ptc', inputs_case) - + reeds.io.write_to_inputs_h5( + h2_ptc_value[['i', 'v', 't', 'h2_ptc_value_monetized']], + 'h2_ptc_in', inputs_case, gamstype='parameter', units='2004$/kg H2 produced', + comment='incentive on hydrogen production by electrolyzers that purchase Energy Attribute Credits', + ) + # Write out the ptc_value_scaled (which incorporates all the adjustments reeds expects) - reeds.financials.param_exporter( + reeds.io.write_to_inputs_h5( ptc_values_df[['i', 'v', 't', 'ptc_value_scaled']], - 'ptc_value_scaled', 'ptc_value_scaled', inputs_case) + 'ptc_value_scaled', inputs_case, gamstype='parameter', units='$/MWh', + comment=( + 'value of the PTC incorporating adjustments for monetization costs, tax grossup ' + 'benefits, and the difference between ptc duration and reeds evaluation period' + ) + ) # Write out the PTC's nominal value, grossup value, tax equity penalty, and duration. This is # used in the retail rate module. @@ -459,22 +488,33 @@ def calc_financial_inputs(inputs_case): # CRF used in sequential case for calculating pvf_onm values (pvf) crf_df = financials_sys[financials_sys['t']==financials_sys['modeled_year']].copy() - reeds.financials.param_exporter(crf_df[['t', 'crf']], 'crf', 'crf', inputs_case) + reeds.io.write_to_inputs_h5( + crf_df[['t', 'crf']], 'crf', inputs_case, gamstype='parameter', units='fraction', + comment='capital recovery factor', + ) # 12-year crf used in sequential case for calculating 12-year payback time of co2_captured_incentive - reeds.financials.param_exporter(crf_df[['t', 'crf_co2_incentive']], 'crf_co2_incentive', 'crf_co2_incentive', inputs_case) + reeds.io.write_to_inputs_h5( + crf_df[['t', 'crf_co2_incentive']], + 'crf_co2_incentive', inputs_case, gamstype='parameter', units='fraction', + comment='capital recovery factor using a 12-year economic lifetime', + ) # 10-year crf used in sequential case for calculating 10-year payback time of h2_ptc - reeds.financials.param_exporter(crf_df[['t', 'crf_h2_incentive']], 'crf_h2_incentive', 'crf_h2_incentive', inputs_case) + reeds.io.write_to_inputs_h5( + crf_df[['t', 'crf_h2_incentive']], + 'crf_h2_incentive', inputs_case, gamstype='parameter', units='fraction', + comment='capital recovery factor using a 10-year economic lifetime', + ) # pvf_onm used in intertemporal pvf_onm_int = financials_sys[['modeled_year', 'pvf_onm']].groupby(by=['modeled_year']).sum() pvf_onm_int = pvf_onm_int.reset_index() pvf_onm_int = pvf_onm_int.rename(columns={'modeled_year':'t'}) - reeds.financials.param_exporter(pvf_onm_int, 'pvf_onm', 'pvf_onm_int', inputs_case) - - # pvf_cap (used in both seq and int modes) - reeds.financials.inv_param_exporter(df_ivt, modeled_years, 'pvf_capital', ['t'], 'pvf_cap', inputs_case) + reeds.io.write_to_inputs_h5( + pvf_onm_int, 'pvf_onm', inputs_case, gamstype='parameter', units='fraction', + comment='present value factor of operations and maintenance costs', + ) # Output some values used in the retail rate module retail_eval_period = df_ivt[['i', 't', 'eval_period']].drop_duplicates(['i', 't']) From ba47c99ccb74c913f8156a7ff7c188645de4f505 Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Tue, 7 Jul 2026 09:45:10 -0600 Subject: [PATCH 09/28] adapt forecast.py for inputs.h5 --- inputs/userinput/futurefiles.csv | 63 +++++++++++++++++++++++++++++- reeds/input_processing/forecast.py | 27 +++++++------ runreeds.py | 2 +- 3 files changed, 78 insertions(+), 14 deletions(-) diff --git a/inputs/userinput/futurefiles.csv b/inputs/userinput/futurefiles.csv index 3c8abcc30..25589c25a 100644 --- a/inputs/userinput/futurefiles.csv +++ b/inputs/userinput/futurefiles.csv @@ -382,7 +382,7 @@ resources.csv,.csv,1,None,9999,None,9999,0,constant,None,None,done,constant retail_cap_cost_mult.h5,.h5,1,None,9999,None,9999,0,constant,None,None,done,constant retail_depreciation_sch.h5,.h5,1,None,9999,None,9999,0,constant,None,None,done,constant retail_eval_period.h5,.h5,1,None,9999,None,9999,0,constant,None,None,done,constant -retire_penalty.csv,.csv,0,None,0,None,0,None,constant,None,None,new, +retire_penalty,inputs.h5,0,None,allt,None,0,None,constant,None,None,new, retirements_energy.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, retirements.csv,.csv,1,None,9999,None,9999,0,constant,None,None,"discuss, make sure it should just be copied",constant rev_paths.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, @@ -493,3 +493,64 @@ x_r.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, x.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, yearafter.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, years_until_endogenous.csv,.csv,1,None,9999,None,9999,0,constant,None,None,done,constant +allh,inputs.h5,1,,,,9999,,,,,, +allszn,inputs.h5,1,,,,9999,,,,,, +cendiv,inputs.h5,1,,,,9999,,,,,, +co2_captured_incentive_in,inputs.h5,1,,,,9999,,,,,, +co2_injection_limit,inputs.h5,1,,,,9999,,,,,, +co2_storage_limit,inputs.h5,1,,,,9999,,,,,, +cost_co2_stor_bec,inputs.h5,1,,,,9999,,,,,, +cost_hurdle_rate1,inputs.h5,1,,,,9999,,,,,, +cost_hurdle_rate2,inputs.h5,1,,,,9999,,,,,, +country,inputs.h5,1,,,,9999,,,,,, +cs,inputs.h5,1,,,,9999,,,,,, +ctt_cc_mult,inputs.h5,1,,,,9999,,,,,, +ctt_cost_vom_mult,inputs.h5,1,,,,9999,,,,,, +ctt_hr_mult,inputs.h5,1,,,,9999,,,,,, +df_capex_init,inputs.h5,1,,,,9999,,,,,, +distance,inputs.h5,1,,,,9999,,,,,, +evmc_storage_energy_h17,inputs.h5,1,,,,9999,,,,,, +firm_import_limit,inputs.h5,1,,,,9999,,,,,, +h2_ptc_in,inputs.h5,1,,,,9999,,,,,, +h2ptcreg,inputs.h5,1,,,,9999,,,,,, +hurdlereg,inputs.h5,1,,,,9999,,,,,, +initv,inputs.h5,1,,,,9999,,,,,, +inputs_0,inputs.h5,1,,,,9999,,,,,, +interconnect,inputs.h5,1,,,,9999,,,,,, +itlgrp,inputs.h5,1,,,,9999,,,,,, +maxdailycf_input,inputs.h5,1,,,,9999,,,,,, +minCF_input,inputs.h5,1,,,,9999,,,,,, +national_gen_frac,inputs.h5,1,,,,9999,,,,,, +nercr,inputs.h5,1,,,,9999,,,,,, +newv,inputs.h5,1,,,,9999,,,,,, +nextszn,inputs.h5,1,,,,9999,,,,,, +offshore,inputs.h5,1,,,,9999,,,,,, +opres_periods_h17,inputs.h5,1,,,,9999,,,,,, +outage_forced_hourly,inputs.h5,1,,,,9999,,,,,, +outage_scheduled_hourly,inputs.h5,1,,,,9999,,,,,, +pvf_capital,inputs.h5,1,,,,9999,,,,,, +pvf_onm,inputs.h5,1,,,,9999,,,,,, +r,inputs.h5,1,,,,9999,,,,,, +r_cs_distance,inputs.h5,1,,,,9999,,,,,, +rep,inputs.h5,1,,,,9999,,,,,, +st,inputs.h5,1,,,,9999,,,,,, +stressperiods_seed,inputs.h5,1,,,,9999,,,,,, +supplycurve_metadata,inputs.h5,1,,,,9999,,,,,, +t,inputs.h5,1,,,,9999,,,,,, +tmodel_new,inputs.h5,1,,,,9999,,,,,, +trancap_fut,inputs.h5,1,,,,9999,,,,,, +trancap_init_energy,inputs.h5,1,,,,9999,,,,,, +trancap_init_prm,inputs.h5,1,,,,9999,,,,,, +trancap_init_transgroup,inputs.h5,1,,,,9999,,,,,, +transgrp,inputs.h5,1,,,,9999,,,,,, +transmission_cost_ac,inputs.h5,1,,,,9999,,,,,, +transmission_cost_nonac,inputs.h5,1,,,,9999,,,,,, +transmission_line_fom,inputs.h5,1,,,,9999,,,,,, +transreg,inputs.h5,1,,,,9999,,,,,, +tsc_binwidth,inputs.h5,1,,,,9999,,,,,, +tsc_forward,inputs.h5,1,,,,9999,,,,,, +tsc_reverse,inputs.h5,1,,,,9999,,,,,, +tscbin,inputs.h5,1,,,,9999,,,,,, +usda_region,inputs.h5,1,,,,9999,,,,,, +v,inputs.h5,1,,,,9999,,,,,, +wst_surface,inputs.h5,1,,,,9999,,,,,, diff --git a/reeds/input_processing/forecast.py b/reeds/input_processing/forecast.py index f1442c469..181824c07 100644 --- a/reeds/input_processing/forecast.py +++ b/reeds/input_processing/forecast.py @@ -21,6 +21,7 @@ import numpy as np import os import sys +import h5py import shutil from glob import glob from warnings import warn @@ -168,7 +169,7 @@ def forecast( # #%% Settings for testing # reeds_path = os.path.expanduser('~/github/ReEDS') - # inputs_case = os.path.join(reeds_path,'runs','v20220411_prmM0_USA2060','inputs_case') + # inputs_case = os.path.join(reeds_path,'runs','v20260707_inputsM0_github_Everything','inputs_case') #%% Settings for debugging ### Set debug == True to write to a new folder (inputs_case/future/), leaving original files @@ -216,23 +217,23 @@ def forecast( ### Get the settings file futurefiles = pd.read_csv( - os.path.join(inputs_case,'futurefiles.csv'), + os.path.join(reeds.io.reeds_path, 'inputs', 'userinput', 'futurefiles.csv'), dtype={ - 'header':'category', 'ignore':int, 'wide':int, + 'ignore':int, 'wide':int, 'year_col':str, 'fix_cols':str, 'header':str, 'clip_min':str, 'clip_max':str, } ) - ### Fill in the missing parts of filenames - futurefiles.filename = futurefiles.filename.map( - lambda x: x.format(casename=casename, distpvscen=distpvscen) - ) ### Fix issue where columns with "None" entries are read in as NaN for col in ['key','fix_cols','header','clip_min','clip_max']: futurefiles[col] = futurefiles[col].fillna('None') ### If any files are missing, stop and alert the user - inputfiles = [os.path.basename(f) for f in glob(os.path.join(inputs_case,'*'))] + inputfiles = [ + Path(f).stem for f in glob(os.path.join(inputs_case,'*')) if not Path(f).is_dir() + ] + with h5py.File(Path(inputs_case, 'inputs.h5'), 'r') as f: + inputfiles += list(f) missingfiles = [ - f for f in inputfiles if ((f not in futurefiles.filename.values) and ('.' in f))] + f for f in inputfiles if f not in futurefiles.filename.map(lambda x: Path(x).stem).values] if any(missingfiles): if missing == 'raise': raise Exception( @@ -321,8 +322,8 @@ def forecast( efs = False ### Load it - if filetype in ['.csv','.csv.gz']: - dfin = pd.read_csv(os.path.join(inputs_case,filename), header=header,) + if filetype in ['inputs.h5', '.csv', '.csv.gz']: + dfin = reeds.io.read_input(inputs_case, filename, header=header) elif filetype == '.h5': ### Currently load.h5 and dr_shed_hourly.h5 are the only h5 files we need to ### project forward, so the procedure is currently specific to these files @@ -463,7 +464,9 @@ def forecast( dfout.rename(columns=the_unnamer, inplace=True) #%% Write it - if filetype in ['.csv','.csv.gz']: + if filetype == 'inputs.h5': + reeds.io.write_to_inputs_h5(dfout, filename, inputs_case, gamstype='parameter') + elif filetype in ['.csv', '.csv.gz']: dfout.round(decimals).to_csv( os.path.join(outpath, filename), header=(False if header is None else True), diff --git a/runreeds.py b/runreeds.py index de569937d..17f1d7fb5 100644 --- a/runreeds.py +++ b/runreeds.py @@ -1289,10 +1289,10 @@ def write_batch_script( 'climateprep', 'hourly_load', 'recf', - 'forecast', 'WriteHintage', 'transmission', 'outage_rates', + 'forecast', 'hourly_repperiods', 'h5_to_gdx', ]: From 2b9dbb07d63e2bf6d6c90796960766002e44f868 Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Tue, 7 Jul 2026 12:24:11 -0600 Subject: [PATCH 10/28] fix a few futurefiles.csv entries --- inputs/userinput/futurefiles.csv | 15 ++++++--------- reeds/input_processing/forecast.py | 4 ++-- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/inputs/userinput/futurefiles.csv b/inputs/userinput/futurefiles.csv index 25589c25a..ed90fe374 100644 --- a/inputs/userinput/futurefiles.csv +++ b/inputs/userinput/futurefiles.csv @@ -52,10 +52,10 @@ climate_param.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, climate_UnappWaterMult.csv,.csv,0,None,wide,"wst,r,szn",1,0,constant,0,None,done,constant climate_UnappWaterMultAnn.csv,.csv,0,None,wide,"wst,r",1,0,constant,0,None,done,constant climate_UnappWaterSeaAnnDistr.csv,.csv,0,None,wide,"wst,r,szn",1,0,constant,0,1,done,constant -co2_cap.csv,.csv,0,None,*t,None,0,0,constant,0,None,"constant, linear, or saturate?",constant +co2_cap.csv,.csv,0,None,allt,None,0,0,constant,0,None,"constant, linear, or saturate?",constant co2_capture_incentive.csv,.csv,1,None,9999,None,9999,0,constant,None,None,[CHECK] do we need to forecast within calc_financial_inputs? Data only extends to 2049; new, co2_site_char.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, -co2_tax.csv,.csv,0,None,*t,None,0,0,linear_5,None,None,"constant, linear, or saturate?",linear_5 +co2_tax.csv,.csv,0,None,allt,None,0,0,linear_5,None,None,"constant, linear, or saturate?",linear_5 coal_fom_adj.csv,.csv,0,None,*t,None,0,0,constant,None,None,"constant, linear, or saturate?",linear_5 coal_price.csv,.csv,0,None,year,None,1,0,constant,None,None,[CHECK] can we expect linear extrapolation for fuel prices (check other fuel prices); new, construction_schedules.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, @@ -332,7 +332,6 @@ plantchar_pvb.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new; used to c plantchar_upgrades.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new; used to create plantcharout.csv so no need to forecast, plantchar_upv.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new; used to create plantcharout.csv so no need to forecast, plantcharout.csv,.csv,0,None,t,"*i,variable",0,0,constant,None,None,new, -plantcharout.txt,.txt,0,None,1,"0,2",0,None,constant,None,None,"done. consider field-specific projections (i.e. linear projection for capcost for PV, but constant projection for heatrate and rte)",constant plexos_inputs.gdx,.gdx,1,None,9999,None,9999,0,constant,None,None,done (wouldn't exist yet in normal run),constant poi_cap_init.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, prepost.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, @@ -396,7 +395,7 @@ rsc_combined.txt,.txt,1,None,9999,None,9999,0,constant,None,None,done,constant rsc_evmc.csv,.csv,1,None,9999,None,9999,0,constant,None,None,"[CHECK] don't know what this input file is supposed to look like, but needs to be forecasted; new", rsc_wsc.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, safe_harbor_max.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new; handled in calc_financial_inputs.py, -safe_harbor.csv,.csv,0,None,t,*i,0,0,constant,None,None,new, +safe_harbor.csv,.csv,0,None,t,i,0,0,constant,None,None,new, sc_cat.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, sc_upv.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, sc_wind-ofs.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, @@ -515,7 +514,7 @@ h2_ptc_in,inputs.h5,1,,,,9999,,,,,, h2ptcreg,inputs.h5,1,,,,9999,,,,,, hurdlereg,inputs.h5,1,,,,9999,,,,,, initv,inputs.h5,1,,,,9999,,,,,, -inputs_0,inputs.h5,1,,,,9999,,,,,, +inputs_0.gdx,.gdx,1,,,,9999,,,,,, interconnect,inputs.h5,1,,,,9999,,,,,, itlgrp,inputs.h5,1,,,,9999,,,,,, maxdailycf_input,inputs.h5,1,,,,9999,,,,,, @@ -526,16 +525,14 @@ newv,inputs.h5,1,,,,9999,,,,,, nextszn,inputs.h5,1,,,,9999,,,,,, offshore,inputs.h5,1,,,,9999,,,,,, opres_periods_h17,inputs.h5,1,,,,9999,,,,,, -outage_forced_hourly,inputs.h5,1,,,,9999,,,,,, -outage_scheduled_hourly,inputs.h5,1,,,,9999,,,,,, +outage_forced_hourly.h5,.h5,1,,,,9999,,,,,, +outage_scheduled_hourly.h5,.h5,1,,,,9999,,,,,, pvf_capital,inputs.h5,1,,,,9999,,,,,, pvf_onm,inputs.h5,1,,,,9999,,,,,, r,inputs.h5,1,,,,9999,,,,,, r_cs_distance,inputs.h5,1,,,,9999,,,,,, -rep,inputs.h5,1,,,,9999,,,,,, st,inputs.h5,1,,,,9999,,,,,, stressperiods_seed,inputs.h5,1,,,,9999,,,,,, -supplycurve_metadata,inputs.h5,1,,,,9999,,,,,, t,inputs.h5,1,,,,9999,,,,,, tmodel_new,inputs.h5,1,,,,9999,,,,,, trancap_fut,inputs.h5,1,,,,9999,,,,,, diff --git a/reeds/input_processing/forecast.py b/reeds/input_processing/forecast.py index 181824c07..7846b62b0 100644 --- a/reeds/input_processing/forecast.py +++ b/reeds/input_processing/forecast.py @@ -169,7 +169,7 @@ def forecast( # #%% Settings for testing # reeds_path = os.path.expanduser('~/github/ReEDS') - # inputs_case = os.path.join(reeds_path,'runs','v20260707_inputsM0_github_Everything','inputs_case') + # inputs_case = os.path.join(reeds_path,'runs','v20260707_inputsM2_github_Everything','inputs_case') #%% Settings for debugging ### Set debug == True to write to a new folder (inputs_case/future/), leaving original files @@ -259,7 +259,7 @@ def forecast( print(f'{filename}', end='') ### If the file isn't in inputs_case, skip it and continue to the next file - if filename not in inputfiles: + if Path(filename).stem not in inputfiles: if verbose > 1: print(' -> skipped since not in inputs_case') continue From ef4bf0571158d551f75126e4df3f73d2c0c5599e Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Wed, 8 Jul 2026 19:43:09 -0600 Subject: [PATCH 11/28] reedsplots.plot_map_diff(): add level kwarg and use it in compare_cases.py when resolutions differ --- postprocessing/compare_cases.py | 5 +++++ reeds/reedsplots.py | 19 ++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/postprocessing/compare_cases.py b/postprocessing/compare_cases.py index cda0f96e7..0bceb552c 100644 --- a/postprocessing/compare_cases.py +++ b/postprocessing/compare_cases.py @@ -2548,6 +2548,8 @@ def two_bars(dfplot, basecase, colors, ax, col=0, ypad=0.02): dfmap = reeds.io.get_dfmap(base) dfba = dfmap['r'] dfstates = dfmap['st'] + resolutions = list(set([sw.GSw_ZoneSet for sw in dictin_sw.values()])) + level = 'r' if len(resolutions) == 1 else 'st' if (len(cases) == 2) and (not forcemulti): for i_plot in maptechs.keys(): plt.close() @@ -2560,6 +2562,7 @@ def two_bars(dfplot, basecase, colors, ax, col=0, ypad=0.02): _,_,dfplot = reedsplots.plot_diff_maps( val=mapdiff, i_plot=i_plot, titles = maptechs[i_plot], year=lastyear, casebase=casebase, casecomp=casecomp, + level=level, plot='base', f=f, ax=ax[0], cmap=cmocean.cm.rain, ) @@ -2570,6 +2573,7 @@ def two_bars(dfplot, basecase, colors, ax, col=0, ypad=0.02): _,_,dfplot = reedsplots.plot_diff_maps( val=mapdiff, i_plot=i_plot, titles = maptechs[i_plot], year=lastyear, casebase=casebase, casecomp=casecomp, + level=level, plot='comp', f=f, ax=ax[1], cmap=cmocean.cm.rain, ) @@ -2580,6 +2584,7 @@ def two_bars(dfplot, basecase, colors, ax, col=0, ypad=0.02): _,_,dfplot = reedsplots.plot_diff_maps( val=mapdiff, i_plot=i_plot, titles = maptechs[i_plot], year=lastyear, casebase=casebase, casecomp=casecomp, + level=level, plot='absdiff', f=f, ax=ax[2], cmap=plt.cm.RdBu_r, ) diff --git a/reeds/reedsplots.py b/reeds/reedsplots.py index 99764d4e6..066c49ce7 100644 --- a/reeds/reedsplots.py +++ b/reeds/reedsplots.py @@ -919,10 +919,13 @@ def plot_trans_onecase( return f, ax, dfplot -def plot_diff_maps(val, i_plot, titles, year, casebase, casecomp, - plot='diff', f=None, ax=None, cmap=plt.cm.Blues, - zmax=None, zlim=None, - legend_kwds=None, plot_kwds=None,): +def plot_diff_maps( + val, i_plot, titles, year, casebase, casecomp, + level:Literal['r','st']='r', + plot='diff', f=None, ax=None, cmap=plt.cm.Blues, + zmax=None, zlim=None, + legend_kwds=None, plot_kwds=None, +): """ Inputs ------ @@ -962,13 +965,19 @@ def plot_diff_maps(val, i_plot, titles, year, casebase, casecomp, ### Get the maps dfmap = reeds.io.get_dfmap(casecomp) - dfba = dfmap['r'] + dfba = dfmap[level] dfstates = dfmap['st'] ### Load the data, sum over hours dfbase = reeds.io.read_output(casebase, val, valname=valcol) dfcomp = reeds.io.read_output(casecomp, val, valname=valcol) + if level != 'r': + hierarchy_base = reeds.io.get_hierarchy(casebase) + hierarchy_comp = reeds.io.get_hierarchy(casecomp) + dfbase.r = dfbase.r.map(hierarchy_base[level]) + dfcomp.r = dfcomp.r.map(hierarchy_comp[level]) + ### Simplify the i names dfbase.i = simplify_techs(dfbase.i) dfcomp.i = simplify_techs(dfcomp.i) From 58db8adbab75782d05ee2fabf26f4d75dc11ffd0 Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Wed, 8 Jul 2026 19:48:13 -0600 Subject: [PATCH 12/28] cases_test.csv: change yearset back to 5-year steps for USA_fast --- cases_test.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cases_test.csv b/cases_test.csv index a87de9670..b678b6c3e 100644 --- a/cases_test.csv +++ b/cases_test.csv @@ -2,7 +2,7 @@ ignore,1,0,,,,,,,,,,,,,,,,,,,,,,,,,,,, GSw_Region,cendiv/Pacific,,country/USA,country/USA,country/USA,,st/ID.WY.NE.IA.IL,st/MA,,,,,,,st/WY,interconnect/western,transreg/PJM,st/NY.VT,st/OR,st/NE.NY.PA,st/NE.NY.PA,st/ID.WY.NE.IA.IL,st/KS,country/USA,country/USA,,,,st/MA.RI.CT.NY.NJ.PA.OH, endyear,2032,,2050,2050,2050,2029,2060,2026,,,,,,,,,,,2035,2030,2030,2060,2035,2050,2050,,,,, -yearset,,,,,,,2010..2060..10,,,,,,,,,,,,,2010..2050..5,2010..2050..5,2010..2060..10,,,2010_2025_2050,,,,, +yearset,,,,,,,2010..2060..10,,,,,,,,,,,,,2010..2050..5,2010..2050..5,2010..2060..10,,2010..2050..5,2010_2025_2050,,,,, GSw_ZoneSet,,,,,,,z54,z3109,,,,,,,z3109,z3109,z3109,PJMcounty,,,,z54,,z54,z48,,,,, GSw_GasCurve,2,,1,1,,,,,,,,,,,,,,,,,,,,1,1,,,,, GSw_Geothermal,,,,2,,,,,,,,,,,,,,,,,,,0,,0,,,,, From 7849a14dd2af33455380fcca8dc83160670fbb1c Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Wed, 8 Jul 2026 20:55:24 -0600 Subject: [PATCH 13/28] calc_financial_inputs.py: t -> allt; reedsplots.py: fix plot_max_imports(); io.py: clean up gamsify_header() --- reeds/input_processing/calc_financial_inputs.py | 4 ++-- reeds/io.py | 6 +++--- reeds/reedsplots.py | 16 +++++++++------- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/reeds/input_processing/calc_financial_inputs.py b/reeds/input_processing/calc_financial_inputs.py index 14ad0cbec..412bc3bba 100644 --- a/reeds/input_processing/calc_financial_inputs.py +++ b/reeds/input_processing/calc_financial_inputs.py @@ -198,7 +198,7 @@ def calc_financial_inputs(inputs_case): h2_ptc_value = df_ivt[['i', 'v', 't', 'h2_ptc_value_monetized', 'h2_ptc_dur']].iloc[0:5,:] h2_ptc_value = h2_ptc_value.drop_duplicates(['i', 'v', 't']) h2_ptc_value['v'] = ['new%s' % v for v in h2_ptc_value['v']] - h2_ptc_value['t'] = h2_ptc_value['t'].astype(int) + h2_ptc_value['allt'] = h2_ptc_value['t'].astype(int) # Expand the various ptc values by the duration of the incentive. # We are tracking various ptc_values (e.g. with and without tax grossups) @@ -459,7 +459,7 @@ def calc_financial_inputs(inputs_case): # Write out the H2 production incentive values reeds.io.write_to_inputs_h5( - h2_ptc_value[['i', 'v', 't', 'h2_ptc_value_monetized']], + h2_ptc_value[['i', 'v', 'allt', 'h2_ptc_value_monetized']], 'h2_ptc_in', inputs_case, gamstype='parameter', units='2004$/kg H2 produced', comment='incentive on hydrogen production by electrolyzers that purchase Energy Attribute Credits', ) diff --git a/reeds/io.py b/reeds/io.py index a48b47ea4..2e4cf6889 100644 --- a/reeds/io.py +++ b/reeds/io.py @@ -1650,10 +1650,10 @@ def assemble_prescribed_builds(filepath, case=None, **kwargs): def gamsify_header(df): """Add '*' to the beginning so GAMS reads the header as a comment""" if isinstance(df, pd.DataFrame): - df = df.rename(columns={df.columns[0]: '*'+str(df.columns[0])}) + dfout = df.rename(columns={df.columns[0]: '*' + str(df.columns[0])}) else: - df = df.rename('*'+df.name) if df.name else df - return df + dfout = df.rename('*' + df.name) if df.name else df + return dfout def get_dtype(col, df=None): diff --git a/reeds/reedsplots.py b/reeds/reedsplots.py index 066c49ce7..37f461922 100644 --- a/reeds/reedsplots.py +++ b/reeds/reedsplots.py @@ -1438,12 +1438,13 @@ def plot_max_imports( flow[level] = flow.r.map(r2agg) flow[levell] = flow.rr.map(r2agg) - tranloss = pd.read_csv( - os.path.join(c,'inputs_case','tranloss.csv') - ).rename(columns={'*r':'r'}).set_index(['r','rr','trtype']).squeeze(1) + tranloss = ( + reeds.io.read_input(c, 'tranloss') + .rename(columns={'*r':'r'}).set_index(['r','rr','trtype']).squeeze(1) + ) peakload = ( - pd.read_csv(os.path.join(c,'inputs_case','peakload.csv')) + reeds.io.read_input(c, 'peakload') .set_index(['level','region']).loc[level].stack() .rename_axis(['r','t']).rename('MW') .reset_index().astype({'t':int}).set_index(['r','t']).squeeze() @@ -1452,9 +1453,10 @@ def plot_max_imports( if _draw_limit: ## Fraction try: - firm_import_limit = pd.read_csv( - os.path.join(c, 'inputs_case', 'firm_import_limit.csv') - ).rename(columns={'*nercr':'nercr'}).set_index(['nercr','t']).squeeze() + firm_import_limit = ( + reeds.io.read_input(c, 'firm_import_limit') + .rename(columns={'*nercr':'nercr'}).set_index(['nercr','t']).squeeze(1) + ) except FileNotFoundError: print("firm_import_limit.csv not found, so it won't be plotted") _draw_limit = False From 05156e15983f5291ced82471744e600bb59cc52b Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Wed, 8 Jul 2026 22:08:14 -0600 Subject: [PATCH 14/28] calc_financial_inputs.py: fix a few more t/allt --- reeds/financials.py | 5 +++-- reeds/input_processing/calc_financial_inputs.py | 9 +++------ reeds/input_processing/writecapdat.py | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/reeds/financials.py b/reeds/financials.py index 0241fc26d..7fe503bc8 100644 --- a/reeds/financials.py +++ b/reeds/financials.py @@ -758,8 +758,9 @@ def inv_param_exporter( # For investment parameters we only care about modeled_year values # Skip this step if there is no 't' index, inducated by modeled_years=None - if 't' in indices: - df = df[df['t'].isin(modeled_years)] + for tcol in ['t', 'allt']: + if tcol in indices: + df = df[df[tcol].isin(modeled_years)] df_param = df[indices + [parameter]].drop_duplicates() df_check_size = df[indices].drop_duplicates() diff --git a/reeds/input_processing/calc_financial_inputs.py b/reeds/input_processing/calc_financial_inputs.py index 412bc3bba..6f086b71b 100644 --- a/reeds/input_processing/calc_financial_inputs.py +++ b/reeds/input_processing/calc_financial_inputs.py @@ -221,7 +221,7 @@ def calc_financial_inputs(inputs_case): 'ptc_value_monetized_posttax', 'ptc_grossup_value', 'ptc_value_scaled']].iloc[0:5,:] # this is just a hack because pjg didn't know how to have gams handle empty files ptc_values_df = ptc_values_df.drop_duplicates(['i', 'v', 't']) ptc_values_df['v'] = ['new%s' % v for v in ptc_values_df['v']] - ptc_values_df['t'] = ptc_values_df['t'].astype(int) + ptc_values_df['allt'] = ptc_values_df['t'].astype(int) @@ -445,10 +445,7 @@ def calc_financial_inputs(inputs_case): # Write out the safe harbor window for each tech, for determining # the tax credit phaseout schedules - reeds.io.write_to_inputs_h5( - df_ivt[['i', 't', 'safe_harbor']], - 'safe_harbor', inputs_case, gamstype='parameter', - ) + df_ivt[['i', 't', 'safe_harbor']].to_csv(Path(inputs_case, 'safe_harbor.csv'), index=False) # Write out the carbon capture incentive values reeds.io.write_to_inputs_h5( @@ -466,7 +463,7 @@ def calc_financial_inputs(inputs_case): # Write out the ptc_value_scaled (which incorporates all the adjustments reeds expects) reeds.io.write_to_inputs_h5( - ptc_values_df[['i', 'v', 't', 'ptc_value_scaled']], + ptc_values_df[['i', 'v', 'allt', 'ptc_value_scaled']], 'ptc_value_scaled', inputs_case, gamstype='parameter', units='$/MWh', comment=( 'value of the PTC incorporating adjustments for monetization costs, tax grossup ' diff --git a/reeds/input_processing/writecapdat.py b/reeds/input_processing/writecapdat.py index ee9dd91af..14aefd9f3 100644 --- a/reeds/input_processing/writecapdat.py +++ b/reeds/input_processing/writecapdat.py @@ -476,7 +476,7 @@ def main(reeds_path, inputs_case): print('Gathering SMR Existing Capacity...') # Grab the first year for smr because that is when new capacity can begin to be built (for # smr, smr_ccs and electrolyzers) - firstyear = reeds.io.read_input(inputs_case, 'firstyear').set_index('i').squeeze(1) + firstyear = reeds.io.read_input(inputs_case, 'firstyear').set_index('i').squeeze(1).astype(int) h2_prod_first_year = firstyear['smr'] # Get exogenous H2 demand h2_exogenous_demand = ( From 066d8fe6cb7d3bb1e5bbfed3a99b7e44ed49eac0 Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Wed, 8 Jul 2026 22:25:36 -0600 Subject: [PATCH 15/28] h5_to_gdx.py: add v to special_keys --- reeds/input_processing/h5_to_gdx.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reeds/input_processing/h5_to_gdx.py b/reeds/input_processing/h5_to_gdx.py index bed3e258c..38aad1d6d 100644 --- a/reeds/input_processing/h5_to_gdx.py +++ b/reeds/input_processing/h5_to_gdx.py @@ -131,7 +131,7 @@ def main(case, overwrite=True, verbose=1): gdxpath = Path(reeds.io.standardize_case(case), 'inputs_case', 'inputs_0.gdx') ## Some sets need to be defined first to conserve ordering keys_in = list(dictin.keys()) - special_keys = ['r'] + special_keys = ['r', 'v'] keys = special_keys + [i for i in keys_in if i not in special_keys] ## Load each h5 key and write it to gdx declare_sets = [] @@ -188,7 +188,7 @@ def main(case, overwrite=True, verbose=1): case = reeds.io.standardize_case(Path(args.inputs_case)) # #%% Inputs for testing - # case = Path(reeds.io.reeds_path, 'runs', 'v20260427_inputsM0_github_Everything') + # case = Path(reeds.io.reeds_path, 'runs', 'v20260708_inputsM1_Pacific') #%% Set up logger log = reeds.log.makelog( From 85fdbc26e2ebbf79b38a2f134a3049b00c66b733 Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Thu, 9 Jul 2026 08:45:42 -0600 Subject: [PATCH 16/28] finish moving outputs of calc_financial_inputs.py to inputs.h5 --- inputs/load/mex_growth_rate.csv | 1 + reeds/core/setup/b_inputs.gms | 85 ------------------- .../input_processing/calc_financial_inputs.py | 36 +++++--- reeds/input_processing/copy_files.py | 27 ++++-- reeds/input_processing/hourly_load.py | 9 +- reeds/input_processing/plantcostprep.py | 2 +- reeds/input_processing/runfiles.csv | 2 +- 7 files changed, 52 insertions(+), 110 deletions(-) diff --git a/inputs/load/mex_growth_rate.csv b/inputs/load/mex_growth_rate.csv index efe22a3ed..fc0e8871b 100644 --- a/inputs/load/mex_growth_rate.csv +++ b/inputs/load/mex_growth_rate.csv @@ -1,3 +1,4 @@ +allt,fraction 2010,0.860050287 2011,0.91512148 2012,0.93208905 diff --git a/reeds/core/setup/b_inputs.gms b/reeds/core/setup/b_inputs.gms index df2a0e16c..65e407a22 100644 --- a/reeds/core/setup/b_inputs.gms +++ b/reeds/core/setup/b_inputs.gms @@ -3249,34 +3249,6 @@ parameter cost_h2_transport_cap(r,rr,allt) "--$/(metric ton/hour)-- cap h2_network_load(h2_st,allt) "--MWh/metric ton-- electricity consumption of H2 network components" ; -* read in capital cost multiplier from financial processing script -parameter h2_cap_cost_mult_pipeline(allt) "capital cost multiplier for h2 pipelines" -/ -$offlisting -$ondelim -$include inputs_case%ds%h2_pipeline_cap_cost_mult.csv -$offdelim -$onlisting -/ ; - -parameter h2_cap_cost_mult_compressor(allt) "capital cost multiplier for h2 compressors" -/ -$offlisting -$ondelim -$include inputs_case%ds%h2_compressor_cap_cost_mult.csv -$offdelim -$onlisting -/ ; - -parameter h2_cap_cost_mult_storage(allt) "capital cost multiplier for h2 storage" -/ -$offlisting -$ondelim -$include inputs_case%ds%h2_storage_cap_cost_mult.csv -$offdelim -$onlisting -/ ; - * here computing capital and FOM costs as $/metric ton-hour for all possible routes * including capital cost multipliers, which are different for pipelines and compressors * note that pipeline distance is between BA centroids @@ -4042,15 +4014,6 @@ $include inputs_case%ds%cangrowth.csv $offdelim $onlisting ; - -parameter mex_growth_rate(allt) "growth rate for mexican demand - national" -/ -$offlisting -$ondelim -$include inputs_case%ds%mex_growth_rate.csv -$offdelim -$onlisting -/ ; $offempty @@ -4067,16 +4030,6 @@ $offdelim $onlisting / ; -$onempty -parameter peakload_nercr(nercr,allt) "--MW-- Peak exogenous demand across all weather years by NERC region" -/ -$offlisting -$ondelim -$include inputs_case%ds%peakload_nercr.csv -$offdelim -$onlisting -/ ; -$offempty * =========================================================================== @@ -4097,24 +4050,6 @@ cost_cap_fin_mult_noITC(i,r,t) "final capital cost multiplier excluding ITC - us cost_cap_fin_mult_no_credits(i,r,t) "final capital cost multiplier ITC/PTC/Depreciation (i.e. the actual expenditures) - used only in outputs", cost_cap_fin_mult_out(i,r,t) "final capital cost multiplier for system cost outputs" ; -parameter trans_cost_cap_fin_mult(allt) "capital cost multiplier for transmission - used in the objective function" -/ -$offlisting -$ondelim -$include inputs_case%ds%trans_cap_cost_mult.csv -$offdelim -$onlisting -/ ; - -parameter trans_cost_cap_fin_mult_noITC(allt) "capital cost multiplier for transmission excluding ITC - used only in outputs" -/ -$offlisting -$ondelim -$include inputs_case%ds%trans_cap_cost_mult_noITC.csv -$offdelim -$onlisting -/ ; - * --- Hybrid PV+Battery --- * Hybrid PV+Battery: PV portion @@ -4213,30 +4148,10 @@ capture_rate_fuel(i,"CO2")$beccs(i) = - emit_rate_fuel(i,"process","CO2") parameter capture_rate(e,i,v,r,t) "--metric tons per MWh-- emissions capture rate" ; -parameter methane_leakage_rate(allt) "--fraction-- methane leakage as fraction of gross production" -* best estimate for fixed leakage rate is 0.023 (Alvarez et al. 2018, https://dx.doi.org/10.1126/science.aar7204) -/ -$offlisting -$ondelim -$include inputs_case%ds%methane_leakage_rate.csv -$offdelim -$onlisting -/ ; - scalar methane_tonperMMBtu "--metric tons per MMBtu-- methane content of natural gas" ; * [ton CO2 / MMBtu] * [ton CH4 / ton CO2] methane_tonperMMBtu = emit_rate_fuel("gas-CC","process","CO2") * molWeightCH4 / molWeightCO2 ; -* H2 leakage rate by technology and etype (broken down to process and upstream) -parameter h2_leakage_rate(i) "--fraction-- h2 leakage rate as a fraction of total production by technology and emission type" -/ -$offlisting -$ondelim -$include inputs_case%ds%h2_leakage_rate.csv -$offdelim -$onlisting -/ ; - parameter prod_emit_rate(etype,e,i,allt) "--metric tons emitted per metric ton product-- emissions rate per metric ton of product (e.g. tonCO2/tonH2 for SMR & SMR-CCS)" ; * Steam methane reformer (SMR)'s process emission here refers to emissions from steam methane reforming process prod_emit_rate("process","CO2","smr",t) = smr_co2_intensity ; diff --git a/reeds/input_processing/calc_financial_inputs.py b/reeds/input_processing/calc_financial_inputs.py index 6f086b71b..0d4f26078 100644 --- a/reeds/input_processing/calc_financial_inputs.py +++ b/reeds/input_processing/calc_financial_inputs.py @@ -95,7 +95,7 @@ def calc_financial_inputs(inputs_case): financials_sys = reeds.financials.import_sys_financials( sw['financials_sys_suffix'], inflation_df, modeled_years, years, year_map, sw['sys_eval_years'], scen_settings, scalars['co2_capture_incentive_length'],scalars['h2_ptc_length']) - financials_sys.to_csv(os.path.join(inputs_case,'financials_sys.csv'),index=False) + financials_sys.to_csv(os.path.join(inputs_case,'financials_sys_full.csv'),index=False) df_ivt = df_ivt.merge( financials_sys[['t', 'pvf_capital', 'crf', 'crf_co2_incentive','crf_h2_incentive','d_real', 'd_nom', 'interest_rate_nom', 'tax_rate', 'debt_fraction', 'rroe_nom']], @@ -268,10 +268,17 @@ def calc_financial_inputs(inputs_case): dftrans.loc[dftrans.t Date: Thu, 9 Jul 2026 08:51:39 -0600 Subject: [PATCH 17/28] adjust parameter names in futurefiles.csv --- inputs/userinput/futurefiles.csv | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/inputs/userinput/futurefiles.csv b/inputs/userinput/futurefiles.csv index ed90fe374..d12b38dd0 100644 --- a/inputs/userinput/futurefiles.csv +++ b/inputs/userinput/futurefiles.csv @@ -144,6 +144,7 @@ exog_wind_ons_rsc.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, f.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, financials_hydrogen.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new; input data extends to 2100, financials_sys.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new; handled in calc_financial_inputs.py, +financials_sys_full.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new; handled in calc_financial_inputs.py, financials_tech.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new; used as input for calc_financials_inputs.py so no need to forecast, financials_transmission.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new; input data extends to 2100, financing_risk_mult.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new; handled in calc_financial_inputs.py, @@ -180,15 +181,15 @@ gswitches.txt,.txt,1,None,9999,None,9999,0,constant,None,None,new, gwp.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, h_dt_szn.csv,.csv,1,None,9999,None,9999,0,constant,None,None,done,constant h2_ba_share.csv,.csv,0,None,t,*r,0,0,constant,0,None,done,constant -h2_compressor_cap_cost_mult.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new; seems to be handled in calc_financial_inputs.py, +h2_cap_cost_mult_compressor.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new; seems to be handled in calc_financial_inputs.py, h2_existing_smr_cap.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, h2_exogenous_demand.csv,.csv,0,None,t,*p,1,0,linear_5,0,None,done,constant h2_leakage_rate.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, -h2_pipeline_cap_cost_mult.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, +h2_cap_cost_mult_pipeline.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, h2_ptc.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new; handled in calc_financial_inputs.py, h2_st.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, h2_stor.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, -h2_storage_cap_cost_mult.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new; seems to be handled in calc_financial_inputs.py, +h2_cap_cost_mult_storage.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new; seems to be handled in calc_financial_inputs.py, h2_storage_rb.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, h2_transport_and_storage_costs.csv,.csv,0,None,t,"*h2_stor_trans,parameter",0,0,constant,None,None,new, heat_rate_adj.csv,.csv,1,None,9999,None,9999,0,constant,None,None,done,constant @@ -444,8 +445,8 @@ tg.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, threads.txt,.txt,1,None,9999,None,9999,0,constant,None,None,done,constant trancap_fut_cat.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, tranloss.csv,.csv,1,None,9999,None,9999,0,constant,None,None,done,constant -trans_cap_cost_mult_noITC.csv,.csv,1,None,*t,None,0,0,constant,None,None,handled in calc_financial_inputs.py,constant -trans_cap_cost_mult.csv,.csv,1,None,*t,None,0,0,constant,None,None,handled in calc_financial_inputs.py,constant +trans_cost_cap_fin_mult_noITC.csv,.csv,1,None,*t,None,0,0,constant,None,None,handled in calc_financial_inputs.py,constant +trans_cost_cap_fin_mult.csv,.csv,1,None,*t,None,0,0,constant,None,None,handled in calc_financial_inputs.py,constant trans_intra_cost_adder.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, trans_itc_fractions.csv,.csv,1,None,9999,None,9999,0,constant,None,None,constant or expire?,constant transmission_distance_cost_500kVac.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, From b644a6d56736fff013a4b99aa9370043f233e72e Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Thu, 9 Jul 2026 09:19:06 -0600 Subject: [PATCH 18/28] more futurefiles.csv --- inputs/userinput/futurefiles.csv | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/inputs/userinput/futurefiles.csv b/inputs/userinput/futurefiles.csv index d12b38dd0..df00ef1fe 100644 --- a/inputs/userinput/futurefiles.csv +++ b/inputs/userinput/futurefiles.csv @@ -249,8 +249,8 @@ maps.gpkg,.gpkg,1,None,9999,None,9999,0,constant,None,None,new, maxage.csv,.csv,1,None,9999,None,9999,0,constant,None,None,done,constant maxdailycf.csv,.csv,1,None,9999,None,9999,0,constant,None,None,done,constant mcs_distributions.yaml,.yaml,1,None,9999,None,9999,0,constant,None,None,new, -methane_leakage_rate.csv,.csv,0,None,*t,None,0,0,constant,None,None,done,constant -mex_growth_rate.csv,.csv,0,None,0,None,0,None,linear_5,0,None,done,linear_5 +methane_leakage_rate.csv,.csv,0,None,allt,None,0,0,constant,None,None,done,constant +mex_growth_rate.csv,.csv,0,None,allt,None,0,None,linear_5,0,None,done,linear_5 min_retire_age.csv,.csv,1,None,9999,None,9999,0,constant,None,None,done,constant minCF.csv,.csv,1,None,9999,None,9999,0,constant,None,None,done,constant mingen_fixed.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, @@ -298,7 +298,7 @@ pcm_defaults.json,.json,1,None,9999,None,9999,0,constant,None,None,new, peak_ccseason.csv,.csv,2,None,wide,"r,ccseason",1,0,linear_5,None,None,"ignore if not EFS, else apply projection",linear_10 peak_h.csv,.csv,2,None,wide,"r,h",1,0,linear_5,None,None,"ignore if not EFS, else apply projection",linear_10 peak_net_imports.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, -peakload_nercr.csv,.csv,0,None,t,*nercr,0,0,linear_5,None,None,new, +peakload_nercr.csv,.csv,0,None,t,nercr,0,0,linear_5,None,None,new, peakload.csv,.csv,0,None,wide,"level,region",1,0,linear_5,None,None,new, period_szn_user.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, pipeline_cost_mult.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, From 488439860205418dccbd35fea1f01d7a82278bb3 Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Fri, 10 Jul 2026 15:59:53 -0600 Subject: [PATCH 19/28] write trancap_init_energy for r2x --- reeds/input_processing/transmission.py | 59 ++++++++++++++------------ 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/reeds/input_processing/transmission.py b/reeds/input_processing/transmission.py index 93c2a5b40..7973a0916 100644 --- a/reeds/input_processing/transmission.py +++ b/reeds/input_processing/transmission.py @@ -779,36 +779,41 @@ def main(case): 'tscbin': False, } sets = ['tscbin', 'routes_adjacent', 'r_cs', 'cs'] - comment = { - 'co2_injection_limit': '--metric tons/hr-- co2 site injection rate upper bound', - 'co2_storage_limit': '--metric tons-- total cumulative storage capacity per carbon storage site', - 'cost_co2_stor_bec': '--$/metric ton-- breakeven cost for storing carbon - CF determined by GSw_CO2_BEC', - 'cost_hurdle_rate1': '--$ per MWh-- raw data cost for transmission hurdle rate for regiongrp1', - 'cost_hurdle_rate2': '--$ per MWh-- raw data cost for transmission hurdle rate for regiongrp2', - 'cs': 'CO2 storage sites', - 'distance': '--miles-- distance between BAs by line type', - 'firm_import_limit': '--fraction-- limit on net firm imports into NERC regions', - 'pipeline_cost_mult': '--fraction-- cost multiplier for H2 pipelines (will be added to 1)', - 'r_cs_distance': '--mi-- euclidean distance between BA transmission endpoints and storage formations', - 'r_cs': 'mapping from BA to carbon storage sites', - 'routes_adjacent': 'all pairs of adjacent land-based BAs', - 'trancap_fut': '--MW-- potential future transmission capacity by type (one direction)', - 'trancap_init_energy': '--MW-- initial transmission capacity for energy trading (both directions)', - 'trancap_init_prm': '--MW-- initial transmission capacity for capacity (PRM) trading (both directions)', - 'trancap_init_transgroup': '--MW-- initial upper limit on interface AC flows', - 'tranloss': '--fraction-- transmission loss between r and rr', - 'transmission_cost_nonac': '--$/MW-- expansion cost for DC interfaces (only lines; converters handled separately)', - 'transmission_line_fom': '--$/MW-year-- fixed O&M cost of transmission lines', - 'tsc_binwidth': '--$-- investment bin widths for transmission interfaces', - 'tsc_forward': '--$/MW-- transmission upgrade cost for forward direction', - 'tsc_reverse': '--$/MW-- transmission upgrade cost for reverse direction', - 'tscbin': 'transmission upgrade supply curve bins', + ## Write some copies for r2x (would be better to avoid by adding compatibility with inputs.h5) + csvs = ['trancap_init_energy'] + units_comment = { + 'co2_injection_limit': ('metric tons/hr', 'co2 site injection rate upper bound'), + 'co2_storage_limit': ('metric tons', 'total cumulative storage capacity per carbon storage site'), + 'cost_co2_stor_bec': ('$/metric ton', 'breakeven cost for storing carbon - CF determined by GSw_CO2_BEC'), + 'cost_hurdle_rate1': ('$/MWh', 'raw data cost for transmission hurdle rate for regiongrp1'), + 'cost_hurdle_rate2': ('$/MWh', 'raw data cost for transmission hurdle rate for regiongrp2'), + 'cs': ('', 'CO2 storage sites'), + 'distance': ('miles', 'distance between BAs by line type'), + 'firm_import_limit': ('fraction', 'limit on net firm imports into NERC regions'), + 'pipeline_cost_mult': ('fraction', 'cost multiplier for H2 pipelines (will be added to 1)'), + 'r_cs_distance': ('miles', 'Euclidean distance between BA transmission endpoints and storage formations'), + 'r_cs': ('', 'mapping from BA to carbon storage sites'), + 'routes_adjacent': ('', 'all pairs of adjacent land-based BAs'), + 'trancap_fut': ('MW', 'potential future transmission capacity by type (one direction)'), + 'trancap_init_energy': ('MW', 'initial transmission capacity for energy trading (both directions)'), + 'trancap_init_prm': ('MW', 'initial transmission capacity for capacity (PRM) trading (both directions)'), + 'trancap_init_transgroup': ('MW', 'initial upper limit on interface AC flows'), + 'tranloss': ('fraction', 'transmission loss between r and rr'), + 'transmission_cost_nonac': ('$/MW', 'expansion cost for DC interfaces (only lines; converters handled separately)'), + 'transmission_line_fom': ('$/MW-year', 'fixed O&M cost of transmission lines'), + 'tsc_binwidth': ('$', 'investment bin widths for transmission interfaces'), + 'tsc_forward': ('$/MW', 'transmission upgrade cost for forward direction'), + 'tsc_reverse': ('$/MW', 'transmission upgrade cost for reverse direction'), + 'tscbin': ('', 'transmission upgrade supply curve bins'), } for key, df in outputs.items(): - if key in comment: + if key in units_comment: gamstype = 'set' if key in sets else 'parameter' - reeds.io.write_to_inputs_h5(df, key, case, gamstype=gamstype, comment=comment[key]) - else: + reeds.io.write_to_inputs_h5( + df, key, case, gamstype=gamstype, + units=units_comment[key][0], comment=units_comment[key][1], + ) + if (key not in units_comment) or (key in csvs): df.to_csv( Path(case, 'inputs_case', f'{key}.csv'), index=False, header=header.get(key, True), From 916654d3ec86da6d933d34f48c4c29554a48e924 Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Fri, 10 Jul 2026 16:01:37 -0600 Subject: [PATCH 20/28] inputs.h5: include units in attrs --- reeds/io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reeds/io.py b/reeds/io.py index 2e4cf6889..3cfd0c7bc 100644 --- a/reeds/io.py +++ b/reeds/io.py @@ -1798,7 +1798,7 @@ def write_to_inputs_h5( dfwrite['Value'] = dfwrite['Value'].astype(np.float32) ### Write record to h5 file calling_file = Path(inspect.stack()[-1][1]).name - attrs = {'gamstype': gamstype.lower(), 'written_by': calling_file} + attrs = {'gamstype': gamstype.lower(), 'units':units, 'written_by': calling_file} if len(units): attrs['comment'] = f'[{units}] {comment} (written by {calling_file})' else: From 70a2c689e502ec658413b1ca0b394bc3ccd8149f Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Thu, 23 Jul 2026 14:57:04 -0600 Subject: [PATCH 21/28] trans_cost_cap_fin_mult_noITC: Fix typo Co-authored-by: kodiobika <35176195+kodiobika@users.noreply.github.com> --- reeds/input_processing/calc_financial_inputs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reeds/input_processing/calc_financial_inputs.py b/reeds/input_processing/calc_financial_inputs.py index 0d4f26078..bafc56234 100644 --- a/reeds/input_processing/calc_financial_inputs.py +++ b/reeds/input_processing/calc_financial_inputs.py @@ -275,7 +275,7 @@ def calc_financial_inputs(inputs_case): comment='capital cost multiplier for transmission - used in the objective function' ) reeds.io.write_to_inputs_h5( - dftrans[['allt','cap_cost_mult']], 'trans_cost_cap_fin_mult_noITC', inputs_case, + dftrans[['allt','cap_cost_mult_noITC']], 'trans_cost_cap_fin_mult_noITC', inputs_case, gamstype='parameter', units='fraction', comment='capital cost multiplier for transmission excluding ITC - used only in outputs', ) From 0d98abe029f3d156a42886dee73636989bf38481 Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Thu, 23 Jul 2026 14:57:47 -0600 Subject: [PATCH 22/28] writecapdat.py: 2010->startyear Co-authored-by: kodiobika <35176195+kodiobika@users.noreply.github.com> --- reeds/input_processing/writecapdat.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reeds/input_processing/writecapdat.py b/reeds/input_processing/writecapdat.py index 14aefd9f3..311491337 100644 --- a/reeds/input_processing/writecapdat.py +++ b/reeds/input_processing/writecapdat.py @@ -787,7 +787,7 @@ def main(reeds_path, inputs_case): } comments = { 'pcat': 'prescribed capacity categories', - 'poi_cap_init': '--MW-- initial (pre-2010) capacity of all types', + 'poi_cap_init': '--MW-- initial (pre-startyear) capacity of all types', } return files_out, comments From 2d91c94b7056d12dc432fe7edddd28eda741a3c5 Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Thu, 23 Jul 2026 15:04:48 -0600 Subject: [PATCH 23/28] runfiles.csv: change 'comment' to 'GAMScomment' --- reeds/input_processing/copy_files.py | 6 +++--- reeds/input_processing/runfiles.csv | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/reeds/input_processing/copy_files.py b/reeds/input_processing/copy_files.py index 7e06532a2..c90f5b273 100644 --- a/reeds/input_processing/copy_files.py +++ b/reeds/input_processing/copy_files.py @@ -716,7 +716,7 @@ def write_non_region_file( case=case, gamstype=row.GAMStype.lower(), name=(None if isinstance(row.GAMSname, float) else row.GAMSname), - comment=(row.comment if isinstance(row.comment, str) else ''), + comment=(row.GAMScomment if isinstance(row.GAMScomment, str) else ''), ) else: shutil.copy(row.full_filepath, os.path.join(dir_dst, row.filename)) @@ -918,8 +918,8 @@ def write_region_indexed_file( case=reeds.io.standardize_case(inputs_case), gamstype=region_file_entry.GAMStype.lower(), comment=( - region_file_entry.comment - if isinstance(region_file_entry.comment, str) else '' + region_file_entry.GAMScomment + if isinstance(region_file_entry.GAMScomment, str) else '' ), ) else: diff --git a/reeds/input_processing/runfiles.csv b/reeds/input_processing/runfiles.csv index 36ac25657..4387e603a 100644 --- a/reeds/input_processing/runfiles.csv +++ b/reeds/input_processing/runfiles.csv @@ -1,4 +1,4 @@ -filename,filepath,required_if,aggfunc,disaggfunc,region_col,fix_cols,i_col,wide,header,key,post_copy,GAMStype,GAMSname,comment,notes +filename,filepath,required_if,aggfunc,disaggfunc,region_col,fix_cols,i_col,wide,header,key,post_copy,GAMStype,GAMSname,GAMScomment,notes #,for input files only,"conditions determinining whether or not the file is required (1 if always required, 0 if always optional)",,,,,,1 if any parameters are in wide format,0 if file has column labels,,files are created after copy_files,for auto-imported files,,, i.csv,inputs/sets/i.csv,1,ignore,ignore,,,,,,,1,set,i,generation technologies, ctt.csv,inputs/sets/ctt.csv,1,ignore,ignore,,,,,,,1,set,ctt,cooling technology type, From f3a3530f62f679fc51829d69da5344e589eef4cb Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Thu, 23 Jul 2026 16:16:14 -0600 Subject: [PATCH 24/28] forecast.py: write params read from inputs.h5 back to inputs.h5 --- inputs/userinput/futurefiles.csv | 1 + reeds/input_processing/forecast.py | 11 +++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/inputs/userinput/futurefiles.csv b/inputs/userinput/futurefiles.csv index 2c961ba59..8fe53c304 100644 --- a/inputs/userinput/futurefiles.csv +++ b/inputs/userinput/futurefiles.csv @@ -517,6 +517,7 @@ df_capex_init,inputs.h5,1,,,,9999,,,,,, distance,inputs.h5,1,,,,9999,,,,,, evmc_storage_energy_h17,inputs.h5,1,,,,9999,,,,,, firm_import_limit,inputs.h5,1,,,,9999,,,,,, +gasreg,inputs.h5,1,,,,9999,,,,,, h2_ptc_in,inputs.h5,1,,,,9999,,,,,, h2ptcreg,inputs.h5,1,,,,9999,,,,,, hurdlereg,inputs.h5,1,,,,9999,,,,,, diff --git a/reeds/input_processing/forecast.py b/reeds/input_processing/forecast.py index 7846b62b0..46f39354d 100644 --- a/reeds/input_processing/forecast.py +++ b/reeds/input_processing/forecast.py @@ -227,11 +227,12 @@ def forecast( for col in ['key','fix_cols','header','clip_min','clip_max']: futurefiles[col] = futurefiles[col].fillna('None') ### If any files are missing, stop and alert the user - inputfiles = [ + inputs_files = [ Path(f).stem for f in glob(os.path.join(inputs_case,'*')) if not Path(f).is_dir() ] with h5py.File(Path(inputs_case, 'inputs.h5'), 'r') as f: - inputfiles += list(f) + inputs_h5 = list(f) + inputfiles = inputs_files + inputs_h5 missingfiles = [ f for f in inputfiles if f not in futurefiles.filename.map(lambda x: Path(x).stem).values] if any(missingfiles): @@ -464,8 +465,10 @@ def forecast( dfout.rename(columns=the_unnamer, inplace=True) #%% Write it - if filetype == 'inputs.h5': - reeds.io.write_to_inputs_h5(dfout, filename, inputs_case, gamstype='parameter') + if Path(filename).stem in inputs_h5: + reeds.io.write_to_inputs_h5( + dfout, Path(filename).stem, inputs_case, gamstype='parameter', + ) elif filetype in ['.csv', '.csv.gz']: dfout.round(decimals).to_csv( os.path.join(outpath, filename), From 9065e6813698d30b026fbe3a95afcc2e1b684528 Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Thu, 23 Jul 2026 17:16:30 -0600 Subject: [PATCH 25/28] futurefiles.csv: fill in forecasts for cost_hurdle_rate* and national_gen_frac --- inputs/userinput/futurefiles.csv | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/inputs/userinput/futurefiles.csv b/inputs/userinput/futurefiles.csv index 8fe53c304..2e2254b7a 100644 --- a/inputs/userinput/futurefiles.csv +++ b/inputs/userinput/futurefiles.csv @@ -506,17 +506,16 @@ co2_captured_incentive_in,inputs.h5,1,,,,9999,,,,,, co2_injection_limit,inputs.h5,1,,,,9999,,,,,, co2_storage_limit,inputs.h5,1,,,,9999,,,,,, cost_co2_stor_bec,inputs.h5,1,,,,9999,,,,,, -cost_hurdle_rate1,inputs.h5,1,,,,9999,,,,,, -cost_hurdle_rate2,inputs.h5,1,,,,9999,,,,,, +cost_hurdle_rate1,inputs.h5,0,None,t,None,9999,0,linear_5,0,,, +cost_hurdle_rate2,inputs.h5,0,None,t,None,9999,0,linear_5,0,,, country,inputs.h5,1,,,,9999,,,,,, cs,inputs.h5,1,,,,9999,,,,,, ctt_cc_mult,inputs.h5,1,,,,9999,,,,,, ctt_cost_vom_mult,inputs.h5,1,,,,9999,,,,,, ctt_hr_mult,inputs.h5,1,,,,9999,,,,,, -df_capex_init,inputs.h5,1,,,,9999,,,,,, distance,inputs.h5,1,,,,9999,,,,,, -evmc_storage_energy_h17,inputs.h5,1,,,,9999,,,,,, -firm_import_limit,inputs.h5,1,,,,9999,,,,,, +evmc_storage_energy_h17,inputs.h5,1,,,,9999,,,,,has a t index so revisit if using, +firm_import_limit,inputs.h5,1,,,,9999,,,,,handled in transmission.py, gasreg,inputs.h5,1,,,,9999,,,,,, h2_ptc_in,inputs.h5,1,,,,9999,,,,,, h2ptcreg,inputs.h5,1,,,,9999,,,,,, @@ -527,7 +526,7 @@ interconnect,inputs.h5,1,,,,9999,,,,,, itlgrp,inputs.h5,1,,,,9999,,,,,, maxdailycf_input,inputs.h5,1,,,,9999,,,,,, minCF_input,inputs.h5,1,,,,9999,,,,,, -national_gen_frac,inputs.h5,1,,,,9999,,,,,, +national_gen_frac,inputs.h5,0,None,allt,None,9999,0,linear_5,0,1,, nercr,inputs.h5,1,,,,9999,,,,,, newv,inputs.h5,1,,,,9999,,,,,, nextszn,inputs.h5,1,,,,9999,,,,,, @@ -535,8 +534,8 @@ offshore,inputs.h5,1,,,,9999,,,,,, opres_periods_h17,inputs.h5,1,,,,9999,,,,,, outage_forced_hourly.h5,.h5,1,,,,9999,,,,,, outage_scheduled_hourly.h5,.h5,1,,,,9999,,,,,, -pvf_capital,inputs.h5,1,,,,9999,,,,,, -pvf_onm,inputs.h5,1,,,,9999,,,,,, +pvf_capital,inputs.h5,1,,,,9999,,,,,handled in calc_financial_inputs.py, +pvf_onm,inputs.h5,1,,,,9999,,,,,handled in calc_financial_inputs.py, r,inputs.h5,1,,,,9999,,,,,, r_cs_distance,inputs.h5,1,,,,9999,,,,,, st,inputs.h5,1,,,,9999,,,,,, From f1ba970a3c375bee5eaf58bde73c2a6f485dfd20 Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Fri, 24 Jul 2026 11:49:54 -0600 Subject: [PATCH 26/28] mcs_sampler.py: remove removed overwrite in get_regions_and_agglevel() --- reeds/input_processing/mcs_sampler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reeds/input_processing/mcs_sampler.py b/reeds/input_processing/mcs_sampler.py index 626eb6240..ae9e804ef 100644 --- a/reeds/input_processing/mcs_sampler.py +++ b/reeds/input_processing/mcs_sampler.py @@ -570,7 +570,7 @@ def get_dist_instructions(reeds_path: str, inputs_case: str) -> Tuple[pd.DataFra # Obtain the data used by copy_files.py to filter regions and create tailored dataframes. regions_and_agglevel = copy_files.get_regions_and_agglevel( - reeds_path, inputs_case, save_regions_and_agglevel=False, overwrite=True) + reeds_path, inputs_case, save_regions_and_agglevel=False) source_deflator_map = copy_files.get_source_deflator_map(reeds_path) From 9249534d7f9efc35b6502ed4d3e02451eb9f426d Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Fri, 24 Jul 2026 13:39:16 -0600 Subject: [PATCH 27/28] fix MARICTNYNJPAOH_Offshore: change trancap_fut t index to allt --- reeds/input_processing/transmission.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reeds/input_processing/transmission.py b/reeds/input_processing/transmission.py index 7973a0916..d84c630e8 100644 --- a/reeds/input_processing/transmission.py +++ b/reeds/input_processing/transmission.py @@ -237,7 +237,7 @@ def get_trancap_fut(case): 'trancap_fut_cat': {0:'possible', 1:'certain'} }) [['r', 'rr', 'trancap_fut_cat', 'trtype', 't', 'MW']] - .astype({'t':int}).round(3) + .astype({'t':int}).round(3).rename(columns={'t':'allt'}) ) return trancap_fut @@ -834,7 +834,7 @@ def main(case): case = Path(args.inputs_case).parent # #%% Settings for testing ### - # case = str(Path(reeds.io.reeds_path, 'runs', 'v22060702_inputsM0_github_Everything')) + # case = str(Path(reeds.io.reeds_path, 'runs', 'v20260724_inputsM0_MARICTNYNJPAOH_Offshore')) #%% Set up logger log = reeds.log.makelog(scriptname=__file__, logpath=Path(case, 'gamslog.txt')) From 1a4a711e8369a1cf5813783c184d4686d8423b28 Mon Sep 17 00:00:00 2001 From: Patrick Brown <25125211+patrickbrown4@users.noreply.github.com> Date: Mon, 27 Jul 2026 13:05:34 -0600 Subject: [PATCH 28/28] transmission.py: fix trancap_fut (move t->allt to end) --- reeds/input_processing/transmission.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reeds/input_processing/transmission.py b/reeds/input_processing/transmission.py index c482d5e48..c1a3f4742 100644 --- a/reeds/input_processing/transmission.py +++ b/reeds/input_processing/transmission.py @@ -242,7 +242,7 @@ def get_trancap_fut(case): 'trancap_fut_cat': {0:'possible', 1:'certain'} }) [['r', 'rr', 'trancap_fut_cat', 'trtype', 't', 'MW']] - .astype({'t':int}).round(3).rename(columns={'t':'allt'}) + .astype({'t':int}).round(3) ) ## Move additions between model years to the next modeled year for i, row in trancap_fut.iterrows(): @@ -251,7 +251,7 @@ def get_trancap_fut(case): trancap_fut.loc[i,'t'] = newyear print(f'trancap_fut: Moved {row.values} to {newyear}') - return trancap_fut + return trancap_fut.rename(columns={'t':'allt'}) def get_firm_import_limit(case):