Geographic utilities: unit conversions and Haversine distance.
EARTH_RADIUS¶
- pastax.geo.EARTH_RADIUS: float = 6371008.8
Mean Earth radius in metres (IUGG 2015 mean radius).
haversine¶
- pastax.geo.haversine(y1, y2)
Great-circle distance between
[lon, lat]points.Uses the spherical haversine formula with
EARTH_RADIUSas the sphere radius :where is latitude and is longitude (in radians). The last axis of each input must have size 2 (lon, lat); leading axes broadcast under standard NumPy/JAX rules.
- Parameters
y1(Float[jaxlib._jax.Array,'...2']) – First point(s)[lon, lat]in degrees, shape(..., 2).y2(Float[jaxlib._jax.Array,'...2']) – Second point(s)[lon, lat]in degrees, shape(..., 2).
- Returns
Great-circle distance in metres, with shape matching the broadcast of the leading axes of
y1andy2.- Return type
Float[jaxlib._jax.Array, ‘…’]
meters_to_degrees¶
- pastax.geo.meters_to_degrees(disp_m, lat_deg)
Convert an
[east, north]displacement in metres to[dlon, dlat]in degrees.Uses a flat-Earth approximation around
lat_deg: the meridional component is converted viaEARTH_RADIUS; the zonal component is additionally divided by to account for shrinking longitude circles toward the poles.The division uses
pastax.safe_divide(), so an exactly zero yields0(with a finite gradient) rather thaninf/nan. Note this is a corner-case guard only: the flat-Earth longitude scaling genuinely diverges at the poles, and near (but not at) — where is tiny but nonzero — the zonal component is still legitimately huge. Treat results within a cell of the poles as unreliable.- Parameters
disp_m(Float[jaxlib._jax.Array,'...2']) – Displacement(s)[east, north]in metres. The last axis must have size 2; leading axes are passed through unchanged.lat_deg(Float[jaxlib._jax.Array,'']) – Reference latitude in degrees, used for the longitude scaling.
- Returns
Same shape as
disp_m, but expressed as[dlon, dlat]in degrees.- Return type
Float[jaxlib._jax.Array, ‘… 2’]
degrees_to_meters¶
- pastax.geo.degrees_to_meters(disp_deg, lat_deg)
Convert a
[dlon, dlat]displacement in degrees to[east, north]in metres.Inverse of
meters_to_degrees(). Uses a flat-Earth approximation aroundlat_deg.- Parameters
disp_deg(Float[jaxlib._jax.Array,'...2']) – Displacement(s)[dlon, dlat]in degrees. The last axis must have size 2; leading axes are passed through unchanged.lat_deg(Float[jaxlib._jax.Array,'']) – Reference latitude in degrees, used for the longitude scaling.
- Returns
Same shape as
disp_deg, but expressed as[east, north]in metres.- Return type
Float[jaxlib._jax.Array, ‘… 2’]
wrap_longitude¶
- pastax.geo.wrap_longitude(lon, period=360.0, lower=-180.0)
Wrap longitude(s) into the half-open window
[lower, lower + period).The solver integrates position without normalising it, so a particle that drifts across the antimeridian accumulates an unbounded longitude (
181°,200°, …) — which is the correct continuous representation for a trajectory. This is a post-processing / display helper that folds such longitudes back into a canonical window. The defaults give the[-180, 180)convention; passlower=0.0for[0, 360).Element-wise and shape-preserving; pure arithmetic, so it is safe under
jit/vmap/grad. For a[lon, lat]trajectory of shape(..., 2), wrap only the longitude column, e.g.:traj = traj.at[..., 0].set(wrap_longitude(traj[..., 0]))- Parameters
lon(Float[jaxlib._jax.Array,'...']) – Longitude value(s) in degrees, any shape.period(float) – Longitude period in degrees (default360.0).lower(float) – Lower edge of the target window (default-180.0); the window is[lower, lower + period).
- Returns
Longitudes folded into
[lower, lower + period), same shape aslon.- Return type
Float[jaxlib._jax.Array, ‘…’]