Skip to main content

Consistent and scalable spatial pattern detection via quadratic forms.

Project description

quadsv: Consistent and scalable spatial pattern detection

Detect spatial patterns in omics data via kernel-based hypothesis tests for spatial variability (Q-tests) and for co-expression (R-tests).

Key features:

  • Reliable: CAR kernel eliminates false negatives from Moran's I spectral cancellation
  • Scalable: Implicit sparse solvers and FFT acceleration handle millions of spots
  • Universal: Works with Visium, Visium HD, MERFISH, lineage trees, any spatial/graph data
  • Integrated: Native AnnData and SpatialData support

Installation

pip install quadsv  # From PyPI
# OR (latest dev version)
pip install git+https://github.com/JiayuSuPKU/EquivSVT.git#egg=quadsv
# OR (for development)
git clone https://github.com/JiayuSuPKU/EquivSVT.git && cd EquivSVT && pip install -e .

Usage

Q-test: Single gene spatial variability

import numpy as np
from quadsv.kernels import SpatialKernel
from quadsv.statistics import spatial_q_test

# simulate coordinates and gene expression
coords = np.random.randn(500, 2)
gene_expression = np.random.randn(500)

# build CAR kernel and run Q-test
kernel = SpatialKernel.from_coordinates(coords, method='car', k_neighbors=15, rho=0.9)
Q, pval = spatial_q_test(gene_expression, kernel)
print(f"Q-statistic: {Q:.4f}, p-value: {pval:.4e}")

R-test: Spatial co-expression

from quadsv.statistics import spatial_r_test

# run R-test with the same kernel
gene1, gene2 = np.random.randn(500), np.random.randn(500)
R, pval = spatial_r_test(gene1, gene2, kernel)
print(f"R-statistic: {R:.4f}, p-value: {pval:.4e}")

FFT-accelerated tests (for regular grids like Visium HD)

from quadsv.fft import FFTKernel

# For grid data (e.g., 1000x1000 Visium HD)
kernel_fft = FFTKernel(shape=(1000, 1000), method='car', rho=0.9)

# simulate gene expression on grid
gene_grid = np.random.randn(1000, 1000)

# run FFT-based Q-test
Q_fft, pval_fft = spatial_q_test(gene_grid, kernel_fft)
print(f"FFT Q-test: Q={Q_fft:.4f}, p-value={pval_fft:.4e}")

# run FFT-based R-test
gene1_grid = np.random.randn(1000, 1000)
gene2_grid = np.random.randn(1000, 1000)
R_fft, pval_fft = spatial_r_test(gene1_grid, gene2_grid, kernel_fft)
print(f"FFT R-test: R={R_fft:.4f}, p-value={pval_fft:.4e}")

Tutorials

Detect SVG and spatial co-expression using AnnData

import anndata as ad
from quadsv.detector import PatternDetector

adata = ad.read_h5ad("spatial_data.h5ad")
detector = PatternDetector(adata, min_cells_frac=0.05)

# build kernel from spatial coordinates
detector.build_kernel_from_coordinates(adata.obsm['spatial'], method='car', rho=0.9, k_neighbors=4)

# alternatively, from a precomputed graph adjacency
adata.obsp['W'] = ...  # Precomputed graph adjacency matrix (usually sparse)
detector.build_kernel_from_obsp(key='W', is_distance=False, method='car', rho=0.9)

# Compute Q-statistics and p-values genome-wide
q_results_df = detector.compute_qstat(source='var', features = None, return_pval = True)

# Returns DataFrame with columns: [Q, P_value, P_adj, Z_score]
significant_genes = q_results_df[q_results_df['P_adj'] < 0.05]
print(f"Found {len(significant_genes)} spatially variable genes")

# Select top 1000 SVGs for pairwise R-test
top_genes = significant_genes.sort_values('Q', ascending=False).head(1000).index.tolist()
r_results_df = detector.compute_rstat(source='var', features_x=top_genes, features_y=None, return_pval=True)
# Returns DataFrame with columns: [Gene_X, Gene_Y, R, P_value, P_adj, Z_score]
significant_pairs = r_results_df[r_results_df['P_adj'] < 0.05]
print(f"Found {len(significant_pairs)} spatially co-expressed gene pairs")

FFT-based Q-test for large grids

import spatialdata as sd
from quadsv.detector_fft import PatternDetectorFFT

sdata = sd.read_zarr("visium_hd.zarr/")
detector = PatternDetectorFFT(sdata, kernel_method='car', rho=0.9, topology='square')

results = detector.compute_qstat(
    bins=['Visium_HD_bin'],
    table_name=['table'],
    n_jobs=4, workers=2, return_pval=True
)

Full tutorials: See docs/quickstart.rst and test suite examples.

Kernel Methods

Method Type Spectrum Parameters Use Case
gaussian Distance Positive Definite bandwidth Isotropic, exponential decay
matern Distance Positive Definite bandwidth, nu Tunable smoothness ✓ Recommended
moran ⚠️ Graph Indefinite k_neighbors Autocorrelation (false negatives)
laplacian Graph Semi-Definite k_neighbors High-frequency filter
car Graph Strictly Positive rho, k_neighbors CAR kernel ✓ Recommended

Recommendation: Use car (CAR kernel) for robust, consistent detection across all functional patterns.

Testing & Development

pytest tests/ --cov=quadsv              # Run all tests
pytest tests/test_tutorials.py -v       # Run tutorial examples
pip install -e ".[dev,docs]"            # Install dev + docs dependencies

Documentation: ReadTheDocs

License & Support

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

quadsv-0.1.1.tar.gz (44.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

quadsv-0.1.1-py3-none-any.whl (46.6 kB view details)

Uploaded Python 3

File details

Details for the file quadsv-0.1.1.tar.gz.

File metadata

  • Download URL: quadsv-0.1.1.tar.gz
  • Upload date:
  • Size: 44.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for quadsv-0.1.1.tar.gz
Algorithm Hash digest
SHA256 10f8497fa2334e46368d5181b8b781dbc7a0ef622da33a5e78614c93f63c3575
MD5 42bf5abd3aece5c270916fb12f11b4fb
BLAKE2b-256 05ba236ed64c7bbc96cfc5851b21f3408a29f20efb6505c58eae8d3a0843d1ed

See more details on using hashes here.

Provenance

The following attestation bundles were made for quadsv-0.1.1.tar.gz:

Publisher: release.yml on JiayuSuPKU/EquivSVT

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quadsv-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: quadsv-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 46.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for quadsv-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 5f8d0b0c3bb8146ee924209eb2f3d1735bd0279f75bd33e3464d4b3f900b7f2d
MD5 044a84c430cce194f717d1eb103002a2
BLAKE2b-256 88edf67f69f810a8f0a24a8481bf8311e82232764dfc5b9fe153d3a6012c4933

See more details on using hashes here.

Provenance

The following attestation bundles were made for quadsv-0.1.1-py3-none-any.whl:

Publisher: release.yml on JiayuSuPKU/EquivSVT

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page