Local DriftCast: trajectory calculations, ensembles, and updates

This document describes the equations and operational workflow implemented by the Local DriftCast trajectory viewer. It is intended to make every displayed track reproducible from its archived forcing inputs and solver settings.

The active viewer contains two kinds of cases:

  • nine observation-backed validation cases for Hooper Bay, Englullrarmiut, and Freebird; and
  • five hypothetical Okinawa priority forecasts, each with a five-point north-south release line and no observations yet.

The operational calculation code is in ../data/SPOTTER/driftcast-local-forcing-qc-2026-08-18/. The generated viewer and its currently published case files are in spotter_validation_viewer/.

1. Coordinate and notation conventions

All horizontal vectors use east-north order:

where is eastward and is northward. Velocities are in , positions are longitude/latitude in decimal degrees, and internal times are UTC Unix seconds.

SymbolMeaningSource variable(s)
Eulerian surface-ocean currentSMOC uo, vo at the shallowest depth
surface Stokes driftSMOC vsdx, vsdy for Okinawa; wave-product VSDX, VSDY for validation
draft-averaged Stokes drift used by the validation casesderived from VSDX, VSDY, and VTPK
10 m windIFS u10, v10
tidal driftSMOC utide, vtide
full SMOC surface velocitySMOC utotal, vtotal
modeled buoy velocitycalculated
local east/north positioncalculated
longitude and latitudecalculated or observed
mean Earth radius6,371,000 m

The full SMOC variables are treated as the composite velocity supplied by the product. The code does not add Stokes drift or tidal drift to again.

2. Forcing products

Operational Okinawa forecasts

The Okinawa calculations use:

  • Copernicus Marine SMOC dataset cmems_mod_glo_phy_anfc_merged-uv_PT1H-i, including uo, vo, vsdx, vsdy, utide, vtide, utotal, and vtotal;
  • ECMWF deterministic IFS 10 m wind, u10 and v10; and
  • the Copernicus global wave forecast for viewer-only wave height, period, and direction backgrounds.

All ocean-velocity components used by a single Okinawa run come from one archived SMOC snapshot. This prevents the SMOC and finite-inertia tracks from silently mixing forecast cycles.

The regional SMOC request spans 115-145 degrees E and 15-35 degrees N, from one hour before release through one hour after the 72-hour forecast. The extra hour on each side is required by the centered material-derivative calculation.

Observation-backed validation cases

The nine fixed examples use the locally archived currents, waves, and winds associated with their historical release windows. Wind switches from ERA5 to the archived IFS forecast. If a gap exists between the last ERA5 time and first IFS time, the code linearly bridges the two endpoints.

The validation cases use a draft-averaged Stokes velocity. With peak period , deep-water wave number

draft , and , the factor is

Therefore

The Okinawa forecast generator instead uses the SMOC vsdx/vsdy surface values directly. This is an intentional implementation difference that must be retained when reproducing the archived results.

3. Interpolation

Forcing is sampled at every ensemble member’s current time and position. The implementation performs:

  1. bilinear interpolation over the four surrounding longitude/latitude cells;
  2. renormalization of the spatial weights if one or more corners are missing;
  3. linear interpolation between the two surrounding forcing times.

For a spatial field value , the four bilinear weights are

and the missing-value-aware estimate is

where contains the finite corners. Linear time interpolation is

Coordinates outside an input axis are clamped to the nearest boundary by the interpolator. Operational input coverage is therefore checked before a run so time-boundary clamping is not used as a substitute for missing forecast data.

4. Trajectory models

The active Okinawa viewer compares two trajectory formulations: the SMOC additive model and the finite-inertia model. The earlier standalone simple track is no longer plotted as a separate model because it differs from the SMOC formulation primarily by omitting the tidal contribution.

4.1 SMOC formulation: simple model plus tides

The SMOC trajectory retains the direct additive structure of the simple model and adds tidal drift. In physical-component notation, the displayed model is

The active coefficients are

CoefficientValueInterpretation
1.0full current
1.0full Stokes term
1.0full tidal term
0.0121.2% of 10 m wind

