Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Making a new domain: CStarSpecBuilder

This notebook demonstrates how to create a new domain and run a ROMS simulation using C-SON Forge.

Setup

First, import the necessary modules and define the domain configuration parameters.

%load_ext autoreload
%autoreload 2

import cson_forge
import cstar.execution.handler as handler
import time
from datetime import datetime
from IPython.display import Markdown, display

Environment and Machine Information

Record the execution environment and machine details for reproducibility.

env = cson_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')}")
Loading...
Execution timestamp: 2026-01-30 07:15:10
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) 
}

Initialize CstarSpecBuilder

Create a CstarSpecBuilder instance with the domain configuration. This initializes the PRECONFIG stage, creating the grid object and blueprint structure.

ocn = cson_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,
)

Visualize the grid

ocn.grid.plot()
<Figure size 1300x700 with 2 Axes>

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 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
✔️  TPXO dataset verified at: /Users/mclong/cson-forge-data/source-data/TPXO/TPXO10.v2
✔️  Using existing BGC dataset: /Users/mclong/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 8 existing .nc files in /Users/mclong/cson-forge-data/input-data/cson_roms-marbl_v0.1_test-tiny_1procs...

▶️  [1/8] Writing ROMS grid...

▶️  [2/8] Generating initial conditions...
[WARNING] Optional variables missing (but not critical): ['Lig', 'DIC_ALT_CO2', 'Alk_ALT_CO2']
[########################################] | 100% Completed | 3.97 sms

▶️  [3/8] 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 | 19.63 ss
[WARNING] Optional variables missing (but not critical): ['pco2_air_alt']

▶️  [4/8] Generating surface forcing...
[########################################] | 100% Completed | 106.75 ms

▶️  [5/8] Generating boundary forcing...
[########################################] | 100% Completed | 206.15 ms
[WARNING] Optional variables missing (but not critical): ['Lig', 'DIC_ALT_CO2', 'Alk_ALT_CO2']

▶️  [6/8] Generating boundary forcing...
[########################################] | 100% Completed | 8.93 ss

▶️  [7/8] Generating tidal forcing...
[########################################] | 100% Completed | 1.37 sms

▶️  [8/8] Generating river 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': '84f4ee7886e9ee4c33b3248b35c955551f3b9c06', '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/mclong/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/mclong/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/mclong/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/mclong/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/mclong/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/mclong/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/mclong/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/mclong/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=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/13)
    title:                   ROMS grid created by ROMS-Tools
    roms_tools_version:      3.4.0
    size_x:                  500
    size_y:                  1000
    center_lon:              0
    center_lat:              55
    ...                      ...
    straddle:                True
    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.4.0
    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: 23kB
Dimensions:   (time: 25, eta_rho: 4, xi_rho: 8)
Coordinates:
    abs_time  (time) datetime64[ns] 200B ...
  * time      (time) float64 200B 4.383e+03 4.383e+03 ... 4.384e+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     (time, eta_rho, xi_rho) float32 3kB ...
    lwrad     (time, eta_rho, xi_rho) float32 3kB ...
    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.4.0
    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.4.0
    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: 1kB
Dimensions:     (bry_time: 2, s_rho: 3, xi_u: 7, xi_rho: 8, eta_rho: 4, eta_v: 3)
Coordinates:
    abs_time    (bry_time) datetime64[ns] 16B ...
  * bry_time    (bry_time) float64 16B 4.383e+03 4.384e+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 168B ...
    v_north     (bry_time, s_rho, xi_rho) float32 192B ...
    temp_north  (bry_time, s_rho, xi_rho) float32 192B ...
    salt_north  (bry_time, s_rho, xi_rho) float32 192B ...
    zeta_north  (bry_time, xi_rho) float32 64B ...
    ubar_north  (bry_time, xi_u) float32 56B ...
    ...          ...
    v_east      (bry_time, s_rho, eta_v) float32 72B ...
    temp_east   (bry_time, s_rho, eta_rho) float32 96B ...
    salt_east   (bry_time, s_rho, eta_rho) float32 96B ...
    zeta_east   (bry_time, eta_rho) float32 32B ...
    ubar_east   (bry_time, eta_rho) float32 32B ...
    vbar_east   (bry_time, eta_v) float32 24B ...
Attributes:
    title:                                ROMS boundary forcing file created ...
    roms_tools_version:                   3.4.0
    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.4.0
    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.4.0
    source:                TPXO
    model_reference_date:  2012-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

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={})
ROMSSimulation( name = cson_roms-marbl_v0.1_test-tiny_1procs, directory = /Users/mclong/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102, start_date = 2012-01-01 00:00:00, end_date = 2012-01-02 00:00:00, valid_start_date = 2012-01-01 00:00:00, valid_end_date = 2012-01-02 00:00:00, discretization = ROMSDiscretization(time_step = 1800, n_procs_x = 1, n_procs_y = 1), codebase = <ROMSExternalCodeBase instance>, runtime_code = <AdditionalCode instance>, compile_time_code = <AdditionalCode instance> model_grid = <ROMSModelGrid instance>, initial_conditions = <ROMSInitialConditions instance>, tidal_forcing = <ROMSTidalForcing instance>, river_forcing = <ROMSRiverForcing instance>, surface_forcing = <list of 2 ROMSSurfaceForcing instances>, boundary_forcing = <list of 2 ROMSBoundaryForcing instances>, )

Build Model Executable

Compile the ROMS/MARBL model source code to create the executable. This uses the C-Star build system to compile the model with the specified configuration.

ocn.build()
[INFO] 🛠️ Configuring ROMSSimulation
[INFO] 🔧 Setting up ROMSExternalCodeBase...
[INFO] 🔧 Setting up MARBLExternalCodeBase...
[INFO] 📦 Fetching compile-time code...
[INFO] 📦 Fetching runtime code... 
[INFO] 📦 Fetching input datasets...
ROMSSimulation( name = cson_roms-marbl_v0.1_test-tiny_1procs, directory = /Users/mclong/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102, start_date = 2012-01-01 00:00:00, end_date = 2012-01-02 00:00:00, valid_start_date = 2012-01-01 00:00:00, valid_end_date = 2012-01-02 00:00:00, discretization = ROMSDiscretization(time_step = 1800, n_procs_x = 1, n_procs_y = 1), codebase = <ROMSExternalCodeBase instance>, runtime_code = <AdditionalCode instance>, compile_time_code = <AdditionalCode instance> model_grid = <ROMSModelGrid instance>, initial_conditions = <ROMSInitialConditions instance>, tidal_forcing = <ROMSTidalForcing instance>, river_forcing = <ROMSRiverForcing instance>, surface_forcing = <list of 2 ROMSSurfaceForcing instances>, boundary_forcing = <list of 2 ROMSBoundaryForcing instances>, )

Pre-Run Setup

Perform pre-run operations, including partitioning input files for parallel execution if needed.

# perform partitioning
ocn.pre_run()
[INFO] Partitioning /Users/mclong/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/input_datasets/cson_roms-marbl_v0.1_test-tiny_1procs_grid.nc into (1,1)
[INFO] Partitioning /Users/mclong/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/input_datasets/cson_roms-marbl_v0.1_test-tiny_1procs_initial_conditions.nc into (1,1)
[INFO] Partitioning /Users/mclong/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/input_datasets/cson_roms-marbl_v0.1_test-tiny_1procs_tidal.nc into (1,1)
[INFO] Partitioning /Users/mclong/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/input_datasets/cson_roms-marbl_v0.1_test-tiny_1procs_river.nc into (1,1)
[INFO] Partitioning /Users/mclong/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/input_datasets/cson_roms-marbl_v0.1_test-tiny_1procs_boundary-physics_201201.nc into (1,1)
[INFO] Partitioning /Users/mclong/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/input_datasets/cson_roms-marbl_v0.1_test-tiny_1procs_boundary-bgc_clim.nc into (1,1)
[INFO] Partitioning /Users/mclong/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/input_datasets/cson_roms-marbl_v0.1_test-tiny_1procs_surface-physics_201201.nc into (1,1)
[INFO] Partitioning /Users/mclong/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/input_datasets/cson_roms-marbl_v0.1_test-tiny_1procs_surface-bgc_clim.nc into (1,1)

Run Model Simulation

Execute the ROMS model simulation. This runs the model with the configured inputs and settings.

# run the model
exec_handler = ocn.run()
print(exec_handler)
[INFO] Running mpirun -n 1 /Users/mclong/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/compile_time_code/roms /Users/mclong/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/runtime_code/cson_roms-marbl_v0.1_test-tiny_1procs.in
LocalProcess
------------
Commands: mpirun -n 1 /Users/mclong/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/compile_time_code/roms /Users/mclong/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/runtime_code/cson_roms-marbl_v0.1_test-tiny_1procs.in
Run path: /Users/mclong/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/output
Output file: /Users/mclong/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/logs/cson_roms-marbl_v0-1_test-tiny_1procs_20120101-20120102.out
Status: running
%%time

while not handler.ExecutionStatus.is_terminal(exec_handler.status):
    print("...", end="", flush=True)
    time.sleep(30)

if exec_handler.status == handler.ExecutionStatus.COMPLETED:
    print()
    print("Completed")
    ocn.post_run()
else:
    raise Exception("Model run failed")
...
Completed
[INFO] Joining netCDF files output_bgc_dia.20120101000000.*.nc...
[INFO] Joining netCDF files output_bgc.20120101000000.*.nc...
[INFO] Joining netCDF files output_rst.20120102000000.*.nc...
[INFO] Joining netCDF files output_rst.20120101120000.*.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.
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.
[INFO] done spatially joining /Users/mclong/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/output/output_bgc.20120101000000.nc
[INFO] Joining netCDF files output_his.20120101000000.*.nc...
[INFO] done spatially joining /Users/mclong/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/output/output_rst.20120102000000.nc
[INFO] done spatially joining /Users/mclong/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/output/output_rst.20120101120000.nc
[INFO] done spatially joining /Users/mclong/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/output/output_his.20120101000000.nc
Numba: Attempted to fork from a non-main thread, the TBB library may be in an invalid state in the child process.
[INFO] done spatially joining /Users/mclong/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/output/output_bgc_dia.20120101000000.nc
CPU times: user 14.7 ms, sys: 127 ms, total: 141 ms
Wall time: 31 s

Visualize Model Output

After the model run completes, you can load and visualize the output data. The code below:

  1. Finds output files: Uses glob to locate all BGC (biogeochemical) output files in the JOINED_OUTPUT directory

  2. Opens the dataset: Uses xarray.open_mfdataset() to open multiple NetCDF files as a single dataset

  3. Applies land mask: Masks out land points using the grid’s mask_rho variable

  4. Plots 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 / "output" / "joined_output" / (ocn.casename + "_bgc.*"))
'/Users/mclong/cson-forge-data/cson-forge-run/cson_roms-marbl_v0.1_test-tiny_1procs_20120101-20120102/output/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")
<Figure size 640x480 with 1 Axes>

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
cson_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')