From c60f554147991a631745d178757f87a885d536f3 Mon Sep 17 00:00:00 2001 From: Brian Sergi Date: Fri, 4 Sep 2026 19:11:27 -0600 Subject: [PATCH 1/6] drop clipping of supply curve costs --- reeds/input_processing/writesupplycurves.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/reeds/input_processing/writesupplycurves.py b/reeds/input_processing/writesupplycurves.py index f726a6252..4669efb11 100644 --- a/reeds/input_processing/writesupplycurves.py +++ b/reeds/input_processing/writesupplycurves.py @@ -30,8 +30,6 @@ numbins_other = 5 ### Rounding precision decimals = 7 -### spur_cutoff [$/MW]: Cutoff for spur line costs; clip cost for sites with larger costs -spur_cutoff = 1e7 # %% =========================================================================== ### --- FUNCTIONS --- @@ -113,8 +111,6 @@ def agg_supplycurve( ) ### Aggregate it dfout = dfin.groupby(index_cols).agg(aggs) - ### Clip negative costs and costs above cutoff - dfout.supply_curve_cost_per_mw = dfout.supply_curve_cost_per_mw.clip(lower=0, upper=spur_cutoff) return dfin, dfout From 64bd14b9eafe51677e96cd88e7335db2c6768208 Mon Sep 17 00:00:00 2001 From: Brian Sergi Date: Fri, 4 Sep 2026 19:33:11 -0600 Subject: [PATCH 2/6] remove references to spur_cutoff --- reeds/input_processing/writesupplycurves.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/reeds/input_processing/writesupplycurves.py b/reeds/input_processing/writesupplycurves.py index 4669efb11..32718cc11 100644 --- a/reeds/input_processing/writesupplycurves.py +++ b/reeds/input_processing/writesupplycurves.py @@ -71,7 +71,6 @@ def agg_supplycurve( numbins_tech, bin_method='equal_cap_cut', bin_col='supply_curve_cost_per_mw', - spur_cutoff=1e7, deflate=None, ): """ @@ -205,7 +204,6 @@ def main( scpath=os.path.join(inputs_case,f'supplycurve_wind-{s}.csv'), inputs_case=inputs_case, numbins_tech=numbins[f'wind-{s}'], - spur_cutoff=spur_cutoff, deflate=deflate, ) @@ -303,7 +301,6 @@ def main( scpath=os.path.join(inputs_case, 'supplycurve_upv.csv'), inputs_case=inputs_case, numbins_tech=numbins['upv'], - spur_cutoff=spur_cutoff, deflate=deflate, ) @@ -383,7 +380,6 @@ def main( scpath=os.path.join(inputs_case, 'supplycurve_csp.csv'), inputs_case=inputs_case, numbins_tech=numbins['csp'], - spur_cutoff=spur_cutoff, deflate=deflate, ) @@ -464,7 +460,6 @@ def main( ), numbins_tech=numbins[s], inputs_case=inputs_case, - spur_cutoff=spur_cutoff, deflate=deflate ) spurout_list.append( From cb7d64b524fc154bb2269e4db59398a42ba0567e Mon Sep 17 00:00:00 2001 From: Brian Sergi Date: Tue, 6 Oct 2026 09:46:37 -0600 Subject: [PATCH 3/6] drop ac suffix from cost columns to fix write_site_parameters.py --- hourlize/write_site_parameters.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/hourlize/write_site_parameters.py b/hourlize/write_site_parameters.py index 6ab073f14..17a04be1e 100644 --- a/hourlize/write_site_parameters.py +++ b/hourlize/write_site_parameters.py @@ -116,6 +116,16 @@ _diff = len(outcols) - dfland.shape[1] assert _diff == 0, len(_diff) +# drop ac suffix for cost columns +cost_cols = { + 'cost_spur_usd_per_mw_ac': 'cost_spur_usd_per_mw', + 'cost_poi_usd_per_mw_ac': 'cost_poi_usd_per_mw', + 'cost_reinforcement_usd_per_mw_ac': 'cost_reinforcement_usd_per_mw', + 'cost_total_trans_usd_per_mw_ac': 'cost_total_trans_usd_per_mw' +} +dfland = dfland.rename(columns=cost_cols) + +# subset to outcols dfland = dfland[list(outcols.keys())].astype(outcols) #%% Write it From a71a60bad150f0ab38c24fa7d082ee291f8c75fa Mon Sep 17 00:00:00 2001 From: Brian Sergi Date: Tue, 6 Oct 2026 13:40:59 -0600 Subject: [PATCH 4/6] add check for negative values --- hourlize/write_site_parameters.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/hourlize/write_site_parameters.py b/hourlize/write_site_parameters.py index 17a04be1e..ff1ef4ebf 100644 --- a/hourlize/write_site_parameters.py +++ b/hourlize/write_site_parameters.py @@ -8,6 +8,26 @@ import reeds +def check_negative_values(df, cost_cols): + neg_vals_all = {} + for cc in cost_cols.values(): + if cc in df.columns: + try: + neg_vals = sum(df[cc] < 0) + except: + breakpoint() + if neg_vals: + neg_vals_all[cc] = neg_vals + + if neg_vals_all: + message = "\n".join( + f"{cc} -> {count}" for cc, count in neg_vals_all.items() + ) + raise ValueError( + f"The following cost columns have negative values:\n{message}" + "Check reV data to confirm these." + ) + #%%### Fixed inputs if reeds.io.hpc: remotepath = '/kfs2/shared-projects/reeds' @@ -128,6 +148,10 @@ # subset to outcols dfland = dfland[list(outcols.keys())].astype(outcols) +# check for negative values +check_negative_values(dfland, cost_cols) + + #%% Write it drop = ['trans_gid', 'trans_type'] drop = [] From 658a0efb57df97ac9767d519268e37d2c896c659 Mon Sep 17 00:00:00 2001 From: Brian Sergi Date: Tue, 6 Oct 2026 13:41:25 -0600 Subject: [PATCH 5/6] extend negative check to wind cost parameters --- hourlize/write_site_parameters.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/hourlize/write_site_parameters.py b/hourlize/write_site_parameters.py index ff1ef4ebf..bafde6ae0 100644 --- a/hourlize/write_site_parameters.py +++ b/hourlize/write_site_parameters.py @@ -141,7 +141,8 @@ def check_negative_values(df, cost_cols): 'cost_spur_usd_per_mw_ac': 'cost_spur_usd_per_mw', 'cost_poi_usd_per_mw_ac': 'cost_poi_usd_per_mw', 'cost_reinforcement_usd_per_mw_ac': 'cost_reinforcement_usd_per_mw', - 'cost_total_trans_usd_per_mw_ac': 'cost_total_trans_usd_per_mw' + 'cost_total_trans_usd_per_mw_ac': 'cost_total_trans_usd_per_mw', + 'cost_export_usd_per_mw_ac': 'cost_export_usd_per_mw' } dfland = dfland.rename(columns=cost_cols) @@ -222,6 +223,14 @@ def check_negative_values(df, cost_cols): columns_meshed = {'Zone_ReEDS':'ba'} #%% Make combined dataframe +for offshoretype in ['radial', 'meshed']: + cost_cols_sub = { + k: v for k, v in cost_cols.items() + if v not in dictin[f'offshore_{offshoretype}'].columns + } + dictin[f'offshore_{offshoretype}'] = dictin[f'offshore_{offshoretype}'].rename(columns=cost_cols_sub) + check_negative_values(dictin[f'offshore_{offshoretype}'], cost_cols) + dfwrite = dictin['offshore_radial'][columns_same].copy() for col in columns_different: for offshoretype in ['radial', 'meshed']: From c3351e5fcadc6bf1de424df57a8952cbb7302589 Mon Sep 17 00:00:00 2001 From: bsergi Date: Thu, 8 Oct 2026 09:30:46 -0400 Subject: [PATCH 6/6] clean up write_site_parameters.py --- hourlize/write_site_parameters.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/hourlize/write_site_parameters.py b/hourlize/write_site_parameters.py index bafde6ae0..bfa6b18de 100644 --- a/hourlize/write_site_parameters.py +++ b/hourlize/write_site_parameters.py @@ -11,11 +11,8 @@ def check_negative_values(df, cost_cols): neg_vals_all = {} for cc in cost_cols.values(): - if cc in df.columns: - try: - neg_vals = sum(df[cc] < 0) - except: - breakpoint() + if cc in df.columns: + neg_vals = sum(df[cc] < 0) if neg_vals: neg_vals_all[cc] = neg_vals @@ -24,7 +21,7 @@ def check_negative_values(df, cost_cols): f"{cc} -> {count}" for cc, count in neg_vals_all.items() ) raise ValueError( - f"The following cost columns have negative values:\n{message}" + f"The following cost columns have negative values:\n{message}\n" "Check reV data to confirm these." )