Skip to main content

gpmap-v2

CI Documentation PyPI Python License Streamlit App

Live interactive tour: gpmap-v2.streamlit.app (source under examples/streamlit/).

A typed, Rust-accelerated container and simulator toolkit for genotype-phenotype maps.

gpmap-v2 is a clean-break rewrite of harmslab/gpmap. It exposes the same conceptual model (a GenotypePhenotypeMap backed by a pandas DataFrame) with a locked schema, vectorized hot paths, and a PyO3 Rust core for the operations that used to be inner Python loops.

An L=4 biallelic genotype-phenotype map drawn as a hypercube laid out by Hamming distance, nodes colored by phenotype

Why

  • Fast. String-encoded genotypes are replaced with packed uint8 matrices. The encoding step (genotypes_to_binary) runs rayon-parallel in Rust. Construction is 5x faster than v1 at L=16 (65k genotypes), and binary_packed is a free cached lookup afterward -- no repeated re-encoding on each access.
  • Typed. Full type hints, mypy-checked, strict mode.
  • Safe. Cartesian-product enumeration is size-guarded out of the box (SpaceTooLargeError). No more silent 10^26 allocations.
  • Stable surface. The container and encoding_table schema are locked in SCHEMA.md for downstream consumers.
  • Modern tooling. uv + maturin + pyproject.toml. Automated releases via python-semantic-release. OIDC-based PyPI publishing.

Install

pip install gpmap-v2

Or with uv:

uv add gpmap-v2

Python 3.10+. Prebuilt wheels ship for Linux (x86_64, aarch64), macOS (x86_64, aarch64), and Windows (x64).

Quick start

from gpmap import GenotypePhenotypeMap

gpm = GenotypePhenotypeMap(
    wildtype="AAA",
    genotypes=["AAA", "AAT", "ATA", "TAA", "ATT", "TAT", "TTA", "TTT"],
    phenotypes=[0.1, 0.2, 0.2, 0.6, 0.4, 0.6, 1.0, 1.1],
    stdeviations=[0.05] * 8,
)

gpm.genotypes        # np.ndarray of strings, shape (8,)
gpm.phenotypes       # np.ndarray[float64], shape (8,)
gpm.binary_packed    # np.ndarray[uint8], shape (8, 3) - the fast path
gpm.binary           # np.ndarray of '0'/'1' strings - back-compat accessor
gpm.n_mutations      # per-genotype Hamming weight
gpm.encoding_table   # pandas DataFrame per SCHEMA.md
gpm.data             # pandas DataFrame view for Jupyter

Simulating landscapes

from gpmap.simulate import NKSimulation, MountFujiSimulation
import numpy as np

sim = NKSimulation(
    wildtype="AAAA",
    mutations={i: ["A", "T"] for i in range(4)},
    K=2,
    rng=np.random.default_rng(0),
)
sim.phenotypes.shape  # (16,)

I/O round-trips

from gpmap import to_json, read_json, to_csv, read_csv

to_json(gpm, "map.json")
gpm2 = read_json("map.json")

to_csv(gpm, "map.csv")   # writes map.csv + map.csv.meta.json
gpm3 = read_csv("map.csv")

Public API surface

The full list of stable exports lives in gpmap.__all__. The ones downstream consumers depend on (notably epistasis-v2) are:

  • GenotypePhenotypeMap, GenotypePhenotypeMap.from_dataframe
  • get_encoding_table, genotypes_to_binary, genotypes_to_binary_packed
  • upper_transform, lower_transform
  • StandardDeviationMap, StandardErrorMap
  • SpaceTooLargeError, SchemaError, UnknownLetterError
  • read_csv, read_json, read_pickle, read_excel (and to_* counterparts)
  • All simulators under gpmap.simulate

The load-bearing schema contract (column names, dtypes, invariants) is in SCHEMA.md. Breaking changes to that document bump the major version.

Benchmarks vs v1

Measured on Windows 11 against gpmap==0.7.0. Full biallelic space (AT alphabet), timeit best-of-5. See benchmarks/vs_v1.py for scripts and setup.

v2 encodes eagerly at construction (Rust, parallel). v1 encodes lazily, so construction is cheaper but binary access costs extra on every call. The table below times construction including encoding for v2 and just object setup for v1.

L genotypes v1 construct (ms) v2 construct (ms) speedup
8 256 2.14 6.23 0.3x
10 1,024 4.48 7.99 0.6x
12 4,096 14.57 10.53 1.4x
14 16,384 59.30 18.68 3.2x
16 65,536 258.18 51.19 5.0x

binary_packed access after construction: v2 ~0 ms (cached); v1 binary access at L=16 costs ~11 ms per call (re-encoded each time from the underlying pandas column).

Development

git clone https://github.com/lperezmo/gpmap-v2
cd gpmap-v2
uv sync
uv run maturin develop --release
uv run pytest
uv run ruff check python/gpmap tests

A typical dev inner loop after editing Rust:

uv run maturin develop --release && uv run pytest

Consuming from another local project

gpmap-v2 is designed to be consumed as an editable dependency during co-development with sister packages (e.g. epistasis-v2). In the consumer's pyproject.toml:

