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.0.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.0-py3-none-any.whl (46.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: quadsv-0.1.0.tar.gz
  • Upload date:
  • Size: 44.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for quadsv-0.1.0.tar.gz
Algorithm Hash digest
SHA256 66f30b4cc6995ef4ed6aca3c9770bf4e2a3d5f0cc95e2475d40aa0e31f1624fa
MD5 d094bba11507859b0f3f744e5adda87e
BLAKE2b-256 8458a71b2391eac5a4b6d4aacc89817bcd09bf033ea70ea850796a24df92ef6c

See more details on using hashes here.

File details

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

File metadata

  • Download URL: quadsv-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 46.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for quadsv-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dedf4870eba183350c714c2388e3e96731abf20548505729c37a5f8853a61ce1
MD5 3859506cc2776a9e4c03731c8f3e6bcc
BLAKE2b-256 f90c9703af67ed86e11787740fabfdfd544e03a5c717b071bac35784c6cb2472

See more details on using hashes here.

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