Changelog#
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
0.2.0 - 2026-02-19#
Added#
- Per-stage completion tracking in the
submitpath's generated runner script: each container stage is recorded in.pipeline_status.jsonas it finishes, enabling mid-pipeline restarts after a SLURM job failure without re-running expensive stages (e.g.,predict_tide). On resubmit, completed stages are automatically skipped. meteo_resoption inSfincsModelConfigto control the output resolution (m) of gridded meteorological forcing (precipitation, wind, pressure). When not set, the resolution is derived from the SFINCS quadtree grid base cell size.- Meteo grid clipping (
_clip_meteo_to_domain) that trims reprojected meteo grids to the model domain extent, preventing the LCC → UTM reprojection from inflating grids to CONUS scale — reducing SFINCS runtime from 15 h+ to under 15 min. - Stale netCDF file cleanup in
SfincsInitStageto prevent HDF5 segfaults when re-running a pipeline over an existing model directory. - Geodataset-based water-level forcing with IDW interpolation to boundary points,
replacing the built-in
model.water_level.create(geodataset=...)which passed all source stations incompatibly with.bndfiles. - Active-cell filtering for discharge source points to prevent a SFINCS Fortran segfault when a source point falls on an inactive grid cell.
apply_all_patches()convenience function in_hydromt_compatthat applies all hydromt/hydromt-sfincs compatibility patches in one call, with logging.quietparameter onWorkflowMonitor.mark_stage_completed()to control whether a visible COMPLETED log line is emitted for externally-executed stages.- Unified
runandsubmitexecution pipelines — both commands now execute the same stage pipeline.submitautomatically partitions stages into login-node (Python-only) and SLURM job (container) groups. --start-fromand--stop-afteroptions forsubmitcommand, matchingrunrequires_containerclass attribute onWorkflowStagefor automatic stage classification (Python-only vs container)schism_obsstage: automatic NOAA CO-OPS water level station discovery via concave hull of open boundary nodes, writingstation.inandstation_noaa_ids.txtschism_plotstage: post-run comparison plots of simulated vs NOAA-observed water levels with MLLW→MSL datum conversionCOOPSAPIClientfor querying the NOAA CO-OPS API (station metadata, water levels, datums) with local caching of station metadatainclude_noaa_gagesoption inSchismModelConfig(defaults tofalse) that enables theschism_obsandschism_plotstages- Automatic
param.nmlpatching (iout_sta = 1,nspool_sta = 18) whenstation.inexists, ensuringmod(nhot_write, nspool_sta) == 0across all domain templates forcing_to_mesh_offset_moption inSfincsModelConfigto apply a vertical offset to boundary-condition water levels before they enter SFINCS. For tidal-only sources like TPXO, this anchors the tidal signal to the correct geodetic height of MSL on the mesh.vdatum_mesh_to_msl_moption inSfincsModelConfigto convert SFINCS output from the mesh vertical datum to MSL for comparison with NOAA CO-OPS observations.- Sanity-check warning in
sfincs_forcingwhen adjusted boundary water levels fall outside the ±15 m range, indicating a possible sign or magnitude error inforcing_to_mesh_offset_m. sfincs_wind,sfincs_pressure, andsfincs_plotstages to SFINCS workflow- SFINCS coastal model workflow with full pipeline (download through sfincs_run)
- Polymorphic
ModelConfigABC withSchismModelConfigandSfincsModelConfigconcrete implementations MODEL_REGISTRYfor automatic model dispatch from YAMLmodel:key--modeloption forinitandstagesCLI commands- Model-specific compute parameters (SCHISM: multi-node MPI; SFINCS: single-node OpenMP)
${model}variable in default path templates for model-aware directory naming
Changed#
DownloadStage.descriptionis now a property that derives its text from the configured data sources (e.g. "Download input data (NWM, TPXO)") instead of a static string.- Hydromt compatibility patches consolidated into
apply_all_patches()with per-patch logging; individual imports replaced by a single call. CoastalCalibConfignow takesmodel_config: ModelConfiginstead of separatemodel,mpi, andsfincsparametersSlurmConfignow contains only scheduling parameters (job_name,partition,time_limit,account,qos,user); compute resources (nodes,ntasks_per_node,exclusive) moved toSchismModelConfig- Default path templates use
${model}_prefix instead of hardcodedschism_ - Stage order and stage creation delegated to
ModelConfigsubclasses - SFINCS datum handling split into two separate offsets: the former single
navd88_to_msl_mfield is replaced byforcing_to_mesh_offset_m(applied to boundary forcing before simulation) andvdatum_mesh_to_msl_m(applied to model output for observation comparison). The two offsets serve fundamentally different purposes and may have different values depending on the boundary source. - SFINCS field renames:
model_dir->prebuilt_dir,obs_points->observation_points,obs_merge->merge_observations,src_locations->discharge_locations_file,src_merge->merge_discharge,docker_tag->container_tag,sif_path->container_image
Fixed#
- Call
expanduser()beforeresolve()on all path config fields so that paths containing~are correctly expanded to the user's home directory. - Call
monitor.end_workflow()before returning early in no-wait mode (submitwithwait=False), so that the workflow timing summary is always closed. - Set
HDF5_USE_FILE_LOCKING=FALSEin container environment to preventPermissionErroron NFS-mounted filesystems. - Add conda environment paths (
PATH,LD_LIBRARY_PATH) to therunpath'sbuild_environment()so thatmpiexecand MPI shared libraries from the conda environment are found, matching the environment set up by the generatedsubmitscripts. Without these paths, therunpath could not locatempiexec, causing MPI stages to hang or fail. - Add MPI/EFA fabric tuning variables (
MPICH_OFI_STARTUP_CONNECT,FI_OFI_RXM_SAR_LIMIT, etc.) to therunpath's SCHISM environment, matching thesubmitpath and preventing hangs on AWSc5nnodes. - Suppress ESMF diagnostic output from SLURM logs by redirecting stdout to
/dev/nullfor MPI stages and settingESMF.Manager(debug=False). - Redirect container stdout/stderr to temporary files instead of pipes to prevent
pipe-buffer deadlocks with MPI process trees (
mpiexec→singularity), where inherited pipe file-descriptors in child processes can fill the OS pipe buffer (64 KB on Linux) and deadlock the entire tree. - Use
$COASTAL_DOMAINinstead of hardcodedprviinmake_tpxo_ocean.bashso the correct open-boundary mesh is used for all domains. - Add missing
$in${PDY}variable expansion inpost_regrid_stofs.bashlog filename. - Correct malformed shebangs (
#/usr/bin/evn) inpre_nwm_forcing_coastal.bashandpost_nwm_forcing_coastal.bash. - Use integer division (
//) for the netCDF array index inWrfHydroFECPP/fecpp/app.pyto avoidfloatindex errors. - Use numeric comparison (
-gt) instead of string comparison (>) forLENGTH_HRSinupdate_param.bash. - Add missing sub-hourly CHRTOUT symlinks for Hawaii in the last-timestep block of
initial_discharge.bash. - Read
NSCRIBESfrom the environment with a fallback default instead of hardcoding it inpre_schism.bashandrun_sing_coastal_workflow_post_schism.bash. - Compute
LENGTH_HRSinSTOFSBoundaryStagedirectly instead of parsing stdout from the pre-script, which was silently lost after thePopen.communicate()fix redirected stdout to/dev/null. - Remove duplicate domain-to-inland/geogrid mappings in
runner.pyand use the canonical properties fromSimulationConfigto prevent the two copies from drifting out of sync. - Correct shebangs (
#!/usr/bin/bash→#!/usr/bin/env bash) inpre_regrid_stofs.bashandpost_regrid_stofs.bashfor consistency and portability. - Source inner bash scripts from
$SCRIPTS_DIRinstead of./in all wrapper scripts, so that the bind-mounted (package) versions are used rather than the stale copies baked into the container image. - Export
COASTAL_SCRIPTS_DIR,WRF_HYDRO_DIR,TPXO_SCRIPTS_DIR, andFORCINGS_SCRIPTS_DIRin thesubmitpath's generated runner script — these variables were only set in therunpath, causing$COASTAL_SCRIPTS_DIR/makeAtmo.py(and similar) to resolve to just/makeAtmo.pyand fail silently. - Export date-component variables (
FORCING_START_YEAR,FORCING_START_MONTH,FORCING_START_DAY,FORCING_START_HOUR,PDY,cyc,FORCING_BEGIN_DATE,FORCING_END_DATE,END_DATETIME) in thesubmitpath header so thatmakeAtmo.py,makeDischarge.py, and other Python scripts inside the container have access to them across all stages. - Add
set -eto all inner bash scripts (post_nwm_forcing_coastal.bash,initial_discharge.bash,merge_source_sink.bash,combine_sink_source.bash,pre_nwm_forcing_coastal.bash,post_regrid_stofs.bash,pre_regrid_stofs.bash,make_tpxo_ocean.bash,pre_schism.bash,post_schism.bash,update_param.bash) so that command failures (e.g.,pythonfile-not-found or import errors) propagate instead of being silently swallowed. - Correct shebang in
make_tpxo_ocean.bashandpre_schism.bash(#!/usr/bin/bash→#!/usr/bin/env bash). - Copy
setup_tpxo.txtandModel_tpxo10_atlasfrom$SCRIPTS_DIRinstead of./inmake_tpxo_ocean.bash, so the bind-mounted (package) versions are used rather than stale copies baked into the container image. - Truncate discharge arrays in
merge_source_sink.pyto match the precipitation timestep count fromprecip_source.nc, preventing a shape-mismatchValueErrorwhen sub-hourly CHRTOUT files (e.g., Hawaii) produce one extra trailing timestep. - Export
SCHISM_BEGIN_DATEandSCHISM_END_DATEin thesubmitpath header so thatupdate_param.bashcan patchparam.nmlwith the correct simulation start/end dates — without these,param.nmlretains its template defaults (2000-01-01) and SCHISM aborts with a time mismatch againstsfluxforcing files. - Report accurately which container stages completed vs failed when a SLURM job ends with a non-zero exit status, instead of marking all container stages as failed.
Removed#
MPIConfigclass (fields absorbed intoSchismModelConfig)
0.1.0 - 2026-02-06#
Added#
- Initial release of NWM Coastal
- SCHISM coastal model workflow support
- YAML configuration with variable interpolation
- Configuration inheritance with
_basefield - CLI commands:
init,validate,submit,run,stages - Python API for programmatic workflow control
- Automatic data download from NWM and STOFS sources
- Support for TPXO and STOFS boundary conditions
- Support for four coastal domains: Hawaii, PRVI, Atlantic/Gulf, Pacific
- Interactive and non-interactive job submission modes
- Partial workflow execution with
--start-fromand--stop-after - Smart default paths with interpolation templates
- Comprehensive configuration validation
- MkDocs documentation with Material theme
Supported Data Sources#
- NWM Retrospective 3.0 (1979-02-01 to 2023-01-31)
- NWM Analysis (2018-09-17 to present)
- STOFS water levels (2020-12-30 to present)
- GLOFS (Great Lakes OFS, 2005-09-30 to present)
- TPXO tidal model (local installation required)