Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
fa7eb03
Create functions for legacy zone-to-county disaggregation and county-…
kodiobika May 18, 2026
9666ee6
Move agg/disagg processing from aggregate_regions.py to copy_files.py…
kodiobika May 18, 2026
928bc91
Ignore aggfunc/disaggfunc for postcopy files and fix bugs
kodiobika May 18, 2026
d01de77
Merge branch 'main' into ko/agg_disagg_refactor
kodiobika May 18, 2026
d10138c
Add function docstrings + cleanup
kodiobika May 20, 2026
a30882b
Merge branch 'main' into ko/agg_disagg_refactor
kodiobika May 20, 2026
15f4bd1
Merge branch 'main' into ko/agg_disagg_refactor
kodiobika May 20, 2026
d49ce8d
Remove duplicate rows from SeaCapAdj_hy.csv
kodiobika May 20, 2026
1fe6627
Cleanup
kodiobika May 20, 2026
f1fd5e9
Delete unused function
kodiobika May 22, 2026
d1c8ea0
Revert changes to SeaCapAdj_hy.csv
kodiobika May 22, 2026
9720eec
For water_req_psh, revert disaggfunc to 'geosize' and change aggfunc …
kodiobika May 22, 2026
e18f59a
Merge branch 'main' into ko/agg_disagg_refactor
kodiobika May 22, 2026
8ad9a42
Merge branch 'main' into ko/agg_disagg_refactor
kodiobika May 22, 2026
6f9e5e8
Merge branch 'main' into ko/agg_disagg_refactor
kodiobika May 22, 2026
4e7ab69
Delete rows from runfiles.csv with null filepaths
kodiobika May 22, 2026
abc5a7e
Delete inputfiles variable and missing file check from aggregate_regi…
kodiobika May 22, 2026
70ee77c
Update reeds/spatial.py
kodiobika May 22, 2026
0931f99
Merge branch 'ko/agg_disagg_refactor' of github.com:ReEDS-Model/ReEDS…
kodiobika May 22, 2026
988dfdb
Add Literal type indicator for disagg_variable
kodiobika May 22, 2026
2f45e9c
Treat 'state_lpf' as valid disagg variable
kodiobika May 23, 2026
3b75dc5
Bugfix
kodiobika May 26, 2026
21dcbcd
Set aggfunc for prescribed builds to 'ignore'
kodiobika May 27, 2026
d17a648
Merge branch 'main' into ko/agg_disagg_refactor
kodiobika May 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 9 additions & 34 deletions reeds/input_processing/aggregate_regions.py
Original file line number Diff line number Diff line change
Expand Up @@ -473,11 +473,6 @@ def agg_disagg(filepath, r2aggreg_glob, r_ba_glob, runfiles_row):
if list_check == agglevel_check :
if row['disaggfunc']=='ignore':
return

# If the file isn't in inputs_case, skip it
if filename not in inputfiles:
if verbose > 1:
logprint(filepath, 'skipped since not in inputs_case')
return

#%%##############
Expand Down Expand Up @@ -1079,33 +1074,6 @@ def agg_disagg(filepath, r2aggreg_glob, r_ba_glob, runfiles_row):
.rename(columns={'wide (1 if any parameters are in wide format)':'wide',
'header (0 if file has column labels)':'header'})
)
#%% If any files are missing, stop and alert the user
inputfiles = sorted([
f.split('inputs_case'+os.sep)[1]
for f in glob(os.path.join(inputs_case,'**'), recursive=True)
if 'metadata' not in f
])
## Drop the directories and backup h17 files
inputfiles = [f for f in inputfiles if (('.' in f) and not f.endswith('_h17.csv'))]
missingfiles = [f for f in inputfiles if (os.path.basename(f) not in runfiles.index.values)
]
if any(missingfiles):
if missing == 'raise':
raise Exception(
'Missing aggregation method for:\n{}\n'
'>>> Need to add entries for these files to runfiles.csv'
.format('\n'.join(missingfiles))
)
else:
from warnings import warn
warn(
'Missing aggregation directions for:\n{}\n'
'>>> For this run, these files are copied without modification'
.format('\n'.join(missingfiles))
)
for f in missingfiles:
shutil.copy(os.path.join(inputs_case, f), os.path.join(inputs_case, f))
print(f'copied {f}, which is missing from runfiles.csv')

#%% Maps (special case)
mapsfile = os.path.join(inputs_case, 'maps.gpkg')
Expand Down Expand Up @@ -1164,8 +1132,15 @@ def agg_disagg(filepath, r2aggreg_glob, r_ba_glob, runfiles_row):
r2aggreg_glob = r2aggreg
r_ba_glob = r_ba

