Skip to main content

A toolkit for spatial pathology analysis

Project description

SpatioPath

SpatioPath is a comprehensive framework designed for spatial statistical analysis of cell-to-cell and region-to-cell interactions. The framework provides robust, reproducible tools for generating simulation data, visualizing results, and analyzing real microscopy images to derive quantitative insights from spatial patterns in the tissue microenvironment.

Key design goals are clarity, separation of concerns, and reproducibility: core numerical routines remain pure and unit-testable, visualization and persistence are encapsulated in a Result object, and logging is controlled by the application (caller) rather than the library.


Highlights

  • Incremental, batch-first API: add any number of patches (single or many) and compute pooled results when required.
  • Clear separation of concerns:
    • numerical/statistical code in helper modules,
    • state + lifecycle in SpatioPath engine,
    • visualization + persistence in SpatioPathResult.
  • No implicit file I/O or logging configuration — the caller controls persistence and logger formatting.
  • Small, human-readable persistence by default (CSV + JSON); optional binary pickle for full fidelity (arrays).

Install

Requires Python 3.9+.

Recommended install (editable for development):

python -m venv .venv
source .venv/bin/activate         # macOS / Linux
# .venv\Scripts\activate          # Windows PowerShell
pip install -e .

Minimum runtime dependencies (also listed in pyproject.toml):

numpy
pandas
scipy
scikit-image
opencv-python
matplotlib
seaborn
shapely
tqdm

Concepts

Patch, Engine, Result

  • Patch — a single analysis unit. Each patch is defined by:

    • setA: polygonal regions (e.g., tumor or tissue compartments),
    • setB: points (e.g., cell centroids),
    • roi: region-of-interest (optional, defaults to full image).
  • Engine (SpatioPath) — stateful object that accepts patches via add_patch(...) and accumulates computed patch-level Result objects.

  • Result (SpatioPathResult) — encapsulates all outputs for a patch or a pooled/global analysis: summary metrics, KTable, IndecesTable, LevelSetsTable, CellsTable, optional arrays (zoneMap, distMap), plotting and save/load helpers.

Regions-of-Interest (ROI)

ROIs are represented using the shapely geometry library. The engine expects ROI polygons as instances of shapely.geometry.Polygon. This enables robust, standard geometric operations and easy interoperability with common geo / spatial toolchains.

Example ROI creation (Shapely):

from shapely.geometry import Polygon

# rectangle ROI spanning a 4096×4096 image
roi = Polygon([(0, 0), (4096, 0), (4096, 4096), (0, 4096)])

When roi is omitted in add_patch(...), the engine uses a default full-image ROI based on the engine's width and height.


Quick start

import logging
from spatiopath import SpatioPath, SpatioPathResult
from shapely.geometry import Polygon

# Configure logging in your application (library does not configure root handlers)
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")

# Create engine (global parameters fixed at init)
engine = SpatioPath(zone_width=10.0, analysis_zone=400.0, pixel_size=0.5, height=4096, width=4096)

# Prepare patch inputs
# setA: list of polygons, each polygon is (xi_array, yi_array)
# setB: Nx2 array-like of (x, y) points
setA_1 = [([100, 200, 200, 100], [100, 100, 200, 200])]
setB_1 = [(150, 150), (300, 300), (350, 180)]
roi = Polygon([(0, 0), (4096, 0), (4096, 4096), (0, 4096)])

# Add one or more patches
patch_result = engine.add_patch(name="patch_01", setA=setA_1, setB=setB_1, roi=roi)

# Patch-level inspection
print(patch_result.analysis)        # one-row DataFrame of summary metrics
print(patch_result.KTable.head())   # KTable per zone

# Add more patches as needed...
# engine.add_patch(...)

# Pool across all added patches
global_result: SpatioPathResult = engine.compute_pooling()

# Plot pooled K0
ax = global_result.plot_k0(title="Global K₀")
import matplotlib.pyplot as plt
plt.show()

# Save results (as CSVs + JSON)
global_result.save("results/patient001/global_result", format="dir", include_arrays=False)

# Optional: save full pickled result (includes arrays)
global_result.save("results/patient001/global_result.pkl", format="pickle")

API reference (concise)

SpatioPath(zone_width, analysis_zone, pixel_size, height=4096, width=4096)

Create a stateful analysis engine.

