multiverse_cache
Download, cache, and read the reference resources used by the M-PACT pipeline. Three kinds of resource are managed through one machine-level cache:
- genomes — genome "info" packages (from
kylessmith/<genome>_infoon GitHub) - datasets — Zenodo data records (e.g. methylation annotation parquet tables)
- models — Zenodo model records (e.g. M-PACT
.pthcheckpoints) - sturgeon — Sturgeon CNS classifier models (zip archives, from the Sturgeon project)
Nothing is written into the installed package directory. Everything lands in a per-machine cache created on first use and reused thereafter.
Cache location
Resolved in priority order:
- an explicit
cache_dir=argument - the
MULTIVERSE_CACHEenvironment variable $XDG_CACHE_HOME/multiverse_cache~/.cache/multiverse_cache
On a cluster, point it at scratch to avoid $HOME quotas:
export MULTIVERSE_CACHE=/scratch/$USER/multiverse_cache
Layout:
<root>/
base/<genome>.pickle # genome info manifest
data/<genome>/... # genome info data + external/
datasets/<name>/... # Zenodo datasets (e.g. methyl_anno)
models/<name>/... # Zenodo models (e.g. MPACT)
sturgeon/<name>/<model>.zip # Sturgeon models (kept zipped, never unpacked)
<name>/.complete # per-resource completion marker
<key>.lock # advisory download lock
Usage
Genome info (unchanged API)
from multiverse_cache import InfoReader
info = InfoReader("hg38") # downloads once, cached after
frame = info["some_key"]
Datasets (replaces import_data / download_data)
from multiverse_cache import get_data_file, download_dataset, list_data_files
download_dataset("methyl_anno") # explicit prefetch (optional)
path = get_data_file("some.parquet") # auto-downloads methyl_anno, returns path
files = list_data_files("methyl_anno")
get_data_file(filename) is the cache-aware drop-in for the old function: it
ensures the dataset is present, then locates the file inside the cache. Pass
dataset=None to search across all cached datasets without downloading.
Models (new)
from multiverse_cache import download_models, list_models, get_model_file, load_model
download_models("MPACT") # explicit prefetch (optional)
list_models("MPACT") # -> [".../MPACT_classifier.pth", ...]
ckpt = load_model("MPACT_classifier.pth") # torch.load(map_location="cpu") -> object
path = get_model_file("MPACT*.pth") # just the path, no load
load_model lazily imports torch and defaults to map_location="cpu" so a
checkpoint trained on H100s loads on a login node before you move it to a
device. weights_only defaults to False (trusted first-party checkpoints
that bundle config/objects); set True for untrusted files.
Sturgeon CNS models (new)
Sturgeon (Vermeulen, Pagès-Gallego, Kester et al., Nature 2023) ships each CNS classifier as a zip holding an ONNX network plus probe/decoding/calibration tables. The zip is the unit of distribution and is opened as-is by Sturgeon's own loader, so it is cached intact and never unpacked.
Licensing. Sturgeon is distributed under an Evaluation Software License Agreement (Oncode/Cyclomics/UMCU), not an open-source licence: academic research only, no derivative works / reimplementation, and clinical/diagnostic use needs a separate commercial licence (
software@cyclomics.com); publishing results requires referral to the source. This package therefore drives the genuine Sturgeon package — it does not vendor or reimplement Sturgeon's prediction code.
from multiverse_cache import (
list_sturgeon, download_sturgeon, get_sturgeon_model_file, predict_sturgeon,
)
list_sturgeon() # -> ['brainstem', 'general']
# Path-only access (no extra deps): hand this to the sturgeon CLI / loader
zip_path = get_sturgeon_model_file("general")
Predicting (recommended: isolated, zero env impact)
Sturgeon's released code needs pandas<2.2, numpy<2, an old onnxruntime,
and matplotlib — versions that usually clash with a modern torch/Mamba stack.
predict_sturgeon sidesteps that by building a dedicated venv under the cache
(once), installing the genuine Sturgeon + compatible deps into it, and running
Sturgeon's own predict CLI there. Your main environment is never modified.
# bed = output of `sturgeon inputtobed` (T2T/CHM13v2-aligned methylation calls)
scores = predict_sturgeon("sample.bed", model="general") # first call builds the venv
# -> {"sample": <per-class score DataFrame>}
Interpreter requirement. Those pinned deps only ship wheels for Python 3.9–3.12. The venv is built from such an interpreter, resolved in order:
python_executable=/$MULTIVERSE_STURGEON_PYTHON→ the current interpreter if it qualifies → the newestpython3.XonPATH→ a conda/mamba env.So if your session is Python 3.13/3.14 (e.g. a bleeding-edge mamba env) and no
python3.Xis onPATH,predict_sturgeonwill, by default, reuse a conda env namedsturgeonor create one automatically:mamba create -y -n sturgeon python=3.10 # run for you (mamba/micromamba/conda)This assumes a conda/mamba tool is installed (it picks
mamba→micromamba→conda). Controls:
predict_sturgeon(..., auto_conda=False)disables the auto-create (you'll get a clear error instead);sturgeon_env_python(conda_env=..., conda_python=...)change the env name / Python version;python_executable=...orexport MULTIVERSE_STURGEON_PYTHON=...pin a specific interpreter and skip discovery entirely (recommended for reproducible cluster runs).(Without a compatible interpreter, pip would try to compile pandas 2.1.x from source and fail against the newer CPython C-API — which is the error you hit on a 3.14 env.)
sturgeon_env_python(python_executable=...) builds/returns that venv's
interpreter directly, and predict_sturgeon(..., env_python=...) lets you point
at a conda env where you already have a compatible Sturgeon.
In-process loading (only on an already-compatible env)
If this environment already satisfies Sturgeon's pins, you can load the ONNX session in-process:
from multiverse_cache import load_sturgeon, install_sturgeon
install_sturgeon() # pip-installs genuine sturgeon into THIS env
model = load_sturgeon("general") # or load_sturgeon("general", auto_install=True)
df = model.predict("sample.bed")
install_sturgeon() installs the package unmodified with
--no-deps --ignore-requires-python (so it won't downgrade your numpy/pandas),
but prediction will still fail here if this env has pandas>=2.2 / numpy>=2
— hence the isolated route above is preferred. download_sturgeon(..., install=True)
fetches the model and installs Sturgeon in one call.
The models are hosted on Dropbox; ?dl=0 share links are normalised to
?dl=1 automatically. If those links rot, re-register the resource with new
files (see below).
To add a Sturgeon model from your own URL:
from multiverse_cache import register, Resource, STURGEON
register(Resource(name="sturgeon_custom", category=STURGEON, source="url",
extract=False,
files=(("custom.zip", "https://host/custom.zip"),)))
predict_sturgeon("sample.bed", model="custom")
MARLIN acute-leukemia classifier (Python/ONNX, no R)
MARLIN (Steinicke, Benfatto et al.,
Nature Genetics 2025, MIT-licensed) classifies acute leukemia from sparse
methylation profiles with a Keras network. MARLIN ships an R prediction script,
but this plugin needs no R: the trained model is converted from Keras HDF5
to ONNX once (in a throwaway TensorFlow env that is then discarded) and run
with onnxruntime, exactly like the Sturgeon runtime. The reference probe order
(an .RData) is read with pyreadr and the class table (.xlsx) with pandas.
from multiverse_cache import predict_marlin
# bed: chrom start end methylation(0-1 or NA) probe (e.g. modkit pileup
# intersected with the MARLIN probe coordinates)
scores = predict_marlin("sample.bed") # first call: download + one-time convert
# -> DataFrame: samples (rows) x 42 methylation classes (cols), softmax probs
Runtime dependencies are pure Python: pip install "multiverse_cache[marlin]"
(onnxruntime, pyreadr, openpyxl). The one-time HDF5→ONNX conversion
needs TensorFlow + tf2onnx; rather than touch your environment, it builds a
temporary venv from a 3.9–3.11 interpreter (TF 2.13's wheel range), converts,
caches marlin_v1.model.onnx, and deletes the temp env. If your session is
outside 3.9–3.11 it uses the same conda/mamba fallback as Sturgeon
(predict_marlin(..., auto_conda=...), python_executable=..., or
$MULTIVERSE_MARLIN_PYTHON). Pass keep_convert_env=True to keep the TF env
for re-conversion.
Acquisition splits across sources automatically: the model HDF5 from Zenodo
(marlin_model) and the probe/annotation files from GitHub (marlin_refs).
from multiverse_cache import download_marlin, load_marlin
download_marlin() # prefetch model + refs (optional)
model = load_marlin() # convert-if-needed + onnxruntime session
df = model.predict("beds/") # a directory of beds, one sample each
Registering more resources
from multiverse_cache import register, Resource, MODELS, DATASETS
register(Resource(name="MPACT_v2", category=MODELS, record_id="12345678",
description="next M-PACT checkpoints"))
load_model("MPACT_v2_classifier.pth", name="MPACT_v2")
Managing the cache
from multiverse_cache import MultiverseCache
cache = MultiverseCache("/scratch/me/multiverse_cache")
cache.list_genomes() # downloaded genome-info packages
cache.list_resources("models") # downloaded models
cache.list_resources("datasets") # downloaded datasets
cache.remove_resource("models", "MPACT")
cache.clear()
Behavior notes
- Atomic downloads — every file streams to a
.parttemp and is renamed into place only on success; checksums from Zenodo are verified before rename. - Completion markers — a resource is only "ready" once
.completeexists, so a half-finished download is re-fetched rather than read. - Concurrency — downloads take a per-resource
flock, so an LSF/SLURM array all requesting the same genome/dataset/model fetches it once; the rest wait. - Extension-aware extraction — archives are unpacked by extension
(
.zip,.tar,.tar.gz/.tgz,.gz); everything else (.parquet,.pth,.npz, ...) is left intact. This fixes a bug in the original loader, which force-extracted every download as a zip and would corrupt a torch.pthcheckpoint (those are themselves zip archives). A resource can also setextract=Falseto keep its archives whole even when they end in.zip— used for Sturgeon model zips, which their own loader opens withzipfile.ZipFile. - Multiple sources — a resource's
sourceis either"zenodo"(files, sizes and checksums discovered from a record) or"url"(explicit(filename, url)pairs, e.g. Dropbox-hosted Sturgeon models). - Source accounts/records: genome info from
REPO_USERindownload.py; dataset/model records inregistry.py.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file multiverse_cache-0.2.0.tar.gz.
File metadata
- Download URL: multiverse_cache-0.2.0.tar.gz
- Upload date:
- Size: 38.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
poetry/2.2.1 CPython/3.13.9 Darwin/25.6.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
818b09426e1785d1b92b5bfe074c22feaa5f44585046c6935df7daf24e66f39f
|
|
| MD5 |
aa47144d1cfbfd0b821d03f751dc711f
|
|
| BLAKE2b-256 |
005d385e20798f25f372408ca082f6a2b947e7e37eeb2dd2b64ce8625e90ab06
|
File details
Details for the file multiverse_cache-0.2.0-py3-none-any.whl.
File metadata
- Download URL: multiverse_cache-0.2.0-py3-none-any.whl
- Upload date:
- Size: 41.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
poetry/2.2.1 CPython/3.13.9 Darwin/25.6.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6c06d6469ea5463ebd1a17a5d53675d8229f971dd5bfed6d85fdb896e4188102
|
|
| MD5 |
fb3dfb649528dc677ffb6a368bc4cc47
|
|
| BLAKE2b-256 |
fa55f0d9c8b7552538aa92e443ad3795afcbadeacf4d680a67b271f57210923e
|