# loop over inputfiles from runfiles and call aggregation/disaggregation function
for filepath in inputfiles:
# loop over transmission_files from runfiles and call aggregation/disaggregation function
transmission_files = [
'transmission_capacity_future.csv',
'transmission_capacity_future_baseline.csv',
'transmission_cost_ac.csv',
'transmission_cost_dc.csv',
'transmission_distance.csv',
]
for filepath in transmission_files:
Comment thread
kodiobika marked this conversation as resolved.
### For debugging: Specify a file
# filepath = ''
### Get the appropriate row from runfiles
Expand Down
106 changes: 34 additions & 72 deletions reeds/input_processing/copy_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -1155,59 +1155,14 @@ def map_and_aggregate(

return df

def upscale_from_county_to_ba(
df,
region_file_entry,
agglevel_variables,
regions_and_agglevel,
aggfunc=None
):
"""
Changes the resolution of the provided region_col from county to BA
or mixed resolution and aggregates according to the provided aggfunc.
"""
original_cols = df.columns
region_col = region_file_entry['region_col']

# Exception for cendiv
if region_col.strip('*') == 'r_cendiv':
val_cendiv = regions_and_agglevel['valid_regions']['cendiv']
df = df.loc[df['r'].isin(regions_and_agglevel['r_county']['county'])]
df = df.loc[:, df.columns.isin(["r"] + val_cendiv)].reset_index(drop=True)
region_col = 'r'

# Aggregate values to ba resolution if not running county-level resolution
# and if county level is not a desired resolution in mixed resolution runs
if 'county' not in agglevel_variables['agglevel']:
df = map_and_aggregate(df,regions_and_agglevel,region_file_entry,region_col,aggfunc)


# Mixed resolution procedure
elif agglevel_variables['lvl'] == 'mult':
df_ba = df[df[region_col].isin(agglevel_variables['BA_county_list'])]
df_ba = map_and_aggregate(df_ba,regions_and_agglevel,region_file_entry,region_col,aggfunc)

# Filter out county regions
df_county = df[df[region_col].isin(agglevel_variables['county_regions'])]
# Combine county and BA
df = pd.concat([df_ba, df_county])

else:
pass

df = df[original_cols]

return df


def write_region_indexed_file(
df,
dir_dst,
source_deflator_map,
sw,
region_file_entry,
regions_and_agglevel,
agglevel_variables
regions_and_agglevel
):
"""
Write a single region-indexed file to the dir_dst directory
Expand All @@ -1216,6 +1171,35 @@ def write_region_indexed_file(
# Get the filetype of the output file from the filename string
filetype_out = os.path.splitext(filename)[1].strip('.')

transmission_files = [
'transmission_capacity_future.csv',
'transmission_capacity_future_baseline.csv',
'transmission_cost_ac.csv',
'transmission_cost_dc.csv',
'transmission_distance.csv',
]
if filename not in transmission_files:
region_col = region_file_entry['region_col']
fix_cols = region_file_entry['fix_cols'].split(',')

if region_file_entry['disaggfunc'] != 'ignore':
df = reeds.spatial.downscale_from_legacy_zone_to_county(
df=df,
region_col=region_col,
fix_cols=fix_cols,
inputs_case=inputs_case,
disaggfunc=region_file_entry['disaggfunc']
)

if region_file_entry['aggfunc'] != 'ignore':
df = reeds.spatial.upscale_from_county_to_zone(
df=df,
region_col=region_col,
fix_cols=fix_cols,
inputs_case=inputs_case,
aggfunc=region_file_entry['aggfunc']
)

#---- Write data to dir_dst (inputs_case) folder ----
if filetype_out == 'h5':
reeds.io.write_profile_to_h5(df, filename, dir_dst)
Expand All @@ -1226,27 +1210,6 @@ def write_region_indexed_file(
case 'bio_supplycurve.csv':
# Adjust for inflation
df['price'] = df['price'].astype(float) * source_deflator_map[filepath]
case (
'can_exports.csv'
| 'can_imports.csv'
| 'demonstration_plants.csv'
| 'distpvcap.csv'
| 'h2_ba_share.csv'
| 'regional_cap_cost_diff.csv'
| 'cendivweights.csv'
| 'cap_existing_psh.csv'
):
# The upscale_from_county_to_ba function correctly handles the different spatial resolution options
# This sections just needs to check if the run is at pure county resolution
# The above listed data need to be upscaled if the run includes anything coarser than county resolution
if agglevel_variables['lvl'] != 'county':
df = upscale_from_county_to_ba(
df=df,
region_file_entry=region_file_entry,
agglevel_variables=agglevel_variables,
regions_and_agglevel=regions_and_agglevel,
aggfunc=region_file_entry.aggfunc
)
case 'unitdata.csv':
fips_ba_map = regions_and_agglevel['ba_county'].dropna().set_index('county')['ba']
df['reeds_ba'] = df['FIPS'].map(fips_ba_map)
Expand Down Expand Up @@ -1301,8 +1264,7 @@ def write_region_indexed_files(
source_deflator_map,
sw,
region_file_entry,
regions_and_agglevel,
agglevel_variables
regions_and_agglevel
)


Expand Down Expand Up @@ -1665,6 +1627,9 @@ def main(reeds_path, inputs_case):

# Copy non-region files
write_non_region_files(non_region_files, sw, inputs_case, regions_and_agglevel, source_deflator_map)

# Write files used for disaggregation
write_disagg_data_files(runfiles, inputs_case)

# Copy region files
write_region_indexed_files(
Expand All @@ -1676,9 +1641,6 @@ def main(reeds_path, inputs_case):
source_deflator_map
)

# Write files used for disaggregation
write_disagg_data_files(runfiles, inputs_case)

# Create a maps.gpkg for this run
# Skip if using region dis/aggregation, maps will be written in aggregation_regions.py.
# Run if using mixed resolution aggreg-county combination
Expand Down
3 changes: 1 addition & 2 deletions reeds/input_processing/mcs_sampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -1830,8 +1830,7 @@ def write_samples(
region_files_row = aux_files['region_files'].query('filename == @file_name').iloc[0]
copy_files.write_region_indexed_file(sample_values, dir_dst, aux_files['source_deflator_map'],
aux_files['sw'], region_files_row,
aux_files['regions_and_agglevel'],
aux_files['agglevel_variables'])
aux_files['regions_and_agglevel'])
# ...if we have a csv file that isn't region-indexed (including switches.csv)
elif file_termination == '.csv':
if file_name == 'switches.csv':
Expand Down
Loading
Loading