Setting up an experiment#
In Fortran TRACMASS an experiment is a project (the GCM-specific code in
projects/<NAME>/) plus a case (a namelist). You choose them in
Makefile.prj and recompile. TRACMASS-JAX splits things the same way, but
nothing is compiled ahead of time:
Fortran TRACMASS |
TRACMASS-JAX |
|---|---|
|
|
|
a named environment |
|
|
This page builds a regional GLORYS12 experiment step by step. Swap
glorys for ecco2, scrippsgog or theoretical to use another GCM.
1. Pick an environment name and a settings file#
Settings live in TOML files read by
Dynaconf. Each top-level table is an
environment, and [default] holds values shared by all of them. Put a
tracmass.toml in the directory you run from:
[default]
base_output_dir = "/data/raid/trm/"
runmonitor_backend = "rich"
[omi]
dtm_start = "2010-06-01"
runtime = "180D" # 180 days forward; "-180D" runs backward
move_vertically = false # keep particles on their seeding level
output_name = "trm_omi"
You can also put the [omi] table in its own trm_omi.toml next to a
shared tracmass.toml. Every trm_*.toml in the current directory is read
too (see Settings files).
2. Choose the GCM and the region#
The [env.gcm] table names the adapter, and its optional subset limits
the part of the grid that is read:
[omi.gcm]
name = "glorys"
subset = { i1 = 2600, i2 = 3700, j1 = 500, j2 = 1600, k1 = 1, k2 = 2 }
i1/i2/j1/j2 are 0-based Python slice limits on the model’s x/y
axes, and k1/k2 are 1-based levels. A subset makes every window much
cheaper to read. See the Subsets tutorial for
details, including what happens at the edges.
3. Seed the particles#
The [env.seed] table says where particles start:
[omi.seed]
approach = "latlon_box" # or "ijk", "latlon_point", "latlon_list"
i_sub_num = 10 # 10 x 10 particles per cell
j_sub_num = 10
box = { lat1 = -64, lat2 = -62, lon1 = -70, lon2 = -68, k1 = 1, k2 = 1 }
See the Seeding tutorial for every approach,
sub-cell distributions and repeated releases (seed_freq).
4. Choose the integrator and its options#
[omi]
integrator = "time_dependent_patched" # full grid / patched / streaming
traj_max_time = "90D" # stop each particle 90 days after release
rampup_windows = 2 # denser output in the first two days
Integrator |
Reads per window |
Good for |
|---|---|---|
|
the whole (sub)grid |
small grids, subsets, particles everywhere |
|
a box around the particles |
clustered particles on a large grid |
|
the six faces of each particle’s cell |
scattered particles, very long runs |
5. Run#
import tracmass
result = tracmass.run(env="omi") # all from settings
result = tracmass.run("2011-06-01", env="omi") # override the start date
result = tracmass.run(env="omi", iter_sub=4, verbose=True)
tracmass.run resolves every argument you leave out from the active
environment:
Argument |
From settings when omitted |
|---|---|
|
|
|
|
|
|
|
|
|
the |
|
|
Other keyword arguments, such as iter_sub, patch_buffer or n_windows,
go straight to the integrator. The integrator in turn reads monitor,
recorder, no_wflux, n_particle_batches, traj_max_time, seed_freq
and the ramp-up options from the settings when they are not passed.
6. Find the output#
With output_name set, the trajectories are written to
{base_output_dir}/{output_name}_{forward|reverse}_{dtm_start}.parquet
e.g. /data/raid/trm/trm_omi_forward_2010-06-01.parquet. Read them back
with
df = tracmass.load(env="omi") # newest omi file
df = tracmass.load(env="omi", lonlat=True) # with lon/lat columns
See Output.
The same thing in plain Python#
Every step above has a Python equivalent. That is useful in notebooks and for experiments that settings cannot express:
import tracmass
from tracmass import gcm, seed
tracmass.settings.setenv("omi") # optional
grid, lazy = tracmass.new_flux(
"glorys", dtm_start="2010-06-01", dtm_end="2010-11-28"
)
state = seed.latlon_box(-64, -62, -70, -68, grid=grid, gcm="glorys",
i_sub_num=10, j_sub_num=10)
result = tracmass.time_dependent_patched(
state, grid, lazy, iter_sub=4,
monitor="rich", recorder="omi_test.parquet",
)