This notebook demonstrates how to create a new domain and run a ROMS simulation using C-STAR Forge.
Setup¶
First, import the necessary modules and define the domain configuration parameters.
%load_ext autoreload
%autoreload 2
import cstar_forge
import cstar.execution.handler as handler
import time
from datetime import datetime
from IPython.display import Markdown, displayEnvironment and Machine Information¶
Record the execution environment and machine details for reproducibility.
env = cstar_forge.config.get_environment_info()
# Display summary
summary = f"""
### Machine Information
- **Hostname**: `{env.hostname}`
- **System Tag**: `{env.system_tag}`
- **OS**: `{env.os_info}`
### Environment Summary
- **Python Version**: `{env.python_version}`
- **Python Executable**: `{env.python_executable}`
- **Conda/Micromamba Environment**: `{env.env_info}`
- **Kernel**: `{env.kernel_spec}`
"""
display(Markdown(summary))
print(f"Execution timestamp: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
Execution timestamp: 2026-05-04 16:19:18
grid_name = "test-tiny"
model_name = "cson_roms-marbl_v0.1"
start_time = datetime(2012, 1, 1)
end_time = datetime(2012, 1, 2)
grid_kwargs = dict[str, float](
nx=6,
ny=2,
size_x=500,
size_y=1000,
center_lon=0,
center_lat=55,
rot=10,
N=3, # number of vertical levels
theta_s=5.0, # surface control parameter
theta_b=2.0, # bottom control parameter
hc=250.0, # critical depth
)
boundaries={
"south": False,
"east": True,
"north": True,
"west": False,
}
partitioning = {
"n_procs_x": 1, # number of partitions in xi (x)
"n_procs_y": 1, # number of partitions in eta (y)
}
Generate CDR Forcing for this grid using ROMS-tools¶
from roms_tools import TracerPerturbation, CDRForcing, Grid
tp = TracerPerturbation(
name="my_cdr",
lat=grid_kwargs["center_lat"]+4, # degree N
lon=grid_kwargs["center_lon"]+1, # degree E
hsc=10,
vsc=10,
depth=1, # m
tracer_fluxes={"ALK": 2 * 10**6}, # meq/s
)
cdr = CDRForcing(
grid=Grid(**grid_kwargs), # for plotting, could omit
start_time=start_time,
end_time=end_time,
releases=[tp],
)
cdr.plot_locations()
cdr.plot_distribution("my_cdr")
cdr.plot_tracer_flux("ALK")
# we should decide how we want to pass the cdr information:
# dict/kwargs? yaml file? object?
cdr_as_dict = cdr.model_dump()["CDRForcing"]
# cdr_as_dict


Initialize CstarSpecBuilder¶
Create a CstarSpecBuilder instance with the domain configuration. This initializes the PRECONFIG stage, creating the grid object and blueprint structure.
ocn = cstar_forge.CstarSpecBuilder(
description="Test tiny",
model_name=model_name,
grid_name=grid_name,
grid_kwargs=grid_kwargs,
open_boundaries=boundaries,
start_time=start_time,
end_time=end_time,
partitioning=partitioning,
cdr_forcing = cdr_as_dict,
#catalog_root="local"
)
CstarSpecBuilder: planned NetCDF outputs
- /Users/eilerman/cson-forge-data/input-data/cson_roms-marbl_v0_1_test-tiny_1procs/cson_roms-marbl_v0_1_test-tiny_1procs_grid.nc
- /Users/eilerman/cson-forge-data/input-data/cson_roms-marbl_v0_1_test-tiny_1procs/cson_roms-marbl_v0_1_test-tiny_1procs_initial_conditions.nc
- /Users/eilerman/cson-forge-data/input-data/cson_roms-marbl_v0_1_test-tiny_1procs/cson_roms-marbl_v0_1_test-tiny_1procs_surface-physics.nc
- /Users/eilerman/cson-forge-data/input-data/cson_roms-marbl_v0_1_test-tiny_1procs/cson_roms-marbl_v0_1_test-tiny_1procs_surface-bgc.nc
- /Users/eilerman/cson-forge-data/input-data/cson_roms-marbl_v0_1_test-tiny_1procs/cson_roms-marbl_v0_1_test-tiny_1procs_boundary-physics.nc
- /Users/eilerman/cson-forge-data/input-data/cson_roms-marbl_v0_1_test-tiny_1procs/cson_roms-marbl_v0_1_test-tiny_1procs_boundary-bgc.nc
- /Users/eilerman/cson-forge-data/input-data/cson_roms-marbl_v0_1_test-tiny_1procs/cson_roms-marbl_v0_1_test-tiny_1procs_tidal.nc
- /Users/eilerman/cson-forge-data/input-data/cson_roms-marbl_v0_1_test-tiny_1procs/cson_roms-marbl_v0_1_test-tiny_1procs_river.nc
CstarSpecBuilder: output locations
NetCDF files: /Users/eilerman/cson-forge-data/input-data/cson_roms-marbl_v0_1_test-tiny_1procs
YAML files: /Users/eilerman/git/cson-forge/cson_forge/catalog/blueprints/MacOS/cson_roms-marbl_v0.1_test-tiny_1procs
Compile-time code: /Users/eilerman/git/cson-forge/cson_forge/catalog/builds/cson_roms-marbl_v0.1_test-tiny_1procs/compile-time
Run-time code: /Users/eilerman/git/cson-forge/cson_forge/catalog/builds/cson_roms-marbl_v0.1_test-tiny_1procs/run-time
Simulation output (scratch): /Users/eilerman/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102
Visualize the grid¶
ocn.grid.plot()
Prepare Source Data¶
Ensure that all required source datasets (GLORYS, UNIFIED, SRTM15, etc.) are staged locally. This downloads and prepares the data needed for input generation.
# ensure that source data is staged locally
ocn.ensure_source_data()
✔️ Using existing GLORYS_REGIONAL file for 2011-12-31: cmems_mod_glo_phy_my_0.083deg_P1D-m_REGIONAL_test-tiny_20111231.nc
✔️ Using existing GLORYS_REGIONAL file for 2012-01-01: cmems_mod_glo_phy_my_0.083deg_P1D-m_REGIONAL_test-tiny_20120101.nc
✔️ Using existing GLORYS_REGIONAL file for 2012-01-02: cmems_mod_glo_phy_my_0.083deg_P1D-m_REGIONAL_test-tiny_20120102.nc
✔️ Using existing GLORYS_REGIONAL file for 2012-01-03: cmems_mod_glo_phy_my_0.083deg_P1D-m_REGIONAL_test-tiny_20120103.nc
✔️ TPXO dataset verified at: /Users/eilerman/cson-forge-data/source-data/TPXO/TPXO10.v2
✔️ Using existing BGC dataset: /Users/eilerman/cson-forge-data/source-data/UNIFIED_BGC/BGCdataset.nc
Generate Input Files¶
Generate all model input files (grid, initial conditions, forcing) from the source data. This completes the POSTCONFIG stage and updates the blueprint with actual file paths.
The system will look for an existing blueprint and, if a match is found, it will use that data unless the user sets clobber=True to force re-generating the data.
# prepare model input
ocn.generate_inputs(clobber=True) # setting clobber=True will overwrite existing files
⚠️ Clobber=True: removing 11 existing .nc files in /Users/eilerman/cson-forge-data/input-data/cson_roms-marbl_v0_1_test-tiny_1procs...
▶️ [1/9] Writing ROMS grid...
▶️ [2/9] Generating initial conditions...
2026-05-04 22:19:20,527 [WARNING] - utils.py:109 - Optional variables missing (but not critical): ['Lig', 'DIC_ALT_CO2', 'Alk_ALT_CO2']
[########################################] | 100% Completed | 1.97 sms
▶️ [3/9] Generating surface forcing...
Numba: Attempted to fork from a non-main thread, the TBB library may be in an invalid state in the child process.
[########################################] | 100% Completed | 636.29 ms
[########################################] | 100% Completed | 1.24 sms
2026-05-04 22:19:40,057 [WARNING] - utils.py:109 - Optional variables missing (but not critical): ['pco2_air_alt']
▶️ [4/9] Generating surface forcing...
[########################################] | 100% Completed | 211.54 ms
▶️ [5/9] Generating boundary forcing...
[########################################] | 100% Completed | 108.09 ms
[########################################] | 100% Completed | 314.98 ms
2026-05-04 22:19:41,239 [WARNING] - utils.py:109 - Optional variables missing (but not critical): ['Lig', 'DIC_ALT_CO2', 'Alk_ALT_CO2']
▶️ [6/9] Generating boundary forcing...
[########################################] | 100% Completed | 3.31 sms
▶️ [7/9] Generating tidal forcing...
[########################################] | 100% Completed | 14.19 s
▶️ [8/9] Generating river forcing...
2026-05-04 22:20:20,057 [WARNING] - cdr_forcing.py:1010 - Grid not provided: cannot verify whether the specified lat/lon/depth location is within the domain or on land. Please check manually or provide a grid when instantiating the class.
▶️ [9/9] Generating CDR forcing...
✅ All input files generated.
RomsMarblBlueprint(name='cson_roms-marbl_v0.1_test-tiny_1procs', description='Test tiny', application=<Application.ROMS_MARBL: 'roms_marbl'>, state=<BlueprintState.NotSet: 'notset'>, valid_start_date=datetime.datetime(2012, 1, 1, 0, 0), valid_end_date=datetime.datetime(2012, 1, 2, 0, 0), code={'roms': {'documentation': '', 'locked': False, 'location': 'https://github.com/CWorthy-ocean/ucla-roms.git', 'commit': '45a9221', 'branch': '', 'filter': None}, 'run_time': {'documentation': '', 'locked': False, 'location': 'placeholder://run_time', 'commit': '', 'branch': 'main', 'filter': None}, 'compile_time': {'documentation': '', 'locked': False, 'location': 'placeholder://compile_time', 'commit': '', 'branch': 'main', 'filter': None}, 'marbl': {'documentation': '', 'locked': False, 'location': 'https://github.com/marbl-ecosys/MARBL.git', 'commit': 'marbl0.45.0', 'branch': '', 'filter': None}}, initial_conditions={'documentation': '', 'locked': False, 'data': [{'location': PosixPath('/Users/eilerman/cson-forge-data/input-data/cson_roms-marbl_v0_1_test-tiny_1procs/cson_roms-marbl_v0_1_test-tiny_1procs_initial_conditions.nc'), 'partitioned': False}]}, grid={'documentation': '', 'locked': False, 'data': [{'location': '/Users/eilerman/cson-forge-data/input-data/cson_roms-marbl_v0_1_test-tiny_1procs/cson_roms-marbl_v0_1_test-tiny_1procs_grid.nc', 'partitioned': False}]}, forcing={'boundary': {'documentation': '', 'locked': False, 'data': [{'location': PosixPath('/Users/eilerman/cson-forge-data/input-data/cson_roms-marbl_v0_1_test-tiny_1procs/cson_roms-marbl_v0_1_test-tiny_1procs_boundary-physics_201112.nc'), 'partitioned': False}, {'location': PosixPath('/Users/eilerman/cson-forge-data/input-data/cson_roms-marbl_v0_1_test-tiny_1procs/cson_roms-marbl_v0_1_test-tiny_1procs_boundary-physics_201201.nc'), 'partitioned': False}, {'location': PosixPath('/Users/eilerman/cson-forge-data/input-data/cson_roms-marbl_v0_1_test-tiny_1procs/cson_roms-marbl_v0_1_test-tiny_1procs_boundary-bgc_clim.nc'), 'partitioned': False}]}, 'surface': {'documentation': '', 'locked': False, 'data': [{'location': PosixPath('/Users/eilerman/cson-forge-data/input-data/cson_roms-marbl_v0_1_test-tiny_1procs/cson_roms-marbl_v0_1_test-tiny_1procs_surface-physics_201112.nc'), 'partitioned': False}, {'location': PosixPath('/Users/eilerman/cson-forge-data/input-data/cson_roms-marbl_v0_1_test-tiny_1procs/cson_roms-marbl_v0_1_test-tiny_1procs_surface-physics_201201.nc'), 'partitioned': False}, {'location': PosixPath('/Users/eilerman/cson-forge-data/input-data/cson_roms-marbl_v0_1_test-tiny_1procs/cson_roms-marbl_v0_1_test-tiny_1procs_surface-bgc_clim.nc'), 'partitioned': False}]}, 'tidal': {'documentation': '', 'locked': False, 'data': [{'location': PosixPath('/Users/eilerman/cson-forge-data/input-data/cson_roms-marbl_v0_1_test-tiny_1procs/cson_roms-marbl_v0_1_test-tiny_1procs_tidal.nc'), 'partitioned': False}]}, 'river': {'documentation': '', 'locked': False, 'data': [{'location': PosixPath('/Users/eilerman/cson-forge-data/input-data/cson_roms-marbl_v0_1_test-tiny_1procs/cson_roms-marbl_v0_1_test-tiny_1procs_river.nc'), 'partitioned': False}]}, 'corrections': None}, partitioning={'documentation': '', 'locked': False, 'hash': None, 'n_procs_x': 1, 'n_procs_y': 1}, model_params=None, runtime_params=None, cdr_forcing={'documentation': '', 'locked': False, 'data': [{'location': '/Users/eilerman/cson-forge-data/input-data/cson_roms-marbl_v0_1_test-tiny_1procs/cson_roms-marbl_v0_1_test-tiny_1procs_cdr.nc', 'partitioned': False}]}, nesting_info=None)Access Generated Input Datasets¶
Input datasets are available on the datasets attribute of the CstarSpecBuilder after generate_inputs() has completed. The datasets dictionary only contains keys for fields that exist in the blueprint and have been successfully generated.
Note: Datasets are only available after generate_inputs() has run and populated the blueprint with actual file paths. If a key doesn’t exist, it means that field wasn’t generated or isn’t in the blueprint.
for key in ocn.datasets.keys():
print("-"*100)
print(key)
print(ocn.datasets[key])----------------------------------------------------------------------------------------------------
grid
<xarray.Dataset> Size: 3kB
Dimensions: (eta_rho: 4, xi_rho: 8, xi_u: 7, eta_v: 3, eta_coarse: 3,
xi_coarse: 5, s_rho: 3, s_w: 4)
Coordinates:
lat_rho (eta_rho, xi_rho) float64 256B ...
lon_rho (eta_rho, xi_rho) float64 256B ...
lat_u (eta_rho, xi_u) float64 224B ...
lon_u (eta_rho, xi_u) float64 224B ...
lat_v (eta_v, xi_rho) float64 192B ...
lon_v (eta_v, xi_rho) float64 192B ...
lat_coarse (eta_coarse, xi_coarse) float64 120B ...
lon_coarse (eta_coarse, xi_coarse) float64 120B ...
Dimensions without coordinates: eta_rho, xi_rho, xi_u, eta_v, eta_coarse,
xi_coarse, s_rho, s_w
Data variables: (12/15)
angle (eta_rho, xi_rho) float64 256B ...
f (eta_rho, xi_rho) float64 256B ...
pm (eta_rho, xi_rho) float64 256B ...
pn (eta_rho, xi_rho) float64 256B ...
spherical |S1 1B ...
mask_rho (eta_rho, xi_rho) int32 128B ...
... ...
mask_coarse (eta_coarse, xi_coarse) int32 60B ...
h (eta_rho, xi_rho) float64 256B ...
sigma_r (s_rho) float32 12B ...
Cs_r (s_rho) float32 12B ...
sigma_w (s_w) float32 16B ...
Cs_w (s_w) float32 16B ...
Attributes: (12/14)
title: ROMS grid created by ROMS-Tools
roms_tools_version: 3.6.1.dev17+g97b5fe39e
size_x: 500
size_y: 1000
center_lon: 0
center_lat: 55
... ...
close_narrow_channels: False
topography_source_name: ETOPO5
hmin: 5.0
theta_s: 5.0
theta_b: 2.0
hc: 250.0
----------------------------------------------------------------------------------------------------
initial_conditions
<xarray.Dataset> Size: 15kB
Dimensions: (ocean_time: 1, s_rho: 3, eta_rho: 4, xi_rho: 8, xi_u: 7,
eta_v: 3, s_w: 4)
Coordinates:
abs_time (ocean_time) datetime64[ns] 8B ...
* ocean_time (ocean_time) float64 8B 3.787e+08
Dimensions without coordinates: s_rho, eta_rho, xi_rho, xi_u, eta_v, s_w
Data variables: (12/42)
temp (ocean_time, s_rho, eta_rho, xi_rho) float32 384B ...
salt (ocean_time, s_rho, eta_rho, xi_rho) float32 384B ...
u (ocean_time, s_rho, eta_rho, xi_u) float32 336B ...
v (ocean_time, s_rho, eta_v, xi_rho) float32 288B ...
zeta (ocean_time, eta_rho, xi_rho) float32 128B ...
ubar (ocean_time, eta_rho, xi_u) float32 112B ...
... ...
Lig (ocean_time, s_rho, eta_rho, xi_rho) float32 384B ...
DIC_ALT_CO2 (ocean_time, s_rho, eta_rho, xi_rho) float32 384B ...
ALK_ALT_CO2 (ocean_time, s_rho, eta_rho, xi_rho) float32 384B ...
w (ocean_time, s_w, eta_rho, xi_rho) float32 512B ...
Cs_r (s_rho) float32 12B ...
Cs_w (s_w) float32 16B ...
Attributes:
title: ROMS initial conditions file create...
roms_tools_version: 3.6.1.dev17+g97b5fe39e
ini_time: 2012-01-01 00:00:00
model_reference_date: 2000-01-01 00:00:00
adjust_depth_for_sea_surface_height: False
source: GLORYS
bgc_source: UNIFIED
theta_s: 5.0
theta_b: 2.0
hc: 250.0
----------------------------------------------------------------------------------------------------
forcing.surface
[<xarray.Dataset> Size: 8kB
Dimensions: (time: 1, eta_rho: 4, xi_rho: 8, rad_time: 28)
Coordinates:
abs_time (time) datetime64[ns] 8B ...
* time (time) float64 8B 4.383e+03
* rad_time (rad_time) float64 224B 4.383e+03 4.383e+03 ... 4.384e+03
Dimensions without coordinates: eta_rho, xi_rho
Data variables:
uwnd (time, eta_rho, xi_rho) float32 128B ...
vwnd (time, eta_rho, xi_rho) float32 128B ...
swrad (rad_time, eta_rho, xi_rho) float32 4kB ...
lwrad (rad_time, eta_rho, xi_rho) float32 4kB ...
Tair (time, eta_rho, xi_rho) float32 128B ...
rain (time, eta_rho, xi_rho) float32 128B ...
qair (time, eta_rho, xi_rho) float32 128B ...
Attributes:
title: ROMS surface forcing file created by ROMS-Tools
roms_tools_version: 3.6.1.dev17+g97b5fe39e
start_time: 2012-01-01 00:00:00
end_time: 2012-01-02 00:00:00
source: ERA5
correct_radiation: True
wind_dropoff: False
use_coarse_grid: False
model_reference_date: 2000-01-01 00:00:00
type: physics, <xarray.Dataset> Size: 25kB
Dimensions: (time: 27, eta_rho: 4, xi_rho: 8, rad_time: 28)
Coordinates:
abs_time (time) datetime64[ns] 216B ...
* time (time) float64 216B 4.383e+03 4.383e+03 ... 4.384e+03 4.384e+03
* rad_time (rad_time) float64 224B 4.383e+03 4.383e+03 ... 4.384e+03
Dimensions without coordinates: eta_rho, xi_rho
Data variables:
uwnd (time, eta_rho, xi_rho) float32 3kB ...
vwnd (time, eta_rho, xi_rho) float32 3kB ...
swrad (rad_time, eta_rho, xi_rho) float32 4kB ...
lwrad (rad_time, eta_rho, xi_rho) float32 4kB ...
Tair (time, eta_rho, xi_rho) float32 3kB ...
rain (time, eta_rho, xi_rho) float32 3kB ...
qair (time, eta_rho, xi_rho) float32 3kB ...
Attributes:
title: ROMS surface forcing file created by ROMS-Tools
roms_tools_version: 3.6.1.dev17+g97b5fe39e
start_time: 2012-01-01 00:00:00
end_time: 2012-01-02 00:00:00
source: ERA5
correct_radiation: True
wind_dropoff: False
use_coarse_grid: False
model_reference_date: 2000-01-01 00:00:00
type: physics, <xarray.Dataset> Size: 10kB
Dimensions: (time: 12, eta_rho: 4, xi_rho: 8)
Coordinates:
month (time) int32 48B ...
abs_time (time) datetime64[ns] 96B ...
pco2_time (time) float64 96B ...
iron_time (time) float64 96B ...
dust_time (time) float64 96B ...
nox_time (time) float64 96B ...
nhy_time (time) float64 96B ...
Dimensions without coordinates: time, eta_rho, xi_rho
Data variables:
pco2_air (time, eta_rho, xi_rho) float32 2kB ...
dust (time, eta_rho, xi_rho) float32 2kB ...
iron (time, eta_rho, xi_rho) float32 2kB ...
nox (time, eta_rho, xi_rho) float32 2kB ...
nhy (time, eta_rho, xi_rho) float32 2kB ...
pco2_air_alt (time, eta_rho, xi_rho) float32 2kB ...
Attributes:
title: ROMS surface forcing file created by ROMS-Tools
roms_tools_version: 3.6.1.dev17+g97b5fe39e
start_time: 2012-01-01 00:00:00
end_time: 2012-01-02 00:00:00
source: UNIFIED
correct_radiation: False
wind_dropoff: False
use_coarse_grid: False
model_reference_date: 2000-01-01 00:00:00
type: bgc
climatology: True]
----------------------------------------------------------------------------------------------------
forcing.boundary
[<xarray.Dataset> Size: 704B
Dimensions: (bry_time: 1, s_rho: 3, xi_u: 7, xi_rho: 8, eta_rho: 4, eta_v: 3)
Coordinates:
abs_time (bry_time) datetime64[ns] 8B ...
* bry_time (bry_time) float64 8B 4.382e+03
Dimensions without coordinates: s_rho, xi_u, xi_rho, eta_rho, eta_v
Data variables: (12/14)
u_north (bry_time, s_rho, xi_u) float32 84B ...
v_north (bry_time, s_rho, xi_rho) float32 96B ...
temp_north (bry_time, s_rho, xi_rho) float32 96B ...
salt_north (bry_time, s_rho, xi_rho) float32 96B ...
zeta_north (bry_time, xi_rho) float32 32B ...
ubar_north (bry_time, xi_u) float32 28B ...
... ...
v_east (bry_time, s_rho, eta_v) float32 36B ...
temp_east (bry_time, s_rho, eta_rho) float32 48B ...
salt_east (bry_time, s_rho, eta_rho) float32 48B ...
zeta_east (bry_time, eta_rho) float32 16B ...
ubar_east (bry_time, eta_rho) float32 16B ...
vbar_east (bry_time, eta_v) float32 12B ...
Attributes:
title: ROMS boundary forcing file created ...
roms_tools_version: 3.6.1.dev17+g97b5fe39e
start_time: 2012-01-01 00:00:00
end_time: 2012-01-02 00:00:00
source: GLORYS
model_reference_date: 2000-01-01 00:00:00
apply_2d_horizontal_fill: False
adjust_depth_for_sea_surface_height: False
theta_s: 5.0
theta_b: 2.0
hc: 250.0, <xarray.Dataset> Size: 2kB
Dimensions: (bry_time: 3, s_rho: 3, xi_u: 7, xi_rho: 8, eta_rho: 4, eta_v: 3)
Coordinates:
abs_time (bry_time) datetime64[ns] 24B ...
* bry_time (bry_time) float64 24B 4.383e+03 4.384e+03 4.385e+03
Dimensions without coordinates: s_rho, xi_u, xi_rho, eta_rho, eta_v
Data variables: (12/14)
u_north (bry_time, s_rho, xi_u) float32 252B ...
v_north (bry_time, s_rho, xi_rho) float32 288B ...
temp_north (bry_time, s_rho, xi_rho) float32 288B ...
salt_north (bry_time, s_rho, xi_rho) float32 288B ...
zeta_north (bry_time, xi_rho) float32 96B ...
ubar_north (bry_time, xi_u) float32 84B ...
... ...
v_east (bry_time, s_rho, eta_v) float32 108B ...
temp_east (bry_time, s_rho, eta_rho) float32 144B ...
salt_east (bry_time, s_rho, eta_rho) float32 144B ...
zeta_east (bry_time, eta_rho) float32 48B ...
ubar_east (bry_time, eta_rho) float32 48B ...
vbar_east (bry_time, eta_v) float32 36B ...
Attributes:
title: ROMS boundary forcing file created ...
roms_tools_version: 3.6.1.dev17+g97b5fe39e
start_time: 2012-01-01 00:00:00
end_time: 2012-01-02 00:00:00
source: GLORYS
model_reference_date: 2000-01-01 00:00:00
apply_2d_horizontal_fill: False
adjust_depth_for_sea_surface_height: False
theta_s: 5.0
theta_b: 2.0
hc: 250.0, <xarray.Dataset> Size: 56kB
Dimensions: (bry_time: 12, s_rho: 3, xi_rho: 8, eta_rho: 4)
Coordinates:
month (bry_time) int32 48B ...
abs_time (bry_time) datetime64[ns] 96B ...
* bry_time (bry_time) float64 96B 15.5 45.0 74.5 ... 319.0 349.5
Dimensions without coordinates: s_rho, xi_rho, eta_rho
Data variables: (12/64)
PO4_north (bry_time, s_rho, xi_rho) float32 1kB ...
NO3_north (bry_time, s_rho, xi_rho) float32 1kB ...
SiO3_north (bry_time, s_rho, xi_rho) float32 1kB ...
Fe_north (bry_time, s_rho, xi_rho) float32 1kB ...
O2_north (bry_time, s_rho, xi_rho) float32 1kB ...
DIC_north (bry_time, s_rho, xi_rho) float32 1kB ...
... ...
diazFe_east (bry_time, s_rho, eta_rho) float32 576B ...
spCaCO3_east (bry_time, s_rho, eta_rho) float32 576B ...
zooC_east (bry_time, s_rho, eta_rho) float32 576B ...
Lig_east (bry_time, s_rho, eta_rho) float32 576B ...
DIC_ALT_CO2_east (bry_time, s_rho, eta_rho) float32 576B ...
ALK_ALT_CO2_east (bry_time, s_rho, eta_rho) float32 576B ...
Attributes:
title: ROMS boundary forcing file created ...
roms_tools_version: 3.6.1.dev17+g97b5fe39e
start_time: 2012-01-01 00:00:00
end_time: 2012-01-02 00:00:00
source: UNIFIED
model_reference_date: 2000-01-01 00:00:00
apply_2d_horizontal_fill: False
adjust_depth_for_sea_surface_height: False
theta_s: 5.0
theta_b: 2.0
hc: 250.0
climatology: True]
----------------------------------------------------------------------------------------------------
forcing.tidal
<xarray.Dataset> Size: 14kB
Dimensions: (ntides: 15, eta_rho: 4, xi_rho: 8, xi_u: 7, eta_v: 3)
Coordinates:
* ntides (ntides) |S3 45B b'm2' b's2' b'n2' b'k2' ... b'ms4' b'2n2' b's1'
omega (ntides) float64 120B ...
Dimensions without coordinates: eta_rho, xi_rho, xi_u, eta_v
Data variables:
ssh_Re (ntides, eta_rho, xi_rho) float32 2kB ...
ssh_Im (ntides, eta_rho, xi_rho) float32 2kB ...
pot_Re (ntides, eta_rho, xi_rho) float32 2kB ...
pot_Im (ntides, eta_rho, xi_rho) float32 2kB ...
u_Re (ntides, eta_rho, xi_u) float32 2kB ...
u_Im (ntides, eta_rho, xi_u) float32 2kB ...
v_Re (ntides, eta_v, xi_rho) float32 1kB ...
v_Im (ntides, eta_v, xi_rho) float32 1kB ...
Attributes:
title: ROMS tidal forcing created by ROMS-Tools
roms_tools_version: 3.6.1.dev17+g97b5fe39e
source: TPXO
model_reference_date: 2000-01-01 00:00:00
----------------------------------------------------------------------------------------------------
forcing.river
<xarray.Dataset> Size: 140kB
Dimensions: (river_time: 12, nriver: 41, ntracers: 34, eta_rho: 4,
xi_rho: 8)
Coordinates:
month (river_time) int32 48B ...
river_name (nriver) object 328B ...
* nriver (nriver) int32 164B 1 2 3 4 5 6 7 ... 35 36 37 38 39 40 41
abs_time (river_time) datetime64[ns] 96B ...
* river_time (river_time) float64 96B 15.0 45.0 74.0 ... 319.0 349.0
tracer_name (ntracers) object 272B ...
tracer_unit (ntracers) object 272B ...
tracer_long_name (ntracers) object 272B ...
Dimensions without coordinates: ntracers, eta_rho, xi_rho
Data variables:
river_volume (river_time, nriver) float64 4kB ...
river_tracer (river_time, ntracers, nriver) float64 134kB ...
river_index (eta_rho, xi_rho) float32 128B ...
river_fraction (eta_rho, xi_rho) float32 128B ...
Attributes:
climatology: True
----------------------------------------------------------------------------------------------------
cdr_forcing
<xarray.Dataset> Size: 1kB
Dimensions: (time: 2, ncdr: 1, ntracers: 34)
Coordinates:
* time (time) datetime64[ns] 16B 2012-01-01 2012-01-02
release_name (ncdr) object 8B ...
tracer_name (ntracers) object 272B ...
tracer_unit (ntracers) object 272B ...
tracer_long_name (ntracers) object 272B ...
Dimensions without coordinates: ncdr, ntracers
Data variables:
cdr_time (time) float64 16B ...
cdr_lon (ncdr) float64 8B ...
cdr_lat (ncdr) float64 8B ...
cdr_dep (ncdr) float64 8B ...
cdr_hsc (ncdr) float64 8B ...
cdr_vsc (ncdr) float64 8B ...
cdr_trcflx (time, ntracers, ncdr) float64 544B ...
Configure Build¶
Render the Jinja2 templates to generate compile-time and run-time configuration files (.opt files, roms.in, etc.). This prepares the BUILD stage.
# configure and build the model
ocn.configure_build(compile_time_settings={}, run_time_settings={})
Run C-Star¶
ocn.prep_cstar_environment(
account_key = None, # None gets from machine config or override here
queue_name = None, # None gets from machine config or override here
walltime = "00:10:00",
clobber = True, # recommend True, but it will clear previous results from this run
n_procs_available = 0, # 0 is auto-detect, change if on a login or shared node to not overuse resources
)# Run C-Star via CLI
# This is recommended in order to get people used to using the CLI for these operations
import os
os.environ["THIS_BP_PATH"] = str(ocn.path_blueprint(stage="build"))
!echo $THIS_BP_PATH
!cstar blueprint run $THIS_BP_PATH/Users/eilerman/git/cson-forge/cson_forge/catalog/blueprints/MacOS/cson_roms-marbl_v0.1_test-tiny_1procs/B_cson_roms-marbl_v0.1_test-tiny_1procs_build.yml
2026-05-04 16:20:26,675 [INFO] - worker.py:275 - Creating simulation runner for /Users/eilerman/git/cson-forge/cson_forge/catalog/blueprints/MacOS/cson_roms-marbl_v0.1_test-tiny_1procs/B_cson_roms-marbl_v0.1_test-tiny_1procs_build.yml
2026-05-04 16:20:26,893 [INFO] - simulation.py:1288 - 🛠️ Configuring ROMSSimulation
2026-05-04 16:20:26,893 [INFO] - simulation.py:1291 - 🔧 Setting up ROMSExternalCodeBase...
2026-05-04 16:20:36,304 [INFO] - simulation.py:1291 - 🔧 Setting up MARBLExternalCodeBase...
2026-05-04 16:20:50,209 [INFO] - simulation.py:1305 - 📦 Fetching compile-time code...
2026-05-04 16:20:50,214 [INFO] - simulation.py:1310 - 📦 Fetching runtime code...
2026-05-04 16:20:50,215 [INFO] - simulation.py:1315 - 📦 Fetching input datasets...
2026-05-04 16:20:50,216 [INFO] - input_dataset.py:97 - 🔗 Created symlink: /Users/eilerman/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/work/cdr.nc → /Users/eilerman/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/input/input_datasets/cson_roms-marbl_v0_1_test-tiny_1procs_cdr.nc
2026-05-04 16:21:01,300 [INFO] - input_dataset.py:279 - Partitioning /Users/eilerman/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/input/input_datasets/cson_roms-marbl_v0_1_test-tiny_1procs_grid.nc into (1,1)
2026-05-04 16:21:01,593 [INFO] - input_dataset.py:279 - Partitioning /Users/eilerman/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/input/input_datasets/cson_roms-marbl_v0_1_test-tiny_1procs_initial_conditions.nc into (1,1)
2026-05-04 16:21:01,620 [INFO] - input_dataset.py:279 - Partitioning /Users/eilerman/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/input/input_datasets/cson_roms-marbl_v0_1_test-tiny_1procs_tidal.nc into (1,1)
2026-05-04 16:21:01,627 [INFO] - input_dataset.py:279 - Partitioning /Users/eilerman/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/input/input_datasets/cson_roms-marbl_v0_1_test-tiny_1procs_river.nc into (1,1)
2026-05-04 16:21:01,635 [INFO] - input_dataset.py:279 - Partitioning /Users/eilerman/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/input/input_datasets/cson_roms-marbl_v0_1_test-tiny_1procs_boundary-physics_201112.nc into (1,1)
2026-05-04 16:21:01,645 [INFO] - input_dataset.py:279 - Partitioning /Users/eilerman/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/input/input_datasets/cson_roms-marbl_v0_1_test-tiny_1procs_boundary-physics_201201.nc into (1,1)
2026-05-04 16:21:01,655 [INFO] - input_dataset.py:279 - Partitioning /Users/eilerman/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/input/input_datasets/cson_roms-marbl_v0_1_test-tiny_1procs_boundary-bgc_clim.nc into (1,1)
2026-05-04 16:21:01,786 [INFO] - input_dataset.py:279 - Partitioning /Users/eilerman/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/input/input_datasets/cson_roms-marbl_v0_1_test-tiny_1procs_surface-physics_201112.nc into (1,1)
2026-05-04 16:21:01,794 [INFO] - input_dataset.py:279 - Partitioning /Users/eilerman/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/input/input_datasets/cson_roms-marbl_v0_1_test-tiny_1procs_surface-physics_201201.nc into (1,1)
2026-05-04 16:21:01,803 [INFO] - input_dataset.py:279 - Partitioning /Users/eilerman/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/input/input_datasets/cson_roms-marbl_v0_1_test-tiny_1procs_surface-bgc_clim.nc into (1,1)
2026-05-04 16:21:01,813 [INFO] - simulation.py:1671 - Running mpirun -n 1 ./roms cstar_generated_roms.in
2026-05-04 16:21:06,830 [WARNING] - handler.py:152 - This job is currently not running (completed). Live updates cannot be provided. See /Users/eilerman/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/logs/cstar_worker_20260504_222022.out for job output
2026-05-04 16:21:06,830 [INFO] - worker.py:226 - Simulation is not running (completed). Allowing shutdown.
2026-05-04 16:21:06,830 [INFO] - worker.py:226 - Simulation is not running (completed). Allowing shutdown.
2026-05-04 16:21:06,830 [INFO] - service.py:319 - Shutting down service.
2026-05-04 16:21:06,830 [INFO] - service.py:319 - Shutting down service.
2026-05-04 16:21:06,833 [INFO] - simulation.py:92 - Joining netCDF files output_cdr.20120101020000.*.nc...
2026-05-04 16:21:06,833 [INFO] - simulation.py:92 - Joining netCDF files output_rst.20120102000000.*.nc...
Numba: Attempted to fork from a non-main thread, the TBB library may be in an invalid state in the child process.
Numba: Attempted to fork from a non-main thread, the TBB library may be in an invalid state in the child process.
2026-05-04 16:21:07,160 [INFO] - simulation.py:101 - Done spatially joining /Users/eilerman/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/output/output_cdr.20120101020000.nc
2026-05-04 16:21:07,162 [INFO] - simulation.py:101 - Done spatially joining /Users/eilerman/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/output/output_rst.20120102000000.nc
2026-05-04 16:21:07,163 [INFO] - worker.py:97 - Completed simulation logs at: /Users/eilerman/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/logs/cstar_worker_20260504_222022.out
2026-05-04 16:21:07,163 [INFO] - worker.py:97 - Completed simulation logs at: /Users/eilerman/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/logs/cstar_worker_20260504_222022.out
2026-05-04 16:21:07,163 [INFO] - worker.py:100 - Simulation completed successfully.
2026-05-04 16:21:07,163 [INFO] - worker.py:100 - Simulation completed successfully.
Blueprint execution completed
# Or use the wrapper function on the SpecBuilder
# This might be needed if the environment on an HPC doesn't handle the !bash commands correctly
# await ocn.run()
# Note: if you want to call this run method from a non-notebook script, you need to do the following:
# import asyncio
# asyncio.run(ocn.run())Visualize Model Output¶
After the model run completes, you can load and visualize the output data. The code below:
Finds output files: Uses
globto locate all BGC (biogeochemical) output files in theJOINED_OUTPUTdirectoryOpens the dataset: Uses
xarray.open_mfdataset()to open multiple NetCDF files as a single datasetApplies land mask: Masks out land points using the grid’s
mask_rhovariablePlots a variable: Creates a plot of dissolved inorganic carbon (DIC) at the first time step and bottom vertical level (
s_rho=-1)
The JOINED_OUTPUT directory contains the spatially-joined output files created by post_run(), which combine partitioned output files from parallel runs into single files.
str(ocn.run_output_dir / "joined_output" / (ocn.casename + "_bgc.*"))'/Users/eilerman/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/joined_output/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102_bgc.*'# import xarray as xr
# from glob import glob
# files = glob(str(ocn.run_output_dir / "output" / ("output_bgc.*")))
# ds = xr.open_mfdataset(files)
# ds = ds.where(ocn.grid.ds.mask_rho)
# ds.DIC.isel(eta_rho=2, xi_rho=6, s_rho=-1).plot(marker="o", color="red")CDR Plots¶
from roms_tools import ROMSOutput
roms_out = ROMSOutput(grid=ocn.grid, path=ocn.run_output_dir / "joined_output" / "output_cdr.*.nc", use_dask=True)
roms_out.cdr_metrics()
Set Blueprint State¶
The set_blueprint_state() method updates the state of the blueprint, which tracks the workflow stage of the simulation specification. Blueprint states indicate the current stage of the workflow (e.g., “draft”, “configured”, “ready”) and are used by the C-Star orchestration system to manage the simulation lifecycle.
Common blueprint states include:
"draft": The blueprint is in development and not yet finalized"validated": The blueprint has been validated
Setting the state to "draft" is useful when you want to mark the blueprint as a work-in-progress that may need further modifications before execution.
ocn.set_blueprint_state(state="draft")Save Executed Notebook¶
Save a timestamped copy of this notebook to executed/forge/{os}/ for reproducibility and record-keeping. The copy is organized by operating system (macOS or Ubuntu/Linux) to track execution history across different platforms.
The saved notebook includes all executed cells and outputs, providing a complete record of the simulation workflow for future reference.
# Save the notebook copy
cstar_forge.save_notebook_copy(notebook_name="CStarSpecBuilder-demo.ipynb")Notebook copy saved to: executed/forge/MacOS/CStarSpecBuilder-demo_MacOS.ipynb
PosixPath('executed/forge/MacOS/CStarSpecBuilder-demo_MacOS.ipynb')