diff --git a/inputs/national_generation/gen_mandate_tech_list.csv b/inputs/national_generation/gen_mandate_tech_list.csv deleted file mode 100644 index f56f0f0d..00000000 --- a/inputs/national_generation/gen_mandate_tech_list.csv +++ /dev/null @@ -1,62 +0,0 @@ -*i,RE,Nuclear,NuclearCCS,RE_NoCombust -can-imports,1,1,1,1 -coal-CCS_mod,0,0,1,0 -coal-CCS_max,0,0,1,0 -coal-CCS-F1,0,0,1,0 -coal-CCS-F2,0,0,1,0 -coal-CCS-F3,0,0,1,0 -Coal-IGCC,0,0,0,0 -coal-new,0,0,0,0 -CoalOldScr,0,0,0,0 -CoalOldUns,0,0,0,0 -CofireNew,0,0,0,0 -CofireOld,0,0,0,0 -Gas-CC,0,0,0,0 -Gas-CC_H_1x1,0,0,0,0 -Gas-CC_H_2x1,0,0,0,0 -Gas-CC-CCS_mod,0,0,1,0 -Gas-CC-CCS_max,0,0,1,0 -Gas-CC_H_1x1-CCS_mod,0,0,1,0 -Gas-CC_H_1x1-CCS_max,0,0,1,0 -Gas-CC_H_2x1-CCS_mod,0,0,1,0 -Gas-CC_H_2x1-CCS_max,0,0,1,0 -Gas-CC-CCS-F1,0,0,1,0 -Gas-CC-CCS-F2,0,0,1,0 -Gas-CC-CCS-F3,0,0,1,0 -Gas-CT,0,0,0,0 -Gas-CT_aero,0,0,0,0 -o-g-s,0,0,0,0 -Nuclear,0,1,1,0 -Nuclear-SMR,0,1,1,0 -H2-CT,1,1,1,0 -H2-CC,1,1,1,0 -ng-fuel-cell,0,0,0,0 -biopower,1,1,1,0 -beccs_mod,1,1,1,0 -beccs_max,1,1,1,0 -geothermal,1,1,1,1 -Hydro,1,1,1,1 -lfill-gas,1,1,1,0 -battery_li,0,0,0,0 -pumped-hydro,0,0,0,0 -pumped-hydro-flex,0,0,0,0 -distpv,1,1,1,1 -upv_1*upv_10,1,1,1,1 -wind-ofs_1*wind-ofs_10,1,1,1,1 -wind-ons_1*wind-ons_10,1,1,1,1 -csp1_1*csp1_12,1,1,1,1 -csp2_1*csp2_12,1,1,1,1 -hydD,1,1,1,1 -hydND,1,1,1,1 -hydSD,1,1,1,1 -hydSND,1,1,1,1 -hydUD,1,1,1,1 -hydUND,1,1,1,1 -hydNPD,1,1,1,1 -hydNPND,1,1,1,1 -hydED,1,1,1,1 -hydEND,1,1,1,1 -egs_allkm_1*egs_allkm_10,1,1,1,1 -geohydro_allkm_1*geohydro_allkm_10,1,1,1,1 -egs_nearfield_1*egs_nearfield_10,1,1,1,1 -dr_shed_1*dr_shed_2,1,1,1,1 diff --git a/inputs/national_generation/nat_gen_tech_frac.csv b/inputs/national_generation/nat_gen_tech_frac.csv new file mode 100644 index 00000000..d7402e91 --- /dev/null +++ b/inputs/national_generation/nat_gen_tech_frac.csv @@ -0,0 +1,139 @@ +*i,RE,Nuclear,NuclearCCS,RE_NoCombust +can-imports,1,1,1,1 +coal-CCS_mod,0,0,1,0 +coal-CCS_max,0,0,1,0 +coal-CCS-F1,0,0,1,0 +coal-CCS-F2,0,0,1,0 +coal-CCS-F3,0,0,1,0 +Coal-IGCC,0,0,0,0 +coal-new,0,0,0,0 +CoalOldScr,0,0,0,0 +CoalOldUns,0,0,0,0 +CofireNew,0,0,0,0 +CofireOld,0,0,0,0 +Gas-CC,0,0,0,0 +Gas-CC_H_1x1,0,0,0,0 +Gas-CC_H_2x1,0,0,0,0 +Gas-CC-CCS_mod,0,0,1,0 +Gas-CC-CCS_max,0,0,1,0 +Gas-CC_H_1x1-CCS_mod,0,0,1,0 +Gas-CC_H_1x1-CCS_max,0,0,1,0 +Gas-CC_H_2x1-CCS_mod,0,0,1,0 +Gas-CC_H_2x1-CCS_max,0,0,1,0 +Gas-CC-CCS-F1,0,0,1,0 +Gas-CC-CCS-F2,0,0,1,0 +Gas-CC-CCS-F3,0,0,1,0 +Gas-CT,0,0,0,0 +Gas-CT_aero,0,0,0,0 +o-g-s,0,0,0,0 +Nuclear,0,1,1,0 +Nuclear-SMR,0,1,1,0 +H2-CT,1,1,1,0 +H2-CC,1,1,1,0 +ng-fuel-cell,0,0,0,0 +biopower,1,1,1,0 +beccs_mod,1,1,1,0 +beccs_max,1,1,1,0 +geothermal,1,1,1,1 +Hydro,1,1,1,1 +lfill-gas,1,1,1,0 +battery_li,0,0,0,0 +pumped-hydro,0,0,0,0 +pumped-hydro-flex,0,0,0,0 +distpv,1,1,1,1 +upv_1,1,1,1,1 +upv_2,1,1,1,1 +upv_3,1,1,1,1 +upv_4,1,1,1,1 +upv_5,1,1,1,1 +upv_6,1,1,1,1 +upv_7,1,1,1,1 +upv_8,1,1,1,1 +upv_9,1,1,1,1 +upv_10,1,1,1,1 +wind-ofs_1,1,1,1,1 +wind-ofs_2,1,1,1,1 +wind-ofs_3,1,1,1,1 +wind-ofs_4,1,1,1,1 +wind-ofs_5,1,1,1,1 +wind-ofs_6,1,1,1,1 +wind-ofs_7,1,1,1,1 +wind-ofs_8,1,1,1,1 +wind-ofs_9,1,1,1,1 +wind-ofs_10,1,1,1,1 +wind-ons_1,1,1,1,1 +wind-ons_2,1,1,1,1 +wind-ons_3,1,1,1,1 +wind-ons_4,1,1,1,1 +wind-ons_5,1,1,1,1 +wind-ons_6,1,1,1,1 +wind-ons_7,1,1,1,1 +wind-ons_8,1,1,1,1 +wind-ons_9,1,1,1,1 +wind-ons_10,1,1,1,1 +csp1_1,1,1,1,1 +csp1_2,1,1,1,1 +csp1_3,1,1,1,1 +csp1_4,1,1,1,1 +csp1_5,1,1,1,1 +csp1_6,1,1,1,1 +csp1_7,1,1,1,1 +csp1_8,1,1,1,1 +csp1_9,1,1,1,1 +csp1_10,1,1,1,1 +csp1_11,1,1,1,1 +csp1_12,1,1,1,1 +csp2_1,1,1,1,1 +csp2_2,1,1,1,1 +csp2_3,1,1,1,1 +csp2_4,1,1,1,1 +csp2_5,1,1,1,1 +csp2_6,1,1,1,1 +csp2_7,1,1,1,1 +csp2_8,1,1,1,1 +csp2_9,1,1,1,1 +csp2_10,1,1,1,1 +csp2_11,1,1,1,1 +csp2_12,1,1,1,1 +egs_allkm_1,1,1,1,1 +egs_allkm_2,1,1,1,1 +egs_allkm_3,1,1,1,1 +egs_allkm_4,1,1,1,1 +egs_allkm_5,1,1,1,1 +egs_allkm_6,1,1,1,1 +egs_allkm_7,1,1,1,1 +egs_allkm_8,1,1,1,1 +egs_allkm_9,1,1,1,1 +egs_allkm_10,1,1,1,1 +geohydro_allkm_1,1,1,1,1 +geohydro_allkm_2,1,1,1,1 +geohydro_allkm_3,1,1,1,1 +geohydro_allkm_4,1,1,1,1 +geohydro_allkm_5,1,1,1,1 +geohydro_allkm_6,1,1,1,1 +geohydro_allkm_7,1,1,1,1 +geohydro_allkm_8,1,1,1,1 +geohydro_allkm_9,1,1,1,1 +geohydro_allkm_10,1,1,1,1 +egs_nearfield_1,1,1,1,1 +egs_nearfield_2,1,1,1,1 +egs_nearfield_3,1,1,1,1 +egs_nearfield_4,1,1,1,1 +egs_nearfield_5,1,1,1,1 +egs_nearfield_6,1,1,1,1 +egs_nearfield_7,1,1,1,1 +egs_nearfield_8,1,1,1,1 +egs_nearfield_9,1,1,1,1 +egs_nearfield_10,1,1,1,1 +dr_shed_1,1,1,1,1 +dr_shed_2,1,1,1,1 +hydD,1,1,1,1 +hydND,1,1,1,1 +hydSD,1,1,1,1 +hydSND,1,1,1,1 +hydUD,1,1,1,1 +hydUND,1,1,1,1 +hydNPD,1,1,1,1 +hydNPND,1,1,1,1 +hydED,1,1,1,1 +hydEND,1,1,1,1 diff --git a/inputs/scalars.csv b/inputs/scalars.csv index 991fed42..bf68a35a 100644 --- a/inputs/scalars.csv +++ b/inputs/scalars.csv @@ -44,6 +44,7 @@ h2_ptc_temporal_match_year,2030,"--year-- year in which the h2 production incent h2_storage_area_threshold,0.01,"--fraction-- fraction of a model region's land area that must overlap with the collective area of H2 storage sites of a given type for the H2 storage type to be considered available in the model region" h2_storage_duration,240,"--hours-- hours of H2 storage capacity associated with a given invesment in H2 storage capacity. Based on relationship in SERA of 10 days storage for a given tons/hour storage inflow (provided by Paige Jadun)." h2_tranloss,0.005,"--fraction-- H2 transmission losses for regional pipeline trade; based on DOE targets at https://www.energy.gov/eere/fuelcells/doe-technical-targets-hydrogen-delivery" +hintage_unit_number,300,"--integer-- Number of hintages to use when numhintage is 'unit' or 'group'" hurdle_rate_floor,0.01,"--2004$/MWh-- lower bound for transmission hurdle rates (used to prevent degeneracy between transmission losses and curtailment)" ilr_dist,1.21,"--MW_dc/MW_ac-- inverter-loading ratio for distpv" ilr_utility,1.34,"--MW_dc/MW_ac-- inverter-loading ratio for UPV and DUPV" @@ -92,4 +93,4 @@ upgrade_inflator,1.72,inflator for 1987 cost values of upgrade costs in the gene years_until_min,1,"--years-- minimum years until generation capacity can be built endogenously" years_until_RPS,1,"--years-- years until state RPS policies start being enforced" years_until_trans_longterm,8,"--years-- years until transmission expansion within Sw_TransInvMaxLongterm is allowed (assuming 8 years for planning + construction based on MISO LRTP 2022 https://www.misoenergy.org/meet-miso/media-center/2022/miso-board-approves-$10.3-in-transmission-projects)" -years_until_trans_nearterm,1,"--years-- years until transmission expansion within Sw_TransInvMaxNearterm is allowed" \ No newline at end of file +years_until_trans_nearterm,1,"--years-- years until transmission expansion within Sw_TransInvMaxNearterm is allowed" diff --git a/inputs/sets/README.md b/inputs/sets/README.md index edfda23e..7384cc99 100644 --- a/inputs/sets/README.md +++ b/inputs/sets/README.md @@ -1,4 +1,48 @@ # Sets -## Notes -* These files can have comment lines but remember to use '*' (for GAMS) instead of '#' -* Don't use * for element expansion + +## Formatting guidelines + +- Primary sets (those that define elements that are not subsets of other sets): + - No header column + - One element per line + - No element-wise comments; each line should contain only the element +- Subsets (groups of elements from other sets, either 1-dimensional or multidimensional): + - Include a header column specifying the relevant primary sets + - The header column should start with a `*` + - Even 1-dimensional subsets should have a header column. + So if the set `food` has elements `[apple, banana, cauliflower]`, the subset `fruit(food)` (specified by `fruit.csv`) has the following lines: + - `*food` + - `apple` + - `banana` +- Don't use * or # for element expansion in GAMS +- Don't use * for full-line comments; only use it for the first (header) row in subset definitions + +## Set-defining files + +- `ctt.csv`: cooling technology types + - `o`: once through + - `r`: recirculating + - `d`: dry cooled + - `p`: pond cooled + - `n`: no cooling (or generic placeholder) +- `sc_cat.csv`: resource supply curve data categories + - `cap`: power capacity available [MW] + - `cost`: total supply curve cost [\$/MW] + - `cost_trans`: transmission (spur, point-of-interconnection, and reinforcement) component of supply curve cost [\$/MW] + - `cost_cap`: economies of scale, land cost, and other modifier components of supply curve cost [\$/MW] +- `wst.csv`: water source type + - `fsu`: fresh surface water that is unappropriated + - `fsa`: fresh surface water that is appropriated + - `fsl`: fresh surface lake + - `fg`: fresh groundwater + - `sg`: brackish or saline groundwater + - `ss`: saline surface water + - `ww`: wastewater effluent + +## Special-case files + +- `_aliases.csv`: aliases (extra names for the same set) used in GAMS + - Aliases of primary sets should be added here + - Aliases of sets defined in `b_inputs.gms` (e.g., `h`→`hh`) should instead be defined in GAMS after the set definition +- `_pcat.csv`: prescribed capacity categories + - The `pcat` set in GAMS (defined in `writecapdat.py`) includes the members of the `i` set; this file includes only the *extra* elements on top of the `i` set diff --git a/inputs/sets/_aliases.csv b/inputs/sets/_aliases.csv new file mode 100644 index 00000000..223ae50a --- /dev/null +++ b/inputs/sets/_aliases.csv @@ -0,0 +1,26 @@ +*parent,alias +allh,allhh +allh,allhhh +allszn,allsznn +allt,alltt +cendiv,cendiv2 +dummy,adummy +fuelbin,afuelbin +gb,gbb +i,ii +i,iii +itlgrp,itlgrpp +nercr,nercrr +pcat,ppcat +r,n +r,nn +r,rr +rscbin,arscbin +st,ast +t,tt +t,ttt +tg,tgg +transgrp,transgrpp +trtype,intype +trtype,outtype +v,vv diff --git a/inputs/sets/_pcat.csv b/inputs/sets/_pcat.csv new file mode 100644 index 00000000..d8a5d237 --- /dev/null +++ b/inputs/sets/_pcat.csv @@ -0,0 +1,8 @@ +upv +pvb +wind-ons +wind-ofs +csp-ws +geohydro_allkm +egs_allkm +egs_nearfield diff --git a/inputs/sets/ctt.csv b/inputs/sets/ctt.csv index b7ab9e4e..e0c031fe 100644 --- a/inputs/sets/ctt.csv +++ b/inputs/sets/ctt.csv @@ -1,5 +1,5 @@ -o "once through", -r "recirculating", -d "dry cooled", -p "pond cooled", -n "no cooling (or generic placeholder)" +o +r +d +p +n diff --git a/inputs/sets/h2_stor.csv b/inputs/sets/h2_stor.csv index 8716b474..f353c7cf 100644 --- a/inputs/sets/h2_stor.csv +++ b/inputs/sets/h2_stor.csv @@ -1,4 +1,4 @@ -*h2_stor +*h2_st h2_storage_saltcavern h2_storage_hardrock h2_storage_undergroundpipe diff --git a/inputs/sets/i.csv b/inputs/sets/i.csv index 8ef1bc17..43f2dd16 100644 --- a/inputs/sets/i.csv +++ b/inputs/sets/i.csv @@ -5,7 +5,6 @@ beccs_max can-imports coal-CCS_mod coal-CCS_max -* flexible CCS technology options that use coal as fuel coal-CCS-F1 coal-CCS-F2 coal-CCS-F3 @@ -26,7 +25,6 @@ Gas-CC_H_1x1-CCS_mod Gas-CC_H_1x1-CCS_max Gas-CC_H_2x1-CCS_mod Gas-CC_H_2x1-CCS_max -* flexible CCS technology options that use natural gas as fuel Gas-CC-CCS-F1 Gas-CC-CCS-F2 Gas-CC-CCS-F3 @@ -215,17 +213,11 @@ egs_nearfield_7 egs_nearfield_8 egs_nearfield_9 egs_nearfield_10 -* consuming technologies -* electrolyzer == h2 production from electricity electrolyzer -* smr = steam methane reforming smr smr_ccs -* dac == direct air capture dac -* dac_gas == direct air capture fueled by natural gas dac_gas -* upgrade technologies Gas-CT_H2-CT Gas-CC_H2-CC CoalOldUns_CoalOldScr @@ -252,4 +244,4 @@ CofireNew_coal-CCS_max CofireOld_coal-CCS_max hydEND_hydED hydED_pumped-hydro -hydED_pumped-hydro-flex \ No newline at end of file +hydED_pumped-hydro-flex diff --git a/inputs/sets/i_h2_ptc_gen.csv b/inputs/sets/i_h2_ptc_gen.csv index 73f7da7d..393ef407 100644 --- a/inputs/sets/i_h2_ptc_gen.csv +++ b/inputs/sets/i_h2_ptc_gen.csv @@ -1,3 +1,4 @@ +*i Gas-CC-CCS_mod Gas-CC-CCS_max Gas-CC_H_1x1-CCS_mod diff --git a/inputs/sets/pcat.csv b/inputs/sets/pcat.csv deleted file mode 100644 index d2696399..00000000 --- a/inputs/sets/pcat.csv +++ /dev/null @@ -1,11 +0,0 @@ -*seldom-used pound/hashtag populates -*elements of this set with the indicated set -#i -upv -pvb -wind-ons -wind-ofs -csp-ws -geohydro_allkm -egs_allkm -egs_nearfield \ No newline at end of file diff --git a/inputs/sets/sc_cat.csv b/inputs/sets/sc_cat.csv index 3395aaeb..d24c99c6 100644 --- a/inputs/sets/sc_cat.csv +++ b/inputs/sets/sc_cat.csv @@ -1,9 +1,4 @@ -* capacity available cap -* total supply curve cost cost -* transmission component of supply curve cost cost_trans -* generation capacity (e.g. economies of scale) component of supply curve cost cost_cap - diff --git a/inputs/sets/wst.csv b/inputs/sets/wst.csv index 10d94b7f..549c1f5a 100644 --- a/inputs/sets/wst.csv +++ b/inputs/sets/wst.csv @@ -1,7 +1,7 @@ -fsu "fresh surface water that is unappropriated (formerly Unappropriated)", -fsa "fresh surface water that is appropriated (formerly Appropriated)", -fsl "fresh surface lake", -fg "fresh groundwater (formerly Potable Groundwater)", -sg "brackish or saline groundwater (formerly Brackish Groundwater)", -ss "saline surface water (new category)", -ww "wastewater effluent (formerly Wastewater)" +fsu +fsa +fsl +fg +sg +ss +ww diff --git a/inputs/sets/sw.csv b/inputs/sets/wst_surface.csv similarity index 100% rename from inputs/sets/sw.csv rename to inputs/sets/wst_surface.csv diff --git a/inputs/userinput/futurefiles.csv b/inputs/userinput/futurefiles.csv index defb65b5..9d30d0d4 100644 --- a/inputs/userinput/futurefiles.csv +++ b/inputs/userinput/futurefiles.csv @@ -163,7 +163,7 @@ gasprice_ref.csv,.csv,0,None,wide,cendiv,1,0,constant,0,None,done,linear_5 gb.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, gbin_min.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, gbin.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, -gen_mandate_tech_list.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, +nat_gen_tech_frac.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, gen_mandate_trajectory.csv,.csv,0,None,*t,None,0,0,constant,None,None,new, geo_discovery_factor.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, geo_discovery_rate.csv,.csv,0,None,*t,None,0,0,linear_5,None,None,new, @@ -233,6 +233,7 @@ i.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, incentives.csv,.csv,0,None,t_start_construction,"i,country",1,0,constant,None,None,[CHECK] do we need to forecast within calc_financial_inputs?; new, inflation.csv,.csv,0,None,t,None,0,0,constant,None,None,done,constant inputs.gdx,.gdx,1,None,9999,None,9999,0,constant,None,None,done (wouldn't exist yet in normal run),constant +inputs.h5,.h5,1,None,9999,None,9999,0,constant,None,None,new, interconnection_queues.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, itc_energy_comm_bonus.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, itc_frac_monetized.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new; handled in calc_financial_inputs.py, @@ -283,7 +284,6 @@ objective_function_params.yaml,.yaml,1,None,9999,None,9999,0,constant,None,None, offshore_goal_fix.csv,.csv,0,None,wide,st,1,0,constant,0,None,done,constant offshore_goal_float.csv,.csv,0,None,wide,st,1,0,constant,0,None,done,constant offshore_req.csv,.csv,0,None,wide,st,1,0,constant,0,None,done,constant -offshore.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, ofstype_i.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, ofstype.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, ofswind_rsc_mult.csv,.csv,0,None,t,None,1,0,constant,0,None,done,linear_5 @@ -433,7 +433,6 @@ supplycurve_geohydro.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, supplycurve_upv.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, supplycurve_wind-ofs.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, supplycurve_wind-ons.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, -sw.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, switches.csv,.csv,1,None,9999,None,9999,0,constant,None,None,done,constant tax_rate.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new; handled in calc_financial_inputs.py, tc_phaseout_schedule.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, @@ -487,23 +486,10 @@ 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_aggreg.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, val_ba.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, -val_cendiv.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, -val_country.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, -val_county.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, +county.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, val_cs.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, -val_h2ptcreg.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, -val_hurdlereg.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, -val_interconnect.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, -val_itlgrp.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, -val_nercr.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, -val_r.csv,.csv,1,None,9999,None,9999,0,constant,None,None,done,constant -val_st.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, -val_transgrp.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, -val_transreg.csv,.csv,1,None,9999,None,9999,0,constant,None,None,new, -val_usda_region.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, wat_access_cap_cost.csv,.csv,1,None,9999,None,9999,0,constant,None,None,done,constant diff --git a/postprocessing/bokehpivot/reeds2.py b/postprocessing/bokehpivot/reeds2.py index 28d3a237..dcb86cfc 100644 --- a/postprocessing/bokehpivot/reeds2.py +++ b/postprocessing/bokehpivot/reeds2.py @@ -99,7 +99,7 @@ def gather_cost_types(df): def pre_systemcost(dfs, **kw): df = dfs['sc'].copy() - sw = dfs['sw'].set_index('switch')['value'].copy() + sw = dfs['switches'].set_index('switch')['value'].copy() scalars = dfs['scalars'].set_index('scalar')['value'].copy() sim_years = sorted(dfs['sc']['year'].unique()) #Years Optimized sys_eval_years = int(sw['sys_eval_years']) @@ -164,7 +164,7 @@ def pre_systemcost(dfs, **kw): ###### Add payments for pre-2010 capacity if ('remove_existing' not in kw) or (kw['remove_existing'] is False): ### Get modeled BAs - val_r = dfs['val_r'][0].values + val_r = dfs['r'].squeeze(1).values ### Get total historical capex in modeled BAs df_capex_init = dfs['df_capex_init'] if 'maintain_ba_index' in kw and kw['maintain_ba_index'] is True: @@ -1135,24 +1135,23 @@ def process_health_damage(df, **kw): rows = product(*allRows.values()) df_all = pd.DataFrame.from_records(rows, columns=allRows.keys()) df_new = df.merge(df_all, how='outer', on=['model', 'cr', 'e', 'rb', 'year']) - df_new['st'] = df_new['st'].interpolate(method="ffill") # sort by category and year df_new = df_new.sort_values(['model', 'cr', 'e', 'rb', 'year']) # interpolate any missing values - df_new = df_new.groupby(['model', 'cr', 'e', 'rb']).apply(lambda group: group.interpolate(method='ffill')) + df_new = df_new.ffill() # sum over rb - df_out = df_new.groupby(['model', 'cr', 'e', 'year'])[ + df_out = df_new.groupby(['model', 'cr', 'e', 'year'])[[ 'Emissions (thousand metric tons)', 'Health damages (billion $)', 'Health damages (lives)', 'Discounted health damages (billion $)' - ].sum().reset_index() + ]].sum().reset_index() # also sum over pollutant - df_poll_agg = df_new.groupby(['model', 'cr', 'year'])[ + df_poll_agg = df_new.groupby(['model', 'cr', 'year'])[[ 'Health damages (billion $)', 'Health damages (lives)', 'Discounted health damages (billion $)' - ].sum().reset_index() + ]].sum().reset_index() df_poll_agg.rename(columns={'Health damages (billion $)' : 'Total health damages (billion $)', 'Health damages (lives)' : 'Total health damages (lives)', @@ -1174,7 +1173,7 @@ def process_social_costs(dfs, **kw): system_costs_agg.rename(columns={'Cost (Bil $)' : 'Cost (Bil $)-system', 'Discounted Cost (Bil $)' : 'Discounted Cost (Bil $)-system'}, inplace=True) - health_costs_agg = health_costs.groupby(['year', 'model', 'cr'])['Health damages (billion $)', 'Discounted health damages (billion $)'].sum().reset_index() + health_costs_agg = health_costs.groupby(['year', 'model', 'cr'])[['Health damages (billion $)', 'Discounted health damages (billion $)']].sum().reset_index() health_costs_agg.rename(columns={'Health damages (billion $)' : 'Cost (Bil $)-health', 'Discounted health damages (billion $)' : 'Discounted Cost (Bil $)-health'}, inplace=True) @@ -2067,7 +2066,7 @@ def pre_spur(dfs, **kw): ('Health Damages from Emissions', {'file':'health_damages_caused_r.csv', - 'columns': ['rb', 'st', 'year', 'e', 'Emissions (thousand metric tons)', 'model', 'cr', 'Marginal damage ($/metric ton)', 'Health damages (billion $)', 'Health damages (lives)'], + 'columns': ['rb', 'year', 'e', 'Emissions (thousand metric tons)', 'model', 'cr', 'Marginal damage ($/metric ton)', 'Health damages (billion $)', 'Health damages (lives)'], 'preprocess': [ {'func': process_health_damage, 'args':{}}, ], @@ -2086,11 +2085,11 @@ def pre_spur(dfs, **kw): {'name': 'sc', 'file': 'systemcost', 'columns': ['cost_cat', 'year', 'Cost (Bil $)']}, {'name': 'q', 'file': 'reqt_quant', 'columns': ['type', 'subtype', 'rb', 'timeslice', 'year', 'q']}, {'name': 'crf', 'file': '../inputs_case/crf.csv', 'columns': ['year', 'crf']}, - {'name': 'val_r', 'file': '../inputs_case/val_r.csv', 'header':None}, + {'name': 'r', 'file': '../inputs_case/val_r.csv', 'header':None}, {'name': 'df_capex_init', 'file': '../inputs_case/df_capex_init.csv'}, - {'name': 'sw', 'file': '../inputs_case/switches.csv', 'header':None, 'columns': ['switch', 'value']}, + {'name': 'switches', 'file': '../inputs_case/switches.csv', 'header':None, 'columns': ['switch', 'value']}, {'name': 'scalars', 'file': '../inputs_case/scalars.csv', 'header':None, 'columns': ['scalar', 'value', 'comment']}, - {'name': 'health_damages', 'file': 'health_damages_caused_r.csv', 'columns': ['rb', 'st', 'year', 'e', 'Emissions (thousand metric tons)', 'model', 'cr', 'Marginal damage ($/metric ton)', 'Health damages (billion $)', 'Health damages (lives)']}, + {'name': 'health_damages', 'file': 'health_damages_caused_r.csv', 'columns': ['rb', 'year', 'e', 'Emissions (thousand metric tons)', 'model', 'cr', 'Marginal damage ($/metric ton)', 'Health damages (billion $)', 'Health damages (lives)']}, ], 'preprocess': [ {'func': process_social_costs, 'args': {}}, @@ -2258,7 +2257,7 @@ def pre_spur(dfs, **kw): {'name': 'sc', 'file': 'systemcost', 'columns': ['cost_cat', 'year', 'Cost (Bil $)']}, {'name': 'pvf_cap', 'file': 'pvf_capital', 'columns': ['year', 'pvfcap']}, {'name': 'pvf_onm', 'file': 'pvf_onm', 'columns': ['year', 'pvfonm']}, - {'name': 'sw', 'file': '../inputs_case/switches.csv', 'header':None, 'columns': ['switch', 'value']}, + {'name': 'switches', 'file': '../inputs_case/switches.csv', 'header':None, 'columns': ['switch', 'value']}, {'name': 'scalars', 'file': '../inputs_case/scalars.csv', 'header':None, 'columns': ['scalar', 'value', 'comment']}, ], 'index': ['cost_cat', 'year'], @@ -2274,7 +2273,7 @@ def pre_spur(dfs, **kw): ('Sys Cost beyond final year (Bil $)', {'sources': [ {'name': 'sc', 'file': 'systemcost_bulk', 'columns': ['cost_cat', 'year', 'Cost (Bil $)']}, - {'name': 'sw', 'file': '../inputs_case/switches.csv', 'header':None, 'columns': ['switch', 'value']}, + {'name': 'switches', 'file': '../inputs_case/switches.csv', 'header':None, 'columns': ['switch', 'value']}, {'name': 'scalars', 'file': '../inputs_case/scalars.csv', 'header':None, 'columns': ['scalar', 'value', 'comment']}, ], 'index': ['cost_cat', 'year'], @@ -2294,9 +2293,9 @@ def pre_spur(dfs, **kw): {'sources': [ {'name': 'sc', 'file': 'systemcost', 'columns': ['cost_cat', 'year', 'Cost (Bil $)']}, {'name': 'crf', 'file': '../inputs_case/crf.csv', 'columns': ['year', 'crf']}, - {'name': 'val_r', 'file': '../inputs_case/val_r.csv', 'header':None}, + {'name': 'r', 'file': '../inputs_case/val_r.csv', 'header':None}, {'name': 'df_capex_init', 'file': '../inputs_case/df_capex_init.csv'}, - {'name': 'sw', 'file': '../inputs_case/switches.csv', 'header':None, 'columns': ['switch', 'value']}, + {'name': 'switches', 'file': '../inputs_case/switches.csv', 'header':None, 'columns': ['switch', 'value']}, {'name': 'scalars', 'file': '../inputs_case/scalars.csv', 'header':None, 'columns': ['scalar', 'value', 'comment']}, ], 'index': ['cost_cat', 'year'], @@ -2318,9 +2317,9 @@ def pre_spur(dfs, **kw): {'sources': [ {'name': 'sc', 'file': 'systemcost_ba', 'columns': ['cost_cat', 'r', 'year', 'Cost (Bil $)']}, {'name': 'crf', 'file': '../inputs_case/crf.csv', 'columns': ['year', 'crf']}, - {'name': 'val_r', 'file': '../inputs_case/val_r.csv', 'header':None}, + {'name': 'r', 'file': '../inputs_case/val_r.csv', 'header':None}, {'name': 'df_capex_init', 'file': '../inputs_case/df_capex_init.csv'}, - {'name': 'sw', 'file': '../inputs_case/switches.csv', 'header':None, 'columns': ['switch', 'value']}, + {'name': 'switches', 'file': '../inputs_case/switches.csv', 'header':None, 'columns': ['switch', 'value']}, {'name': 'scalars', 'file': '../inputs_case/scalars.csv', 'header':None, 'columns': ['scalar', 'value', 'comment']}, ], 'index': ['cost_cat', 'r', 'year'], @@ -2349,9 +2348,9 @@ def pre_spur(dfs, **kw): {'name': 'sc', 'file': 'systemcost', 'columns': ['cost_cat', 'year', 'Cost (Bil $)']}, {'name': 'q', 'file': 'reqt_quant', 'columns': ['type', 'subtype', 'rb', 'timeslice', 'year', 'q']}, {'name': 'crf', 'file': '../inputs_case/crf.csv', 'columns': ['year', 'crf']}, - {'name': 'val_r', 'file': '../inputs_case/val_r.csv', 'header':None}, + {'name': 'r', 'file': '../inputs_case/val_r.csv', 'header':None}, {'name': 'df_capex_init', 'file': '../inputs_case/df_capex_init.csv'}, - {'name': 'sw', 'file': '../inputs_case/switches.csv', 'header':None, 'columns': ['switch', 'value']}, + {'name': 'switches', 'file': '../inputs_case/switches.csv', 'header':None, 'columns': ['switch', 'value']}, {'name': 'scalars', 'file': '../inputs_case/scalars.csv', 'header':None, 'columns': ['scalar', 'value', 'comment']}, ], 'preprocess': [ @@ -2374,9 +2373,9 @@ def pre_spur(dfs, **kw): {'name': 'powerfrac_downstream', 'file': 'powerfrac_downstream', 'columns': ['rr', 'r', 'timeslice', 'year', 'frac']}, {'name': 'powerfrac_upstream', 'file': 'powerfrac_upstream', 'columns': ['r', 'rr', 'timeslice', 'year', 'frac']}, {'name': 'crf', 'file': '../inputs_case/crf.csv', 'columns': ['year', 'crf']}, - {'name': 'val_r', 'file': '../inputs_case/val_r.csv', 'header':None}, + {'name': 'r', 'file': '../inputs_case/val_r.csv', 'header':None}, {'name': 'df_capex_init', 'file': '../inputs_case/df_capex_init.csv'}, - {'name': 'sw', 'file': '../inputs_case/switches.csv', 'header':None, 'columns': ['switch', 'value']}, + {'name': 'switches', 'file': '../inputs_case/switches.csv', 'header':None, 'columns': ['switch', 'value']}, {'name': 'scalars', 'file': '../inputs_case/scalars.csv', 'header':None, 'columns': ['scalar', 'value', 'comment']}, ], 'preprocess': [ @@ -2394,9 +2393,9 @@ def pre_spur(dfs, **kw): {'name': 'sc', 'file': 'systemcost', 'columns': ['cost_cat', 'year', 'Cost (Bil $)']}, {'name': 'emit', 'file': 'emit_nat', 'columns': ['year', 'CO2 (MMton)']}, {'name': 'crf', 'file': '../inputs_case/crf.csv', 'columns': ['year', 'crf']}, - {'name': 'val_r', 'file': '../inputs_case/val_r.csv', 'header':None}, + {'name': 'r', 'file': '../inputs_case/val_r.csv', 'header':None}, {'name': 'df_capex_init', 'file': '../inputs_case/df_capex_init.csv'}, - {'name': 'sw', 'file': '../inputs_case/switches.csv', 'header':None, 'columns': ['switch', 'value']}, + {'name': 'switches', 'file': '../inputs_case/switches.csv', 'header':None, 'columns': ['switch', 'value']}, {'name': 'scalars', 'file': '../inputs_case/scalars.csv', 'header':None, 'columns': ['scalar', 'value', 'comment']}, ], 'preprocess': [ diff --git a/postprocessing/bokehpivot/reeds_bokeh.py b/postprocessing/bokehpivot/reeds_bokeh.py index 105128d2..40f6c69a 100644 --- a/postprocessing/bokehpivot/reeds_bokeh.py +++ b/postprocessing/bokehpivot/reeds_bokeh.py @@ -22,7 +22,7 @@ this_dir_path = os.path.dirname(os.path.realpath(__file__)) sys.path.append(os.path.abspath(os.path.join(this_dir_path,'..','..'))) -from reeds.io import read_output +from reeds.io import read_input, read_output logger = logging.getLogger('') #ReEDS globals @@ -350,10 +350,11 @@ def get_src(scen, src): df_src = pd.DataFrame(data) df_src.columns = src['columns'] elif src['file'].endswith('.csv'): - if 'header' in src and src['header'] == None: - df_src = pd.read_csv(filepath, low_memory=False, header=None) - else: - df_src = pd.read_csv(filepath, low_memory=False) + kwargs = {'header': None} if ('header' in src and src['header'] is None) else {} + try: + df_src = pd.read_csv(filepath, low_memory=False, **kwargs) + except FileNotFoundError: + df_src = read_input(scen['path'], src['name'], low_memory=False, **kwargs) else: df_src = read_output(scen['path'], filepath) if 'transpose' in src and src['transpose'] is True: @@ -619,4 +620,4 @@ def df_to_lowercase(df): for col in df: if df[col].dtype == object: df[col] = df[col].str.lower() - return df \ No newline at end of file + return df diff --git a/postprocessing/hybrid_pvwind_minLCOE.py b/postprocessing/hybrid_pvwind_minLCOE.py index f574ac6a..aa7b1f88 100644 --- a/postprocessing/hybrid_pvwind_minLCOE.py +++ b/postprocessing/hybrid_pvwind_minLCOE.py @@ -304,9 +304,7 @@ def cfcorr(dspv, dswind): sitemap['profile'] = sitemap.i.map(lambda x: x.split('_')[1]) + '|' + sitemap.r sitemap['tech'] = sitemap.i.map(lambda x: x.split('_')[0]) ### Get list of valid regions and subset to those regions -val_r = pd.read_csv( - os.path.join(inp['case'],'inputs_case','val_r.csv') -).columns.values +val_r = reeds.io.read_input(inp['case'], 'r').squeeze(1).values sitemap = sitemap.loc[sitemap.r.isin(val_r)].copy() ### Make lookup and a single-level column version to write out profilemap = sitemap.pivot(columns='tech',index='x',values=['profile','i','r']).dropna() diff --git a/postprocessing/retail_rate_module/calculate_historical_capex.py b/postprocessing/retail_rate_module/calculate_historical_capex.py index 60699eb9..9b8e4df7 100644 --- a/postprocessing/retail_rate_module/calculate_historical_capex.py +++ b/postprocessing/retail_rate_module/calculate_historical_capex.py @@ -33,22 +33,16 @@ def get_historical_units(inputs_case): # Rename techs for consistency with capital cost data from inputs.gdx tech_name_map = { - 'coal-igcc': 'Coal-IGCC', - 'coaloldscr': 'CoalOldScr', - 'coalolduns': 'CoalOldUns', 'csp-ns': 'csp1_1', 'dupv': 'upv_1', - 'gas-cc': 'Gas-CC', - 'gas-ct': 'Gas-CT', 'geohydro_allkm': 'geohydro_allkm_1', - 'hydED': 'hydND', - 'hydEND': 'hydND', - 'nuclear': 'Nuclear', + 'hyded': 'hydnd', + 'hydend': 'hydnd', 'pvb': 'upv_1', 'upv': 'upv_1', 'wind-ons': 'wind-ons_1' } - init_cap['i'] = init_cap['i'].replace(tech_name_map) + init_cap['i'] = init_cap['i'].str.lower().replace(tech_name_map) return init_cap @@ -60,11 +54,13 @@ def get_earliest_cap_costs(inputs_case): 'cost_cap', old_interface=False ) + cost_cap.i = cost_cap.i.str.lower() cost_cap_energy = gdxpds.to_dataframe( os.path.join(inputs_case, 'inputs.gdx'), 'cost_cap_energy', old_interface=False ) + cost_cap_energy.i = cost_cap_energy.i.str.lower() cost_cap = ( pd.concat([cost_cap, cost_cap_energy]) .groupby(['i', 't'], as_index=False) @@ -85,6 +81,7 @@ def get_earliest_cap_costs(inputs_case): 'cost_cap_fin_mult_out', old_interface=False ) + cost_cap_mult.i = cost_cap_mult.i.str.lower() cost_cap_mult['t'] = cost_cap_mult['t'].astype(int) cost_cap_mult = cost_cap_mult.rename( columns={'Value': 'cap_cost_mult_for_ratebase'} @@ -114,6 +111,7 @@ def get_earliest_cap_costs(inputs_case): 'rsc_dat', old_interface=False ) + rsc_dat.i = rsc_dat.i.str.lower() cost_cap_rsc = ( rsc_dat.loc[~rsc_dat.i.isin(cost_cap_earliest['i'])] .pivot_table( diff --git a/postprocessing/single_case_plots.py b/postprocessing/single_case_plots.py index 79a31000..8851b3d4 100644 --- a/postprocessing/single_case_plots.py +++ b/postprocessing/single_case_plots.py @@ -105,8 +105,7 @@ os.path.join(case,'inputs_case','modeledyears.csv') ).columns.astype(int).values yearstep = years[-1] - years[-2] -val_r = pd.read_csv( - os.path.join(case, 'inputs_case', 'val_r.csv'), header=None).squeeze(1).tolist() +val_r = reeds.io.read_input(case, 'r').squeeze(1).tolist() ## If year not provided, use final solve year year = year if year > 0 else max(years) @@ -367,9 +366,7 @@ ### Specify BAs to plot (None = aggregate all together) bas = [None] if int(sw['plot_ba_level']): - bas += pd.read_csv( - os.path.join(case, 'inputs_case', 'val_r.csv'), header=None, - ).squeeze(1).tolist() + bas += reeds.io.read_input(case, 'r').squeeze(1).tolist() savepath_ba = os.path.join(savepath, 'ba') os.makedirs(savepath_ba, exist_ok=True) else: diff --git a/reeds/core/setup/b_inputs.gms b/reeds/core/setup/b_inputs.gms index e2a65430..83a4fd6f 100644 --- a/reeds/core/setup/b_inputs.gms +++ b/reeds/core/setup/b_inputs.gms @@ -14,29 +14,6 @@ $ifthen.unix %system.filesys% == UNIX $setglobal ds / $endif.unix -*need to convert the 'unit' numhintage to some large value -$ifthen.unithintage %numhintage%=="unit" -$eval numhintage 300 -$endif.unithintage - -* Under the Clean Air Act, all coal plants are regulated individually. Therefore, we need a large value of hintages to represent these plants -$include inputs_case%ds%max_hintage_number.txt - -$ifthen.unithintage %GSw_Clean_Air_Act%==1 -$eval numhintage max_hintage_number -$endif.unithintage - -*need to convert the 'group' numhintage to some large value -$ifthen.unithintage %numhintage%=="group" -$eval numhintage 300 -$endif.unithintage - -* there are numeraire hintages on either sides of the outer breaks -* when using calcmethod = 1, here adding two for safety -* NB this will not increase model size given conditions -* dictating valcap and valgen for initial classes -$eval numhintage %numhintage% + 2 - *$ontext * --- print timing profile --- option profile = 3 @@ -53,9 +30,6 @@ option solprint = off ; option sysout = off ; *$offtext -set dummy "set used for initialization of numerical sets" / 0*10000 / ; -alias(dummy,adummy) ; - *====================== * -- Local Switches -- @@ -98,29 +72,6 @@ $include inputs_case%ds%scalars.txt * --- Set Declarations --- *========================== -*## Spatial sets (define first so case stays consistent) -* written by copy_files.py -$onOrder -set r "regions" -/ -$offlisting -$include inputs_case%ds%val_r.csv -$onlisting -/ ; -$offOrder - -$onempty -set offshore(r) "offshore zones" -/ -$offlisting -$include inputs_case%ds%offshore.csv -$onlisting -/ ; -$offempty - -set land(r) "land-based (not offshore) zones" ; -land(r)$[not offshore(r)] = yes ; - * written by copy_files.py $onempty set cs(*) "carbon storage sites" @@ -131,109 +82,16 @@ $onlisting / ; $offempty -* created in and mapped to hierarchy in recf.py -set ccreg "capacity credit regions" -/ -$offlisting -$include inputs_case%ds%ccreg.csv -$onlisting -/ ; - -set eall "emission categories used in reporting" -/ -$offlisting -$include inputs_case%ds%eall.csv -$onlisting -/ ; - -set e(eall) "emission categories used in model" -/ -$offlisting -$include inputs_case%ds%e.csv -$onlisting -/ ; - -set etype "emission types used in model (upstream and process)" -/ -$offlisting -$include inputs_case%ds%etype.csv -$onlisting -/ ; - -Sets -nercr "NERC regions" -* https://www.nerc.com/pa/RAPA/ra/Reliability%20Assessments%20DL/NERC_LTRA_2021.pdf -/ -* written by copy_files.py -$include inputs_case%ds%val_nercr.csv -/ - -transreg "Transmission Planning Regions from FERC order 1000" -* (https://www.ferc.gov/sites/default/files/industries/electric/indus-act/trans-plan/trans-plan-map.pdf) -/ -* written by copy_files.py -$include inputs_case%ds%val_transreg.csv -/, - -transgrp "sub-FERC-1000 regions" -/ -* written by copy_files.py -$include inputs_case%ds%val_transgrp.csv -/, - -itlgrp "ReEDS zones for additional ITL constraints when doing a run that includes county resolution" -/ -* written by copy_files.py -$include inputs_case%ds%val_itlgrp.csv -/, - -cendiv "census divisions" -/ -* written by copy_files.py -$include inputs_case%ds%val_cendiv.csv -/, - -interconnect "interconnection regions" -/ -* written by copy_files.py -$include inputs_case%ds%val_interconnect.csv -/, - -country "country regions" -/ -* written by copy_files.py -$include inputs_case%ds%val_country.csv -/, - -st "US, Mexico, and/or Canadian States/Provinces" -/ -* written by copy_files.py -$include inputs_case%ds%val_st.csv -/, - -* biomass supply curves defined by USDA region -usda_region "Biomass supply curve regions" -/ -* written by copy_files.py -$include inputs_case%ds%val_usda_region.csv -/, - -h2ptcreg "Regions which enforce the H2 production incentive regulations, for the US these are the National Transmission Needs Study regions" -* https://www.energy.gov/sites/default/files/2023-12/National%20Transmission%20Needs%20Study%20Supplemental%20Material%20-%20Final_2023.12.1.pdf -/ -* written by copy_files.py -$include inputs_case%ds%val_h2ptcreg.csv -/ - -* Hurdle rate regions -hurdlereg "Hurdle regions" -/ -$include inputs_case%ds%val_hurdlereg.csv -/ -; +* Written by h5_to_gdx.py +$include autocode%ds%b_declare_sets.gms +$include autocode%ds%b_declare_parameters.gms +$gdxin inputs_case%ds%inputs_0.gdx +$include autocode%ds%b_load_sets.gms +$include autocode%ds%b_load_parameters.gms +$gdxin -* Written by copy_files.py -$include autocode%ds%b_sets.gms +set land(r) "land-based (not offshore) zones" ; +land(r)$[not offshore(r)] = yes ; sets *The following two sets: @@ -299,17 +157,6 @@ $endif.hydup2 ss / ; -alias(i,ii,iii) ; - -set i_water_nocooling(i) "technologies that use water, but are not differentiated by cooling tech and water source" -/ -$offlisting -$ondelim -$include inputs_case%ds%i_water_nocooling.csv -$offdelim -$onlisting -/ ; - set i_water_cooling(i) "derived technologies from original technologies with cooling technologies other than just none", *Hereafter numeraire techs in cooling-water context mean original technologies, *like gas-CC, and non-numeraire techs mean techs that are derived from numeraire techs @@ -390,22 +237,6 @@ $offdelim $onlisting ; -set allt "all potential years" -/ -$offlisting -$include inputs_case%ds%allt.csv -$onlisting -/ ; - -set i_geotech(i,geotech) "crosswalk between an individual geothermal technology and its category" -/ -$offlisting -$ondelim -$include inputs_case%ds%i_geotech.csv -$offdelim -$onlisting -/ ; - set *technology-specific subsets battery(i) "battery storage technologies", @@ -489,65 +320,16 @@ set vre_no_csp(i) "variable renewable energy technologies that are not csp", vre_utility(i) "utility scale wind and PV technologies", vre(i) "variable renewable energy technologies", - wind(i) "wind generation technologies", - -t(allt) "full set of years" /%startyear%*%endyear%/, - -* Each generation technology is broken out by class: -* 1. initial capacity: init-1, init-2, ..., init-n -* 2. prescribed capacity: prescribed -* 3. new capacity: new -* This allows us to distinguish between existing, prescribed, and model-chosen builds -* The number of classes is set by numhintage for initial capacity and numclass for new capacity -v "technology class" - / - init-1*init-%numhintage%, - new1*new%numclass% - /, - -initv(v) "initial technologies" /init-1*init-%numhintage%/, - -newv(v) "new tech set" /new1*new%numclass%/ - + wind(i) "wind generation technologies" ; -* DAC == direct air capture -* H2 == hydrogen -* Note: no longer tracking H2 by color. This means ReEDS internalizes -* emissions for any H2 produced for non-power sector demands -set p "products produced" -/ -$offlisting -$include inputs_case%ds%p.csv -$onlisting -/ ; - - hyd_add_pump('hydED_pumped-hydro') = yes ; hyd_add_pump('hydED_pumped-hydro-flex') = yes ; * Sets involved with resource supply curve definitions -set sc_cat "supply curve categories (capacity and cost)" -/ -$offlisting -$include inputs_case%ds%sc_cat.csv -$onlisting -/ ; - set rscbin "Resource supply curves bins" /bin1*bin%numbins%/, rscfeas(i,r,rscbin) "feasibility set for technologies that have resource supply curves" ; -alias(r,rr,n,nn) ; -alias(v,vv) ; -alias(t,tt,ttt) ; -alias(st,ast) ; -alias(allt,alltt) ; -alias(cendiv,cendiv2) ; -alias(rscbin,arscbin) ; -alias(nercr,nercrr) ; -alias(transgrp,transgrpp) ; -alias(itlgrp,itlgrpp) ; - parameter yeart(t) "numeric value for year", year(allt) "numeric year value for allt" ; @@ -577,16 +359,6 @@ $offdelim $onlisting / ; -*various parameters needed for Present Value Factor (PVF) calculations before solving -*specifically these are used in the aggregating of the PVF of -*onm and capital when years are skipped -set yearafter "set to loop over for the final year calculation" -/ -$offlisting -$include inputs_case%ds%yearafter.csv -$onlisting -/ ; - * --- Upgrade link definitions --- Set upgrade_to(i,ii) "mapping set that allows for i to be upgraded to ii" upgrade_from(i,ii) "mapping set that allows for i to be upgraded from ii" @@ -606,15 +378,6 @@ upgrade(i)$[sum{(ii,iii), upgrade_link(i,ii,iii) }] = yes ; upgrade_to(i,ii)$[sum{iii, upgrade_link(i,iii,ii) }] = yes ; upgrade_from(i,ii)$[sum{iii, upgrade_link(i,ii,iii) }] = yes ; -set unitspec_upgrades(i) "upgraded technologies that get unit-specific characteristics" -/ -$offlisting -$ondelim -$include inputs_case%ds%unitspec_upgrades.csv -$offdelim -$onlisting -/ ; - unitspec_upgrades(i)$[sum{ii$ctt_i_ii(i,ii), unitspec_upgrades(ii) }$Sw_WaterMain] = sum{ii$ctt_i_ii(i,ii), unitspec_upgrades(ii) } ; @@ -873,13 +636,6 @@ $ifthen.naris %GSw_Region% == "naris" ban(i)$i_subsets(i,'canada') = yes ; $endif.naris -* Ban DUPV, CSP, and Geothermal resources that do not remain after aggregation -set resourceclass "renewable resource classes" -/ -$offlisting -$include inputs_case%ds%resourceclass.csv -$onlisting -/ ; 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" @@ -1042,48 +798,9 @@ tg_i('biomass',i)$bio(i) = yes ; tg_i('pumped-hydro',i)$psh(i) = yes ; tg_i('dr_shed',i)$dr_shed(i) = yes ; -*Hybrid pv+battery (PVB) configurations are defined by: -* (1) inverter loading ratio (DC/AC) and -* (2) battery capacity ratio (Battery/PV Array) -*Each configuration has ten resource classes -*The PV portion refers to "UPV", but not "DUPV" -*The battery portion refers to "battery_li" -set pvb_config "set of hybrid pv+battery configurations" -/ -$offlisting -$include inputs_case%ds%pvb_config.csv -$onlisting -/ ; - -set pvb_agg(pvb_config,i) "crosswalk between hybrid pv+battery configurations and technology options" -/ -$offlisting -$ondelim -$include inputs_case%ds%pvb_agg.csv -$offdelim -$onlisting -/ ; - *add non-numeraire CSPs in index i of already defined set tg_i(tg,i) tg_i("csp",i)$[(csp1(i) or csp2(i) or csp3(i) or csp4(i))$Sw_WaterMain] = yes ; -*Offhsore wind turbine types -set ofstype "offshore types used in offshore requirement constraint (eq_RPS_OFSWind)" -/ -$offlisting -$include inputs_case%ds%ofstype.csv -$onlisting -/ ; - -set ofstype_i(ofstype,i) "crosswalk between ofstype and i" -/ -$offlisting -$ondelim -$include inputs_case%ds%ofstype_i.csv -$offdelim -$onlisting -/ ; - storage_interday(i)$(Sw_InterDayLinkage = 0) = no ; $onempty @@ -1176,15 +893,6 @@ $onlisting / ; -set prescriptivelink0(pcat,ii) "initial set of prescribed categories and their technologies - used in assigning prescribed builds" -/ -$offlisting -$ondelim -$include inputs_case%ds%prescriptivelink0.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 prescriptivelink0("csp-ws",ii)$[(csp1(ii) or csp2(ii) or csp3(ii) or csp4(ii))$Sw_WaterMain] = yes ; @@ -1194,8 +902,6 @@ set prescriptivelink(pcat,i) "final set of prescribed categories and their techn prescriptivelink(pcat,i)$prescriptivelink0(pcat,i) = yes ; -alias(pcat,ppcat) ; - * active prescriptivelink for all techs not included in the table above * but restrict out csp techs in this calculation - since they * are indexed by a separate pcat (csp-ws) and have special considerations @@ -1209,15 +915,6 @@ prescriptivelink(pcat,i)$[upgrade(i)] = no ; set rsc_agg(i,ii) "rsc technologies that belong to the same class" ; -set tg_rsc_cspagg(i,ii) "csp technologies that belong to the same class" -/ -$offlisting -$ondelim -$include inputs_case%ds%tg_rsc_cspagg.csv -$offdelim -$onlisting -/ ; - set tg_rsc_cspagg_tmp(i,ii) "expanded tg_rsc_cspagg(i,ii) to include new non-numeraire CSP techs" ; *input parameters for linking set only when Sw_WaterMain is ON and start with a blank slate @@ -1247,15 +944,6 @@ Replicating the construct for CSP to link Hybrid PV+battery and UPV for the reso Because the first index of rsc_agg is only a UPV technology the above constraint will never be generated when "i" is a pvb(i). $offtext -set tg_rsc_upvagg(i,ii) "pv and pvb technologies that belong to the same class" -/ -$offlisting -$ondelim -$include inputs_case%ds%tg_rsc_upvagg.csv -$offdelim -$onlisting -/ ; - *initialize rsc aggregation set for 'i'='ii' *rsc_agg(i,ii)$[sameas(i,ii)$(not csp(i))$(not csp(ii))$rsc_i(i)$rsc_i(ii)] = yes ; rsc_agg(i,ii)$[sameas(i,ii)$rsc_i(i)$rsc_i(ii)] = yes ; @@ -1267,19 +955,8 @@ rsc_agg(i,ii)$tg_rsc_upvagg(i,ii) = yes ; rsc_agg('pumped-hydro',ii)$psh(ii) = yes ; rsc_agg(i,ii)$[ban(i) or ban(ii)] = no ; -*============================ -* -- Demand flexibility setup -- -*============================ - -set flex_type "set of demand flexibility types: daily, previous, next, adjacent" -/ -$offlisting -$include inputs_case%ds%flex_type.csv -$onlisting -/ ; - *====================================== -* --- Begin hierarchy --- +* --- Region hierarchy --- *====================================== set hierarchy(r,nercr,transreg,transgrp,cendiv,st,interconnect,country,usda_region,h2ptcreg,hurdlereg,ccreg) "hierarchy of various regional definitions" @@ -1360,16 +1037,6 @@ tsolved(t) = no ; * Year specification *============================== -* declared over allt to allow for external data files that extend beyond end_year -set tmodel_new(allt) "years to run the model" -/ -$offlisting -$include inputs_case%ds%modeledyears.csv -$onlisting -/ ; - -tmodel_new(allt)$[year(allt) > %endyear%]= no ; - *reset the first and last year indices of the model tfirst(t)$[ord(t) = smin{tt$tmodel_new(tt), ord(tt) }] = yes ; tlast(t)$[ord(t) = smax{tt$tmodel_new(tt), ord(tt) }] = yes ; @@ -1743,13 +1410,6 @@ forced_retire(i,r,t)$[sum{st$r_st(r,st), (yeart(t)>=forced_retirements(i,st))$fo * upgrade tech in forced_retire forced_retire(i,r,t)$[upgrade(i)$(sum{ii$upgrade_to(i,ii), forced_retire(ii,r,t) })] = yes ; -set hintage_char "characteristics available in hintage_data" -/ -$offlisting -$include inputs_case%ds%hintage_char.csv -$onlisting -/ ; - *created by reeds/input_processing/writehintage.py table hintage_data(i,v,r,allt,hintage_char) "table of existing unit characteristics" $offlisting @@ -1765,15 +1425,6 @@ if((not Sw_UpgradeHeatRateAdj), = hintage_data(i,initv,r,t,"wHR") ; ) ; -set upgrade_hintage_char(hintage_char) "sets to operate over in extension of hintage_data characteristics when sw_upgrades = 1" -/ -$offlisting -$ondelim -$include inputs_case%ds%upgrade_hintage_char.csv -$offdelim -$onlisting -/ ; - * need to extend characteristics for years where a tech could still exist if it was upgraded in a previous year * - ie a hintages characteristics would need to persist if it is upgraded and has a lifetime extension if(Sw_Upgrades = 1, @@ -2351,8 +2002,6 @@ m_rscfeas(r,i,"bin1")$[sum{(pcat,t)$[sameas(pcat,i)$tmodel_new(t)], noncumulativ *========================================================== *--- Interconnection queues (Capacity deployment limit) --- *========================================================== -alias(tg,tgg) ; - $onempty table cap_limit(tg,r,allt) "--MW-- capacity deployment limit by region and technology based on interconnection queues" $offlisting @@ -2784,19 +2433,10 @@ h2_ptc_years(t) = tmodel_new(t)$[sum{(i,v,r),h2_ptc(i,v,r,t)}]; * --- Parameters for water constraints --- *========================================== -set sw(wst) "surface water types where access is based on consumption not withdrawal" -/ -$offlisting -$ondelim -$include inputs_case%ds%sw.csv -$offdelim -$onlisting -/ ; - set i_water_surf(i) "subset of technologies that uses surface water", i_w(i,w) "linking set between technology and water use type used in constraining water availability" ; -i_water_surf(i)$[sum{(sw,ctt,ii)$i_ii_ctt_wst(i,ii,ctt,sw), 1}] = yes ; +i_water_surf(i)$[sum{(wst_surface,ctt,ii)$i_ii_ctt_wst(i,ii,ctt,wst_surface), 1}] = yes ; i_w(i,"cons")$[i_water(i)$i_water_surf(i)] = yes ; i_w(i,"with")$[i_water(i)$(not i_water_surf(i))] = yes ; @@ -2891,13 +2531,6 @@ $onlisting / ; $offempty -set climate_param "parameters defined in climate_heuristics_finalyear" -/ -$offlisting -$include inputs_case%ds%climate_param.csv -$onlisting -/ ; - parameter climate_heuristics_finalyear(climate_param) "--fraction-- climate heuristic adjustment in final year" $onempty / @@ -2920,13 +2553,6 @@ hydro_capcredit_delta(i,t)$hydro_d(i) = * --- RPS data --- *==================================== -set RPSCat "RPS constraint categories, including clean energy standards" -/ -$offlisting -$include inputs_case%ds%RPSCat.csv -$onlisting -/ ; - set RPSCat_i(RPSCat,i,st) "mapping between rps category and technologies for each state", RecMap(i,RPSCat,st,ast,t) "Mapping set for technologies to RPS categories and indicates if credits can be sent from st to ast", RecStates(RPSCat,st,t) "states that can generate RECS for their own or other states' requirements", @@ -3221,23 +2847,6 @@ REC_unbundled_limit("CES",st,t) = CES_unbundled_limit_in(st,t) ; st_unbundled_limit(RPSCat,st)$sum{t, REC_unbundled_limit(RPSCat,st,t) } = yes ; -parameter national_gen_frac(allt) "--%-- national fraction of load + losses that must be met by RE" -/ -$offlisting -$ondelim -$include inputs_case%ds%gen_mandate_trajectory.csv -$offdelim -$onlisting -/ ; - -parameter nat_gen_tech_frac(i) "--fraction-- fraction of each tech generation that may be counted toward eq_national_gen" -/ -$offlisting -$ondelim -$include inputs_case%ds%gen_mandate_tech_list.csv -$offdelim -$onlisting -/ ; nat_gen_tech_frac(i)$[i_water_cooling(i)$Sw_WaterMain] = sum{ii$ctt_i_ii(i,ii), nat_gen_tech_frac(ii) } ; *==================== @@ -3246,21 +2855,7 @@ nat_gen_tech_frac(i)$[i_water_cooling(i)$Sw_WaterMain] = sum{ii$ctt_i_ii(i,ii), * a CSAPR budget indicates the cap for trading whereas * assurance indicates the maximum amount a state can emit regardless of trading -set csapr_cat "CSAPR regulation categories" -/ -$offlisting -$include inputs_case%ds%csapr_cat.csv -$onlisting -/ ; - *trading rules dictate there are two groups of states that can trade with each other -set csapr_group "CSAPR trading group" -/ -$offlisting -$include inputs_case%ds%csapr_group.csv -$onlisting -/ ; - $onempty table csapr_cap(st,csapr_cat,allt) "--metric tons-- maximum amount of NOX emissions during the ozone season (May-September)" $offlisting @@ -3309,55 +2904,12 @@ parameter quarter_weight_csapr(quarter) "quarter weights for CSAPR ozone season *============================== * --- transmission sets --- -set trtype "transmission capacity type" -/ -$offlisting -$include inputs_case%ds%trtype.csv -$onlisting -/ ; - -set aclike(trtype) "AC transmission capacity types" -/ -$offlisting -$ondelim -$include inputs_case%ds%aclike.csv -$offdelim -$onlisting -/ ; - -set notvsc(trtype) "transmission capacity types that are not VSC" -/ -$offlisting -$ondelim -$include inputs_case%ds%notvsc.csv -$offdelim -$onlisting -/ ; - -set lcclike(trtype) "transmission capacity types where lines are bundled with AC/DC converters" -/ -$offlisting -$ondelim -$include inputs_case%ds%lcclike.csv -$offdelim -$onlisting -/ ; - -set trancap_fut_cat "categories of near-term transmission projects that describe the likelihood of being completed" -/ -$offlisting -$include inputs_case%ds%trancap_fut_cat.csv -$onlisting -/ ; - set routes(r,rr,trtype,t) "final conditional on transmission feasibility" routes_inv(r,rr,trtype,t) "routes where new transmission investment is allowed" routes_prm(r,rr) "routes where PRM trading is allowed" opres_routes(r,rr,t) "final conditional on operating reserve flow feasibility" ; -alias(trtype,intype,outtype) ; - * Specify the transmission types that are limited by Sw_TransCapMax and Sw_TransCapMaxTotal set trtypemax(trtype) "trtypes to limit" ; trtypemax(trtype)$[(Sw_TransCapMaxTypes=0)] = no ; @@ -3772,22 +3324,6 @@ trans_inv_max(t)$[ *============================ *Note - NG supply curve has its own section -set f "fuel types" -/ -$offlisting -$include inputs_case%ds%f.csv -$onlisting -/ ; - -set fuel2tech(f,i) "mapping between fuel types and generations" -/ -$offlisting -$ondelim -$include inputs_case%ds%fuel2tech.csv -$offdelim -$onlisting -/ ; - *double check in case any sets have been changed. fuel2tech("coal",i)$coal(i) = yes ; fuel2tech("naturalgas",i)$gas(i) = yes ; @@ -3800,13 +3336,6 @@ fuel2tech(f,i)$upgrade(i) = sum{ii$upgrade_to(i,ii), fuel2tech(f,ii) } ; * Generator Characteristics *=============================== -set plantcat "categories for plant characteristics" -/ -$offlisting -$include inputs_case%ds%plantcat.csv -$onlisting -/ ; - * declared over allt to allow for external data files that extend beyond end_year parameter plant_char0(i,allt,plantcat) "--units vary-- input plant characteristics" / @@ -3937,13 +3466,6 @@ plant_char0(i,t,"fom")$smr(i) = deflator("2018") * consume_char0(i,t,"fom") / plant_char0("electrolyzer",t,"capcost") = deflator("2022") * consume_char0("electrolyzer",t,"cost_cap") * 1000 ; plant_char0("electrolyzer",t,"fom") = deflator("2022") * consume_char0("electrolyzer",t,"fom") * 1000 ; -set consumecat "categories for consuming facility characteristics" -/ -$offlisting -$include inputs_case%ds%consumecat.csv -$onlisting -/ ; - * capcost - $/(metric ton CO2/hr) * fom - $/(metric ton CO2/hr)/yr * vom - $/metric ton CO2 @@ -4007,15 +3529,6 @@ plant_char(i,v,t,plantcat) = plant_char0(i,t,plantcat) ; * -- Consuming Technologies costs and demands -- -set i_p(i,p) "mapping from technologies to the products they produce" -/ -$offlisting -$ondelim -$include inputs_case%ds%i_p.csv -$offdelim -$onlisting -/ ; - * see note from earlier... converting from MT / MWh from kg / kWh does not require adjustment.. * but we still need to convert from MWh / MT to MT / MWh <- could choose either units * just need to make sure we change signs throughout @@ -4039,22 +3552,6 @@ h2_combustion_intensity = (1/h2_energy_intensity) * (1/lb_per_tonne) * 1e6 ; * -- H2 Transport network -- -set h2_st "defines investments needed to store and transport H2" -/ -$offlisting -$include inputs_case%ds%h2_st.csv -$onlisting -/ ; - -set h2_stor(h2_st) "H2 storage options" -/ -$offlisting -$ondelim -$include inputs_case%ds%h2_stor.csv -$offdelim -$onlisting -/ ; - * Units for H2 transport and storage * See ReEDS_2.0_Input_Processing for formatting *Pipelines @@ -4171,13 +3668,6 @@ h2_network_load(h2_st,allt) = h2_cost_inputs(h2_st,allt,"electric_load") ; * --- Flexible CCS Parameters --- *================================== -set ccsflex_cat "flexible ccs performance parameter categories" -/ -$offlisting -$include inputs_case%ds%ccsflex_cat.csv -$onlisting -/ ; - table ccsflex_perf(i,ccsflex_cat) "--varies-- flexible ccs performance characteristics" $offlisting $ondelim @@ -4552,13 +4042,6 @@ heat_rate(i,v,r,t)$[valcap(i,v,r,t)$sum{allt$att(allt,t), binned_heatrates(i,v,r sum{allt$att(allt,t), binned_heatrates(i,v,r,allt) } / 1000 ; -set prepost "set defining pre-2010 values versus post-2010 values" -/ -$offlisting -$include inputs_case%ds%prepost.csv -$onlisting -/ ; - *part load heatrate adjust based on historical EIA generation and fuel use data *this reflects the indescrepancy from the partial-loaded heat rate *and the fully-loaded heat rate @@ -4720,22 +4203,8 @@ cf_adj_t(i,newv,t)$[(pv(i) or pvb(i))$countnc(i,newv)$sum{r, valcap(i,newv,r,t) * --- OPERATING RESERVES --- *======================================== -set ortype "types of operating reserve constraints" -/ -$offlisting -$include inputs_case%ds%ortype.csv -$onlisting -/ ; - set opres_model(ortype) "operating reserve types modeled" ; -set orcat "operating reserve category for RHS calculations" -/ -$offlisting -$include inputs_case%ds%orcat.csv -$onlisting -/ ; - * define elements in opres_model based on sw_opres opres_model(ortype)$[not Sw_Opres] = no ; opres_model(ortype)$[(Sw_Opres = 1)$(not sameas(ortype,"combo"))] = yes ; @@ -5288,14 +4757,6 @@ emit_rate("process",e,i,v,r,t) * set upgraded H2 tech emissions emit_rate("process","H2",i,v,r,t)$[upgrade(i)] = sum{ii$upgrade_to(i,ii), emit_rate("process","H2",ii,v,r,t) } ; -* Global warming potential of different pollutants -parameter gwp(e) "--metric ton CO2-equivalents --global warming potential" -/ -$ondelim -$include inputs_case%ds%gwp.csv -$offdelim -/ ; - * CO2(e) emissions rate (used in postprocessing only) emit_rate(etype,"CO2e",i,v,r,t)$[Sw_AnnualCap=2] = round(sum{e, emit_rate(etype,e,i,v,r,t) * gwp(e)$[(not sameas(e, "H2"))]},10) ; @@ -5331,13 +4792,6 @@ emit_rate_limit(e,r,t) = 0 ; * Growth limits and penalties *============================ -set gbin "growth bins" -/ -$offlisting -$include inputs_case%ds%gbin.csv -$onlisting -/ ; - *absolute growth penalties based on greatest annual change of capacity for each tech group from 1990-2016 parameter growth_limit_absolute(tg) "--MW-- growth limit for technology groups in absolute terms" / @@ -5389,15 +4843,6 @@ cost_growth(i,st,t) = 0 ; * --- CES Gas supply curve setup --- *==================================== -set gb "gas price bin must be an odd number of bins, e.g. gb1*gb15" -/ -$offlisting -$include inputs_case%ds%gb.csv -$onlisting -/ ; - -alias(gb,gbb) ; - * gassupply scale determines how far the bins reference quantity should deviate from its reference price * with gassupply scale = -0.5, the center of the reference price bin will be the reference quantity * with gassupplyscale = 0, the end of the reference gas price's bin will the limit for that reference bin @@ -5576,15 +5021,6 @@ ng_crf_penalty_nat(i,t)$[gas(i)$ccs(i)$sum{r, valcap_irt(i,r,t) }] = 1 ; * --- Regional Gas supply curve --- *=========================================== -set fuelbin "gas usage bracket" -/ -$offlisting -$include inputs_case%ds%fuelbin.csv -$onlisting -/ ; - -alias(fuelbin,afuelbin) ; - Scalar numfuelbins "number of fuel bins", normfuelbinwidth "typical fuel bin width", botfuelbinwidth "bottom fuel bin width" @@ -6063,14 +5499,6 @@ if((not Sw_UpgradeDerate), * --- BIOMASS SUPPLY CURVES --- *============================== -* supply curves defined by 21 price increments -set bioclass -/ -$offlisting -$include inputs_case%ds%bioclass.csv -$onlisting -/ ; - set biofeas(r) "regions with biomass supply and biopower"; * supply curve derived from 2016 ORNL Billion Ton study @@ -6137,15 +5565,6 @@ yearweight(t) = 0 ; yearweight(t)$tmodel_new(t) = sum{tt$tprev(tt,t), yeart(tt) } - yeart(t) ; yearweight(t)$tlast(t) = 1 + smax{yearafter, yearafter.val } ; -* declared over allt to allow for external data files that extend beyond end_year -parameter co2_cap(allt) "--metric tons-- CO2 emissions cap used when Sw_AnnualCap is on" -/ -$offlisting -$ondelim -$include inputs_case%ds%co2_cap.csv -$offdelim -$onlisting -/ ; if(Sw_AnnualCap = 1, emit_cap("CO2",t) = co2_cap(t) ; ) ; @@ -6154,16 +5573,6 @@ if(Sw_AnnualCap > 1, emit_cap("CO2e",t) = co2_cap(t) ; ) ; -parameter co2_tax(allt) "--$/metric ton-- CO2 tax used when Sw_CarbTax is on" -/ -$offlisting -$ondelim -$include inputs_case%ds%co2_tax.csv -$offdelim -$onlisting -/ ; - - * set the carbon tax based on switch arguments if(Sw_CarbTax = 1, emit_tax("CO2",r,t) = co2_tax(t) ; @@ -6215,15 +5624,6 @@ emit_capped(e)$[gwp(e)$(Sw_AnnualCap=3)] = yes ; set valret(i,v) "technologies and classes that can be retired" ; -set noretire(i) "technologies that will never be retired" -/ -$offlisting -$ondelim -$include inputs_case%ds%noretire.csv -$offdelim -$onlisting -/ ; - * storage technologies are not appropriately attributing capacity value to CAP variable * therefore not allowing them to endogenously retire noretire(i)$[(storage_standalone(i) or hyd_add_pump(i))] = yes ; @@ -6601,21 +6001,6 @@ z_rep_op(t) = 0 ; *== h- and szn-dependent sets and parameters (declared here, populated in 2_temporal_params) === *================================================================================================ -* allh and allszn need to be populated here so they can be used in c_model and d_objective -Set allh "all potentially modeled hours" -/ -$offlisting -$include inputs_case%ds%set_allh.csv -$onlisting -/ ; - -Set allszn "all potentially modeled seasons (used as representative days/weks for hourly resolution)" -/ -$offlisting -$include inputs_case%ds%set_allszn.csv -$onlisting -/ ; - Set * Timeslices h(allh) "representative and stress timeslices" @@ -6660,6 +6045,10 @@ Set hour_szn_group(allh,allh) "h and hh in the same season - used in minloading constraint" ; +alias(h,hh,hhh) ; +alias(szn,sznn) ; +alias(actualszn,actualsznn,actualsznnn) ; + Parameter * Hour/period weighting hours(allh) "--hours-- number of hours in each time block" @@ -6744,12 +6133,6 @@ Parameter szn_adj_gas(allh) "--fraction-- seasonal adjustment for gas prices" ; -alias(allh,allhh,allhhh) ; -alias(h,hh,hhh) ; -alias(allszn,allsznn) ; -alias(actualszn,actualsznn,actualsznnn) ; -alias(szn,sznn) ; - * Initialize some parameters sdbin_size(ccreg,ccseason,sdbin,"%startyear%") = 1000 ; cc_int(i,v,r,ccseason,t) = 0 ; diff --git a/reeds/core/setup/e_solveprep.gms b/reeds/core/setup/e_solveprep.gms index 1d30682b..ba54eaf1 100644 --- a/reeds/core/setup/e_solveprep.gms +++ b/reeds/core/setup/e_solveprep.gms @@ -197,7 +197,6 @@ cc_old(i,r,ccseason,t) = 0 ; *following sets are needed for linear interpolation of price *that determine the year before the non-solved year and the year after set t_before, t_after ; -alias(t,ttt) ; t_before(t,tt)$[tprev(t,tt)$(ord(tt) = smax{ttt, ord(ttt)$tprev(t,ttt) })] = yes ; t_after(t,tt)$tprev(tt,t) = yes ; diff --git a/reeds/input_processing/WriteHintage.py b/reeds/input_processing/WriteHintage.py index b193e8d4..755993d1 100644 --- a/reeds/input_processing/WriteHintage.py +++ b/reeds/input_processing/WriteHintage.py @@ -467,12 +467,6 @@ def main(reeds_path, inputs_case): tdat = pd.concat([tdat_non_coal, tdat_coal], ignore_index=True, axis=0) - # calculate the maximum hintage number, to be used in b_inputs.gms, and export it - max_hintage_number = tdat['bin'].max() - max_hintage_number_text = f'scalar max_hintage_number "--number-- the maximum number of bins used in this ReEDS run" /{max_hintage_number}/ ;' - with open(os.path.join(inputs_case,'max_hintage_number.txt'), 'w') as file: - file.write(f'{max_hintage_number_text}') - # calculate the capacity-weighted average heat rate for each bin # by taking the product of the sum of the capacity and the centroid of the bin tdat['wHR'] = tdat.HR * tdat['Summer.capacity'] @@ -600,7 +594,48 @@ def main(reeds_path, inputs_case): zout.wCCS_Retro_HR = zout.wCCS_Retro_HR.round(decimals=1) zout.wCCS_Retro_CapAdjust = zout.wCCS_Retro_CapAdjust.round(decimals=3) zout.wCCS_Retro_LocFactor = zout.wCCS_Retro_LocFactor.round(decimals=3) - + + #%% Get vintages + # Each generation technology is broken out by class: + # 1. initial capacity: init-1, init-2, ..., init-n + # 2. prescribed capacity: prescribed + # 3. new capacity: new + # This allows us to distinguish between existing, prescribed, and model-chosen builds + # The number of classes is set by numhintage for initial capacity and numclass for new capacity + # Under the Clean Air Act, all coal plants are regulated individually. + # Therefore, we need a large value of hintages to represent these plants + scalars = reeds.io.get_scalars(inputs_case) + max_hintage_number = tdat['bin'].max() + if sw.numhintage in ['unit', 'group']: + numhintage = int(scalars.hintage_unit_number) + else: + if int(sw.GSw_Clean_Air_Act) == 1: + numhintage = max_hintage_number + else: + numhintage = int(sw.numhintage) + # there are numeraire hintages on either sides of the outer breaks + # when using calcmethod = 1, here adding two for safety + # NB this will not increase model size given conditions + # dictating valcap and valgen for initial classes + numhintage += 2 + + initv = [f'init-{i}' for i in range(1, numhintage+1)] + newv = [f'new{i}' for i in range(1, int(sw.numclass)+1)] + v = initv + newv + + reeds.io.write_to_inputs_h5( + pd.Series(v), 'v', inputs_case, gamstype='set', + comment='technology class', + ) + for (name, ds, comment) in [ + ('initv', initv, 'initial technologies'), + ('newv', newv, 'new technologies'), + ]: + reeds.io.write_to_inputs_h5( + pd.Series(ds, name='v'), name, inputs_case, gamstype='set', + comment=comment, + ) + #%% Save output dataframe in inputs_case folder cols = ['TECH', 'bin', 'r', 'yr', 'cap', 'wintercap', 'wHR', 'wFOM', 'wVOM', 'wOnlineYear', diff --git a/reeds/input_processing/copy_files.py b/reeds/input_processing/copy_files.py index 55a60880..0d874903 100644 --- a/reeds/input_processing/copy_files.py +++ b/reeds/input_processing/copy_files.py @@ -181,6 +181,7 @@ 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. @@ -308,7 +309,7 @@ def get_regions_and_agglevel( # Write out val_county and val_ba before collapsing to unique regions hier_sub['county'].dropna().to_csv( - os.path.join(inputs_case, 'val_county.csv'), header=False, index=False) + os.path.join(inputs_case, 'county.csv'), header=False, index=False) hier_sub['ba'].drop_duplicates().to_csv( os.path.join(inputs_case, 'val_ba.csv'), header=False, index=False) @@ -355,9 +356,12 @@ def get_regions_and_agglevel( hier_sub[['r','itlgrp']].rename(columns={'r':'*r'}).to_csv( os.path.join(inputs_case, 'hierarchy_itlgrp.csv'), index=False) - # save the itlgrp values - hier_sub[['itlgrp']].drop_duplicates().to_csv( - os.path.join(inputs_case, 'val_itlgrp.csv'), header=False, index=False) + itlgrp = hier_sub['itlgrp'].drop_duplicates().rename() + 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 hier_sub = hier_sub.drop(['county', 'ba', 'itlgrp'], axis=1) @@ -369,13 +373,31 @@ def get_regions_and_agglevel( # Write out the unique values of each column in hier_sub to val_[column name].csv # Note the conversion to a pd Series is necessary to leverage the to_csv function if save_regions_and_agglevel: - for i in hier_sub.columns.drop('offshore', errors='ignore'): - pd.Series(hier_sub[i].unique()).to_csv( - os.path.join(inputs_case,'val_' + i + '.csv'),index=False,header=False) + comments = { + 'aggreg': 'aggregated region', + 'cendiv': 'census division', + 'country': 'nation', + 'h2ptcreg': 'H2 production tax credit region', + 'hurdlereg': 'hurdle rate region (for extra costs on interregional flows)', + 'interconnect': 'synchronous interconnection', + 'nercr': 'NERC region', + 'transgrp': 'sub-FERC-1000 region', + 'transreg': 'Transmission Planning Regions from FERC Order 1000', + 'usda_region': 'biomass supply curve region', + } + for level, comment in comments.items(): + df = pd.Series(hier_sub[level].unique()) + reeds.io.write_to_inputs_h5( + df, level, inputs_case, gamstype='set', comment=comment, + overwrite=overwrite, + ) - # Overwrite val_st with the val_st used here (which includes 'voluntary') - pd.Series(val_st).to_csv( - os.path.join(inputs_case, 'val_st.csv'), header=False, index=False) + # 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 ( @@ -385,8 +407,10 @@ def get_regions_and_agglevel( ).to_csv(os.path.join(inputs_case, 'hierarchy.csv'), index=False) # Write offshore zones - hier_sub.loc[hier_sub.offshore == 1, 'r'].to_csv( - os.path.join(inputs_case, 'offshore.csv'), index=False, header=False, + 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'] @@ -396,8 +420,10 @@ def get_regions_and_agglevel( # Export region files if save_regions_and_agglevel: - pd.Series(val_r).to_csv( - os.path.join(inputs_case, 'val_r.csv'), header=False, index=False) + reeds.io.write_to_inputs_h5( + pd.Series(val_r), 'r', inputs_case, gamstype='set', + comment='regions', overwrite=overwrite, + ) regions_and_agglevel = { "valid_regions": valid_regions, @@ -907,59 +933,38 @@ def write_scalars(scalars, inputs_case): scalar_csv_to_txt(os.path.join(inputs_case,'scalars.csv')) -def write_GAMS_sets(runfiles, reeds_path, inputs_case): - """ - Write GAMS-readable sets to the inputs_case directory - """ - casedir = os.path.dirname(inputs_case) - - # Create Sets folder - shutil.copytree( - os.path.join(reeds_path,'inputs','sets'), - os.path.join(inputs_case,'sets'), - dirs_exist_ok=True, - ignore=shutil.ignore_patterns('README*','readme*'), - ) - - # Write commands to load sets - sets = runfiles.loc[runfiles.GAMStype=='set'].copy() - settext = '$offlisting\n' + '\n\n'.join([ - f"set {row.GAMSname} '{row.comment:.255}'" - '\n/' - f"\n$include inputs_case%ds%{row.filename}" - '\n/ ;' - for i, row in sets.iterrows() - ]) + '\n$onlisting\n' - # Write to file - with open(os.path.join(casedir, 'autocode', 'b_sets.gms'), 'w') as f: - f.write(settext) - - -def write_non_region_file(filename, filepath, src_file, dir_dst, sw, regions_and_agglevel, source_deflator_map): +def write_non_region_file( + row, + case, + dir_dst, + sw, + regions_and_agglevel, + source_deflator_map, +): """ Copy a non-region specific file (filename) from src_file to dir_dst """ # Check if source file exists and is not rev_paths.csv - if (os.path.exists(src_file)) and (filename!='rev_paths.csv'): + if (os.path.exists(row.full_filepath)) and (row.filename != 'rev_paths.csv'): # Special Case: Values in load_multiplier.csv need to be rounded prior to copy - if filename == 'load_multiplier.csv': - df_load_multiplier = pd.read_csv(src_file).round(6) + if row.filename == 'load_multiplier.csv': + df_load_multiplier = pd.read_csv(row.full_filepath).round(6) df_load_multiplier.to_csv(os.path.join(dir_dst,'load_multiplier.csv'),index=False) - elif filename == 'h2_exogenous_demand.csv': + elif row.filename == 'h2_exogenous_demand.csv': # h2_exogenous_demand.csv has a path in runfiles.csv (considered a non-region file) - df=pd.read_csv(src_file,index_col=['p','t']) + df=pd.read_csv(row.full_filepath, index_col=['p','t']) df[sw['GSw_H2_Demand_Case']].round(3).rename_axis(['*p','t']).to_csv( os.path.join(dir_dst,'h2_exogenous_demand.csv') ) - elif filename in ['energy_communities.csv', 'nuclear_energy_communities.csv']: + elif row.filename in ['energy_communities.csv', 'nuclear_energy_communities.csv']: # Map energy communities to regions and compute the percentage of energy communities # within each region to assign a weighted bonus. # Rename column in energy_communities.csv and map county to r, save as energy_communities.csv - energy_communities = pd.read_csv(src_file) + energy_communities = pd.read_csv(row.full_filepath) energy_communities.rename(columns={'County Region': 'county'}, inplace=True) r_county = regions_and_agglevel ['r_county'] @@ -978,18 +983,27 @@ def write_non_region_file(filename, filepath, src_file, dir_dst, sw, regions_and # Rename columns from ['r','county'] to ['r','percentage_energy_communities'] e_df.columns = ['r', 'percentage_energy_communities'] - e_df.to_csv(os.path.join(dir_dst,filename),index=False) + e_df.to_csv(os.path.join(dir_dst, row.filename),index=False) - elif filename == 'co2_site_char.csv': + elif row.filename == 'co2_site_char.csv': # Adjust for inflation - df = pd.read_csv(src_file) - df[f"bec_{sw['GSw_CO2_BEC']}"] *= source_deflator_map[filepath] + 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: - shutil.copy(src_file, os.path.join(dir_dst,filename)) + if str(row.GAMStype).lower() == 'set': + reeds.io.write_csv_to_inputs_h5( + filepath=row.full_filepath, + case=case, + gamstype=row.GAMStype.lower(), + comment=(row.comment if isinstance(row.comment, str) else ''), + overwrite=True, + ) + else: + shutil.copy(row.full_filepath, os.path.join(dir_dst, row.filename)) - if filename == 'scalars.csv': + if row.filename == 'scalars.csv': # Rewrite scalars.csv as GAMS-readable definition scalars = reeds.io.get_scalars(full=True) write_scalars(scalars, dir_dst) @@ -1000,7 +1014,7 @@ def write_non_region_files(non_region_files, sw, inputs_case, regions_and_agglev Copy non-region specific files to the input case directory. """ print('Copying non-region-indexed files') - + case = reeds.io.standardize_case(inputs_case) for _, row in non_region_files.iterrows(): if row['filepath'].split('/')[0] in ['inputs','postprocessing','tests']: dir_dst = inputs_case @@ -1014,10 +1028,14 @@ def write_non_region_files(non_region_files, sw, inputs_case, regions_and_agglev write_empty_file(os.path.join(dir_dst,row['filename'])) else: print(f'...copying {row.filename}') - filename = row['filename'] - filepath = row['filepath'] - src_file = row['full_filepath'] - write_non_region_file(filename, filepath, src_file, dir_dst, sw, regions_and_agglevel, source_deflator_map) + write_non_region_file( + row, + case, + dir_dst, + sw, + regions_and_agglevel, + source_deflator_map, + ) def calculate_county_fractions(df, county2zone): @@ -1370,7 +1388,10 @@ def write_miscellaneous_files( gwp_write['H2'] = scalars.loc['h2_gwp','value'].copy() - gwp_write.to_csv(os.path.join(inputs_case,'gwp.csv'), header=False) + reeds.io.write_to_inputs_h5( + gwp_write, 'gwp', inputs_case, gamstype='parameter', + comment='--metric ton CO2-equivalents-- global warming potential', + ) # Calculate CO2 cap based on GSw_Region chosen (national or sub-national regions) # Read in national co2 cap @@ -1380,7 +1401,7 @@ def write_miscellaneous_files( index_col='t', ) .loc[sw['GSw_AnnualCapScen']] - .rename_axis('*t') + .rename_axis('allt') .rename('tonne_per_year') ) @@ -1391,7 +1412,7 @@ def write_miscellaneous_files( index_col=0) # Filter the counties that are in chosen GSw_Region - val_county = pd.read_csv(os.path.join(inputs_case,'val_county.csv'),names=['r']) + val_county = pd.read_csv(os.path.join(inputs_case,'county.csv'),names=['r']) # Merge emission share by county with the counties in GSw_Region and calculate emission share of GSw_Region region_em_share = val_county.merge(em_share, on='r', how='left').fillna(0) @@ -1399,13 +1420,19 @@ def write_miscellaneous_files( # Apply the emission share to national cap to get the emission cap trajectory of GSw_Region co2_cap *= region_em_share - co2_cap.round(0).to_csv(os.path.join(inputs_case, 'co2_cap.csv')) + + reeds.io.write_to_inputs_h5( + co2_cap, 'co2_cap', inputs_case, gamstype='parameter', + comment='--metric tons-- CO2 emissions cap used when Sw_AnnualCap is on', + ) # CO2 tax - pd.read_csv( + co2_tax = pd.read_csv( os.path.join(reeds_path,'inputs','emission_constraints','co2_tax.csv'), index_col='t', - )[sw['GSw_CarbTaxOption']].rename_axis('*t').round(2).to_csv( - os.path.join(inputs_case,'co2_tax.csv') + )[sw['GSw_CarbTaxOption']].rename_axis('allt') + reeds.io.write_to_inputs_h5( + co2_tax, 'co2_tax', inputs_case, gamstype='parameter', + comment='--$/metric ton-- CO2 tax used when Sw_CarbTax is on', ) solveyears = reeds.inputs.parse_yearset(sw['yearset']) @@ -1415,19 +1442,33 @@ def write_miscellaneous_files( solveyears = [y for y in solveyears if (y >= int(sw['startyear'])) and (y <= int(sw['endyear']))] pd.DataFrame(columns=solveyears).to_csv( os.path.join(inputs_case,'modeledyears.csv'), index=False) + reeds.io.write_to_inputs_h5( + pd.Series(solveyears, name='allt'), 'tmodel_new', inputs_case, gamstype='set', + comment='years to run the model', + ) - pd.read_csv( + t = pd.Series(range(int(sw.startyear), int(sw.endyear)+1), name='allt') + reeds.io.write_to_inputs_h5( + pd.Series(t, name='allt'), 't', inputs_case, gamstype='set', + comment='full set of years', + ) + + gen_mandate_trajectory = pd.read_csv( os.path.join(reeds_path,'inputs','national_generation','gen_mandate_trajectory.csv'), index_col='GSw_GenMandateScen' - ).loc[sw['GSw_GenMandateScen']].rename_axis('*t').round(5).to_csv( - os.path.join(inputs_case,'gen_mandate_trajectory.csv') + ).loc[sw['GSw_GenMandateScen']].rename_axis('allt') + reeds.io.write_to_inputs_h5( + gen_mandate_trajectory, 'national_gen_frac', inputs_case, gamstype='parameter', + comment='--fraction-- national fraction of load + losses that must be met by RE', ) - pd.read_csv( - os.path.join(reeds_path,'inputs','national_generation','gen_mandate_tech_list.csv'), + nat_gen_tech_frac = pd.read_csv( + os.path.join(reeds_path,'inputs','national_generation','nat_gen_tech_frac.csv'), index_col='*i', - )[sw['GSw_GenMandateList']].to_csv( - os.path.join(inputs_case,'gen_mandate_tech_list.csv') + )[sw['GSw_GenMandateList']].rename_axis('i') + reeds.io.write_to_inputs_h5( + nat_gen_tech_frac, 'nat_gen_tech_frac', inputs_case, gamstype='parameter', + comment='--fraction-- fraction of each tech generation that may be counted toward eq_national_gen', ) pd.read_csv( @@ -1463,9 +1504,12 @@ def write_miscellaneous_files( index_col=['month', 'day'], )[sw['GSw_PRM_CapCreditSeasons']].rename('ccseason') ccseason_dates.to_csv(os.path.join(inputs_case, 'ccseason_dates.csv')) - ccseason_dates.drop_duplicates().to_csv( - os.path.join(inputs_case, 'ccseason.csv'), - index=False, header=False, + reeds.io.write_to_inputs_h5( + df=ccseason_dates.drop_duplicates().rename().reset_index(drop=True), + key='ccseason', + case=inputs_case, + gamstype='set', + comment='seasons used for capacity credit', ) prm_profiles = pd.read_csv( @@ -1613,10 +1657,6 @@ def main(reeds_path, inputs_case): agglevel_variables ) - # Write general GAMS files - # Write GAMS-readable sets to the inputs_case directory - write_GAMS_sets(runfiles, reeds_path, inputs_case) - # Rewrite the switches tables as GAMS-readable definition # (gswitches.csv is first written at runreeds.py) scalar_csv_to_txt(os.path.join(inputs_case,'gswitches.csv')) @@ -1673,7 +1713,7 @@ def main(reeds_path, inputs_case): # #%% Settings for testing ### # reeds_path = reeds.io.reeds_path - # inputs_case = os.path.join(reeds_path,'runs','v20260305_itlM0_USA_defaults','inputs_case') + # inputs_case = os.path.join(reeds_path,'runs','v20260425_inputsM0_Pacific','inputs_case') # ---- Set up logger ---- diff --git a/reeds/input_processing/fuelcostprep.py b/reeds/input_processing/fuelcostprep.py index 5ea65223..51f4b605 100644 --- a/reeds/input_processing/fuelcostprep.py +++ b/reeds/input_processing/fuelcostprep.py @@ -49,10 +49,8 @@ sw = reeds.io.get_switches(inputs_case) # Load valid regions -val_r = pd.read_csv( - os.path.join(inputs_case, 'val_r.csv'), header=None).squeeze(1).tolist() -val_cendiv = pd.read_csv( - os.path.join(inputs_case, 'val_cendiv.csv'), header=None).squeeze(1).tolist() +val_r = reeds.io.read_input(inputs_case, 'r').squeeze(1).tolist() +val_cendiv = reeds.io.read_input(inputs_case, 'cendiv').squeeze(1).tolist() r_cendiv = pd.read_csv(os.path.join(inputs_case,"r_cendiv.csv")) diff --git a/reeds/input_processing/h5_to_gdx.py b/reeds/input_processing/h5_to_gdx.py new file mode 100644 index 00000000..bed3e258 --- /dev/null +++ b/reeds/input_processing/h5_to_gdx.py @@ -0,0 +1,203 @@ +#%% Imports +import sys +import h5py +import gdxpds +import argparse +import datetime +import numpy as np +import pandas as pd +from pathlib import Path +from typing import Literal +sys.path.append(str(Path(__file__).parent.parent.parent)) +import reeds + + +#%% Functions +def read_inputs(case:str|Path) -> tuple: + """ + Read a ReEDS-formatted inputs.h5 file + + Args: + case: Path to a ReEDS case + + Returns: + tuple of 3 dictionaries, where the keys of each are the names of the elements + read from the inputs.h5 file: + - dictin (first element of tuple): pd.DataFrame of contents + - gamstypes (second element of tuple): 'set' or 'parameter' + - comments (third element of tuple): string to be used as comment in GAMS + """ + ## Allow either a ReEDS case or a .h5 path to be provided + if Path(case).suffix == '.h5': + h5path = case + else: + h5path = Path(case, 'inputs_case', 'inputs.h5') + dictin = {} + gamstypes = {} + comments = {} + with h5py.File(h5path, 'r') as f: + keys = list(f) + for key in keys: + gamstypes[key] = f[key].attrs['gamstype'] + if 'comment' in f[key].attrs: + comments[key] = f[key].attrs['comment'] + if isinstance(comments[key], np.float64): + comments[key] = '' + columns = [i.decode() for i in list(f[key]['columns'])] + try: + df = pd.DataFrame({col: f[key][col] for col in columns}) + except KeyError: + df = pd.DataFrame(columns=columns) + for col in df: + if df[col].dtype == 'O': + df[col] = df[col].str.decode('utf-8') + dictin[key] = df + return dictin, gamstypes, comments + + +def get_declaration(df): + """ + For everything except primary sets, return the domain as "(dim1,dim2,...)" + """ + columns = [i for i in df.columns if i != 'Value'] + if (len(columns) == 1) and (columns[0] == '*'): + out = '' + else: + out = '(' + ','.join(columns) + ')' + return out + + +def sort_primary_first(declarations:list): + """Put primary sets before subsetes""" + writelist = ( + [i for i in declarations if '(' not in i] + + [i for i in declarations if '(' in i] + ) + return writelist + + +def write_declaration( + case:str|Path, + declarations:list, + gamstype:Literal['set','parameter'], +): + """ + Write GAMS code to declare sets/parameters before loading them from a .gdx file + """ + ## Get aliases so we can define them after the parent is defined + aliases = pd.read_csv( + Path(reeds.io.reeds_path, 'inputs', 'sets', '_aliases.csv'), + header=0, index_col=0, + ).squeeze() + ## Need to write primary sets before subsets + if gamstype == 'set': + writelist = sort_primary_first(declarations) + else: + writelist = declarations + fpath = Path(case, 'autocode', f'b_declare_{gamstype}s.gms') + with open(fpath, 'w') as f: + if len(writelist): + for line in writelist: + f.write(f'{gamstype} {line} ;\n') + name = line.split('(')[0] + for alias in aliases.get([name], []): + f.write(f'alias({name},{alias}) ;\n') + print(f'Wrote {fpath}') + + +def write_gdxread( + case:str|Path, + declarations:list, + gamstype:Literal['set','parameter'], +): + """ + Write GAMS code to read sets/parameters from .gdx file + """ + ## Need to write primary sets before subsets + if gamstype == 'set': + writelist = sort_primary_first(declarations) + else: + writelist = declarations + fpath = Path(case, 'autocode', f'b_load_{gamstype}s.gms') + with open(fpath, 'w') as f: + for line in writelist: + key = line.split('(')[0] + f.write(f'$loadDCR {key} = {key}\n') + print(f'Wrote {fpath}') + + +def main(case, overwrite=True, verbose=1): + dictin, gamstypes, comments = read_inputs(case) + 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'] + 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 = [] + declare_parameters = [] + if gdxpath.is_file(): + if overwrite: + gdxpath.unlink() + else: + raise FileExistsError(gdxpath) + with gdxpds.gdx.GdxFile() as gdx: + for key in keys: + df = dictin[key] + if gamstypes[key] == 'set': + gdxpds.gdx.append_set( + gdx_file=gdx, + set_name=key, + df=df, + description=comments.get(key, None), + ) + declare_sets.append(f'{key}{get_declaration(df)}') + elif gamstypes[key] == 'parameter': + gdxpds.gdx.append_parameter( + gdx_file=gdx, + param_name=key, + df=df, + description=comments.get(key, None), + ) + declare_parameters.append(f'{key}{get_declaration(df)}') + else: + raise NotImplementedError(gamstypes[key]) + gdx.write(gdxpath) + print(f'Wrote inputs.h5 to {gdxpath}') + ## Write GAMS code to declare and load the sets/parameters + write_declaration(case, declare_sets, 'set') + write_declaration(case, declare_parameters, 'parameter') + write_gdxread(case, declare_sets, 'set') + write_gdxread(case, declare_parameters, 'parameter') + + +#%% Procedure +if __name__ == '__main__': + #%% Time the operation of this script + tic = datetime.datetime.now() + + #%% Parse arguments + parser = argparse.ArgumentParser( + description='Convert a ReEDS-formatted .h5 file to .gdx', + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + ) + parser.add_argument('reeds_path', help='ReEDS directory') + parser.add_argument('inputs_case', help='ReEDS/runs/{case}/inputs_case directory') + + args = parser.parse_args() + case = reeds.io.standardize_case(Path(args.inputs_case)) + + # #%% Inputs for testing + # case = Path(reeds.io.reeds_path, 'runs', 'v20260427_inputsM0_github_Everything') + + #%% Set up logger + log = reeds.log.makelog( + scriptname=__file__, + logpath=Path(case, 'gamslog.txt'), + ) + + #%% Run it + main(case) + + #%% Record the runtime + reeds.log.toc(tic=tic, year=0, process='input_processing/h5_to_gdx.py', path=case) diff --git a/reeds/input_processing/hourly_repperiods.py b/reeds/input_processing/hourly_repperiods.py index 5570f603..9e933085 100644 --- a/reeds/input_processing/hourly_repperiods.py +++ b/reeds/input_processing/hourly_repperiods.py @@ -794,10 +794,7 @@ def main( timestamps_day = make_timestamps(sw=pd.Series({**sw, **{'GSw_HourlyType':'day'}})) timestamps_wek = make_timestamps(sw=pd.Series({**sw, **{'GSw_HourlyType':'wek'}})) ## Include all possible seasons so dispatch mode can be rerun with any of them - quarters = pd.read_csv( - os.path.join(inputs_case, 'sets', 'quarter.csv'), - header=None, - ).squeeze(1).tolist() + quarters = reeds.io.read_input(inputs_case, 'quarter').squeeze(1).tolist() set_allszn = pd.Series( list(timestamps_day.period.unique()) + list(timestamps_wek.period.unique()) @@ -871,11 +868,14 @@ def main( return period_szn_write #%% Write the sets over all possible periods (representative and stress) - set_allszn.to_csv( - os.path.join(inputs_case, 'set_allszn.csv'), header=False, index=False) - - set_allh.to_csv( - os.path.join(inputs_case, 'set_allh.csv'), header=False, index=False) + reeds.io.write_to_inputs_h5( + set_allszn.rename(), 'allszn', inputs_case, gamstype='set', + comment='all potentially modeled time periods (days/weks)', + ) + reeds.io.write_to_inputs_h5( + set_allh.rename(), 'allh', inputs_case, gamstype='set', + comment='all potentially modeled time chunks (hour groupings)', + ) #%% Write the seed stress periods to use for the PRM constraint if 'user' in sw.GSw_PRM_StressModel: diff --git a/reeds/input_processing/mcs_sampler.py b/reeds/input_processing/mcs_sampler.py index 2b6cac27..deee88d6 100644 --- a/reeds/input_processing/mcs_sampler.py +++ b/reeds/input_processing/mcs_sampler.py @@ -609,7 +609,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) + reeds_path, inputs_case, save_regions_and_agglevel=False, overwrite=True) source_deflator_map = copy_files.get_source_deflator_map(reeds_path) diff --git a/reeds/input_processing/outage_rates.py b/reeds/input_processing/outage_rates.py index 80d7d00a..7ccadf22 100644 --- a/reeds/input_processing/outage_rates.py +++ b/reeds/input_processing/outage_rates.py @@ -132,10 +132,10 @@ def fill_empty_techs(df_prefill, inputs_case, fillvalues_tech=None, during_quart ------- """ ### Parse inputs - quarters = pd.read_csv( - os.path.join(inputs_case, 'sets', 'quarter.csv'), - header=None, - ).squeeze(1).map(lambda x: x[:4]).tolist() + quarters = ( + reeds.io.read_input(inputs_case, 'quarter') + .squeeze(1).map(lambda x: x[:4]).tolist() + ) if isinstance(during_quarters, str): assert during_quarters == 'all' elif isinstance(during_quarters, list): diff --git a/reeds/input_processing/recf.py b/reeds/input_processing/recf.py index a340bb9f..a8ed76b2 100644 --- a/reeds/input_processing/recf.py +++ b/reeds/input_processing/recf.py @@ -523,8 +523,11 @@ def main(reeds_path, inputs_case): ### Overwrite the original hierarchy.csv based on capcredit_hierarchy_level hierarchy.rename_axis('*r').to_csv( os.path.join(inputs_case, 'hierarchy.csv'), index=True, header=True) - pd.Series(hierarchy.ccreg.unique()).to_csv( - os.path.join(inputs_case,'ccreg.csv'), index=False, header=False) + ccreg = pd.Series(hierarchy.ccreg.unique()) + reeds.io.write_to_inputs_h5( + ccreg, 'ccreg', inputs_case, gamstype='set', comment='capacity credit region', + ) + #%% =========================================================================== diff --git a/reeds/input_processing/runfiles.csv b/reeds/input_processing/runfiles.csv index 5a3d6d36..06961a99 100644 --- a/reeds/input_processing/runfiles.csv +++ b/reeds/input_processing/runfiles.csv @@ -9,12 +9,11 @@ i_subtech.csv,inputs/sets/i_subtech.csv,1,ignore,ignore,,,,,,,1,set,i_subtech,te i_h2_ptc_gen.csv,inputs/sets/i_h2_ptc_gen.csv,1,ignore,ignore,,,,,,,1,set,i_h2_ptc_gen,technology subset category for clean generators which qualify for the hydrogen production tax credit, sdbin.csv,inputs/sets/sdbin.csv,1,ignore,ignore,,,,,,,1,set,sdbin,storage duration bins, tg.csv,inputs/sets/tg.csv,1,ignore,ignore,,,,,,,1,set,tg,tech groups for growth constraints, -pcat.csv,inputs/sets/pcat.csv,1,ignore,ignore,,,,,,,1,set,pcat,prescribed capacity categories, ccseason.csv,,1,ignore,ignore,,,,,,,1,set,ccseason,seasons used for capacity credit; cold is Oct 15-April 14 and hot is April 15-Oct 14, quarter.csv,inputs/sets/quarter.csv,1,ignore,ignore,,,,,,,1,set,quarter,original h17 seasons (four per year), 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,,,,,,,,,RPSCat,, -aclike.csv,inputs/sets/aclike.csv,1,ignore,ignore,,,,,0,,,,aclike,, +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_prices.csv,inputs/state_policies/acp_prices.csv,int(sw.GSw_StateRPS) != 0,ignore,ignore,st,st,,1,0,,,,,, tscbin.csv,,1,ignore,ignore,,,,,,,1,set,tscbin,transmission upgrade supply curve bins, @@ -23,10 +22,10 @@ agglevels.csv,,1,ignore,ignore,ignore,,,,0,,,,,, aggreg.csv,,1,ignore,ignore,ignore,,,0,0,,,,,, aggreg2anchorreg.csv,,1,ignore,ignore,ignore,,,0,0,,,,,, anchorreg2aggreg.csv,,1,ignore,ignore,ignore,,,0,0,,,,,, -allt.csv,inputs/sets/allt.csv,1,ignore,ignore,,,,,,,,,allt,, +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,,,,,, bio_supplycurve.csv,inputs/supply_curve/bio_supplycurve.csv,1,ignore,ignore,usda_region,,,,0,,,,,, -bioclass.csv,inputs/sets/bioclass.csv,1,ignore,ignore,,,,,,,,,bioclass,, +bioclass.csv,inputs/sets/bioclass.csv,1,ignore,ignore,,,,,,,,set,bioclass,, can_exports.csv,inputs/canada_imports/can_exports.csv,int(sw.GSw_Canada) != 0,sum,ignore,r,wide,,1,0,,,,,, can_exports_h_frac.csv,,1,ignore,ignore,,,,,0,,,,,, can_exports_szn_frac.csv,inputs/canada_imports/can_exports_szn_frac.csv,int(sw.GSw_Canada) != 0,ignore,ignore,,,,,0,,,,,, @@ -51,7 +50,7 @@ ccreg.csv,,1,ignore,ignore,,,,,0,,,,,, ccs_link.csv,inputs/emission_constraints/ccs_link.csv,1,ignore,ignore,,,,,0,,,,,, ccs_link_water.csv,inputs/emission_constraints/ccs_link_water.csv,1,ignore,ignore,,,,,0,,,,,, ccseason_dates.csv,,1,ignore,ignore,,,,,0,,,,,, -ccsflex_cat.csv,inputs/sets/ccsflex_cat.csv,1,ignore,ignore,,,,,,,,,ccsflex_cat,, +ccsflex_cat.csv,inputs/sets/ccsflex_cat.csv,1,ignore,ignore,,,,,,,,set,ccsflex_cat,flexible ccs performance parameter categories, ccsflex_perf.csv,,1,ignore,ignore,,,,,0,,,,,, 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,,,,,, @@ -67,7 +66,7 @@ climate_heuristics_yearfrac.csv,,1,ignore,ignore,,,,,0,,,,,, climate_hydadjann.csv,,1,ignore,ignore,,,,,0,,1,,,,created by climateprep.py climate_hydadjsea.csv,,1,ignore,ignore,,,,,0,,1,,,,created by hourly_writetimeseries.py from temp_hydadjsea.csv data climate_loaddelta_timeslice.csv,,1,ignore,ignore,,"r,h",,1,0,,,,,,not done but rarely used; ignore for now -climate_param.csv,inputs/sets/climate_param.csv,1,ignore,ignore,,,,,,,,,climate_param,, +climate_param.csv,inputs/sets/climate_param.csv,1,ignore,ignore,,,,,,,,set,climate_param,parameters defined in climate_heuristics_finalyear, co2_cap.csv,,int(sw.GSw_AnnualCap) != 0,ignore,ignore,,,,0,0,,,,,, co2_capture_incentive.csv,,1,ignore,ignore,,,,,0,,,,,, co2_site_char.csv,inputs/ctus/co2_site_char.csv,1,ignore,ignore,,,,0,,,,,,, @@ -76,7 +75,7 @@ coal_price.csv,inputs/fuelprices/coal_{coalscen}.csv,1,ignore,ignore,wide_cendiv 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,,,,,, 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,,,,,,,,,consumecat,, +consumecat.csv,inputs/sets/consumecat.csv,1,ignore,ignore,,,,,,,,set,consumecat,categories for consuming facility characteristics, consumechardac.csv,,1,ignore,ignore,,"*i,t,variable",,0,0,,,,,, cost_cap_mult.csv,inputs/waterclimate/cost_cap_mult.csv,int(sw.GSw_WaterMain) != 0,ignore,ignore,,,,,0,,,,,, cost_hurdle_country.csv,inputs/transmission/cost_hurdle_country.csv,1,ignore,ignore,*country,,,,0,,,,,, @@ -93,8 +92,8 @@ county2zone_original.csv,,1,ignore,ignore,,,,,,,1,,,, crf.csv,,1,ignore,ignore,,,,0,,,,,,, crf_co2_incentive.csv,,1,ignore,ignore,,,,,0,,,,,, crf_h2_incentive.csv,,1,ignore,ignore,,,,,0,,,,,, -csapr_cat.csv,inputs/sets/csapr_cat.csv,1,ignore,ignore,,,,,,,,,csapr_cat,, -csapr_group.csv,inputs/sets/csapr_group.csv,1,ignore,ignore,,,,,,,,,csapr_group,, +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,,,,,, csapr_group2_ex.csv,inputs/emission_constraints/csapr_group2_ex.csv,int(sw.GSw_CSAPR) != 0,ignore,ignore,*st,,,,0,,,,,, csapr_ozone_season.csv,inputs/emission_constraints/csapr_ozone_season.csv,int(sw.GSw_CSAPR) != 0,ignore,ignore,st,,,,0,,,,,, @@ -123,17 +122,17 @@ dr_shed_cap.csv,inputs/supply_curve/dr_shed_cap_{dr_shedscen}.csv,int(sw.GSw_DRS dr_shed_cost.csv,inputs/supply_curve/dr_shed_cost_{dr_shedscen}.csv,int(sw.GSw_DRShed) != 0,ignore,ignore,wide,tech,,1,0,,,,,,done dr_shed_capacity_scalar.csv,inputs/demand_response/dr_shed_capacity_scalar_{dr_shedscen}.csv,int(sw.GSw_DRShed) != 0,ignore,ignore,r,"tech,wide",,1,0,,,,,,done dr_shed_hourly.h5,inputs/profiles_dr/dr_shed_hourly_{dr_shedscen}.h5,int(sw.GSw_DRShed) != 0,ignore,ignore,wide,"datetime,year",,1,keepindex,,,,,,Agg/Disagg handled in hourly_load -e.csv,inputs/sets/e.csv,1,ignore,ignore,,,,,0,,,,e,, -eall.csv,inputs/sets/eall.csv,1,ignore,ignore,,,,,,,,,eall,, +e.csv,inputs/sets/e.csv,1,ignore,ignore,,,,,0,,,set,e,emission categories used in model, +eall.csv,inputs/sets/eall.csv,1,ignore,ignore,,,,,,,,set,eall,emission categories used in reporting, emit_rate.csv,,1,ignore,ignore,,"etype,e,i,v,r",,0,0,,,,,,ReEDS-to-PLEXOS output emitrate.csv,inputs/emission_constraints/emitrate.csv,1,ignore,ignore,,,,,0,,,,,, energy_communities.csv,inputs/financials/energy_communities.csv,1,ignore,ignore,,,,,0,,,,,,region aggregation and filtering is handled in copy_files -etype.csv,inputs/sets/etype.csv,1,ignore,ignore,,,,,,,,,etype,, +etype.csv,inputs/sets/etype.csv,1,ignore,ignore,,,,,,,,set,etype,emission types used in model (upstream and process), eval_period_adj_mult.csv,,1,ignore,ignore,,,,,0,,,,,, exog_cap_geohydro.csv,inputs/capacity_exogenous/exog_cap_geohydro_{GSw_SitingGeo}.csv,int(sw.GSw_Geothermal) != 0,ignore,ignore,region,"*tech,sc_point_gid,year",,0,0,,,,,, exog_cap_upv.csv,inputs/capacity_exogenous/exog_cap_upv_{GSw_SitingUPV}.csv,1,ignore,ignore,region,"*tech,sc_point_gid,year",,0,0,,,,,, exog_cap_wind-ons.csv,inputs/capacity_exogenous/exog_cap_wind-ons_{GSw_SitingWindOns}.csv,1,ignore,ignore,region,"*tech,sc_point_gid,year",,0,0,,,,,, -f.csv,inputs/sets/f.csv,1,ignore,ignore,,,,,,,,,f,, +f.csv,inputs/sets/f.csv,1,ignore,ignore,,,,,,,,set,f,fuel types, financials_hydrogen.csv,inputs/financials/financials_hydrogen.csv,int(sw.GSw_H2) != 0,ignore,ignore,,,,,0,,,,,, financials_sys.csv,inputs/financials/financials_sys_{financials_sys_suffix}.csv,1,ignore,ignore,,,,,0,,,,,, financials_tech.csv,inputs/financials/financials_tech_{financials_tech_suffix}.csv,1,ignore,ignore,,,,,0,,,,,, @@ -143,20 +142,20 @@ firm_import_limit.csv,,1,ignore,ignore,,,,,0,,1,,,, firstyear.csv,,1,ignore,ignore,,,,,0,,1,,,, years_until_endogenous.csv,inputs/plant_characteristics/years_until_endogenous.csv,1,ignore,ignore,,,,,0,,,,,, flex_frac_all.csv,,1,mean,population,r,"*flextype,h,wide",,1,0,,1,,,, -flex_type.csv,inputs/sets/flex_type.csv,1,ignore,ignore,,,,,,,,,flex_type,, +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,,,,,, forceperiods.csv,,1,ignore,ignore,,,,,,,,,,, frac_h_ccseason_weights.csv,,1,ignore,ignore,,,,,,,,,,, frac_h_month_weights.csv,,1,ignore,ignore,,,,,,,,,,, frac_h_quarter_weights.csv,,1,ignore,ignore,,,,,,,,,,, -fuel2tech.csv,inputs/sets/fuel2tech.csv,1,ignore,ignore,,,,,0,,,,fuel2tech,, +fuel2tech.csv,inputs/sets/fuel2tech.csv,1,ignore,ignore,,,,,0,,,set,fuel2tech,mapping between fuel types and generations, fuel_price.csv,,1,ignore,ignore,,"i,r",,0,0,,,,,,ReEDS-to-PLEXOS output -fuelbin.csv,inputs/sets/fuelbin.csv,1,ignore,ignore,,,,,,,,,fuelbin,, +fuelbin.csv,inputs/sets/fuelbin.csv,1,ignore,ignore,,,,,,,,set,fuelbin,gas usage bracket, futurefiles.csv,inputs/userinput/futurefiles.csv,1,ignore,ignore,,,,,0,,,,,, -gb.csv,inputs/sets/gb.csv,1,ignore,ignore,,,,,,,,,gb,, -gbin.csv,inputs/sets/gbin.csv,1,ignore,ignore,,,,,,,,,gbin,, +gb.csv,inputs/sets/gb.csv,1,ignore,ignore,,,,,,,,set,gb,gas price bins; must have an odd number of bins; e.g. gb1*gb15, +gbin.csv,inputs/sets/gbin.csv,1,ignore,ignore,,,,,,,,set,gbin,growth bins, gbin_min.csv,inputs/growth_constraints/gbin_min.csv,1,ignore,ignore,,,,,0,,,,,, -gen_mandate_tech_list.csv,,1,ignore,ignore,,,,,0,,,,,, +nat_gen_tech_frac.csv,,1,ignore,ignore,,,,,0,,,,,, gen_mandate_trajectory.csv,,1,ignore,ignore,,,,,0,,,,,, geo_discovery_factor.csv,inputs/geothermal/geo_discovery_factor_{geohydrosupplycurve}.csv,int(sw.GSw_Geothermal) != 0,mean,uniform,r,*i,*i,0,0,,,,,, geo_discovery_rate.csv,inputs/geothermal/geo_discovery_{geodiscov}.csv,int(sw.GSw_Geothermal) != 0,ignore,ignore,,,,0,,,,,,, @@ -171,15 +170,15 @@ growth_limit_absolute.csv,inputs/growth_constraints/growth_limit_absolute.csv,1, growth_penalty.csv,inputs/growth_constraints/growth_penalty.csv,1,ignore,ignore,,,,,0,,,,,, gswitches.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,,,,gwp,, +gwp.csv,inputs/emission_constraints/gwp.csv,1,ignore,ignore,,,,,0,,1,parameter,gwp,, h2_existing_smr_cap.csv,,1,sum,population,*r,t,,0,0,,1,,,, h_preh.csv,,1,ignore,ignore,,,,,0,,,,,, 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_pipeline_cap_cost_mult.csv,,1,ignore,ignore,,,,,,,1,,,, h2_ptc.csv,,1,ignore,ignore,,,*i,,0,,,,,, -h2_st.csv,inputs/sets/h2_st.csv,1,ignore,ignore,,,,,,,,,h2_st,, -h2_stor.csv,inputs/sets/h2_stor.csv,1,ignore,ignore,,,,,0,,,,h2_stor,, +h2_st.csv,inputs/sets/h2_st.csv,1,ignore,ignore,,,,,,,,set,h2_st,investments needed to store and transport H2, +h2_stor.csv,inputs/sets/h2_stor.csv,1,ignore,ignore,,,,,0,,,set,h2_stor,H2 storage options, h2_storage_rb.csv,,int(sw.GSw_H2) != 0,ignore,ignore,rb,,,0,0,,1,,,, h2_transport_and_storage_costs.csv,inputs/consume/h2_transport_and_storage_costs.csv,int(sw.GSw_H2) != 0,ignore,ignore,,,,,,,,,,, h_actualszn.csv,,1,ignore,ignore,,,,,0,,,,,, @@ -196,7 +195,7 @@ hierarchy.csv,,1,first,ignore,*r,"nercr,transreg,transgrp,cendiv,st,interconnect hierarchy_itlgrp.csv,,1,ignore,ignore,,,,,0,,1,,,,post_copy column set to 1 since copy_files copies this file separately hierarchy_original.csv,,1,ignore,ignore,,,,,0,,1,,,,post_copy column set to 1 since copy_files copies this file separately hierarchy_with_res.csv,,1,ignore,ignore,,,,,0,,1,,,,post_copy column set to 1 since copy_files copies this file separately -hintage_char.csv,inputs/sets/hintage_char.csv,1,ignore,ignore,,,,,,,,,hintage_char,, +hintage_char.csv,inputs/sets/hintage_char.csv,1,ignore,ignore,,,,,,,,set,hintage_char,characteristics available in hintage_data, hintage_data.csv,,1,ignore,ignore,,,,,0,,,,,,handled separately in WriteHintage.py hmap_allyrs.csv,,1,ignore,ignore,,,,,0,,,,,, hmap_myr.csv,,1,ignore,ignore,,,,,0,,,,,, @@ -222,9 +221,9 @@ i_coolingtech_watersource.csv,inputs/waterclimate/i_coolingtech_watersource.csv, i_coolingtech_watersource_link.csv,inputs/waterclimate/i_coolingtech_watersource_link.csv,int(sw.GSw_WaterMain) != 0,ignore,ignore,,,,,0,,,,,, i_coolingtech_watersource_upgrades.csv,inputs/upgrades/i_coolingtech_watersource_upgrades.csv,1,ignore,ignore,,,,,0,,,,,, i_coolingtech_watersource_upgrades_link.csv,inputs/upgrades/i_coolingtech_watersource_upgrades_link.csv,1,ignore,ignore,,,,,0,,,,,, -i_geotech.csv,inputs/sets/i_geotech.csv,1,ignore,ignore,,,,,0,,,,i_geotech,, -i_p.csv,inputs/sets/i_p.csv,1,ignore,ignore,,,,,0,,,,i_p,, -i_water_nocooling.csv,inputs/sets/i_water_nocooling.csv,1,ignore,ignore,,,,,0,,,,i_water_nocooling,, +i_geotech.csv,inputs/sets/i_geotech.csv,1,ignore,ignore,,,,,0,,,set,i_geotech,crosswalk between an individual geothermal technology and its category, +i_p.csv,inputs/sets/i_p.csv,1,ignore,ignore,,,,,0,,,set,i_p,mapping from technologies to the products they produce, +i_water_nocooling.csv,inputs/sets/i_water_nocooling.csv,1,ignore,ignore,,,,,0,,,set,i_water_nocooling,technologies that use water but are not differentiated by cooling tech and water source, incentives.csv,inputs/financials/incentives_{incentives_suffix}.csv,1,ignore,ignore,,,,,0,,,,,, inflation.csv,inputs/financials/inflation_{inflation_suffix}.csv,1,ignore,ignore,,,,0,0,,,,,, interconnection_queues.csv,inputs/capacity_exogenous/interconnection_queues.csv,1,ignore,ignore,r,"tg,r",,1,0,,,,,, @@ -233,7 +232,7 @@ itc_frac_monetized.csv,,1,ignore,ignore,,,,,0,,,,,, itc_fractions.csv,,1,ignore,ignore,,"i,country,t",,0,0,,,,,, ivt.csv,,1,ignore,ignore,,,,,0,,,,,,created in runreeds.py ivt_step.csv,,1,ignore,ignore,,,,,0,,,,,, -lcclike.csv,inputs/sets/lcclike.csv,1,ignore,ignore,,,,,0,,,,lcclike,, +lcclike.csv,inputs/sets/lcclike.csv,1,ignore,ignore,,,,,0,,,set,lcclike,transmission capacity types where lines are bundled with AC/DC converters, load_2010.csv,,1,sum,ignore,r,wide,,1,0,,1,,,,disaggfunc set to ignore because load will already be in correct spatial resolution load_allyear.csv,,1,sum,ignore,*r,"h,t",,0,0,,1,,,,disaggfunc set to ignore because load will already be in correct spatial resolution load_multiplier.csv,inputs/load/demand_{demandscen}.csv,1,ignore,ignore,,,,,0,,,,,, @@ -265,8 +264,8 @@ ng_crf_penalty.csv,,1,ignore,ignore,,,,0,0,,,,,, ng_crf_penalty_st.csv,inputs/state_policies/ng_crf_penalty_st.csv,1,ignore,ignore,st,*t,,0,0,,,,,, ng_demand_elec.csv,inputs/fuelprices/ng_demand_{ngscen}.csv,1,ignore,ignore,wide_cendiv,year,,1,0,,,,,, ng_demand_tot.csv,inputs/fuelprices/ng_tot_demand_{ngscen}.csv,1,ignore,ignore,wide_cendiv,year,,1,0,,,,,, -noretire.csv,inputs/sets/noretire.csv,1,ignore,ignore,,,,,0,,,,noretire,, -notvsc.csv,inputs/sets/notvsc.csv,1,ignore,ignore,,,,,0,,,,notvsc,, +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_ba_ban_list.csv,,int(sw.GSw_NukeStateBan) != 0,ignore,ignore,,,,,,,,,,, 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,,,,,, @@ -274,22 +273,21 @@ numhours.csv,,1,ignore,ignore,,,,,0,,,,,, numhours_nexth.csv,,1,ignore,ignore,,,,,0,,1,,,, 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,,,,,, -offshore.csv,,1,ignore,ignore,,,,0,none,,,,,, -ofstype.csv,inputs/sets/ofstype.csv,1,ignore,ignore,,,,,,,,,ofstype,, -ofstype_i.csv,inputs/sets/ofstype_i.csv,1,ignore,ignore,,,,,0,,,,ofstype_i,, +ofstype.csv,inputs/sets/ofstype.csv,1,ignore,ignore,,,,,,,,set,ofstype,offshore types used in offshore requirement constraint (eq_RPS_OFSWind), +ofstype_i.csv,inputs/sets/ofstype_i.csv,1,ignore,ignore,,,,,0,,,set,ofstype_i,crosswalk between ofstype and i, ofswind_rsc_mult.csv,,1,ignore,ignore,,,,1,0,,,,,, oosfrac.csv,inputs/state_policies/oosfrac.csv,int(sw.GSw_StateRPS) != 0,ignore,ignore,*st,,,,0,,,,,, opres_periods.csv,inputs/reserves/opres_periods.csv,int(sw.GSw_OpRes) != 0,ignore,ignore,,,,,0,,,,,, -orcat.csv,inputs/sets/orcat.csv,1,ignore,ignore,,,,,,,,,orcat,, +orcat.csv,inputs/sets/orcat.csv,1,ignore,ignore,,,,,,,,set,orcat,operating reserve category for RHS calculations, orperc.csv,inputs/reserves/orperc.csv,int(sw.GSw_OpRes) != 0,ignore,ignore,,,,,0,,,,,, -ortype.csv,inputs/sets/ortype.csv,1,ignore,ignore,,,,,,,,,ortype,, +ortype.csv,inputs/sets/ortype.csv,1,ignore,ignore,,,,,,,,set,ortype,types of operating reserve constraints, outage_forced_h.csv,,1,ignore,ignore,r,"*i,h",,0,0,,1,,,,handled in outage_rates.py outage_forced_hourly.h5,,1,ignore,ignore,wide,index,index,1,keepindex,,1,,,,handled in outage_rates.py outage_forced_static.csv,inputs/plant_characteristics/outage_forced_static.csv,1,ignore,ignore,,,,,none,,,,,, outage_forced_temperature.csv,inputs/plant_characteristics/outage_forced_temperature_{GSw_OutageScen}.csv,sw.GSw_OutageScen != 'static',ignore,ignore,,,,,0,,,,,, outage_scheduled_static.csv,inputs/plant_characteristics/outage_scheduled_static.csv,1,ignore,ignore,,,,,0,,,,,, outage_scheduled_monthly.csv,inputs/plant_characteristics/outage_scheduled_monthly.csv,1,ignore,ignore,,,,,0,,,,,, -p.csv,inputs/sets/p.csv,1,ignore,ignore,,,,,,,,,p,, +p.csv,inputs/sets/p.csv,1,ignore,ignore,,,,,,,,set,p,products produced, peak_ccseason.csv,,1,sum,ignore,*r,"ccseason,t",,0,0,,1,,,,ok because it's load during peak NERC hour peak_h.csv,,1,sum,ignore,r,"h,wide",,1,0,,1,,,, peakload.csv,,1,ignore,ignore,,,,,0,,1,,,, @@ -299,7 +297,7 @@ period_szn_user.csv,inputs/temporal/period_szn_{GSw_HourlyClusterAlgorithm}.csv, period_weights.csv,,1,ignore,ignore,,,,,0,,,,,, periodmap_1yr.csv,,1,ignore,ignore,,,,0,0,,,,,, pipeline_cost_mult.csv,,int(sw.GSw_H2) != 0,trans_lookup,uniform,"*r,rr",,,0,0,drop_dup_r,1,,,, -plantcat.csv,inputs/sets/plantcat.csv,1,ignore,ignore,,,,,,,,,plantcat,, +plantcat.csv,inputs/sets/plantcat.csv,1,ignore,ignore,,,,,,,,set,plantcat,categories for plant characteristics, plantcharout.csv,,1,ignore,ignore,,"0,2",,0,,,,,,, plantchar_beccs.csv,inputs/plant_characteristics/{plantchar_beccs}.csv,int(sw.GSw_BECCS) != 0,ignore,ignore,,,,,0,,,,,,used to define plantcharout.csv plantchar_biopower.csv,inputs/plant_characteristics/{plantchar_biopower}.csv,1,ignore,ignore,,,,,0,,,,,,used to define plantcharout.csv @@ -329,12 +327,12 @@ plantchar_pvb.csv,inputs/plant_characteristics/pvb_{pvbscen}.csv,int(sw.GSw_PVB) plantchar_upgrades.csv,inputs/upgrades/{upgradescen}.csv,sw.upgradescen != 'default',ignore,ignore,,,,,0,,,,,,used to define plantcharout.csv plantchar_upv.csv,inputs/plant_characteristics/{plantchar_upv}.csv,1,ignore,ignore,,,,,0,,,,,,used to define plantcharout.csv poi_cap_init.csv,,1,sum,ignore,*r,,,0,0,,1,,,,disaggfunc set to ignore because data will be written at county resolution by writecapdat.py -prepost.csv,inputs/sets/prepost.csv,1,ignore,ignore,,,,,,,,,prepost,, +prepost.csv,inputs/sets/prepost.csv,1,ignore,ignore,,,,,,,,set,prepost,defines pre-2010 versus post-2010 years, prescribed_builds_wind-ofs.csv,inputs/capacity_exogenous/prescribed_builds_wind-ofs_{GSw_OffshoreFiles}_{GSw_SitingWindOfs}.csv,int(sw.GSw_OfsWind) != 0,sum,ignore,region,year,,0,0,,,,,,disaggfunc set to ignore because data will be read in at the correct spatial resolution prescribed_builds_wind-ons.csv,inputs/capacity_exogenous/prescribed_builds_wind-ons_{GSw_SitingWindOns}.csv,1,sum,ignore,region,year,,0,0,,,,,,disaggfunc set to ignore because data will be read in at the correct spatial resolution prescribed_nonRSC.csv,,1,sum,ignore,r,"t,i",,0,0,,1,,,,disaggfunc set to ignore because data will be written at county resolution by writecapdat.py prescribed_rsc.csv,,1,sum,ignore,r,"t,i",,0,0,,1,,,,disaggfunc set to ignore because data will be written at county resolution by writecapdat.py -prescriptivelink0.csv,inputs/sets/prescriptivelink0.csv,1,ignore,ignore,,,,,0,,,,prescriptivelink0,, +prescriptivelink0.csv,inputs/sets/prescriptivelink0.csv,1,ignore,ignore,,,,,0,,,set,prescriptivelink0,initial set of prescribed categories and their technologies - used in assigning prescribed builds, prm_initial.csv,,1,ignore,ignore,*r,,,,0,,1,,,, prm.csv,,1,ignore,ignore,*r,,,,0,,1,,,, psh_sc_duration.csv,,1,ignore,ignore,,,,,0,,1,,,,Delete once aggregate_regions.py is moved up @@ -342,9 +340,9 @@ psh_supply_curves_duration.csv,inputs/storage/PSH_supply_curves_durations.csv,in psh_supply_curves_capacity.csv,inputs/supply_curve/PSH_supply_curves_capacity_{pshsupplycurve}.csv,int(sw.GSw_Storage) != 0,sum,geosize,r,wide,,1,0,,,,,, psh_supply_curves_cost.csv,inputs/supply_curve/PSH_supply_curves_cost_{pshsupplycurve}.csv,int(sw.GSw_Storage) != 0,mean,uniform,r,wide,,1,0,,,,,, pv_cf_improve.csv,,1,ignore,ignore,,,,0,,,,,,, -pvb_agg.csv,inputs/sets/pvb_agg.csv,1,ignore,ignore,,,,,0,,,,pvb_agg,, +pvb_agg.csv,inputs/sets/pvb_agg.csv,1,ignore,ignore,,,,,0,,,set,pvb_agg,crosswalk between hybrid pv+battery configurations and technology options, pvb_bir.csv,,1,ignore,ignore,,,,,0,,,,,, -pvb_config.csv,inputs/sets/pvb_config.csv,1,ignore,ignore,,,,,,,,,pvb_config,, +pvb_config.csv,inputs/sets/pvb_config.csv,1,ignore,ignore,,,,,,,,set,pvb_config,set of hybrid pv+battery configurations, pvb_ilr.csv,,1,ignore,ignore,,,,,0,,,,,, pvbcapcostmult.csv,,1,ignore,ignore,,,,0,0,,,,,, r.csv,,1,first,ignore,0,,,0,,,1,,,,disaggfunc set to ignore because this file is dynamic to the user-defined spatial aggregation level @@ -362,7 +360,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 regions.csv,,1,ignore,ignore,,,,,0,,,,,,not done but only for retail -resourceclass.csv,inputs/sets/resourceclass.csv,1,ignore,ignore,,,,,,,,,resourceclass,, +resourceclass.csv,inputs/sets/resourceclass.csv,1,ignore,ignore,,,,,,,,set,resourceclass,renewable resource classes, resources.csv,,1,resources,ignore,r,"i,ccreg",i,0,0,,1,,,,disaggfunc set to ignore because this file contains all spatial resolutions valid to the model run retire_penalty.csv,inputs/financials/retire_penalty.csv,1,ignore,ignore,,,,,0,,,,,, retirements.csv,,1,sum,ignore,r,"t,i",,0,0,,1,,,,disaggfunc set to ignore because data will be written at county resolution by writecapdat.py @@ -374,11 +372,9 @@ rggicon.csv,inputs/emission_constraints/rggicon.csv,int(sw.GSw_RGGI) != 0,ignore rps_fraction.csv,inputs/state_policies/rps_fraction.csv,int(sw.GSw_StateRPS) != 0,ignore,ignore,st,st,,1,0,,,,,, rsc_combined.csv,,1,sc_cat,ignore,r,"*i,rscbin",*i,0,0,value,1,,,,done for upv/csp/wind; disaggfunc set to ignore because supply curve data is already at county level rsc_wsc.csv,,1,ignore,ignore,,,,,0,,,,,, -sc_cat.csv,inputs/sets/sc_cat.csv,1,ignore,ignore,,,,,0,,,,sc_cat,, +sc_cat.csv,inputs/sets/sc_cat.csv,1,ignore,ignore,,,,,0,,,set,sc_cat,supply curve categories (capacity and cost), scalars.csv,inputs/scalars.csv,1,ignore,ignore,,,,,0,,1,,,, set_actualszn.csv,,1,ignore,ignore,,,,,0,,,,,, -set_allh.csv,,1,ignore,ignore,,,,,0,,,,,, -set_allszn.csv,,1,ignore,ignore,,,,,0,,,,,, set_h.csv,,1,ignore,ignore,,,,,,,,,,, set_szn.csv,,1,ignore,ignore,,,,,,,,,,, site_bin_map.csv,,1,ignore,ignore,,,,,0,,,,,, @@ -398,7 +394,7 @@ supplycurve_egs.csv,inputs/supply_curve/supplycurve_egs-reference.csv,int(sw.GSw supplycurve_upv.csv,inputs/supply_curve/supplycurve_upv-{GSw_SitingUPV}.csv,1,ignore,ignore,region,,,,0,,,,,,No fix_col (only region_col) because this is an intermediate input file supplycurve_wind-ofs.csv,inputs/supply_curve/supplycurve_wind-ofs-{GSw_SitingWindOfs}.csv,int(sw.GSw_OfsWind) != 0,ignore,ignore,region,,,,0,,,,,,No fix_col (only region_col) because this is an intermediate input file supplycurve_wind-ons.csv,inputs/supply_curve/supplycurve_wind-ons-{GSw_SitingWindOns}.csv,1,ignore,ignore,region,,,,0,,,,,,No fix_col (only region_col) because this is an intermediate input file -sw.csv,inputs/sets/sw.csv,1,ignore,ignore,,,,,0,,,,sw,, +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, switches.csv,,1,ignore,ignore,,,,,0,,,,,, szn_actualszn.csv,,1,ignore,ignore,,,,,0,,,,,, tc_phaseout_schedule.csv,inputs/financials/tc_phaseout_schedule_{GSw_TCPhaseout_schedule}.csv,int(sw.GSw_TCPhaseout) != 0,ignore,ignore,,,,,0,,,,,, @@ -412,12 +408,12 @@ techs_banned_rps.csv,inputs/state_policies/techs_banned_rps.csv,int(sw.GSw_State temp_UnappWaterMult.csv,,1,ignore,ignore,,,,,0,,1,,,,intermediate file created in climateprep.py to create climate_UnappWaterMult.csv temp_UnappWaterSeaAnnDistr.csv,,1,ignore,ignore,,,,,0,,1,,,,intermediate file created in climateprep.py to create climate_UnappWaterSeaAnnDistr.csv temp_hydadjsea.csv,,1,ignore,ignore,,,,,0,,1,,,,intermediate file created in climateprep.py to create climate_hydadjsea.csv -tg_rsc_cspagg.csv,inputs/sets/tg_rsc_cspagg.csv,1,ignore,ignore,,,,,0,,,,tg_rsc_cspagg,, +tg_rsc_cspagg.csv,inputs/sets/tg_rsc_cspagg.csv,1,ignore,ignore,,,,,0,,,set,tg_rsc_cspagg,csp technologies that belong to the same class, tg_rsc_cspagg_tmp.csv,inputs/waterclimate/tg_rsc_cspagg_tmp.csv,(int(sw.GSw_CSP) != 0) and (int(sw.GSw_WaterMain) != 0),ignore,ignore,,,,,0,,,,,, -tg_rsc_upvagg.csv,inputs/sets/tg_rsc_upvagg.csv,1,ignore,ignore,,,,,0,,,,tg_rsc_upvagg,, +tg_rsc_upvagg.csv,inputs/sets/tg_rsc_upvagg.csv,1,ignore,ignore,,,,,0,,,set,tg_rsc_upvagg,pv and pvb technologies that belong to the same class, timestamps.csv,,1,ignore,ignore,,,,,0,,,,,, trancap_fut.csv,,1,sum,ignore,"*r,rr","status,trtype,t",,0,0,drop_dup_r,1,,,,disaggfunc set to ignore because all transmisison data will be read into model at the correct spatial resolution -trancap_fut_cat.csv,inputs/sets/trancap_fut_cat.csv,1,ignore,ignore,,,,,,,,,trancap_fut_cat,, +trancap_fut_cat.csv,inputs/sets/trancap_fut_cat.csv,1,ignore,ignore,,,,,,,,set,trancap_fut_cat,categories of near-term transmission projects that describe the likelihood of being completed, trancap_init_energy.csv,,1,ignore,ignore,"*r,rr",trtype,,0,0,drop_dup_r,1,,,, trancap_init_prm.csv,,1,ignore,ignore,"*r,rr",trtype,,0,0,drop_dup_r,1,,,, trancap_init_transgroup.csv,,1,ignore,ignore,,,,0,0,,,,,, @@ -430,7 +426,7 @@ transmission_cost_ac.csv,inputs/transmission/transmission_cost_ac_{GSw_TransUpgr transmission_cost_dc.csv,inputs/transmission/transmission_cost_dc_{lvl}.csv,1,trans_lookup,ignore,"r,rr",,,0,0,drop_dup_r,,,,, transmission_distance.csv,inputs/transmission/transmission_distance_{lvl}.h5,1,trans_lookup,ignore,"r,rr",,,0,0,drop_dup_r,,,,,Stored in wide-format h5 to reduce county filesize but converted to long in copy_files.py transmission_line_fom.csv,,1,trans_lookup,ignore,"*r,rr",trtype,,0,0,drop_dup_r,1,,,,disaggfunc set to ignore because all transmisison data will be read into model at the correct spatial resolution -trtype.csv,inputs/sets/trtype.csv,1,ignore,ignore,,,,,,,,,trtype,, +trtype.csv,inputs/sets/trtype.csv,1,ignore,ignore,,,,,,,,set,trtype,transmission capacity type, unapp_water_sea_distr.csv,inputs/waterclimate/unapp_water_sea_distr.csv,int(sw.GSw_WaterMain) != 0,mean,geosize,r,"wst,wide",,1,0,,,,,, UnappWaterMult.csv,inputs/climate/{climatescen}/UnappWaterMult.csv,int(sw.GSw_ClimateWater) != 0,mean,uniform,r,"wst,month,t",,0,0,,,,,, UnappWaterMultAnn.csv,inputs/climate/{climatescen}/UnappWaterMultAnn.csv,int(sw.GSw_ClimateWater) != 0,mean,uniform,r,"wst,t",,0,0,,,,,, @@ -439,10 +435,10 @@ unbundled_limit_ces.csv,inputs/state_policies/unbundled_limit_ces.csv,int(sw.GSw unbundled_limit_rps.csv,inputs/state_policies/unbundled_limit_rps.csv,int(sw.GSw_StateRPS) != 0,ignore,ignore,st,,,,0,,,,,, unitdata.csv,inputs/capacity_exogenous/ReEDS_generator_database_final_{unitdata}.csv,1,ignore,ignore,FIPS,,,,0,,,,,, unitsize.csv,,1,ignore,ignore,,,,,0,,1,,,, -unitspec_upgrades.csv,inputs/sets/unitspec_upgrades.csv,1,ignore,ignore,,,,,0,,,,unitspec_upgrades,, +unitspec_upgrades.csv,inputs/sets/unitspec_upgrades.csv,1,ignore,ignore,,,,,0,,,set,unitspec_upgrades,upgraded technologies that get unit-specific characteristics, upgrade_costs_ccs_coal.csv,,1,ignore,ignore,,,,,0,,,,,, upgrade_costs_ccs_gas.csv,,1,ignore,ignore,,,,,0,,,,,, -upgrade_hintage_char.csv,inputs/sets/upgrade_hintage_char.csv,1,ignore,ignore,,,,,0,,,,upgrade_hintage_char,, +upgrade_hintage_char.csv,inputs/sets/upgrade_hintage_char.csv,1,ignore,ignore,,,,,0,,,set,upgrade_hintage_char,sets to operate over in extension of hintage_data characteristics when sw_upgrades = 1, upgrade_link.csv,inputs/upgrades/upgrade_link.csv,1,ignore,ignore,,,,,0,,,,,, upgrade_mult_advanced.csv,inputs/upgrades/upgrade_mult_atb23_ccs_mid.csv,int(sw.GSw_UpgradeCost_Mult) != 0,ignore,ignore,,,,,0,,,,,, upgrade_mult_conservative.csv,inputs/upgrades/upgrade_mult_atb23_ccs_con.csv,int(sw.GSw_UpgradeCost_Mult) == 2,ignore,ignore,,,,,0,,,,,, @@ -451,23 +447,10 @@ upgrade_mult_mid.csv,inputs/upgrades/upgrade_mult_atb23_ccs_mid.csv,"int(sw.GSw_ upgradelink_water.csv,inputs/upgrades/upgradelink_water.csv,1,ignore,ignore,,,,,0,,,,,, uranium_price.csv,inputs/fuelprices/uranium_{uraniumscen}.csv,1,ignore,ignore,,,,0,0,,,,,, va_ng_crf_penalty.csv,,1,ignore,ignore,,,,0,0,,,,,, -val_aggreg.csv,,1,ignore,ignore,,,,0,none,,,,,, val_ba.csv,,1,ignore,ignore,,,,,,,1,,,, -val_itlgrp.csv,,1,ignore,ignore,,,,,,,1,,,, -val_cendiv.csv,,1,ignore,ignore,,,,0,none,,,,,, -val_country.csv,,1,ignore,ignore,,,,0,none,,,,,, -val_county.csv,,1,ignore,ignore,,,,0,none,,,,,, +county.csv,,1,ignore,ignore,,,,0,none,,,,,, val_cs.csv,,1,ignore,ignore,,,,0,none,,,,,, -val_hurdlereg.csv,,1,ignore,ignore,,,,0,none,,,,,, -val_interconnect.csv,,1,ignore,ignore,,,,0,none,,,,,, -val_nercr.csv,,1,ignore,ignore,,,,0,none,,,,,, -val_h2ptcreg.csv,,1,ignore,ignore,,,,0,none,,,,,, -val_r.csv,,1,ignore,ignore,0,,,0,none,,1,,,, val_r_all.csv,,1,ignore,ignore,,,,0,none,,,,,, -val_st.csv,,1,ignore,ignore,,,,0,none,,,,,, -val_transgrp.csv,,1,ignore,ignore,,,,0,none,,,,,, -val_transreg.csv,,1,ignore,ignore,,,,0,none,,,,,, -val_usda_region.csv,,1,ignore,ignore,,,,0,none,,,,,, 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),mean,geosize,r,wide,,1,0,,,,,,not yet ready for county-level disaggregation @@ -476,11 +459,12 @@ wind_retirements.csv,,1,sum,ignore,r,"i,v,wide",,1,0,,1,,,,disaggfunc set to ign windcfmult.csv,,1,ignore,ignore,,,,1,0,,,,,, windcfout.csv,,1,ignore,ignore,,,,1,0,,,,,, windows.csv,inputs/userinput/windows_{windows_suffix}.csv,1,ignore,ignore,,,,,0,,,,,, -wst_climate.csv,inputs/sets/wst_climate.csv,1,ignore,ignore,,,,,0,,,,wst_climate,, +wst_climate.csv,inputs/sets/wst_climate.csv,1,ignore,ignore,,,,,0,,,set,wst_climate,, x.csv,,1,ignore,ignore,,,,,0,,,,,, x_r.csv,,1,first,ignore,"*x,r",,,0,0,,1,,,,handled in writesupplycurves.py -yearafter.csv,inputs/sets/yearafter.csv,1,ignore,ignore,,,,,,,,,yearafter,, +yearafter.csv,inputs/sets/yearafter.csv,1,ignore,ignore,,,,,,,,set,yearafter,set to loop over for the final year calculation, inputs.gdx,,1,ignore,ignore,,,,,0,,,,,, +inputs.h5,,1,ignore,ignore,,,,,0,,,,,, plexos_inputs.gdx,,1,ignore,ignore,,,,,0,,,,,, load.h5,,1,ignore,ignore,wide,"year,hour",,1,keepindex,,1,,,,Disaggregation and aggregation handled in hourly_load.py recf.h5,,1,recf,ignore,wide,datetime,,1,keepindex,,1,,,, diff --git a/reeds/input_processing/transmission.py b/reeds/input_processing/transmission.py index 8b733df6..88f32895 100644 --- a/reeds/input_processing/transmission.py +++ b/reeds/input_processing/transmission.py @@ -52,8 +52,7 @@ valid_regions = {} for level in ['r','itlgrp','transgrp']: - valid_regions[level] = pd.read_csv( - os.path.join(inputs_case, f'val_{level}.csv'), header=None).squeeze(1).tolist() + valid_regions[level] = reeds.io.read_input(inputs_case, level).squeeze(1).tolist() #%% =========================================================================== @@ -494,10 +493,12 @@ def getloss(row, trtype='AC'): os.path.join(inputs_case, f'tsc_{label}.csv'), index=False, ) -transmission_cost_ac.tscbin.drop_duplicates().to_csv( - os.path.join(inputs_case, 'tscbin.csv'), - index=False, - header=False, +reeds.io.write_to_inputs_h5( + df=transmission_cost_ac.tscbin.drop_duplicates().rename(), + key='tscbin', + case=inputs_case, + gamstype='set', + comment='transmission upgrade supply curve bins', ) diff --git a/reeds/input_processing/writecapdat.py b/reeds/input_processing/writecapdat.py index 42a391fa..b123be47 100644 --- a/reeds/input_processing/writecapdat.py +++ b/reeds/input_processing/writecapdat.py @@ -763,6 +763,12 @@ def main(reeds_path, inputs_case, agglevel, regions): .stack().rename_axis(['*r','t']).rename('MW').round(3) ) + #%% Prescribed capacity categories + fpath = Path(reeds.io.reeds_path, 'inputs', 'sets', '_pcat.csv') + _pcat = pd.read_csv(fpath, header=None).squeeze(1).tolist() + i = reeds.io.read_input(inputs_case, 'i').squeeze(1).tolist() + pcat = pd.Series(i + _pcat) + #%%---------------------------------------------------------------------------- ############################## @@ -796,10 +802,14 @@ def main(reeds_path, inputs_case, agglevel, regions): 'hydcapadj_ccszn' : hydcapadj_ccszn[['*i','ccseason','r','value']], 'can_imports_capacity' : can_imports_capacity, 'geoexist' : geoexist, - 'h2_ba_share': h2_ba_share_out + 'h2_ba_share': h2_ba_share_out, + 'pcat': pcat, } + comments = { + 'pcat': 'prescribed capacity categories', + } - return files_out + return files_out, comments #%% =========================================================================== ### --- PROCEDURE --- @@ -831,17 +841,27 @@ def main(reeds_path, inputs_case, agglevel, regions): # For mixed resolution runs the main function of writecapdat needs to be executed separately for each desired resolution # Then the data from each resolution are combined and written to the inputs_case folder + comments = {} if agglevel_variables['lvl'] == 'mult': for resolution in agglevel_variables['agglevel']: if resolution == 'aggreg': - aggreg_data = main(reeds_path, inputs_case, agglevel=resolution, - regions=agglevel_variables['ba_regions'] ) + aggreg_data, _comments = main( + reeds_path, inputs_case, agglevel=resolution, + regions=agglevel_variables['ba_regions'], + ) + comments = {**comments, **_comments} if resolution == 'ba': - ba_data = main(reeds_path, inputs_case, agglevel=resolution, - regions=agglevel_variables['ba_regions']) + ba_data, _comments = main( + reeds_path, inputs_case, agglevel=resolution, + regions=agglevel_variables['ba_regions'], + ) + comments = {**comments, **_comments} if resolution == 'county': - county_data = main(reeds_path, inputs_case, agglevel=resolution, - regions=agglevel_variables['county_regions'],) + county_data, _comments = main( + reeds_path, inputs_case, agglevel=resolution, + regions=agglevel_variables['county_regions'], + ) + comments = {**comments, **_comments} # Combine and write mixed resolution data # ReEDS only supports county-BA, county-aggreg combinations @@ -869,8 +889,8 @@ def main(reeds_path, inputs_case, agglevel, regions): # Single Resolution Procedure else: agglevel = agglevel_variables['agglevel'] - regions = pd.read_csv(os.path.join(inputs_case,f'val_{agglevel}.csv'),header=None).squeeze(1).values - data = main(reeds_path, inputs_case,agglevel, regions) + regions = reeds.io.read_input(inputs_case, agglevel).squeeze(1).values + data, comments = main(reeds_path, inputs_case,agglevel, regions) # Write it print('Writing out capacity data') @@ -885,11 +905,20 @@ def main(reeds_path, inputs_case, agglevel, regions): 'cap_cspns': True, 'can_imports_capacity': True, } + gamstype = { + 'pcat': 'set', + } for key, df in data.items(): - df.to_csv( - os.path.join(inputs_case, f'{outname.get(key, key)}.csv'), - index=keep_index.get(key, False), - ) + if gamstype.get(key, False): + reeds.io.write_to_inputs_h5( + df=df, key=outname.get(key, key), case=inputs_case, gamstype=gamstype[key], + comment=comments.get(key, ''), + ) + else: + df.to_csv( + os.path.join(inputs_case, f'{outname.get(key, key)}.csv'), + index=keep_index.get(key, False), + ) reeds.log.toc(tic=tic, year=0, process='input_processing/writecapdat.py', path=os.path.join(inputs_case,'..')) diff --git a/reeds/input_processing/writedrshift.py b/reeds/input_processing/writedrshift.py index 2d6d99dd..a8bc631c 100644 --- a/reeds/input_processing/writedrshift.py +++ b/reeds/input_processing/writedrshift.py @@ -59,12 +59,7 @@ #%% Inputs from switches sw = reeds.io.get_switches(inputs_case) - - val_r = ( - pd.read_csv(os.path.join(inputs_case, "val_r.csv"), header=None) - .squeeze(1) - .tolist() - ) + val_r = reeds.io.read_input(inputs_case, 'r').squeeze(1).tolist() ### Create empty EVMC data files if GSw_EVMC == 0: evmc_files = [ diff --git a/reeds/input_processing/writesupplycurves.py b/reeds/input_processing/writesupplycurves.py index 342b5e94..39dd1722 100644 --- a/reeds/input_processing/writesupplycurves.py +++ b/reeds/input_processing/writesupplycurves.py @@ -987,10 +987,7 @@ def main( sitemap = reeds.io.get_sitemap() county2zone = reeds.io.get_county2zone(os.path.dirname(os.path.normpath(inputs_case))) interconnection_cost['r'] = interconnection_cost.index.map(sitemap.FIPS).map(county2zone) - val_r = pd.read_csv( - os.path.join(inputs_case, 'val_r.csv'), - header=None, - ).squeeze(1).values + val_r = reeds.io.read_input(inputs_case, 'r').squeeze(1).values spursites = interconnection_cost.loc[interconnection_cost.r.isin(val_r)].copy() spursites['x'] = 'i' + spursites.index.astype(str) if write: diff --git a/reeds/io.py b/reeds/io.py index d4bcd313..9d35ab7b 100644 --- a/reeds/io.py +++ b/reeds/io.py @@ -5,10 +5,12 @@ import datetime import h5py import ctypes +import inspect import numpy as np import pandas as pd import geopandas as gpd from pathlib import Path +from typing import Literal from pandas.api.types import is_float_dtype sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) @@ -450,6 +452,60 @@ def get_h2_storage_sites(h2_storage_type="salt"): ### Read files from a ReEDS case +def read_h5(h5path:str|Path, key:str) -> pd.DataFrame: + """Read a key from a ReEDS-formatted .h5 file""" + if not Path(h5path).is_file(): + raise FileNotFoundError(h5path) + with h5py.File(h5path, 'r') as f: + columns = [i.decode() for i in list(f[key]['columns'])] + try: + df = pd.DataFrame({col: f[key][col] for col in columns}) + except KeyError: + df = pd.DataFrame(columns=columns) + for col in df: + if df[col].dtype == 'O': + df[col] = df[col].str.decode('utf-8') + return df + + +def read_input( + case:str|Path, + name:str, + **kwargs, +) -> pd.DataFrame: + """ + Read a ReEDS input set or parameter (name) from {case}/inputs_case. + If {case}/inputs_case/inputs.h5 exists, the named parameter is read from there; + otherwise, it is read from {case}/inputs_case/{name}.csv; + if that doesn't exist, an error is raised. + + Args: + case (str or Path): Absolute path to a ReEDS case + name (str): Name of the ReEDS parameter or {case}/inputs_case/{name}.csv + + Returns: + pd.DataFrame + """ + key = Path(name).stem + h5path = Path(reeds.io.standardize_case(case), 'inputs_case', 'inputs.h5') + csvpath = Path(h5path.parent, f'{key}.csv') + if h5path.is_file(): + try: + df = read_h5(h5path, key) + ## Fall back to csv if the requested dataset is not yet in inputs.h5 + except KeyError: + try: + df = pd.read_csv(csvpath, **kwargs) + except FileNotFoundError: + err = f"{h5path} has no '{name}' key and {csvpath} does not exist" + raise FileNotFoundError(err) + elif csvpath.is_file(): + df = pd.read_csv(csvpath, **kwargs) + else: + raise FileNotFoundError(f'Neither {h5path} nor {csvpath} exist') + return df + + def read_output( case: str, filename: str, @@ -481,12 +537,7 @@ def read_output( if os.path.exists(h5path) and not filename.endswith('.csv'): key = os.path.basename(filename) try: - with h5py.File(h5path, 'r') as f: - columns = [i.decode() for i in list(f[key]['columns'])] - df = pd.DataFrame({col: f[key][col] for col in columns}) - for col in df: - if df[col].dtype == 'O': - df[col] = df[col].str.decode('utf-8') + df = read_h5(h5path, key) except KeyError: ## Empty dataframes aren't written to h5 file, so make one ourselves fpath = Path(case, 'reeds', 'core', 'terminus', 'report_params.csv') @@ -1015,10 +1066,7 @@ def get_temperatures(case, tz_in='UTC', tz_out='Etc/GMT+6', subset_years=True): ## Add one more year on either end of weather years to allow for timezone conversion weather_years = sw.resource_adequacy_years_list read_years = range(min(weather_years)-1, max(weather_years)+2) - val_st = ( - pd.read_csv(os.path.join(inputs_case, 'val_st.csv'), header=None) - .squeeze(1).values - ) + val_st = reeds.io.read_input(inputs_case, 'st').squeeze(1).values ### Load temperatures _temperatures = {} with h5py.File(h5path, 'r') as f: @@ -1724,6 +1772,126 @@ def write_to_h5( ) +def write_to_inputs_h5( + df:pd.DataFrame|pd.Series, + key:str, + case:str|Path, + gamstype:Literal['set','parameter'], + comment:str='', + units:str='', + verbose:int|bool=1, + **kwargs, +): + """ + Write a Series or DataFrame (long format) to a ReEDS-formatted inputs.h5 file + + Args: + df (pd.Series or pd.DataFrame): Long-formatted series/dataframe (where "long + format" means there is a single data column; all the other columns are indices). + If an unnamed pd.Series is provided, it is assumed to be a primary set and + is renamed to '*'. Otherwise, the name of the pd.Series (or the column names of + a pd.DataFrame) should match the indices used by the corresponding set/parameter + in GAMS. + key (str): Name of the key to be written to inputs.h5 + case (str or Path): Absolute path to a ReEDS case OR inputs_case OR inputs.h5. + That is, any of the following work as inputs: + - {absolute_casepath} + - {absolute_casepath}/inputs_case + - {absolute_casepath}/inputs_case/inputs.h5 + gamstype (str): 'set' or 'parameter', indicating the kind of data to write + comment (str): Comment assigned to the data in GAMS. + If the `units` input is provided, the comment is written as, + "[{units}] {comment} (written by {script that called this function})". + If the `units` input is not provided, the comment is written as, + "{comment} (written by {script that called this function})". + units (str): Physical units, like MW or MMBtu + verbose (bool or int): If true, prints a message to the log after successful write + """ + ### Parse inputs + if Path(case).name == 'inputs_case': + h5path = os.path.join(case, 'inputs.h5') + elif Path(case).suffix == '.h5': + h5path = case + else: + h5path = Path(case, 'inputs_case', 'inputs.h5') + + dfwrite = df.copy() + ## We write all the info in the dataframe but ignore the index, so if sets are used + ## as the index, move them into the dataframe + if isinstance(dfwrite, pd.Series): + if dfwrite.name is None: + dfwrite.name = '*' + dfwrite = dfwrite.to_frame() + if isinstance(dfwrite.index, pd.MultiIndex) or dfwrite.index.name: + dfwrite = dfwrite.reset_index() + ## Format for GAMS: The final column of a parameter should be named 'Value' and + ## should contain the data as floats; all the other columns are treated as indices + if gamstype == 'parameter': + dfwrite.columns = dfwrite.columns.tolist()[:-1] + ['Value'] + ### Write record to h5 file + calling_file = Path(inspect.stack()[-1][1]).name + attrs = {'gamstype': gamstype.lower(), 'written_by': calling_file} + if len(units): + attrs['comment'] = f'[{units}] {comment} (written by {calling_file})' + else: + attrs['comment'] = f'{comment} (written by {calling_file})' + write_to_h5( + dfwrite, + key, + h5path, + attrs=attrs, + **kwargs, + ) + if verbose: + print(f'{Path(h5path).name}: Wrote {key} from {calling_file}') + + +def write_csv_to_inputs_h5( + filepath:str|Path, + case:str|Path, + gamstype:Literal['set','parameter'], + comment:str='', + **kwargs, +): + """ + Read a csv file (formatted as described in inputs/sets/README.md) + and write it to inputs.h5 + """ + df = pd.read_csv(filepath, dtype=str, header=None) + key = Path(filepath).stem + if df.shape[1] == 1: + ## Subsets have a header column beginning with '*'; + ## primary sets do not have a header + primary = False if df.loc[0,0].startswith('*') else True + else: + ## Multidimensional sets must be subsets so must have a header + primary = False + ## For primary sets we use the set name as the output header; + ## for subsets we read the header from the file + if primary: + df.columns = ['*'] + else: + df.columns = df.loc[0].str.replace('*','').values + df = df.drop(0) + ## No other *'s are allowed + if df.applymap(lambda x: '*' in x).any().any(): + err = ( + "'*' characters are only allowed in subset headers.\n" + f"{filepath} has at least one disallowed '*' character." + ) + raise ValueError(err) + ## Write it + reeds.io.write_to_inputs_h5( + df=df, + key=key, + case=case, + comment=comment, + gamstype=gamstype, + **kwargs, + ) + return df + + def write_output_to_h5( df, key, diff --git a/reeds/reedsplots.py b/reeds/reedsplots.py index dae1aa92..479386ef 100644 --- a/reeds/reedsplots.py +++ b/reeds/reedsplots.py @@ -1239,9 +1239,7 @@ def plot_transmission_utilization( dftrans['trans_flow_power'].loc[dftrans['trans_flow_power'].Value < 0, ['rr','r']].values ) dftrans['trans_flow_power'].Value = dftrans['trans_flow_power'].Value.abs() - val_r = pd.read_csv( - os.path.join(case,'inputs_case','val_r.csv'), header=None, - ).squeeze(1).values.tolist() + val_r = reeds.io.read_input(case, 'r').squeeze(1).tolist() ### Combine all transmission types for data in ['trans_flow_power','trans_cap']: dftrans[data]['trtype'] = 'all' @@ -1736,9 +1734,7 @@ def plot_prmtrade( dfba = dfmap['r'] dfstates = dfmap['st'] ## Downselect to modeled regions - val_r = pd.read_csv( - os.path.join(case,'inputs_case','val_r.csv'), header=None, - ).squeeze(1).values.tolist() + val_r = reeds.io.read_input(case, 'r').squeeze(1).tolist() dfba = dfba.loc[val_r].copy() if sw.get('GSw_RegionResolution', 'ba') != 'county': @@ -1825,9 +1821,7 @@ def plot_average_flow( dfmap = reeds.io.get_dfmap(case) dfba = dfmap['r'] dfstates = dfmap['st'] - val_r = pd.read_csv( - os.path.join(case,'inputs_case','val_r.csv'), header=None, - ).squeeze(1).values.tolist() + val_r = reeds.io.read_input(case, 'r').squeeze(1).tolist() if extent.lower() not in ['usa','full','nation','us','country','all']: dfba = dfba.loc[val_r] diff --git a/reeds/remote.py b/reeds/remote.py index 11cf2879..7b6c4e35 100644 --- a/reeds/remote.py +++ b/reeds/remote.py @@ -98,6 +98,8 @@ def download_remote_files(only=None, force=False, access_token=None): "of inputs/remote_files.csv." ) raise ValueError(err) + else: + print(f'local version ok: {filename}') ## Always update the link linkpath = Path(row.linkpath) linkpath.unlink(missing_ok=True) diff --git a/reeds/resource_adequacy/prep_data.py b/reeds/resource_adequacy/prep_data.py index f7ad96c6..eebb2f0a 100644 --- a/reeds/resource_adequacy/prep_data.py +++ b/reeds/resource_adequacy/prep_data.py @@ -174,10 +174,7 @@ def main(t, casedir, iteration=0): )) try: - offshore = pd.read_csv( - os.path.join(casedir, 'inputs_case', 'offshore.csv'), - header=None, - ).squeeze(1).tolist() + offshore = reeds.io.read_input(casedir, 'offshore').squeeze(1).tolist() except pd.errors.EmptyDataError: offshore = [] diff --git a/reeds/results.py b/reeds/results.py index 92ab66cc..a475cfe5 100644 --- a/reeds/results.py +++ b/reeds/results.py @@ -318,10 +318,7 @@ def calc_systemcost( scalars = reeds.io.get_scalars(case) # Valid regions - val_r = pd.read_csv( - os.path.join(inputs_case, 'val_r.csv'), - header=None, - ).squeeze(1).values + val_r = reeds.io.read_input(case, 'r').squeeze(1).values # Rename columns to match the expected format systemcost.rename(columns={'t':'year', 'sys_costs':'cost_cat'}, inplace=True) @@ -530,10 +527,7 @@ def calc_reinforcement_spur_capacity_miles(case): scalars = reeds.io.get_scalars(case) # Valid regions - val_r = pd.read_csv( - os.path.join(inputs_case, 'val_r.csv'), - header=None, - ).squeeze(1).values + val_r = reeds.io.read_input(case, 'r').squeeze(1).values # Get the spur/reinforcement distance for each i/r/rscbin spur_parameters = pd.read_csv(os.path.join(inputs_case, 'spur_parameters.csv')) diff --git a/runreeds.py b/runreeds.py index 5fb0a021..ac9a8b6a 100644 --- a/runreeds.py +++ b/runreeds.py @@ -1302,6 +1302,7 @@ def write_batch_script( 'transmission', 'outage_rates', 'hourly_repperiods', + 'h5_to_gdx', ]: OPATH.writelines(f"echo {'-'*12+'-'*len(s)}\n") OPATH.writelines(f"echo 'starting {s}.py'\n")