Methods

  • add_patch(name: str, setA, setB, roi: shapely.geometry.Polygon | None = None) -> SpatioPathResult Analyze the patch, return a SpatioPathResult and keep it in the engine store.
  • compute_pooling() -> Optional[SpatioPathResult] Pool all stored patches and return a single pooled SpatioPathResult. Returns None if no patches exist.
  • list_patches() -> List[str] Names of stored patches.
  • reset() -> None Clear stored patches.

SpatioPathResult

Encapsulates a single analysis outcome.

Attributes

  • name — identifier (patch name or "GLOBAL").
  • analysis — one-row pandas.DataFrame containing summary statistics (MODIFIED_ASI, meanCouplingDistance, log p-value, etc.).
  • KTable, IndecesTable, LevelSetsTable, CellsTablepandas.DataFrames produced by the pipeline.
  • omega, total_points — numeric metadata.
  • zoneMap, distMap — optional numpy arrays (may be None).

Methods

  • plot_k0(ax: Optional[matplotlib.axes.Axes] = None, colors: Optional[List] = None, title: Optional[str] = None) -> matplotlib.axes.Axes Plot K₀ barplot for this result (patch or pooled).
  • save(path: str, format: str = "dir" | "pickle", include_arrays: bool = False) -> None Persist the result. 'dir' writes CSVs + JSON; 'pickle' pickles the full object (includes arrays).
  • load(path: str) -> SpatioPathResult (static/classmethod) Load a previously saved result (folder or pickle).

Logging

The package exposes a module-level logger spatiopath but intentionally does not configure handlers or formatters. This allows calling applications to centrally configure logging behavior. Example:

import logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
logging.getLogger("spatiopath").setLevel(logging.DEBUG)

Use standard logging levels (DEBUG, INFO, WARNING, ERROR, CRITICAL) in your application.


Persistence & Interoperability

  • Default persistence format (format='dir') stores human-readable CSVs and a JSON summary for easy inspection and version control.
  • Optionally use pickled results (format='pickle') when you need to preserve large arrays (zoneMap, distMap) or Python objects — note that pickles are not cross-version stable and should be used with caution for long-term archives.
  • The output tables (KTable, LevelSetsTable, IndecesTable, CellsTable) are standard pandas.DataFrames and can be exported to any format supported by pandas.

Development & Contribution


License

MIT — see LICENSE for full text.


Citation

If you use SpatioPath in published work, please cite it and include a brief description of the analysis parameters (zone width, pixel size, pooling mode) for reproducibility.

@article{Benimam2025,
   doi = {10.1038/s41467-025-57943-y},
   issn = {2041-1723},
   issue = {1},
   journal = {Nature Communications 2025 16:1},
   keywords = {Bioinformatics,Biomedical engineering,Predictive markers,Statistical methods,Tumour immunology},
   month = {3},
   pages = {1-20},
   pmid = {40164621},
   publisher = {Nature Publishing Group},
   title = {Statistical analysis of spatial patterns in tumor microenvironment images},
   volume = {16},
   url = {https://www.nature.com/articles/s41467-025-57943-y},
   year = {2025}
}

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

spatiopath-0.5.0.tar.gz (27.0 kB view details)

Uploaded Source

Built Distribution

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

spatiopath-0.5.0-py3-none-any.whl (28.4 kB view details)

Uploaded Python 3

File details

Details for the file spatiopath-0.5.0.tar.gz.

File metadata

  • Download URL: spatiopath-0.5.0.tar.gz
  • Upload date:
  • Size: 27.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for spatiopath-0.5.0.tar.gz
Algorithm Hash digest
SHA256 597428314c3c38e9ff4c02ad332cfdb85bbd54a5457e9e0b617569aace3a209d
MD5 0bff01025313413e2145ed95e25a0da5
BLAKE2b-256 a167500c8af1198bc850840c255860a3549351e55d2873eed8b5bfca7a6d3930

See more details on using hashes here.

File details

Details for the file spatiopath-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: spatiopath-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 28.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for spatiopath-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2d67a406aeb68180b8c13d8b7f31a36395b6b9b61928bb3d9da71c33e550b3b0
MD5 5e336284a054d740cbe970079186fce9
BLAKE2b-256 c8f616ae734f84a0f2a413269c9ad7b6b22e101b37d2a912979a4b764ce5b3df

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