Metadata-Version: 2.4
Name: pycellchat
Version: 1.5.0.post1
Summary: Atlas-scale, GPU-accelerated cell-cell communication analysis with single-precision numerical parity
Author-email: Ali Khadim <ali.khadim@innere.med.uni-giessen.de>
License-Expression: MIT
Project-URL: Homepage, https://github.com/alikhadim/pycellchat
Project-URL: Repository, https://github.com/alikhadim/pycellchat.git
Project-URL: Bug Tracker, https://github.com/alikhadim/pycellchat/issues
Keywords: single-cell,cell-cell-communication,ligand-receptor,bioinformatics,gpu-acceleration,torch,cuda,apple-silicon,scanpy,anndata,atlas-scale,differential-communication
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: OS Independent
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: anndata>=0.9.0
Requires-Dist: scanpy>=1.9.0
Requires-Dist: pandas<3.0,>=1.5.0
Requires-Dist: numpy<2.0,>=1.22.0
Requires-Dist: scipy>=1.9.0
Requires-Dist: scikit-learn>=1.1.0
Requires-Dist: torch>=2.5.0
Requires-Dist: joblib>=1.2.0
Requires-Dist: matplotlib>=3.6.0
Requires-Dist: seaborn>=0.12.0
Requires-Dist: networkx>=2.8.0
Requires-Dist: venn>=0.1.3
Requires-Dist: upsetplot>=0.8.0
Requires-Dist: tqdm>=4.64.0
Provides-Extra: gpu
Requires-Dist: torch>=2.5.0; extra == "gpu"
Provides-Extra: test
Requires-Dist: pytest>=7.4; extra == "test"
Requires-Dist: pytest-cov>=4.1; extra == "test"
Requires-Dist: scipy>=1.9.0; extra == "test"
Requires-Dist: matplotlib>=3.6.0; extra == "test"
Provides-Extra: dev
Requires-Dist: pytest>=7.4; extra == "dev"
Requires-Dist: pytest-cov>=4.1; extra == "dev"
Requires-Dist: ruff>=0.3.0; extra == "dev"
Requires-Dist: mypy>=1.5.0; extra == "dev"
Requires-Dist: pre-commit>=3.5.0; extra == "dev"
Requires-Dist: scipy>=1.9.0; extra == "dev"
Requires-Dist: matplotlib>=3.6.0; extra == "dev"
Dynamic: license-file

# pyCellChat