[tool.uv.sources]
gpmap-v2 = { path = "/absolute/path/to/gpmap-v2", editable = true }

[project]
dependencies = ["gpmap-v2"]

Then uv sync or uv add gpmap-v2 in the consumer. Imports remain import gpmap.

Migration from v1 (harmslab/gpmap)

gpmap-v2 is not wire-compatible with v1. Key differences:

  • Distribution name is gpmap-v2 on PyPI; import path is still gpmap.
  • The encoding_table column genotype_index has been renamed to site_index to match its actual meaning. The old name is still readable via a deprecated alias.
  • read_dataframe is now from_dataframe.
  • binary_packed (uint8 2D) is exposed alongside the string-form binary. Prefer the packed form for any hot-path consumer.
  • JSON files must carry "schema_version": "1". Legacy files are readable with a warning.
  • upper_transform and lower_transform are now genuinely distinct (v1 had a copy-paste bug where they were identical).
  • stats.unbiased_var honors the axis kwarg (v1 ignored it and hardcoded axis=1).
  • simulate.random_mutation_set no longer mutates the module-level amino-acid list.
  • simulate.MultiPeakMountFujiSimulation peak search has a retry cap; it raises instead of spinning forever on infeasible constraints.

See CHANGELOG.md for the full list.

Releases

Releases are driven by python-semantic-release on merge to main. Commit messages follow Conventional Commits:

  • fix: ... -> patch
  • feat: ... -> minor
  • feat!: ... or BREAKING CHANGE: footer -> major

CHANGELOG.md, version bumps, Git tags, GitHub Releases, wheel builds, and PyPI uploads all happen automatically.

License

MIT. See LICENSE.

Metadata

Release files for gpmap-v2 1.0.2

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

Source distribution (sdist)

Source distribution for gpmap-v2 1.0.2
File Size Uploaded
gpmap_v2-1.0.2.tar.gz 25.6 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for gpmap-v2 1.0.2
File
gpmap_v2-1.0.2-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details
gpmap_v2-1.0.2-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.10 abi3 Linux glibc 2.17+ x86-64 Details
gpmap_v2-1.0.2-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.10 abi3 Linux glibc 2.17+ ARM64 Details
gpmap_v2-1.0.2-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details
gpmap_v2-1.0.2-cp310-abi3-macosx_10_12_x86_64.whl CPython 3.10 abi3 macOS 10.12+ x86-64 Details

Total release size: 1.8 MB

Release files / gpmap_v2-1.0.2.tar.gz

Download URL gpmap_v2-1.0.2.tar.gz
Size 25.6 kB
Tags Source
SHA-256 checksum
How to use checksums
6e56ce890a431bcfaacb4313b7b1869a09b34376bae5909685ed829e4641816e
BLAKE2b-256 checksum
How to use checksums
10e5c7156608d3136b5954676e702d76ba75e894f7994d21a8ed0e856ace398e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / gpmap_v2-1.0.2-cp310-abi3-win_amd64.whl

Download URL gpmap_v2-1.0.2-cp310-abi3-win_amd64.whl
Size 232.4 kB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
2e4cb6c153fa69ba25d094fa4d607098f32c37c92655b541a67cfffdbf724c9d
BLAKE2b-256 checksum
How to use checksums
c08553a6154ceedd93c523a3493e0784431c623b75b7a6053387787d21895454
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / gpmap_v2-1.0.2-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL gpmap_v2-1.0.2-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 408.0 kB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
33584c4deeea18a4294be051d1bc4a69a68b8ce7069ae68d28657917aae8469f
BLAKE2b-256 checksum
How to use checksums
22c6e3589245a176241a5c5d5408dcde8c234d4754cc328d5220c83aa611b573
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / gpmap_v2-1.0.2-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL gpmap_v2-1.0.2-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 400.7 kB
Tags CPython 3.10 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
b2776aaaf33153c3ed604b9b93c1b5a4783bb5fa0e07d37cc920ad6e5aec7f9d
BLAKE2b-256 checksum
How to use checksums
e468f80c11da58f846271a24fbf22baa1cf3ff77d3f58c5cf19428159bc20ffc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / gpmap_v2-1.0.2-cp310-abi3-macosx_11_0_arm64.whl

Download URL gpmap_v2-1.0.2-cp310-abi3-macosx_11_0_arm64.whl
Size 356.7 kB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
5bc2ba03a530171ca67392b513f28d652d5e92e2ffe3af806d29e01b1adba3ca
BLAKE2b-256 checksum
How to use checksums
ece1fe4def3bd98bb03c02622ba0e5842e41c3f4774ce6adf4e29ae1e023b90d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / gpmap_v2-1.0.2-cp310-abi3-macosx_10_12_x86_64.whl

Download URL gpmap_v2-1.0.2-cp310-abi3-macosx_10_12_x86_64.whl
Size 354.5 kB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
5e9417afe22c0df4ebe37b28239eafd5e92c082336ced36dcd9dc484a4efa955
BLAKE2b-256 checksum
How to use checksums
e2d3f45b20c7fa407c4099e8e80e510c0273f1de1d9c23cae80650a60b732b0f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

1.0.2 This release

6 release files

1.0.1

6 release files

1.0.0

6 release files

0.0.1

6 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