goatpy.annotation
=================

.. py:module:: goatpy.annotation

.. autoapi-nested-parse::

   annotation.py
   =============
   Add QuPath GeoJSON annotations to a SpatialData object produced by
   load_and_align().

   The preferred workflow is to pass geojson_path directly to load_and_align()
   so annotations are transformed at registration time.  Use
   add_qupath_annotations() when you want to add annotations to an already-built
   sdata object (e.g. loaded from disk).

   The affine matrix stored in sdata['maldi_adata'].uns['he_transform']['affine_matrix']
   is a 3x3 matrix mapping reg-resolution H&E coords -> buffer canvas coords.
   It was derived empirically by _fit_affine_from_pil() in auto_align.py, which
   fits a least-squares affine from a dense grid of point correspondences computed
   through PIL's exact rotation geometry.  This is robust to PIL's internal
   conventions about expand=True, rotation centre, and canvas placement.

   annotation.py then folds in the scale_to_reg and img_upscaling factors to
   produce the final native-H&E-pixel -> upscaled-canvas transform.



Functions
---------

.. autoapisummary::

   goatpy.annotation.add_qupath_annotations
   goatpy.annotation.annotations_to_pixels


Module Contents
---------------

.. py:function:: add_qupath_annotations(sdata, geojson_path, shapes_key='annotations', classification_key='classification', he_pixel_um=None)

.. py:function:: annotations_to_pixels(sdata: spatialdata.SpatialData, shapes_key: str = 'annotations', classification_key: str = 'classification', table_name: str = 'maldi_adata', points_name: str = 'centroids', obs_column: str = 'annotation', other_label: str = 'other', coordinate_system: str = 'aligned') -> spatialdata.SpatialData

   Label each pixel in sdata[table_name].obs with its annotation class.

   For each point in sdata.points[points_name], tests whether its (x, y)
   centroid falls within any polygon in sdata.shapes[shapes_key].

   If coordinate_system='global', geometries and points are used as-is
   (i.e. automatic alignment where data is already in the correct space).
   Otherwise both shapes and points are transformed into coordinate_system
   before the point-in-polygon test (i.e. manual alignment).

   The ID column in the points layer may be named 'instance_id' or 'cell_id';
   both are handled automatically and normalised to 'instance_id' for the
   join to adata.obs.

   :param sdata:
   :type sdata: SpatialData object
   :param shapes_key:
   :type shapes_key: key in sdata.shapes holding annotation polygons
   :param classification_key:
   :type classification_key: column in the shapes GeoDataFrame with class labels
   :param table_name:
   :type table_name: key in sdata.tables to annotate
   :param points_name:
   :type points_name: key in sdata.points holding pixel centroids
   :param obs_column:
   :type obs_column: name of the new column added to adata.obs
   :param other_label:
   :type other_label: label for pixels outside all polygons
   :param coordinate_system: Use 'global' for automatic alignment (no transform
                             needed); use 'aligned' for manual alignment.
   :type coordinate_system: coordinate system to resolve coordinates in.


