curryer.correction.error_stats ============================== .. py:module:: curryer.correction.error_stats .. autoapi-nested-parse:: 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 :func:`compute_percent_below` for custom threshold queries, or compare the fixed threshold-table entries (``percent_below_100m``, ``percent_below_250m``, etc.) directly. Attributes ---------- .. autoapisummary:: curryer.correction.error_stats.logger Classes ------- .. autoapisummary:: curryer.correction.error_stats.ViewPlaneVectors curryer.correction.error_stats.ScalingFactors curryer.correction.error_stats.ErrorStatsConfig curryer.correction.error_stats.ErrorStatsProcessor Functions --------- .. autoapisummary:: curryer.correction.error_stats.compute_percent_below Module Contents --------------- .. py:data:: logger .. py:class:: ViewPlaneVectors Bases: :py:obj:`NamedTuple` Unit vectors spanning the view plane in UEN coordinates. .. py:attribute:: v_uen :type: numpy.ndarray .. py:attribute:: x_uen :type: numpy.ndarray .. py:class:: ScalingFactors Bases: :py:obj:`NamedTuple` Scaling factors for nadir-equivalent error projection. .. py:attribute:: vp_factor :type: float .. py:attribute:: xvp_factor :type: float .. py:function:: 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 :meth:`ErrorStatsProcessor._calculate_statistics`. :param errors: Array of nadir-equivalent geolocation errors in meters. :type errors: np.ndarray :param threshold_m: Threshold in meters. :type threshold_m: float :returns: Percentage (0–100) of errors strictly below *threshold_m*. Returns ``0.0`` when *errors* is empty. :rtype: float .. py:class:: ErrorStatsConfig Configuration for geolocation error statistics processing. :param minimum_correlation: 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). :type minimum_correlation: float or None, optional :param variable_names: Mission-agnostic variable name mappings from semantic names to actual dataset variable names. If ``None``, generic defaults are used. :type variable_names: dict of str to str or None, optional .. rubric:: 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. .. py:attribute:: minimum_correlation :type: float | None :value: None .. py:attribute:: variable_names :type: dict[str, str] | None :value: None .. py:method:: from_setup(setup) -> ErrorStatsConfig :classmethod: Create an :class:`ErrorStatsConfig` from a :class:`GeolocationSetup`. Extracts the science-Dataset variable names and ``minimum_correlation`` from the setup, the single source of truth for those settings. :param setup: The geolocation setup (variable names + geo settings). :type setup: GeolocationSetup :rtype: ErrorStatsConfig .. py:method:: get_variable_name(semantic_name: str) -> str Get actual variable name for a semantic concept. :param semantic_name: Semantic name like 'spacecraft_position', 'boresight', etc. :type semantic_name: str :returns: Actual variable name in the dataset. :rtype: str :raises ValueError: If variable_names is None or semantic_name is not found. .. py:class:: ErrorStatsProcessor(config: ErrorStatsConfig) Production-ready processor for geolocation error statistics. .. py:attribute:: config .. py:method:: 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 :meth:`process_geolocation_errors` for the final aggregate pass (nadir-equivalent + comprehensive statistics). :param input_data: Dataset with required error measurement variables and a ``measurement`` dimension. :type input_data: xr.Dataset :returns: Dataset with ``nadir_equiv_total_error_m`` and related intermediate variables. No statistical attributes are set on the output. :rtype: xr.Dataset :raises ValueError: If required variables are missing or all measurements are filtered out by the correlation threshold. .. py:method:: 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 :func:`verify`. For per-iteration computation (single GCP pair), prefer :meth:`compute_nadir_equivalent_errors` to avoid computing aggregate statistics on a small or single-measurement sample. :param input_data: Dataset with required error measurement variables. :type input_data: xr.Dataset :returns: Dataset with ``nadir_equiv_total_error_m`` and related intermediate variables, plus comprehensive statistics as global attributes. :rtype: xr.Dataset .. py:method:: process_from_netcdf(filepath: Union[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. :param filepath: Path to NetCDF file from previous Correction run :param minimum_correlation: Override correlation threshold (if provided) :returns: Xarray Dataset with reprocessed error statistics .. rubric:: 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 ... )