From 1c08737956fe21ce592d33b8dc7550c25203dfc8 Mon Sep 17 00:00:00 2001 From: "Olmez Turan, Merve" Date: Mon, 4 May 2026 12:14:35 -0600 Subject: [PATCH 1/6] Improve last-iteration g00 file selection Replace the previous lexicographic ordering with numeric-aware selection for the final g00 file. --- runbatch.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/runbatch.py b/runbatch.py index 60c2e2fb..c7630ad0 100644 --- a/runbatch.py +++ b/runbatch.py @@ -1429,9 +1429,13 @@ def write_batch_script( ### Otherwise, run for the last iteration (lexicographically sorted) else: OPATH.writelines( - f"for r in g00files/{batch_case}_*.g00; do true; done\n" + f"r=$(ls g00files/{batch_case}_*.g00 2>/dev/null | sort -V | tail -1)\n" if LINUXORMAC else - f'for %%i in (g00files\{batch_case}_*.g00) do (set "r=%%i")\n' + f'for /f "delims=" %%i in (\'python -c ' + f'"from pathlib import Path; ' + f'print(max(Path(\'g00files\').glob(\'{batch_case}_{max(solveyears)}i*.g00\'), ' + f'key=lambda f: int(f.stem[f.stem.rfind(\'i\')+1:])).name)"\') ' + f'do set "r=g00files\\%%i"\n' ) OPATH.writelines( "gams e_report.gms" From 2854e17b40f587461457bc045a7b333bad0502f9 Mon Sep 17 00:00:00 2001 From: "Olmez Turan, Merve" Date: Mon, 4 May 2026 21:43:37 -0600 Subject: [PATCH 2/6] Adding get_last_iter.py and modify runbatch.py --- reeds/get_last_iter.py | 42 ++++++++++++++++++++++++++++++++++++++++++ runbatch.py | 10 ++++------ 2 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 reeds/get_last_iter.py diff --git a/reeds/get_last_iter.py b/reeds/get_last_iter.py new file mode 100644 index 00000000..66d64bf2 --- /dev/null +++ b/reeds/get_last_iter.py @@ -0,0 +1,42 @@ +""" +This script contains the function to get the last iteration g00 file for a given case. +This is used in the batch call scripts to identify the last iteration of a solved year +for output processing. +""" + + +#%% =========================================================================== +### --- IMPORTS --- +### =========================================================================== +import sys +import argparse +from pathlib import Path + +#%% =========================================================================== +### --- Function --- +### =========================================================================== + +def get_last_g00(batch_case, max_year): + pattern = f'{batch_case}_{max_year}i*.g00' + matches = list(Path('g00files').glob(pattern)) + + if not matches: + print(f"ERROR: The run {batch_case} has not solved last modeled year {max_year}.", file=sys.stderr) + sys.exit(1) + + last_file = max( + matches, + key=lambda f: int(f.stem[f.stem.rfind('i')+1:]) + ) + + # Use forward slashes universally, works on both OS + print(Path('g00files') / last_file.name) + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Get the last iteration g00 file for a given batch case.') + parser.add_argument('batch_case', type=str, help='The batch case name (e.g., v20260504_Pacific)') + parser.add_argument('max_year', type=int, help='The last modeled year to check for (e.g., 2032)') + args = parser.parse_args() + + + get_last_g00(args.batch_case, args.max_year) \ No newline at end of file diff --git a/runbatch.py b/runbatch.py index c7630ad0..ff7e70f3 100644 --- a/runbatch.py +++ b/runbatch.py @@ -1429,13 +1429,11 @@ def write_batch_script( ### Otherwise, run for the last iteration (lexicographically sorted) else: OPATH.writelines( - f"r=$(ls g00files/{batch_case}_*.g00 2>/dev/null | sort -V | tail -1)\n" + f'r=$(python {os.path.join(casedir, "reeds", "get_last_iter.py")} {batch_case} {max(solveyears)})\n' if LINUXORMAC else - f'for /f "delims=" %%i in (\'python -c ' - f'"from pathlib import Path; ' - f'print(max(Path(\'g00files\').glob(\'{batch_case}_{max(solveyears)}i*.g00\'), ' - f'key=lambda f: int(f.stem[f.stem.rfind(\'i\')+1:])).name)"\') ' - f'do set "r=g00files\\%%i"\n' + f'for /f "delims=" %%i in ' + f'(\'python {os.path.join(casedir, "reeds", "get_last_iter.py")} {batch_case} {max(solveyears)}\')' + f'do set "r=%%i"\n' ) OPATH.writelines( "gams e_report.gms" From 92851a35f4e3c1b032261d9e1a6d0f90322002a2 Mon Sep 17 00:00:00 2001 From: Merve Turan <107019199+merveturan@users.noreply.github.com> Date: Wed, 6 May 2026 14:19:42 -0600 Subject: [PATCH 3/6] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- runbatch.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runbatch.py b/runbatch.py index 59b7f782..27bf868e 100644 --- a/runbatch.py +++ b/runbatch.py @@ -1432,8 +1432,8 @@ def write_batch_script( f'r=$(python {os.path.join(casedir, "reeds", "get_last_iter.py")} {batch_case} {max(solveyears)})\n' if LINUXORMAC else f'for /f "delims=" %%i in ' - f'(\'python {os.path.join(casedir, "reeds", "get_last_iter.py")} {batch_case} {max(solveyears)}\')' - f'do set "r=%%i"\n' + f'(\'python {os.path.join(casedir, "reeds", "get_last_iter.py")} {batch_case} {max(solveyears)}\')' + f' do set "r=%%i"\n' ) OPATH.writelines( "gams e_report.gms" From 88a2c761d13ff517c027fd992b2ee4b5c3da5a84 Mon Sep 17 00:00:00 2001 From: Merve Turan <107019199+merveturan@users.noreply.github.com> Date: Wed, 6 May 2026 14:19:52 -0600 Subject: [PATCH 4/6] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- runbatch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runbatch.py b/runbatch.py index 27bf868e..bfc9ca75 100644 --- a/runbatch.py +++ b/runbatch.py @@ -1426,7 +1426,7 @@ def write_batch_script( if LINUXORMAC else f'set "r={os.path.join("g00files", f"{batch_case}_{max(solveyears)}i0")}"\n' ) - ### Otherwise, run for the last iteration (lexicographically sorted) + ### Otherwise, run for the last iteration (selected numerically) else: OPATH.writelines( f'r=$(python {os.path.join(casedir, "reeds", "get_last_iter.py")} {batch_case} {max(solveyears)})\n' From ab5ddb072e4884f78e9daab3239a9226599e6a7c Mon Sep 17 00:00:00 2001 From: Merve Turan <107019199+merveturan@users.noreply.github.com> Date: Wed, 6 May 2026 14:20:18 -0600 Subject: [PATCH 5/6] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- reeds/get_last_iter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reeds/get_last_iter.py b/reeds/get_last_iter.py index 66d64bf2..f6b6c92c 100644 --- a/reeds/get_last_iter.py +++ b/reeds/get_last_iter.py @@ -30,7 +30,7 @@ def get_last_g00(batch_case, max_year): ) # Use forward slashes universally, works on both OS - print(Path('g00files') / last_file.name) + print((Path('g00files') / last_file.name).as_posix()) if __name__ == '__main__': parser = argparse.ArgumentParser(description='Get the last iteration g00 file for a given batch case.') From 9b00f0bfbde51daafda01b793b4aa2e6c557aefb Mon Sep 17 00:00:00 2001 From: challora Date: Wed, 6 May 2026 17:22:57 -0600 Subject: [PATCH 6/6] Refactor get_last_iteration to use pathlib for file matching and improve error handling --- reeds/io.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/reeds/io.py b/reeds/io.py index 57d7dec6..434ee172 100644 --- a/reeds/io.py +++ b/reeds/io.py @@ -1228,15 +1228,18 @@ def get_last_iteration(case, year=2050, datum=None, samples=None): """Get the last iteration of PRAS for a given case/year""" if datum not in [None,'flow','energy']: raise ValueError(f"datum must be in [None,'flow','energy'] but is {datum}") - infile = sorted(glob( - os.path.join( - case, 'ReEDS_Augur', 'PRAS', - f"PRAS_{year}i*" - + (f'-{samples}' if samples is not None else '') - + (f'-{datum}' if datum is not None else '') - + '.h5' - ) - ))[-1] + pattern = f"PRAS_{year}i*" \ + + (f'-{samples}' if samples is not None else '') \ + + (f'-{datum}' if datum is not None else '') \ + + '.h5' + matches = list(Path(case, 'ReEDS_Augur', 'PRAS').glob(pattern)) + if not matches: + print(f"ERROR: The run {case} has not solved last modeled year {year}.", file=sys.stderr) + sys.exit(1) + infile = max( + matches, + key=lambda f: int(f.stem[f.stem.rfind('i')+1:].split('-')[0]) + ) iteration = int( os.path.splitext(os.path.basename(infile))[0] .split('-')[0].split('_')[1].split('i')[1]