For the operational calculation, SMOC supplies these water-motion components as the composite utotal and vtotal variables. The equation evaluated by the integrator is therefore

This is the former simple current + Stokes + windage formulation with the tidal term included. The windage coefficient remains , or 1.2% of the 10 m wind.

For the validation examples, in this expression is replaced by the draft-averaged defined above.

utotal and vtotal are used exactly once. The separately published current, Stokes, and tidal fields remain available as diagnostic viewer backgrounds; they are not added a second time to the SMOC trajectory.

The SMOC model uses a 60 s integration step. For a velocity held over one step , the spherical position update is

with angular increments converted from radians to degrees. Positions are saved hourly, including the release position, producing 73 points for a 72-hour run.

4.2 Finite-inertia formulation

The finite-inertia model evolves both position and buoy velocity. Define the water velocity and relative velocities as

Again, the validation cases use , while Okinawa uses the SMOC surface Stokes velocity.

The effective mass includes added mass:

For each fluid ,

and the drag coefficient is evaluated in three Reynolds-number regimes:

The water and air drag accelerations are represented by

With Coriolis parameter

the exact component equations implemented in the solver are

The water material derivative is

It is evaluated with centered differences using and :

with analogous centered differences in east and north. The derivative is refreshed every 600 s and the local water and wind velocities every 60 s.

The solver uses forward Euler:

The Okinawa finite-inertia runs use . The northern validation cases use 4 s and the Freebird validation cases use 1 s. Okinawa is initialized with the local current + Stokes + windage velocity. Its subsequent finite-inertia evolution remains unchanged and does not substitute the SMOC tidal composite for . The validation cases instead initialize velocity from a linear fit to the observed track over approximately +/-30 minutes for the northern buoys and +/-15 minutes for Freebird.

Finite-inertia constants

VariableValueUnitsMeaning
7.45kgbuoy mass
0.0072683m3submerged volume
0.5dimensionlessadded-mass coefficient
11.17500375kgeffective mass
0.03643m2submerged frontal area
0.2993mwater-side characteristic length
0.0406875m2exposed frontal area
0.42mair-side characteristic length
1025kg m-3seawater density
1.225kg m-3air density
1.05e-6m2 s-1water kinematic viscosity
1.50e-5m2 s-1air kinematic viscosity
7.2921159e-5s-1Earth rotation rate
9.80665m s-2gravitational acceleration
0.155mdraft used for validation Stokes averaging
6,371,000mEarth radius

These are fixed engineering parameters, not fitted separately for each case.

5. Ensemble construction

Only the initial position is perturbed. For each member,

The conversion to geographic coordinates is

The 1 km setting is the standard deviation of each east/north component, not a hard radial limit. For an ideal two-dimensional Gaussian, its initial 80% radial quantile is approximately 1.794 km.

Sampling is antithetic: every random offset is paired with . This centers each finite ensemble exactly on the requested release. The same offsets are shared across models, and the five Okinawa sites also share the same offset set, making model/site comparisons paired rather than confounded by different random draws.

Current Okinawa settings are:

  • 100 members per site per model;
  • five sites per priority area;
  • 500 tracks per model and 1,000 displayed tracks per priority forecast;
  • two displayed models: SMOC (current + Stokes + tides + 0.012 wind) and finite inertia;
  • random seed 20260825.

Across all five priorities this is 5,000 displayed trajectories per initialization time. The four Okinawa initialization batches contain 20,000 displayed trajectories in total. The nine validation cases contain 100 members per model, with case-specific deterministic seeds derived from 20260819.

6. The 80% trajectory cone

At each saved hour, the viewer product calculates component-wise median longitude and latitude. It then computes every member’s great-circle distance from that median and stores the 0.8 quantile as .

Great-circle distance uses the haversine expression

The cone is a single merged geometry, rather than many overlapping translucent circles. In a local tangent plane, the code:

  1. offsets the median centerline by +/- along its local normal;
  2. joins adjacent left/right offsets with quadrilaterals;
  3. unions those pieces with a circular buffer at every hourly center;
  4. uses 16 segments per quadrant for the round buffers.

