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
AnnDataandSpatialDatasupport
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
- License: BSD-3-Clause – see LICENSE
- Issues: GitHub Issues
- Docs: ReadTheDocs
Release files for quadsv 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| quadsv-0.1.1.tar.gz | 44.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| quadsv-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 91.3 kB
Release files / quadsv-0.1.1.tar.gz
| Download URL | quadsv-0.1.1.tar.gz |
|---|---|
| Size | 44.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
10f8497fa2334e46368d5181b8b781dbc7a0ef622da33a5e78614c93f63c3575
|
|
BLAKE2b-256 checksum How to use checksums |
05ba236ed64c7bbc96cfc5851b21f3408a29f20efb6505c58eae8d3a0843d1ed
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 2, 2026.
Transparency logRelease files / quadsv-0.1.1-py3-none-any.whl
| Download URL | quadsv-0.1.1-py3-none-any.whl |
|---|---|
| Size | 46.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5f8d0b0c3bb8146ee924209eb2f3d1735bd0279f75bd33e3464d4b3f900b7f2d
|
|
BLAKE2b-256 checksum How to use checksums |
88edf67f69f810a8f0a24a8481bf8311e82232764dfc5b9fe153d3a6012c4933
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 2, 2026.
Transparency log