curryer.correction.error_stats

Geolocation statistics processor with Xarray inputs and outputs.

This module processes geolocation errors from the image matching algorithm and produces nadir-equivalent geolocation errors together with mission-agnostic summary statistics.

The main processing pipeline:

  1. Convert angular errors to N-S and E-W distances.

  2. Transform error components to view-plane / cross-view-plane distances.

  3. Scale to nadir-equivalent using geometric factors.

  4. (Optional) Compute comprehensive statistics across all measurements.

Pass/fail evaluation is intentionally not included here — whether the statistics meet mission requirements is the caller’s responsibility. Use compute_percent_below() for custom threshold queries, or compare the fixed threshold-table entries (percent_below_100m, percent_below_250m, etc.) directly.

Attributes

Classes

ViewPlaneVectors

Unit vectors spanning the view plane in UEN coordinates.

ScalingFactors

Scaling factors for nadir-equivalent error projection.

ErrorStatsConfig

Configuration for geolocation error statistics processing.

ErrorStatsProcessor

Production-ready processor for geolocation error statistics.

Functions

compute_percent_below(→ float)

Compute the percentage of errors below a given threshold.

Module Contents

curryer.correction.error_stats.logger
curryer.correction.error_stats._EARTH_RADIUS_M: float = 6378137.0
class curryer.correction.error_stats.ViewPlaneVectors

Bases: NamedTuple

Unit vectors spanning the view plane in UEN coordinates.

v_uen: numpy.ndarray
x_uen: numpy.ndarray
class curryer.correction.error_stats.ScalingFactors

Bases: NamedTuple

Scaling factors for nadir-equivalent error projection.

vp_factor: float
xvp_factor: float
curryer.correction.error_stats.compute_percent_below(errors: numpy.ndarray, threshold_m: float) float

Compute the percentage of errors below a given threshold.

Useful for evaluating custom thresholds not in the standard table produced by ErrorStatsProcessor._calculate_statistics().

Parameters:
  • errors (np.ndarray) – Array of nadir-equivalent geolocation errors in meters.

  • threshold_m (float) – Threshold in meters.

Returns:

Percentage (0–100) of errors strictly below threshold_m. Returns 0.0 when errors is empty.

Return type:

float

class curryer.correction.error_stats.ErrorStatsConfig

Configuration for geolocation error statistics processing.

Parameters:
  • minimum_correlation (float or None, optional) – Minimum correlation filter threshold (0.0–1.0). Measurements whose correlation score falls below this value are excluded before processing. Default is None (no filtering).

  • variable_names (dict of str to str or None, optional) – Mission-agnostic variable name mappings from semantic names to actual dataset variable names. If None, generic defaults are used.

Notes

Pass/fail thresholds are not part of this config. ErrorStatsProcessor computes statistics only; whether those numbers meet mission requirements is the caller’s responsibility.

Earth radius is not a config field either. _EARTH_RADIUS_M (derived from curryer.compute.constants.WGS84_SEMI_MAJOR_AXIS_KM) is used directly in all calculations.

minimum_correlation: float | None = None
variable_names: dict[str, str] | None = None
classmethod from_setup(setup) ErrorStatsConfig

Create an ErrorStatsConfig from a GeolocationSetup.

Extracts the science-Dataset variable names and minimum_correlation from the setup, the single source of truth for those settings.

Parameters:

setup (GeolocationSetup) – The geolocation setup (variable names + geo settings).

Return type:

ErrorStatsConfig

get_variable_name(semantic_name: str) str

Get actual variable name for a semantic concept.

Parameters:

semantic_name (str) – Semantic name like ‘spacecraft_position’, ‘boresight’, etc.

Returns:

Actual variable name in the dataset.

Return type:

str

Raises:

ValueError – If variable_names is None or semantic_name is not found.

class curryer.correction.error_stats.ErrorStatsProcessor(config: ErrorStatsConfig)

Production-ready processor for geolocation error statistics.

config
_filter_by_correlation(data: xarray.Dataset) xarray.Dataset

Filter measurements by correlation coefficient threshold.

Parameters:

data – Input dataset with optional ‘correlation’ or ‘ccv’ variable

Returns:

Filtered dataset with low-correlation measurements removed

compute_nadir_equivalent_errors(input_data: xarray.Dataset) xarray.Dataset

