Single-frequency ionospheric group-delay corrections.
Two models are exposed over the sidereon-core crate: the GPS broadcast
Klobuchar model (eight alpha/beta coefficients, IS-GPS-200), and an IONEX
vertical-TEC-grid slant delay (single-layer model). Both return the group
delay in positive meters.
This is the ionosphere correction for a GNSS signal. It is not
Sidereon.Atmosphere, which is NRLMSISE-00 neutral-atmosphere mass density for
drag, a different quantity entirely.
Sign convention
The returned delay is a group delay and is positive: it increases the
measured pseudorange (the signal arrives later than vacuum geometry would
predict). The carrier-phase advance is the negation of this value. The
ionosphere is dispersive, so the delay reported on a carrier other than the
model's native L1 is the L1 delay scaled by (f_L1 / f)^2; pass the carrier
via frequency_hz.
Units at the boundary
Public inputs are in degrees (_deg) and meters/hertz, per the Sidereon naming
convention. Latitude is positive north, longitude positive east, azimuth
clockwise from north.
Summary
Functions
Build an IONEX product from one sample per TEC grid node.
Build an IONEX product directly from whole-grid TEC samples.
Galileo NeQuick-G single-frequency ionospheric group delay, scaled to
frequency_hz.
IONEX vertical-TEC-grid slant ionospheric group delay, scaled to frequency_hz.
Serialize a parsed IONEX product back to standard IONEX text.
GPS broadcast Klobuchar L1 ionospheric group delay, scaled to frequency_hz.
Load and parse an IONEX file into a product handle.
Galileo NeQuick-G full slant ionospheric group delay (positive meters).
Galileo NeQuick-G full three-dimensional slant total electron content (TECU).
Parse an in-memory IONEX byte buffer into a product handle.
Extract an IONEX handle as whole-grid TEC samples.
Extract an IONEX handle as one TEC sample per grid node.
Functions
@spec from_node_samples( [Sidereon.GNSS.Ionosphere.TecSample.t()], number(), number(), integer() ) :: {:ok, reference()} | {:error, term()}
Build an IONEX product from one sample per TEC grid node.
shell_height_km and base_radius_km are kilometers. Each
Sidereon.GNSS.Ionosphere.TecSample carries latitude/longitude in degrees
and vertical TEC/RMS in TECU.
@spec from_samples(Sidereon.GNSS.Ionosphere.TecGridSamples.t()) :: {:ok, reference()} | {:error, term()}
Build an IONEX product directly from whole-grid TEC samples.
Axes are degrees, shell and base radii are kilometers, and TEC/RMS grids are
TECU. The returned handle is accepted anywhere a parsed IONEX handle is
accepted, including ionex_slant_delay/7.
@spec galileo_nequick_g_delay( map(), number(), number(), number(), number(), NaiveDateTime.t() | tuple(), number() ) :: {:ok, float()} | {:error, term()}
Galileo NeQuick-G single-frequency ionospheric group delay, scaled to
frequency_hz.
coeffs carries the three Galileo broadcast effective-ionisation coefficients
as %{ai0: a0, ai1: a1, ai2: a2}. The receiver geodetic latitude/longitude and
the satellite azimuth/elevation are in degrees; epoch is a NaiveDateTime or
{{y, m, d}, {h, min, s}} tuple in Galileo system time. The NeQuick-G arm maps
the slant delay by elevation only, so azimuth_deg is accepted (to match the
shared ionosphere-model boundary) but does not change the result. Returns
{:ok, delay_m} (positive meters) or {:error, reason}.
@spec ionex_slant_delay( reference(), number(), number(), number(), number(), NaiveDateTime.t() | tuple(), number() ) :: {:ok, float()} | {:error, term()}
IONEX vertical-TEC-grid slant ionospheric group delay, scaled to frequency_hz.
handle is a parsed-IONEX reference from parse_ionex/1 or load_ionex/1.
The receiver geodetic latitude/longitude and the satellite azimuth/elevation
are in degrees; epoch is a NaiveDateTime or {{y, m, d}, {h, min, s}}
tuple (the pierce point rides on the IONEX shell, so the receiver height is not
used). Returns {:ok, delay_m} (positive meters) or {:error, reason}.
Serialize a parsed IONEX product back to standard IONEX text.
handle is a parsed-IONEX reference from parse_ionex/1 or load_ionex/1.
This is the inverse of parse_ionex/1: re-parsing the output reproduces the
same TEC grids. The serialization is deterministic and performs no I/O.
Returns {:ok, text} or {:error, reason}.
Examples
{:ok, handle} = Sidereon.GNSS.Ionosphere.parse_ionex(ionex_bytes)
{:ok, text} = Sidereon.GNSS.Ionosphere.ionex_to_string(handle)
{:ok, _reparsed} = Sidereon.GNSS.Ionosphere.parse_ionex(text)
@spec klobuchar_delay( map(), number(), number(), number(), number(), NaiveDateTime.t() | tuple(), number() ) :: {:ok, float()} | {:error, term()}
GPS broadcast Klobuchar L1 ionospheric group delay, scaled to frequency_hz.
params carries the eight broadcast coefficients as
%{alpha: {a0, a1, a2, a3}, beta: {b0, b1, b2, b3}} (or lists). The receiver
geodetic latitude/longitude and the satellite azimuth/elevation are in
degrees; epoch is a NaiveDateTime or {{y, m, d}, {h, min, s}} tuple in
GPS time. Returns {:ok, delay_m} (positive meters) or {:error, reason}.
Load and parse an IONEX file into a product handle.
Returns {:ok, reference()} or {:error, reason}.
Galileo NeQuick-G full slant ionospheric group delay (positive meters).
The full 3D slant TEC from nequick_g_stec/2 mapped to a dispersive group
delay on frequency_hz. coeffs and ray are as in nequick_g_stec/2.
Returns {:ok, delay_m} (positive meters) or {:error, reason}.
Galileo NeQuick-G full three-dimensional slant total electron content (TECU).
This is the reference-grade full 3D NeQuick-G integration, distinct from the
compact single-layer galileo_nequick_g_delay/7. The coeffs map carries the
broadcast effective-ionisation coefficients %{ai0:, ai1:, ai2:}. The ray
map carries both endpoints of the receiver-to-satellite line of sight, in the
reference algorithm's native units:
:month- month of the year,1..12:utc_hours- UTC time of day in hours,[0, 24]:station_lon_deg,:station_lat_deg,:station_height_m:satellite_lon_deg,:satellite_lat_deg,:satellite_height_m
Returns {:ok, stec_tecu} (slant TEC in TECU) or {:error, reason}.
Parse an in-memory IONEX byte buffer into a product handle.
Returns {:ok, reference()} or {:error, reason}. The buffer is parsed
exactly once; the parsed grid is held as a resource handle.
@spec tec_grid_samples(reference()) :: Sidereon.GNSS.Ionosphere.TecGridSamples.t() | {:error, term()}
Extract an IONEX handle as whole-grid TEC samples.
This is the inverse IR for from_samples/1. Axes are degrees, shell and base
radii are kilometers, and TEC/RMS grids are TECU.
@spec tec_samples(reference()) :: [Sidereon.GNSS.Ionosphere.TecSample.t()] | {:error, term()}
Extract an IONEX handle as one TEC sample per grid node.
Each returned sample has latitude/longitude in degrees and vertical TEC/RMS in TECU.