This creates a clean outline with a rounded end cap whose radius is the final 80% spread. It is a visualization of hourly marginal 80% spread, not a formal simultaneous 80% confidence region for the entire trajectory.

For a five-site forecast, each release group has its own cone. A combined outline is also stored; disconnected pieces fall back to their convex hull for viewer rendering.

7. Okinawa release geometry and timing

Each priority transect is evaluated at four initialization times. Every case runs for 72 hours and saves positions hourly.

Initialization in JSTInitialization in UTCForecast end in UTC
2026-08-25 09:00 JST2026-08-25 00:00 UTC2026-08-28 00:00 UTC
2026-08-25 21:00 JST2026-08-25 12:00 UTC2026-08-28 12:00 UTC
2026-08-26 09:00 JST2026-08-26 00:00 UTC2026-08-29 00:00 UTC
2026-08-26 21:00 JST2026-08-26 12:00 UTC2026-08-29 12:00 UTC

The same release geometry, initial perturbations, random seed, coefficients, models, and numerical settings are used at every initialization. Only the release time and therefore the sampled time-evolving forcing change. The viewer groups the twenty priority cases by JST initialization time.

Each provided midpoint is site 3. Sites 1-5 are at latitude offsets arcminutes with unchanged longitude, so adjacent nominal release points are one nautical mile apart north-south.

PriorityCenter latitudeCenter longitude
127 deg 16 min 0.61 sec N127 deg 38 min 41.64 sec E
226 deg 55 min 47.44 sec N127 deg 16 min 57.56 sec E
326 deg 12 min 24.34 sec N126 deg 40 min 54.52 sec E
425 deg 59 min 25.80 sec N126 deg 39 min 44.00 sec E
525 deg 59 min 0.06 sec N127 deg 10 min 45.89 sec E

There are no observations for these hypothetical releases, so no forecast error or skill score is assigned to them before deployment.

8. Validation metrics

For observation-backed cases, pointwise position error is the great-circle distance

The stored headline metrics are:

Hourly interval velocity is reconstructed from consecutive positions:

Velocity error is

With observed-motion unit vector and perpendicular , the diagnostic magnitudes are

For candidate-minus-reference comparisons, positive improvement is defined as

Thus positive values mean the candidate has less error. Error growth rate is approximated by

The primary coefficient-tuning objective used in the diagnostic suite is the median across forecasts of mean 0-72 h position error:

9. Coefficient experiments versus active settings

The repository contains earlier tuning products; these do not silently alter the active viewer model.

ExperimentValues testedCoefficients held fixed
windage0.000-0.015 in 0.001 increments
current0.5-1.5 in 0.1 increments
Stokes0, 0.25, 0.5, …, 2.0
hourly rolling comparison versus 0.6

The tuned case and the earlier no-tide simple track remain analysis products. Neither is presented as a separate active Okinawa model. The active additive track uses unit current, Stokes, and tidal contributions plus through the SMOC composite formulation in Section 4.1.

10. Forecast selection and automatic updates

The macOS LaunchAgent runs poll_forecasts.py every 900 s (15 minutes) while the user is logged in and the Mac is awake. The workflow is:

  1. poll and archive eligible ECMWF IFS cycles;
  2. poll and archive Copernicus forecast updates;
  3. if both pollers succeed, check whether the Okinawa cases need rebuilding;
  4. archive the complete new run first;
  5. atomically replace the five cases belonging to that initialization and update the manifest without removing the other initialization batches.

IFS cycles are initialized at 00, 06, 12, and 18 UTC. The 00/12 UTC products extend to 240 h; 06/18 UTC extend to 144 h. For the Okinawa experiment the refresh controller selects the latest initialization that is no later than the release time and still covers the complete 72-hour interval:

This is the closest eligible pre-release forecast, not simply the newest file on disk.

A fresh regional SMOC snapshot is requested no more often than every six hours by default. Its coordinate arrays and all eight trajectory variables are content-hashed with SHA-256. Trajectories are rebuilt only if the eligible IFS cycle changes, the SMOC content hash changes, or a forced run is requested.

