goatpy.filter
=============

.. py:module:: goatpy.filter

.. autoapi-nested-parse::

   filter.py
   =========
   A wrapper around spatialdata's filter_by_table_query that preserves
   images, points, and non-pixel shapes rather than dropping them.

   Usage
   -----
   >>> from goatpy.filter import filter_spatialdata

   # Filter by any obs column
   >>> sub = filter_spatialdata(sdata, "annotation == 'Tumor'")
   >>> sub = filter_spatialdata(sdata, "GPCA_clusters == '3'")
   >>> sub = filter_spatialdata(sdata, "MPI > 1000")

   # Filter by ion intensity (var_names)
   >>> sub = filter_spatialdata(sdata, "1581.6 > 500", on="expression")

   # Keep points unsubsetted (just retain all centroids)
   >>> sub = filter_spatialdata(sdata, "annotation == 'Tumor'", subset_points=False)



Functions
---------

.. autoapisummary::

   goatpy.filter.filter_spatialdata


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

.. py:function:: filter_spatialdata(sdata: spatialdata.SpatialData, query: str, on: Literal['obs', 'expression'] = 'obs', table_name: str = 'maldi_adata', subset_points: bool = True, subset_annotations: bool = False) -> spatialdata.SpatialData

   Subset a SpatialData object by a query string, preserving images, points,
   and annotation shapes.

   Internally builds a boolean mask from the query, filters the table and
   pixel shapes consistently, then re-attaches images, centroids, and
   annotation polygons so nothing is silently dropped.

   :param sdata:
   :type sdata: SpatialData
   :param query: A pandas ``.query()`` string.
   :type query: str
   :param on:
              ``"obs"``        — query runs against ``maldi_adata.obs`` columns
                                 (annotation, GPCA_clusters, MPI, he_x, he_y …).
              ``"expression"`` — query runs against ion intensity columns
                                 (m/z var_names, dots auto-sanitised to underscores).
   :type on: "obs" | "expression"
   :param table_name: Default ``"maldi_adata"``.
   :type table_name: str
   :param subset_points: If True (default), centroids are subsetted to match the filtered pixels.
                         If False, all original centroids are kept as-is.
   :type subset_points: bool
   :param subset_annotations: If True, annotation polygon shapes are filtered to only keep classes
                              that are present in the filtered pixels' ``annotation`` obs column.
                              If False (default), all annotation polygons are kept as-is.
   :type subset_annotations: bool

   :returns:

             - ``images``      — always kept unchanged
             - ``shapes["pixels"]``  — subsetted to matching pixels
             - ``shapes["annotations"]`` — kept or filtered depending on subset_annotations
             - ``points["centroids"]``   — subsetted or kept depending on subset_points
             - ``tables[table_name]``    — subsetted to matching rows
   :rtype: SpatialData with

   .. rubric:: Examples

   >>> filter_spatialdata(sdata, "annotation == 'Tumor'")
   >>> filter_spatialdata(sdata, "GPCA_clusters == '3'")
   >>> filter_spatialdata(sdata, "MPI > 1000")
   >>> filter_spatialdata(sdata, "annotation == 'Tumor' and MPI > 500")
   >>> filter_spatialdata(sdata, "1581.6 > 500", on="expression")