[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![Python 3.10+](https://img.shields.io/badge/Python-3.10%2B-3776AB?logo=python&logoColor=white)](https://www.python.org/)
[![PyTorch 2.5+](https://img.shields.io/badge/PyTorch-2.5%2B-EE4C2C?logo=pytorch&logoColor=white)](https://pytorch.org/)
[![CUDA](https://img.shields.io/badge/CUDA-11.8%2B-76B900?logo=nvidia&logoColor=white)](https://developer.nvidia.com/cuda-toolkit)
[![Apple Silicon](https://img.shields.io/badge/Apple_Silicon-MPS-000000?logo=apple&logoColor=white)](https://developer.apple.com/metal/)
[![Version](https://img.shields.io/badge/Version-1.5.0-brightgreen)](.)

pyCellChat is a GPU-accelerated Python implementation of CellChat's communication-probability model for atlas-scale single-cell cell-cell communication (CCC) analysis. It reproduces CellChat's core communication-probability model to numerical precision — median relative difference 9.3x10⁻⁸ against R CellChat across 316,412 interactions — while removing the scale ceiling of the reference R workflow, processing atlases up to 19.1 million cells. The package focuses on the validated core required for reproducible CCC inference: a CellChat-parity-validated communication-probability engine, GPU-accelerated permutation testing on CUDA, Apple Silicon MPS, and CPU, multi-sample batch execution, and differential CCC workflows with explicit exchangeability-unit guidance. In cross-subject comparisons, pyCellChat treats donors or samples as the inferential unit through replicated differential testing; cell-level differential testing is retained for within-dataset or deliberately cell-level analyses.

---

## Contents

- [What pyCellChat includes](#what-pycellchat-includes)
- [What is not included](#what-is-not-included)
- [Installation](#installation)
- [Quick start](#quick-start)
- [Validation scope](#validation-scope)
- [Save & Load](#save--load)
- [Command-Line Interface](#command-line-interface)
- [Contributing](#contributing)
- [Citation](#citation)
- [Authors](#authors)

Further reading: **[BENCHMARKS.md](documentation/BENCHMARKS.md)** (full parity and timing tables) · **[DIFFERENTIAL_CCC.md](documentation/DIFFERENTIAL_CCC.md)** (calibration, power, reachability of the two differential CCC tests) · **[REPRODUCIBILITY.md](documentation/REPRODUCIBILITY.md)** (seeding, backend guards, permutation p-value conventions).

---

## What pyCellChat includes

1. **Core CellChat-parity-validated CCC** — `compute_communication_prob()`. Implements triMean expression summary, complex geometric mean (for multi-subunit ligands/receptors), Hill-function probability, mediator/cofactor (co-receptor, agonist, antagonist) modulation, population-size weighting, and permutation p-values.

2. **GPU permutation engine** — CUDA / Apple Silicon MPS / CPU, with reproducible permutation behaviour across backends. Requires `torch >= 2.5.0` (earlier releases have a confirmed MPS numerical defect; see [Installation](#installation)).

3. **Multi-sample batch execution** — `run_batch()` and `run_batch_backed()`. CSV/HDF5 output, resume-safe execution on interrupted runs.

4. **Cell-level differential CCC** — `compute_differential_ccc()`. This treats cells as exchangeable and is appropriate only for within-dataset or deliberately cell-level analyses. It is not the recommended default for donor-structured cross-subject inference.

5. **Subject/sample-level differential CCC** — `compute_differential_communication_replicated()`. The recommended default when conditions are assigned across donors, subjects, samples, or biological replicates, because donors/samples — not cells — are the exchangeable units in that setting.

6. **Minimal plotting** — `pcc.pl`, covering core CCC and differential CCC visualisation only.

---

## What is not included

pyCellChat's validated scope is the core communication-probability engine and the two differential CCC tests above. This package does not include:

- spatial CCC
- RNA velocity integration
- temporal / pseudotime / trajectory workflows
- perturbation / knockout simulation
- ligand-target coupling
- pathway/network enrichment
- NicheNet-like scoring
- OmniPath integration
- LIANA conversion
- a rare-cell annotator
- a broad general-purpose plotting gallery

---

## Installation

### Requirements

| Platform | Prerequisites |
| :--- | :--- |
| NVIDIA GPU | CUDA Toolkit >= 11.8, PyTorch >= 2.5 |
| Apple Silicon | macOS >= 12.3, PyTorch >= 2.5 |
| CPU only | Python >= 3.10, NumPy |

pyCellChat requires PyTorch >= 2.5. Earlier releases (2.2.2-2.4.x) have a
confirmed, reproducible MPS (Apple Silicon) numerical defect in the
triMean/permutation calculations — not float noise, real errors that
silently inflate significant-interaction counts. `pyproject.toml`/
`environment.yml` pin the floor at install time, and it is also enforced
at runtime, so a stale `torch` fails loudly rather than silently
returning wrong numbers.

### From source

```bash
git clone https://github.com/alikhadim/pycellchat.git
cd pycellchat
pip install -e .
```

The software is named **pyCellChat**; the Python import namespace is `pycellchat`:

```python
import pycellchat as pcc
```

### Conda (recommended for reproducibility)

```bash
conda env create -f environment.yml
conda activate pycellchat
pip install -e .
```

### Verify installation

```python
import pycellchat as pcc
print(pcc.__version__)

import anndata as ad, numpy as np, scanpy as sc
adata = ad.AnnData(
    X=np.random.rand(100, 200).astype("float32"),
    obs={"celltype": ["A"] * 50 + ["B"] * 50},
)
sc.pp.normalize_total(adata, target_sum=1e4)
sc.pp.log1p(adata)
cc = pcc.CellChat(adata, group_by="celltype", species="human", _silent=True)
print("OK:", cc.n_groups, "groups")
```

---

## Quick start

### Single sample

```python
import scanpy as sc
import pycellchat as pcc

adata = sc.read_h5ad("sample.h5ad")
db = pcc.load_cellchat_db("human")
cc = pcc.CellChat(adata, group_by="celltype", species="human", db=db)
cc.compute_communication_prob(n_permutations=500, random_state=42)
cc.aggregate_communication_prob()
pcc.save_CellChat(cc, "sample.h5")
```

### Multi-sample batch

```python
results = pcc.run_batch(
    adata,
    group_by="sample",
    cell_type="celltype",
    species="human",
    n_perm=500,
    out_dir="results",
    skip_existing=True,
)
```

For datasets too large to hold every sample's `CellChat` object in memory at once, `run_batch_backed()` provides the same per-sample processing with a memory-efficient/backed execution path.

### Differential CCC

For donor/sample-structured comparisons, use the recommended default:

```python
diff = pcc.compute_differential_communication_replicated(
    cc_list, condition_labels=["control", "control", "disease", "disease"],
    reference="control",
)
```

For within-dataset cell-level analyses only:

```python
diff_cell = pcc.compute_differential_ccc(cc_a, cc_b)
```

See [Validation scope](#validation-scope) and [DIFFERENTIAL_CCC.md](documentation/DIFFERENTIAL_CCC.md) for why these two functions are not interchangeable.

---

## Validation scope

Parity claims apply specifically to the core communication-probability model: triMean expression aggregation, complex geometric mean, Hill-function probability, permutation p-values, and pathway-level aggregation. The parity-locked implementation lives in `pycellchat/core/cellchat.py` and `pycellchat/utils/stats.py`.

Validated line-by-line against CellChat v2 (`modeling.R`) on the Human ILD Atlas (Jaiswal et al., *Cell Genomics* 2026; 698,344 cells across 8 disease categories):

| Sample | Cells | Pearson *r* | Spearman *ρ* | RMSE |
| :--- | ---: | :---: | :---: | :---: |
| uILD | 4,226 | 0.99999999999999840 | 0.999999999998714 | 6.09x10⁻⁸ |
| Myo-ILD | 7,192 | 0.99999999999999770 | 0.999999999995853 | 5.90x10⁻⁸ |
| Sarcoidosis | 7,324 | 0.99999999999999860 | 0.999999999998841 | 5.99x10⁻⁸ |
| NSIP | 9,077 | 0.99999999999999770 | 0.999999999998647 | 6.22x10⁻⁸ |
| Fibrotic HP | 17,685 | 0.99999999999999790 | 0.999999999998026 | 6.16x10⁻⁸ |
| SSC-ILD | 64,742 | 0.99999999999999730 | 0.999999999998302 | 5.93x10⁻⁸ |
| Non-ILD Control | 212,703 | 0.99999999999999830 | 0.999999999997869 | 6.49x10⁻⁸ |
| IPF | 297,695 | 0.99999999999999840 | 0.999999999998767 | 5.93x10⁻⁸ |

Pooled across all 316,412 shared interactions: *r* = 0.999999999999997 (1 - *r* = 1.55x10⁻¹⁵), median relative difference 9.3x10⁻⁸. Full methodology and per-cohort tables: **[BENCHMARKS.md](documentation/BENCHMARKS.md)**.

**Algorithm:** `p = lr^h / (K^h + lr^h)` (Hill function, default *K*=0.5, *h*=1), where `lr` is the triMean of sender ligand expression times the triMean of receiver receptor expression, geometric-mean-aggregated across subunits for complexes.

**Scale.** On a same-machine, matched-input benchmark (identical exported matrix, 500 permutations), the core engine is substantially faster than R CellChat, and pyCellChat completes atlases R CellChat cannot compute at all — R's sparse `dgCMatrix` representation fails at a hard 2³¹ non-zero-entry limit before inference begins. Full timing tables and methodology, including engine-only vs. end-to-end comparisons and run-to-run variance: **[BENCHMARKS.md](documentation/BENCHMARKS.md)**.

**Differential CCC calibration.** `compute_differential_ccc()` (cell-level) has an empirically calibrated false-positive rate near the nominal 0.05 under a cell-level-exchangeable null, but is severely anticonservative under realistic donor-structured data. `compute_differential_communication_replicated()` (subject-level) controls the error rate under the same donor-structured conditions. This is why subject/sample-level permutation is the recommended default for cross-subject inference, and cell-level testing is reserved for within-dataset or deliberately cell-level analyses. Full calibration, power curves, and reachability tables: **[DIFFERENTIAL_CCC.md](documentation/DIFFERENTIAL_CCC.md)**.

---

## Save & Load

pyCellChat uses a compact HDF5 format. The default save omits the expression matrix; all network, pathway, and visualisation functions remain fully functional. Add `keep_expression=True` to also enable gene-level plots.

```python
pcc.save_CellChat(cc, "sample.h5")
pcc.save_CellChat(cc, "sample.h5", keep_expression=True)

cc = pcc.load_CellChat("sample.h5")
```

Database version is stored in the HDF5 metadata and restored on load (`cc.db_version`), ensuring reproducibility across package updates.

---

## Command-Line Interface

```bash
pycellchat run \
    --input atlas.h5ad --species human --group-by celltype \
    --out results/ --n-perms 1000 --gpu

pycellchat plot circle  --input results/sample.h5 --output circle.pdf
pycellchat plot heatmap --input results/sample.h5 --output heatmap.pdf

pycellchat db list
pycellchat version
```

---

## Contributing

```bash
pip install -e ".[dev]"
pip install -r requirements-dev.txt
pre-commit install

ruff check pycellchat/
pytest tests/ -x -q
```

**Critical constraint:** `pycellchat/core/cellchat.py` and `pycellchat/utils/stats.py` are parity-locked to R CellChat. Do not modify any mathematical operation, aggregation logic, permutation semantics, or filtering logic in these files without a full R comparison.

---

**Development assistance**

> Portions of this project were developed with the assistance of Claude (Anthropic) — for algorithmic optimisation, code cleanup, test scaffolding, and documentation. All AI-assisted code was reviewed and validated by the author, who retains full responsibility for the methods, results, and their scientific interpretation.

---

## Citation

If you use pyCellChat, please cite the manuscript:

> Khadim, A., Bartkuhn, M., Seeger, W., El Agha, E. Donors, not cells, are the exchangeable units for differential cell-cell communication analysis. *bioRxiv* (2026). doi: pending — a preprint will be posted ahead of peer-reviewed submission; this entry will be updated with the bioRxiv DOI once it is assigned.

A peer-reviewed manuscript is in preparation and not yet published. **Until a DOI is available, please also cite this repository together with the specific version or commit hash used** (see [CITATION.cff](CITATION.cff)), so results remain reproducible.

**CellChat (algorithm reference):**
> Jin, S. et al. Inference and analysis of cell-cell communication using CellChat. *Nat Commun* **12**, 1088 (2021). https://doi.org/10.1038/s41467-021-21246-9

**Validation datasets used in this repository's benchmarks:**
> Jaiswal, A., Kooistra, T., Pokatayev, V. et al. Spatial transcriptomics reveals altered communities and drivers of aberrant epithelia and pro-fibrotic fibroblasts in interstitial lung diseases. *Cell Genomics* (2026). https://doi.org/10.1016/j.xgen.2025.101066

> Sikkema, L. et al. An integrated cell atlas of the lung in health and disease. *Nat Med* **29**, 1563-1577 (2023). https://doi.org/10.1038/s41591-023-02327-2

---

## Authors

**Ali Khadim** · Institute for Lung Health (ILH), Universities of Giessen and Marburg Lung Center (UGMLC), Giessen, Germany

**License:** [MIT](LICENSE)
