Metadata-Version: 2.4
Name: scimappro
Version: 0.1.20
Summary: Spatial single-cell analysis tools for AnnData workflows
Author-email: Ajit Johnson Nirmal <ajitjohnson.n@gmail.com>
License-Expression: LicenseRef-Scimappro-EULA-1.0
Project-URL: Homepage, https://pro.scimap.xyz
Project-URL: Documentation, https://pro.scimap.xyz
Project-URL: Repository, https://github.com/nirmallab/scimappro
Project-URL: Issues, https://github.com/nirmallab/scimappro/issues
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Intended Audience :: Science/Research
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
Requires-Python: <3.15,>=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: anndata>=0.13.3
Requires-Dist: certifi>=2025.1.31
Requires-Dist: cryptography>=42
Requires-Dist: dask>=2026.8.0
Requires-Dist: igraph>=1.0.0
Requires-Dist: joblib>=1.6.0
Requires-Dist: leidenalg>=0.12.0
Requires-Dist: matplotlib>=3.11.1
Requires-Dist: numba>=0.67.0
Requires-Dist: numpy>=2.5.2
Requires-Dist: pandas>=3.0.5
Requires-Dist: plotly>=7.0.0
Requires-Dist: platformdirs>=4.3.0
Requires-Dist: polars>=1.44.1
Requires-Dist: psutil>=7.0.0
Requires-Dist: py-machineid>=0.8.0
Requires-Dist: pyarrow>=25.0.1
Requires-Dist: pyyaml>=6.0.3
Requires-Dist: requests>=2.32.0
Requires-Dist: scikit-learn>=1.9.0
Requires-Dist: scipy>=1.18.1
Requires-Dist: spatialdata>=0.8.0
Requires-Dist: threadpoolctl>=3.6.0
Requires-Dist: tifffile>=2026.8.23
Requires-Dist: tqdm>=4.70.0
Requires-Dist: umap-learn>=0.5.12
Requires-Dist: zarr>=3.3.0
Provides-Extra: roi
Requires-Dist: shapely>=2.1.2; extra == "roi"
Provides-Extra: de
Requires-Dist: pydeseq2>=0.5; extra == "de"
Provides-Extra: interactive
Requires-Dist: anywidget>=0.9; extra == "interactive"
Requires-Dist: ipywidgets>=8.1; extra == "interactive"
Provides-Extra: ai
Requires-Dist: mcp<3,>=2.2; extra == "ai"
Dynamic: license-file

# scimappro

**Documentation: <https://pro.scimap.xyz>**

`scimappro` is a Python toolkit for spatial single-cell analysis workflows. It
provides preprocessing, analysis, and plotting utilities for `AnnData` objects,
large `.h5ad` datasets, and scverse `SpatialData` stores.

