Skip to content

Commit 943f1c1

Browse files
authored
Add ilamb_input_format option to batch processing (#484)
* add ilamb_input format option in batch_processing * pre-commit fix * add test * remove changes in batch_tipmip_config.yml
1 parent 3a02637 commit 943f1c1

3 files changed

Lines changed: 82 additions & 0 deletions

File tree

docs/source/CMORise_ILAMB_workflow.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,12 @@ cmip_version: CMIP7
147147
input_folder: "/g/data/p73/archive/CMIP7/ACCESS-ESM1-6/production/historical-02"
148148
output_folder: "YOUR_OUTPUT_PATH"
149149

150+
# When true, after all variables finish the monitor automatically creates an
151+
# <output_folder>/ilamb_input/ directory of <variable_id>.nc symlinks pointing
152+
# at the CMORised files — ready to use as ILAMB model input (see
153+
# "Preparing ILAMB-Ready Files" below). Default: false.
154+
ilamb_input_format: true
155+
150156
# File patterns (relative to input_folder)
151157
# All atmosphere/land variables share the same pattern
152158
file_patterns:
@@ -353,6 +359,16 @@ output_folder/
353359

354360
## Preparing ILAMB-Ready Files
355361

362+
:::{tip}
363+
If you set `ilamb_input_format: true` in the batch configuration (see above), the
364+
monitor already builds the model-input symlinks for you: once all variables
365+
finish, an `<output_folder>/ilamb_input/` directory is created containing one
366+
`<variable_id>.nc` symlink per CMORised file. You can point ILAMB's `MODELS`
367+
entry straight at that directory and skip the manual `create_ilamb_model_symlinks`
368+
step below — you still need the `DATA` observational link (Step 1) to complete the
369+
ILAMB-ROOT layout.
370+
:::
371+
356372
ILAMB requires a specific directory layout called **ILAMB-ROOT**:
357373

358374
```

src/access_moppy/batch_cmoriser.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,22 @@ def finalize_monitor(
877877
f"Warning: failed to write batch coordination report: {e}", file=sys.stderr
878878
)
879879

880+
if config.get("ilamb_input_format"):
881+
output_dir = Path(db_path).parent
882+
ilamb_dir = output_dir / "ilamb_input"
883+
try:
884+
from access_moppy.utilities import create_ilamb_model_symlinks
885+
886+
links = create_ilamb_model_symlinks(
887+
output_dir, ilamb_dir, drs_format="auto", overwrite=True
888+
)
889+
print(f"Created {len(links)} ILAMB input symlink(s) in: {ilamb_dir}")
890+
except Exception as e:
891+
print(
892+
f"Warning: failed to create ILAMB input symlinks: {e}",
893+
file=sys.stderr,
894+
)
895+
880896
sidecar = Path(db_path).parent / SIDECAR_FILENAME
881897
try:
882898
sidecar.unlink()

tests/unit/test_batch_cmoriser.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,6 +1163,56 @@ def test_finalize_tolerates_missing_sidecar(self, temp_dir):
11631163
# No sidecar to begin with — should not raise
11641164
finalize_monitor(tracker, {"variables": []}, "historical", db_path)
11651165

1166+
@pytest.mark.unit
1167+
def test_finalize_creates_ilamb_symlinks_when_enabled(self, temp_dir):
1168+
"""ilamb_input_format=True builds <output>/ilamb_input/<var>.nc symlinks."""
1169+
db_path = temp_dir / "test.db"
1170+
# Flat-DRS CMORised output living alongside the db in output_folder.
1171+
tas = temp_dir / "tas_Amon_ACCESS_historical.nc"
1172+
pr = temp_dir / "pr_Amon_ACCESS_historical.nc"
1173+
tas.write_text("x")
1174+
pr.write_text("x")
1175+
1176+
with TaskTracker(db_path) as tracker:
1177+
config = {"variables": ["Amon.tas"], "ilamb_input_format": True}
1178+
finalize_monitor(tracker, config, "historical", db_path)
1179+
1180+
ilamb_dir = temp_dir / "ilamb_input"
1181+
assert (ilamb_dir / "tas.nc").is_symlink()
1182+
assert (ilamb_dir / "pr.nc").is_symlink()
1183+
assert (ilamb_dir / "tas.nc").resolve() == tas.resolve()
1184+
assert (ilamb_dir / "pr.nc").resolve() == pr.resolve()
1185+
1186+
@pytest.mark.unit
1187+
def test_finalize_skips_ilamb_symlinks_when_disabled(self, temp_dir):
1188+
"""No ilamb_input directory is created when the flag is unset."""
1189+
db_path = temp_dir / "test.db"
1190+
(temp_dir / "tas_Amon_ACCESS_historical.nc").write_text("x")
1191+
1192+
with TaskTracker(db_path) as tracker:
1193+
finalize_monitor(tracker, {"variables": []}, "historical", db_path)
1194+
1195+
assert not (temp_dir / "ilamb_input").exists()
1196+
1197+
@pytest.mark.unit
1198+
def test_finalize_survives_ilamb_symlink_failure(self, temp_dir):
1199+
"""A symlink-build error is swallowed so finalize still completes."""
1200+
db_path = temp_dir / "test.db"
1201+
sidecar = temp_dir / SIDECAR_FILENAME
1202+
sidecar.write_text("12345.gadi-pbs\n2026-05-15T00:00:00\n")
1203+
1204+
with TaskTracker(db_path) as tracker:
1205+
config = {"variables": [], "ilamb_input_format": True}
1206+
with patch(
1207+
"access_moppy.utilities.create_ilamb_model_symlinks",
1208+
side_effect=ValueError("multiple files for variable"),
1209+
):
1210+
# Must not raise despite the symlink builder blowing up.
1211+
finalize_monitor(tracker, config, "historical", db_path)
1212+
1213+
# Finalize still ran to completion (sidecar cleanup happened).
1214+
assert not sidecar.exists()
1215+
11661216

11671217
class TestMonitorMain:
11681218
"""Unit tests for monitor_main entry point: env validation and submit flow."""

0 commit comments

Comments
 (0)