Automatic updating stops at the release time. This prevents post-release model updates from introducing hindsight into later validation. Retrospective runs are possible only with the explicit --allow-after-release option and remain timestamped in the archive.

The refresh refuses to run with less than 15 GiB of free disk space, validates full SMOC time coverage and required variables, and uses a filesystem lock to prevent concurrent rebuilds.

Manual update commands

From the repository root:

cd data/SPOTTER/driftcast-local-forcing-qc-2026-08-18
 
# Inspect the selected IFS cycle and whether a SMOC refresh is due.
.venv/bin/python refresh_okinawa_priority_forecasts.py --check-only
 
# Poll all operational sources, then refresh if inputs changed.
.venv/bin/python poll_forecasts.py
 
# Force a new pre-release SMOC snapshot and recalculation.
.venv/bin/python refresh_okinawa_priority_forecasts.py --force

The trajectory generator itself uses the Python interpreter named by DRIFTCAST_TRAJECTORY_PYTHON; if unset, it prefers /Users/wyn/miniforge3/envs/Pacific/bin/python and otherwise falls back to the current interpreter.

11. Archive and provenance

The active viewer contains twenty Okinawa cases: five priorities at four initialization times. Recalculating one initialization replaces only its five active viewer JSON files. Historical calculations are never overwritten in the archive.

Immutable runs live at:

data/SPOTTER/driftcast-local-forcing-qc-2026-08-18/
  forecast_archive/okinawa_priority_forecasts/
    index.json
    runs/
      YYYYMMDDTHHMMSSZ/
        run.json
        cases/
          ensemble_okinawa_priority-1_YYYYMMDDTHHZ.json
          ...
          ensemble_okinawa_priority-5_YYYYMMDDTHHZ.json

Every run records:

  • UTC calculation time and unique run ID;
  • release and forecast-end time;
  • IFS path, initialization cycle, SHA-256, and byte count;
  • SMOC snapshot path, retrieval time, content SHA-256, byte count, and variable list;
  • generator path and SHA-256;
  • ensemble size, position sigma, seed, and finite-inertia time step; and
  • all five complete case payloads, including every member track, medians, cones, fields, and viewer metadata.

JSON publication is atomic: data are written to a temporary file and moved into place only after serialization succeeds. A failed recalculation therefore does not leave a partially written active case.

For later deployment validation, match observations to archived cases by forecast_run_id, release.time, and release_sites[].id. Do not use only the current viewer JSON, because it intentionally represents the latest eligible run rather than the full forecast history.

To see the calculation date and forcing cycles for the latest archived run:

jq '.runs[-1]' \
  data/SPOTTER/driftcast-local-forcing-qc-2026-08-18/forecast_archive/okinawa_priority_forecasts/index.json

12. Viewer forcing layers

The following time-evolving backgrounds are packaged with each Okinawa case:

  • Eulerian ocean-current speed and vectors;
  • Stokes-drift speed and vectors;
  • significant wave height with mean wave direction;
  • peak wave period with peak direction;
  • mean wave period;
  • 10 m wind speed and vectors;
  • combined SMOC current + Stokes + tidal speed and vectors; and
  • tidal-drift speed and vectors.

Viewer fields are snapshots every 3 h, independent of the solver sampling. The high-resolution immediate context uses a 31 x 21 display grid. A coarser 29 x 15 East China Sea field over 115-145 degrees E and 15-35 degrees N supplies basin-wide context. These display grids do not control trajectory resolution; the trajectories sample the underlying forcing grids directly.

13. Running the viewer

From the repository root:

./code/start

Open http://localhost:8000/. A local web server is required because browsers do not allow the case files to be fetched reliably from a file:// URL. Keep the terminal process running and press Ctrl-C to stop it.

To use another port:

SPOTTER_VIEWER_PORT=8765 ./code/start

The older observation-validation builder can still be run with:

python3 code/spotter_validation.py

That command regenerates the legacy validation product; it is separate from the archived operational Okinawa refresh workflow described above.

14. Primary implementation files