quadsv.detectors.grid
=====================

.. py:module:: quadsv.detectors.grid


Classes
-------

.. autoapisummary::

   quadsv.detectors.grid.DetectorGrid


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

.. py:class:: DetectorGrid(kernel_method = 'car', **kernel_params)

   Bases: :py:obj:`quadsv.detectors.base.Detector`


   Detect spatial patterns on **regular grids** (SpatialData bins) with
   FFT-accelerated kernel tests.

   Univariate (Q-test) and bivariate (R-test) kernel-based spatial statistics
   on rasterized :class:`spatialdata.SpatialData` bins.

   Workflow
   --------
   1. **Construct** with kernel method + kernel hyperparameters / grid controls.
   2. **Setup** with :meth:`setup_data` passing the :class:`spatialdata.SpatialData`
      plus the bin / table / col / row keys. Setup rasterizes the table and
      builds the :class:`~quadsv.FFTKernel` at the resulting grid shape.
   3. **Compute** with :meth:`compute_qstat` / :meth:`compute_rstat`.

   :param kernel_method: One of ``'gaussian'``, ``'matern'``, ``'moran'``, ``'graph_laplacian'``,
                         ``'car'``.
   :type kernel_method: str, default ``'car'``
   :param \*\*kernel_params: Kernel hyperparameters plus grid controls (``spacing``, ``topology``,
                             ``fft_solver``, ``workers``). See :class:`~quadsv.FFTKernel`.

   :ivar sdata: Input container set by :meth:`setup_data`.
   :vartype sdata: :class:`spatialdata.SpatialData` or None
   :ivar min_count: Feature count threshold; set by :meth:`setup_data`.
   :vartype min_count: int or None
   :ivar kernel\_: Built in :meth:`setup_data` once the grid shape is known.
   :vartype kernel\_: :class:`~quadsv.FFTKernel` or None
   :ivar kernel_method\_, kernel_params\_, n: See :class:`Detector`.


   .. rubric:: Examples

   >>> det = DetectorGrid(kernel_method='car', rho=0.8)
   >>> det.setup_data(sdata, bins='grid', table_name='table',
   ...                col_key='col_idx', row_key='row_idx')  # doctest: +SKIP
   >>> q = det.compute_qstat(features=['Gene_1', 'Gene_2'])  # doctest: +SKIP


   .. py:method:: compute_qstat(features = None, n_jobs = 'auto', workers = 'auto', return_pval = True, chunk_size = 'auto', show_progress = True)

      Compute the spatial Q-statistic across features in parallel.

      Requires :meth:`setup_data` to have been called; rasterization and
      kernel construction happen there. This method pulls the rasterized
      feature tensor from :attr:`sdata` and runs per-feature FFT Q-tests.

      :param features: Feature names to analyze. ``None`` uses all features that pass
                       the ``min_count`` filter from :meth:`setup_data`.
      :type features: list of str, optional
      :param n_jobs: Joblib workers over feature batches. ``'auto'`` balances against
                     ``workers`` — see :meth:`_auto_schedule`. ``-1`` is also accepted
                     and behaves like ``'auto'``.
      :type n_jobs: int or ``'auto'``, default ``'auto'``
      :param workers: Threads for scipy.fft inside each worker. ``'auto'`` co-balances with
                      ``n_jobs``; ``None`` defers to scipy's default.
      :type workers: int, ``'auto'``, or None, default ``'auto'``
      :param return_pval: Whether to compute p-values + Benjamini–Hochberg–adjusted p-values.
      :type return_pval: bool, default True
      :param chunk_size: Features per worker batch. ``'auto'`` resolves to ``~256 MB / (ny·nx·24)``
                         via :meth:`_auto_chunk_size` and clips to ``[16, 1024]``.
      :type chunk_size: int or ``'auto'``, default ``'auto'``
      :param show_progress: Show a tqdm progress bar over worker chunks.
      :type show_progress: bool, default True

      :returns: Indexed by feature. Columns: ``Q``, ``Z_score``, and (if
                ``return_pval=True``) ``P_value``, ``P_adj``. Sorted by ``Q`` desc.
      :rtype: pandas.DataFrame



   .. py:method:: compute_rstat(features_x = None, features_y = None, return_pval = True, chunk_size = 'auto', workers = 'auto', show_progress = True)

      Compute the bivariate spatial R-statistic across feature pairs.

      Requires :meth:`setup_data` to have been called.

      :param features_x: Features for the X variable. If ``None`` and ``features_y`` is
                         ``None``, uses all features (symmetric pairwise mode).
      :type features_x: list of str, optional
      :param features_y: Features for the Y variable. If ``None``, pairs are drawn from
                         ``features_x`` (symmetric, upper-triangular). If provided, returns
                         all X × Y pairs (bipartite).
      :type features_y: list of str, optional
      :param return_pval: Whether to compute p-values + Benjamini–Hochberg–adjusted p-values.
      :type return_pval: bool, default True
      :param chunk_size: Y-features per batch (reuses the pre-computed ``K @ Y`` block).
                         ``'auto'`` targets ~256 MB per embedding batch via
                         :meth:`_auto_chunk_size`.
      :type chunk_size: int or ``'auto'``, default ``'auto'``
      :param workers: Threads for scipy.fft inside the embedding pass. ``'auto'`` gives
                      every FFT all CPU cores (the R-test loop is sequential over X/Y
                      chunk pairs so there is no joblib contention).
      :type workers: int, ``'auto'``, or None, default ``'auto'``
      :param show_progress: Show a tqdm progress bar over X chunks.
      :type show_progress: bool, default True

      :returns: Columns ``Feature_1``, ``Feature_2``, ``R``, ``Z_score`` and (if
                ``return_pval=True``) ``P_value``, ``P_adj``. Sorted by ``R`` desc.
      :rtype: pandas.DataFrame



   .. py:method:: setup_data(sdata, *, bins, table_name, col_key, row_key, value_key = None, min_count = None)

      Attach ``sdata``, rasterize the chosen bins table, and build the FFTKernel.

      :param sdata: Input container.
      :type sdata: :class:`spatialdata.SpatialData`
      :param bins: Name of the SpatialElement (Shape) defining the grid-like bins.
      :type bins: str
      :param table_name: Name of the table annotating the SpatialElement in ``sdata.tables``.
      :type table_name: str
      :param col_key: ``.obs`` columns holding integer column / row indices for the bins.
      :type col_key: str
      :param row_key: ``.obs`` columns holding integer column / row indices for the bins.
      :type row_key: str
      :param value_key: Value column in ``.obs`` to rasterize. ``None`` uses counts / presence.
      :type value_key: str, optional
      :param min_count: Minimum total count for a feature to pass filtering. ``None`` disables.
      :type min_count: int, optional

      :returns: **self**
      :rtype: DetectorGrid



   .. py:attribute:: min_count
      :type:  int | None
      :value: None


      Minimum total count per feature applied in :meth:`setup_data`.


   .. py:attribute:: sdata
      :type:  spatialdata.SpatialData | None
      :value: None


      Reference to the input :class:`spatialdata.SpatialData`, set by :meth:`setup_data`.


