Skip to main content

bioIOT

Plug-and-play semi-relaxed inverse optimal transport for single-cell state transitions

PyPI CI Python License


English | 简体中文

bioIOT solves the semi-relaxed inverse optimal transport problem: given state-transition features, source/target state masses and observed transitions, it learns feature weights θ such that the soft-marginal optimal-transport plan induced by the linear cost C = -einsum(φ, θ) reproduces the data — then turns the fit into state transition matrices, random-walk pseudotime and publication-ready plots.

The solver was developed and validated as part of a research project on treatment-resistance state transitions, and is packaged here for general use.

Why bioIOT?

  • Identifiable by construction. Hard-marginal OT makes pure column features unidentifiable; bioIOT's KL-soft column anchoring restores identifiability while preserving the target composition constraint.
  • Exact implicit gradients. The forward solve is an Anderson-accelerated fixed-point iteration; gradients come from the implicit function theorem — numerically stable where unrolled backpropagation diverges.
  • Denoises finite-sampling noise. In a 50-replicate benchmark with 30 cells per state, bioIOT recovers the true transition matrix ~3× more accurately than using the observed transitions raw (mean per-row L1 0.013 vs 0.039), with feature-weight correlation 0.96.
  • Truly plug-and-play. numpy in, numpy out; inputs are validated and normalized automatically; one line to fit, one line to plot.

Installation

pip install bioIOT

Requires Python ≥ 3.10. Core dependencies: numpy, torch (CPU is fine). Optional: matplotlib for plots, anndata for the scanpy adapter.

From source
pip install git+https://github.com/XTSgreen/bioIOT-py.git

Quick start

import bioiot

# 1) Generate (or load) scenarios: phi (K, K, F) features, a/b (K,) masses,
#    T (K, K) observed row-conditional transitions
sim = bioiot.simulate_iot_states(K=6, seed=1)   # synthetic ground truth

# 2) Fit feature weights — multi-restart + two-stage debiasing, one line
model = bioiot.IOTModel().fit(sim["phi"], sim["a"], sim["b"], sim["T_true"])
model.theta_        # debiased coefficients
model.support_      # selected-feature mask

# 3) Trajectory layer
Q  = bioiot.transition_matrix(model)              # (K, K) transitions
pt = bioiot.pseudotime_from_transition(Q, root="S1")

# 4) Straight from cell-level data (embedding + cluster labels + 2 timepoints)
res = bioiot.run_iot(sim["cell_embedding"], sim["cell_state"],
                     from_mask=sim["cell_time"] == "t0",
                     to_mask=sim["cell_time"] == "t1",
                     root="S1")
res["Q"]; res["pseudotime"]
# AnnData/scanpy: bioiot.run_iot_adata(adata, "state", "time", "t0", "t1")

# 5) Plots (matplotlib)
ax = bioiot.plot_transition_heatmap(Q)
ax = bioiot.plot_transition_flow(Q, sim["embedding"], threshold=0.05)
ax = bioiot.plot_theta(model)

Functional core

For users who want the low-level solver (notation follows the paper):

C = bioiot.make_cost(phi, theta)                  # C = -einsum(phi, theta)
P = bioiot.soft_sinkhorn(C, a, b, mu=0.5, eps=1.0)  # (K, K) plan, P @ 1 = a
P = bioiot.uot_plan(phi, theta, a, b)             # cost + solve in one call
loss = bioiot.row_ce_loss([T], [P], [a])
phi_z, meta = bioiot.zscore_phi(phi)

soft_sinkhorn accepts numpy arrays or torch tensors; the returned plan is differentiable in C through exact implicit differentiation.

How it works

bioIOT solves

min_P  <C, P> − eps·H(P) + mu·KL(col(P) ‖ b)    s.t.  P·1 = a

with a hard source-side row marginal and a KL-anchored column marginal:

  • mu → ∞ recovers hard-marginal OT (pure column features unidentifiable);
  • mu → 0 recovers a plain row-softmax (no target-composition anchoring);
  • finite mu interpolates the two — the paper's working point is mu = 0.5, eps = 1.0, lam = 0.05.

Fitting (IOTModel, fit_iot) uses Adam with exact implicit gradients, l1 selection followed by a Bühlmann-style debias refit on the selected support, and multiple random restarts.

Testing

python -m unittest discover -s tests -v   # from the repository root
python -c "import bioiot; bioiot.self_test()"   # numerical self-check

Citation

If you use bioIOT, please cite:

@misc{dong2026bioiot,
  author       = {Dong, Han},
  title        = {bioIOT: Plug-and-Play Semi-Relaxed Inverse Optimal
                  Transport for Single-Cell State Transitions},
  year         = {2026},
  howpublished = {\url{https://github.com/XTSgreen/bioIOT-py}},
  note         = {Python package version 0.2.0}
}

License

MIT © 2026 Han Dong (XTSgreen)

Metadata

Release files for bioIOT 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bioIOT 0.2.1
File Size Uploaded
bioiot-0.2.1.tar.gz 24.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for bioIOT 0.2.1
File Interpreter ABI Platform
bioiot-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 50.0 kB

Release files / bioiot-0.2.1.tar.gz

Download URL bioiot-0.2.1.tar.gz
Size 24.7 kB
Tags Source
SHA-256 checksum
How to use checksums
9d1334004aac04c8074ea7f6b9bc7dd514afab95e42577911e38fa6f87deecd9
BLAKE2b-256 checksum
How to use checksums
c5dc8c3524c68d3b8dc22d91cec69564f5e3fb455d05487e0a5c5d68b420b449
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / bioiot-0.2.1-py3-none-any.whl

Download URL bioiot-0.2.1-py3-none-any.whl
Size 25.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
02c2bc3869883460bdc75ef85b61dec9e05310f961a2abd332dca617b4fe90e2
BLAKE2b-256 checksum
How to use checksums
b5714f3cb0a1dae2c9561c69c556b9948d98f5133a45e4ee3e3ceced9eecdf6f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page