curryer.correction.image_match ============================== .. py:module:: curryer.correction.image_match Attributes ---------- .. autoapisummary:: curryer.correction.image_match.logger Classes ------- .. autoapisummary:: curryer.correction.image_match.ImageMatchingFunc curryer.correction.image_match.IntegratedImageMatchResult Functions --------- .. autoapisummary:: curryer.correction.image_match.validate_image_matching_output curryer.correction.image_match.integrated_image_match curryer.correction.image_match.load_image_grid_from_mat curryer.correction.image_match.load_optical_psf_from_mat curryer.correction.image_match.load_los_vectors_from_mat Module Contents --------------- .. py:data:: logger .. py:class:: ImageMatchingFunc Bases: :py:obj:`Protocol` Protocol for image matching functions in Correction pipeline. Image matching functions perform spatial correlation between geolocated observations and GCP reference imagery to measure geolocation errors. Standard Signature: def image_matching( geolocated_data: xr.Dataset, gcp_reference_file: Path, telemetry: pd.DataFrame, calibration_dir: Path, params_info: list, config, los_vectors_cached: Optional[np.ndarray] = None, optical_psfs_cached: Optional[list] = None, ) -> xr.Dataset Required Output Fields: - lat_error_deg: (measurement,) Latitude errors in degrees - lon_error_deg: (measurement,) Longitude errors in degrees - gcp_lat_deg, gcp_lon_deg, gcp_alt: GCP location - Spacecraft state: position, boresight, transformation matrix See correction.image_matching() for reference implementation. .. py:method:: __call__(geolocated_data: xarray.Dataset, gcp_reference_file: pathlib.Path, telemetry: pandas.DataFrame, calibration_dir: pathlib.Path, params_info: list, config, los_vectors_cached: numpy.ndarray | None = None, optical_psfs_cached: list | None = None) -> xarray.Dataset Perform image matching and return error measurements. .. py:function:: validate_image_matching_output(output: xarray.Dataset) -> None Validate image matching output conforms to expected format. :param output: Dataset returned by image matching function. :type output: xr.Dataset :raises TypeError: If output is not an xarray Dataset. :raises ValueError: If required fields are missing or malformed. .. rubric:: Examples >>> result = image_matching_func(...) >>> validate_image_matching_output(result) .. py:class:: IntegratedImageMatchResult .. py:attribute:: lat_error_km :type: float .. py:attribute:: lon_error_km :type: float .. py:attribute:: ccv_final :type: float .. py:attribute:: final_index_row :type: int .. py:attribute:: final_index_col :type: int .. py:attribute:: final_grid_step_m :type: float .. py:attribute:: dynamic_psf :type: curryer.correction.data_structures.PSFGrid .. py:attribute:: projected_psf :type: curryer.correction.data_structures.ProjectedPSF .. py:attribute:: convolved_gcp :type: curryer.correction.data_structures.ImageGrid .. py:function:: integrated_image_match(subimage: curryer.correction.data_structures.ImageGrid, gcp: curryer.correction.data_structures.ImageGrid, r_iss_midframe_m: numpy.ndarray, los_vectors_hs: numpy.ndarray, optical_psfs: collections.abc.Iterable[curryer.correction.data_structures.OpticalPSFEntry], geolocation_config: curryer.correction.data_structures.GeolocationConfig | None = None, search_config: curryer.correction.data_structures.SearchConfig | None = None) -> IntegratedImageMatchResult Perform complete image matching workflow with PSF modeling. Replicates MATLAB IntegratedImageMatch: projects PSF, applies spacecraft motion blur, convolves with GCP, and performs correlation-based search. :param subimage: Observed image data with geolocation. :type subimage: ImageGrid :param gcp: Ground control point reference image. :type gcp: ImageGrid :param r_iss_midframe_m: Spacecraft position at mid-frame, shape (3,), units: meters. :type r_iss_midframe_m: np.ndarray :param los_vectors_hs: Line-of-sight vectors in instrument frame, shape (n_pixels, 3). :type los_vectors_hs: np.ndarray :param optical_psfs: Optical PSF samples at different field angles. :type optical_psfs: Iterable[OpticalPSFEntry] :param geolocation_config: PSF geolocation parameters. Defaults to standard config. :type geolocation_config: GeolocationConfig, optional :param search_config: Image search parameters. Defaults to standard config. :type search_config: SearchConfig, optional :returns: Geolocation errors, correlation value, and intermediate products. :rtype: IntegratedImageMatchResult .. py:function:: load_image_grid_from_mat(mat_file: pathlib.Path, key: str = 'subimage', name: str | None = None, as_named: bool = False) -> curryer.correction.data_structures.ImageGrid | curryer.correction.data_structures.NamedImageGrid Load ImageGrid from MATLAB .mat file. :param mat_file: Path to .mat file. :type mat_file: Path :param key: MATLAB struct key (e.g., "subimage" for L1A, "GCP" for reference). :type key: str, default="subimage" :param name: Name for NamedImageGrid. Defaults to file path. :type name: str, optional :param as_named: If True, return NamedImageGrid; otherwise return ImageGrid. :type as_named: bool, default=False :returns: Loaded image grid with data, lat, lon, h fields. :rtype: ImageGrid or NamedImageGrid :raises FileNotFoundError: If mat_file doesn't exist. :raises KeyError: If key not found in MATLAB file. .. rubric:: Examples >>> # Load L1A subimage >>> l1a = load_image_grid_from_mat(Path("subimage.mat"), key="subimage") >>> # Load GCP reference >>> gcp = load_image_grid_from_mat(Path("gcp.mat"), key="GCP") .. py:function:: load_optical_psf_from_mat(mat_file: pathlib.Path, key: str = 'PSF_struct_675nm') -> list[curryer.correction.data_structures.OpticalPSFEntry] Load optical PSF entries from MATLAB .mat file. :param mat_file: Path to MATLAB file with PSF data. :type mat_file: Path :param key: Primary key to try for PSF data. :type key: str, default="PSF_struct_675nm" :returns: Optical PSF samples with data, x, and field_angle arrays. :rtype: list[OpticalPSFEntry] :raises FileNotFoundError: If mat_file doesn't exist. :raises KeyError: If no PSF data found with common key names. :raises ValueError: If PSF entries missing field angle attribute. .. py:function:: load_los_vectors_from_mat(mat_file: pathlib.Path, key: str = 'b_HS') -> numpy.ndarray Load line-of-sight vectors from MATLAB .mat file. :param mat_file: Path to MATLAB file with LOS vectors. :type mat_file: Path :param key: Primary key to try for LOS data. :type key: str, default="b_HS" :returns: LOS unit vectors in instrument frame, shape (n_pixels, 3). :rtype: np.ndarray :raises FileNotFoundError: If mat_file doesn't exist. :raises KeyError: If no LOS vectors found with common key names.