Compute per-measurement nadir-equivalent errors WITHOUT aggregate statistics.

This is the method to call inside the correction loop — it requires observation geometry (spacecraft position, boresight, transformation matrix) that is only available during each iteration, and produces nadir-equivalent errors for each measurement. No aggregate statistics are computed (meaningless for a single GCP pair in isolation).

Use this inside the loop for checkpoint/resume support. Call process_geolocation_errors() for the final aggregate pass (nadir-equivalent + comprehensive statistics).

Parameters:

input_data (xr.Dataset) – Dataset with required error measurement variables and a measurement dimension.

Returns:

Dataset with nadir_equiv_total_error_m and related intermediate variables. No statistical attributes are set on the output.

Return type:

xr.Dataset

Raises:

ValueError – If required variables are missing or all measurements are filtered out by the correlation threshold.

process_geolocation_errors(input_data: xarray.Dataset) xarray.Dataset

Full processing: nadir-equivalent errors + aggregate statistics.

Use this for final aggregation after the loop, or in verify(). For per-iteration computation (single GCP pair), prefer compute_nadir_equivalent_errors() to avoid computing aggregate statistics on a small or single-measurement sample.

Parameters:

input_data (xr.Dataset) – Dataset with required error measurement variables.

Returns:

Dataset with nadir_equiv_total_error_m and related intermediate variables, plus comprehensive statistics as global attributes.

Return type:

xr.Dataset

_validate_input_data(data: xarray.Dataset) None

Validate that input dataset contains all required variables.

_transform_boresight_vectors(bhat_hs: numpy.ndarray, t_hs2ctrs: numpy.ndarray) numpy.ndarray

Transform boresight vectors from HS to CTRS coordinate system.

_process_to_nadir_equivalent(ns_error_m: numpy.ndarray, ew_error_m: numpy.ndarray, riss_ctrs: numpy.ndarray, bhat_ctrs: numpy.ndarray, gcp_lat_rad: numpy.ndarray, gcp_lon_rad: numpy.ndarray, n_measurements: int) dict[str, numpy.ndarray]

Process error measurements to nadir-equivalent values.

_create_ctrs_to_uen_transform(lat_rad: float, lon_rad: float) numpy.ndarray

Create transformation matrix from CTRS to Up-East-North coordinates.

_calculate_view_plane_vectors(bhat_uen: numpy.ndarray) ViewPlaneVectors

Calculate view-plane and cross-view-plane unit vectors in UEN coordinates.

_calculate_scaling_factors(riss_ctrs: numpy.ndarray, theta: float) ScalingFactors

Calculate scaling factors for nadir-equivalent transformation.

_create_output_dataset(input_data: xarray.Dataset, results: dict[str, numpy.ndarray]) xarray.Dataset

Create output Xarray Dataset with processing results.

_calculate_statistics(nadir_equiv_errors_m: numpy.ndarray) dict[str, float | int]

Calculate comprehensive, mission-agnostic performance statistics.

This method intentionally does NOT include any pass/fail evaluation. Whether these statistics meet mission requirements is the caller’s responsibility. Use compute_percent_below() for custom threshold queries not covered by the standard table.

Parameters:

nadir_equiv_errors_m (np.ndarray) – Array of nadir-equivalent geolocation errors in meters.

Returns:

Keys: central tendency (mean_error_m, median_error_m, rms_error_m), spread (std_error_m, min_error_m, max_error_m), percentiles (p25_error_mp99_error_m), count (total_measurements), and a threshold table at standard intervals (percent_below_100mpercent_below_1000m).

Return type:

dict[str, float | int]

process_from_netcdf(filepath: str | pathlib.Path, minimum_correlation: float | None = None) xarray.Dataset

Load previous results from NetCDF and reprocess error statistics.

This enables iterative post-processing of Correction results without re-running expensive image matching operations.

Parameters:
  • filepath – Path to NetCDF file from previous Correction run

  • minimum_correlation – Override correlation threshold (if provided)

Returns:

Xarray Dataset with reprocessed error statistics

Example

>>> processor = ErrorStatsProcessor()
>>> # Try different correlation thresholds
>>> results_50 = processor.process_from_netcdf(
...     "correction_results/run_001.nc",
...     minimum_correlation=0.5
... )
>>> results_70 = processor.process_from_netcdf(
...     "correction_results/run_001.nc",
...     minimum_correlation=0.7
... )