It is the professional edition of [SCIMAP](https://scimap.xyz) and a deliberate
API break from it — see the
[migration guide](https://pro.scimap.xyz/migrating/).

## Requirements

Python 3.12, 3.13, or 3.14.

## Installation

```bash
pip install scimappro
```

The package runs immediately without a licence, in **Starter mode**: every
function, on datasets up to 100,000 cells, single-threaded, with watermarked
plots. Larger datasets, out-of-core streaming, `SpatialData` input, and parallel
execution need a subscription — from $149/year for academics. See
[Pricing](https://pro.scimap.xyz/pricing) and
[Licensing](https://pro.scimap.xyz/licensing).

```bash
scimappro license activate SCP-XXXX-XXXX-XXXX-XXXX
scimappro license status
```

On a cluster or an air-gapped machine, activate offline — no step needs that
machine to reach the internet:

```bash
scimappro license fingerprint --out fingerprint.json
# upload at https://pro.scimap.xyz/portal, download scimappro.lic
scimappro license install scimappro.lic
```

scimappro reports anonymous usage data — which functions are called, how long
they take, dataset sizes as ranges, and scrubbed error signatures. It never
sends your data, file names, paths, sample names or results; see
[Usage reporting](https://pro.scimap.xyz/docs/telemetry) for every field, and
`scimappro telemetry show` to read what is queued on your own machine before it
goes. One command turns it off:

```bash
scimappro telemetry status   # what is being sent
scimappro telemetry off      # nothing at all
```

Optional extras:

```bash
pip install "scimappro[roi]"   # shapely, for hl.addROI_omero
```

## Development

Dependencies are managed with [uv](https://docs.astral.sh/uv/) and pinned in
`uv.lock`.

```bash
SCIMAPPRO_PURE_PYTHON=1 uv sync --all-extras   # create the environment
uv run pytest                                  # run the test suite
uv sync --all-extras -p 3.12                   # or 3.13 / 3.14
uv lock --upgrade                              # re-resolve every dependency
```

`SCIMAPPRO_PURE_PYTHON=1` skips Cython compilation. Released wheels are
compiled; a development install does not need to be.

The test suite sets `SCIMAPPRO_TESTING=1`, which stops usage reporting: a
maintainer's own runs and CI would otherwise be the loudest installations in
the product data. Three generated files have `--check` modes that CI runs, and
that need regenerating whenever the code they read changes:

```bash
uv run python tools/syncTelemetryWords.py      # the error-template vocabulary
uv run python tools/syncTelemetryVectors.py    # the allowlist the Worker validates against
uv run python tools/syncTelemetryDocs.py       # the field table in website/content/docs/telemetry.mdx
```

### Documentation

The site is a Next.js app under `website/`, so it needs Node as well as Python.
Neither toolchain is pulled in by `pip install scimappro`:

```bash
uv sync --group docs      # griffe, which reads the docstrings
cd website && npm ci      # Next, Fumadocs
npm run dev               # http://localhost:3000
npm run build             # what CI runs
```

Every API page and every tutorial page is generated on each build — from the
docstrings and the notebooks respectively — and none of them is committed.
`uv run python tools/syncDocs.py --check` validates the inputs without writing.

`.github/workflows/docs.yml` deploys to <https://pro.scimap.xyz> on every push
to `main`. See `website/content/docs/contribute.mdx` for the docstring
conventions the API reference is generated from, and `website/README.md` for
the layout of the site itself.

If the checkout lives on a cloud-synced folder (Dropbox, OneDrive), sync locks
can break venv writes. Build the environment outside the synced tree instead:

```bash
UV_PROJECT_ENVIRONMENT=~/.venvs/scimappro uv sync --all-extras
```

## Modules

Eight namespaces, split by what a function *reads* rather than by what it is
for — anything that reads a coordinate is `sp`, even when the question it
answers is a single-cell one.

- `scimappro.io`: getting data in and out — vendor readers, `readMcmicro`,
  format conversion, storage, export.
- `scimappro.pp`: preprocessing shared by imaging and transcriptomics —
  `qcMetrics`, `rescale`, `normalizeTotal`, `pca`, `integrate`.
- `scimappro.sc`: what a cell is — `phenotype`, `classify`.
- `scimappro.sp`: tissue architecture — the spatial graph, neighbourhood
  counts and motifs, distance, co-occurrence, proximity, autocorrelation,
  ligand–receptor scoring.
- `scimappro.tl`: what works equally on cells, domains or samples —
  `cluster`, `umap`, `foldChange`, `pseudobulk`, `rename` — and the
  statistical framework the rest of the package feeds:
  `compareGroups`, `associationTest`, `summarizeSamples`, all testing at the
  unit of replication rather than across cells.
- `scimappro.cl`: clinical association, linking those features to outcomes.
- `scimappro.pl`: analytical plots.
- `scimappro.hl`: helpers for external tools such as OMERO.
- `scimappro.license`: activate, inspect, and move the licence on this machine.
- `scimappro.telemetry`: see, change or switch off usage reporting.

Every function in these modules accepts `AnnData`, `.h5ad`, `SpatialData`, and
`.zarr` inputs through its `data` argument.

## Example

```python
import scimappro as sm

# Preprocessing
# sm.pp.rescale(...)

# Analysis
# sm.sp.spatialDistance(...)

# Plotting
# sm.pl.heatmap(...)
```

## Coding agents

Tell SCIMAP Pro what you want to learn biologically. The agent finds the right
analysis, explains the plan, and runs the right functions for you -- you do not
need to know any function names.

```bash
pip install "scimappro[ai]"
scimappro ai init
```

That configures every coding agent on the machine -- Claude Code, Codex CLI,
Cursor, VS Code Copilot, Gemini CLI, Claude Desktop -- to use scimappro's MCP
server. Then restart your agent and ask it something real:

> Do T cells sit closer to tumour cells than expected in my sections?

It inspects the dataset, reads the spatial-analysis skill, searches 128
functions by intent, tells you what the result could and could not support as
a claim, runs it, and reports exactly what it wrote. Everything runs locally;
your data never leaves the process. `scimappro ai doctor` checks it is working.

The same description of the package is readable from Python, with no agent
involved:

```python
sm.ai.search("which cell types sit next to which")
sm.ai.describe("sp.spatialDistance")["experimental_unit"]
```

See `website/content/docs/ai.mdx` for the tools, the four scope states, and the
nine scientific skills.

## SpatialData support

Every public function takes its cell table as the first argument, named `data`.
It accepts an `AnnData`, a path to an `.h5ad` file, a scverse `SpatialData`, or
a path to a `.zarr` SpatialData store:

```python
import scimappro as sm
import spatialdata as sd

sdata = sd.read_zarr("sample.zarr")

# In memory: the returned SpatialData carries the result in its table.
sdata = sm.sp.spatialDistance(sdata, sdataTable="table")
sdata.tables["table"].uns["spatial_distance"]

# On disk: rewrite just that table inside the store it came from.
sm.sp.spatialDistance(sdata, sdataTable="table", outputDir="sample.zarr")
```

- `sdataTable` names the table to work on. Leave it out when the store has
  exactly one table; with several, scimappro raises a `ValueError` listing them.
- Functions read coordinates from `obs['X_centroid']`/`obs['Y_centroid']` and
  group cells by `obs['imageid']`. When a table lacks those columns, scimappro
  derives them from the elements the table annotates — `imageid` from the
  region-key column and the centroids from the annotated shapes, points, or
  labels — and stores them on the table, preserving row order.
- With `outputDir=None` the updated `SpatialData` is returned, with its table
  modified in memory. Supplying `outputDir` writes `<inputFilename>.zarr` there
  and returns `None`; if `outputDir` points at the store the object was read
  from, only the table is rewritten in place.
- `streamData=True` works for a `.zarr` store as it does for an `.h5ad`: its
  table is read and written where it lies. Passing it alongside an in-memory
  `SpatialData` warns and continues in memory, since its tables are already
  loaded.

Functions that build a new table (`sc.classify`, `tl.rename`, `pp.dropFeatures`,
`hl.addROI_omero`) replace the table inside the `SpatialData` you passed and
return that container. Keep the table's `region_key` and `instance_key` obs
columns intact, or the write-back will not validate.

### Converting an existing cell table

`io.toSpatialData` turns a scimap-style `AnnData` (or `.h5ad`) into a
`SpatialData`: one circles element per image holding that image's cell
centroids, with the whole table attached to those elements.

```python
sdata = sm.io.toSpatialData(adata)                      # radius from obs['Area']
sm.io.toSpatialData(adata, outputDir="converted")       # writes converted/<name>.zarr
```

Every obs column is preserved, so nothing is lost even though the geometry is
two-dimensional. `radius` takes an obs column name or a number when you do not
want `sqrt(Area / pi)`; `CellID` is generated as 1..n when the table has no
instance-key column; and image ids that are not valid element names are
sanitised into a separate `region` column, leaving `imageid` untouched.

## License

SCIMAP Pro End User Licence Agreement 1.0 (`LicenseRef-Scimappro-EULA-1.0`) —
see [LICENSE](LICENSE).

Commercial software, free to install and use in Starter mode. You own your
results and any analysis code you write against the public API, and you may
publish or commercialize those freely. Redistribution and licence-key sharing
are not permitted.

Versions 0.1.0 and 0.1.1 were released under the Scimappro Academic License 1.0
and remain available under those terms.

The community edition, [SCIMAP](https://scimap.xyz), is MIT-licensed and stays
free. Sales: <sales@scimap.xyz>. Support: <support@scimap.xyz>.
