Skip to main content

engin-core

Open toolkit for fermentation scale-up: a mechanistic fed-batch simulator, a Gaussian-process titer model with conformally calibrated uncertainty, an active-learning next-batch recommender, and reproducible benchmarks. Built on mature libraries — scipy (integration), scikit-learn (GP), MAPIE (conformal) — with only the domain models hand-written.

Part of the engin-suite strain-to-scale monorepo.

Why

Most bioprocess optimizers give point predictions or intervals that quietly lie. The trap is easy to fall into: form a 90% interval from the model's uncertainty alone and assume normality, and it covers only ~55% of held-out runs — badly overconfident. engin-core forecasts titer with honest coverage and recommends the runs worth doing next.

Calibrated uncertainty is the whole point of the wedge: a scale-up decision needs P(hit $/kg target), not a number with no error bar.

Install

Not published to PyPI yet — pip install engin-core will not find anything. Install from a checkout of the monorepo:

git clone https://github.com/enginbio/engin-suite
cd engin-suite
pip install -e "packages/engin-core[dev]"

Quickstart

import numpy as np
from engin_core import (
    simulate_unit, fit_gp, split_conformal_multiplier,
    recommend_batch, ard_importance, unit_to_physical,
)

rng = np.random.default_rng(0)
U = rng.random((120, 5))                       # unit-cube DoE (5 design knobs)
y = simulate_unit(U)                            # titer (g/L) from the simulator

tr, ca, te = slice(0, 70), slice(70, 100), slice(100, 120)
gp = fit_gp(U[tr], y[tr])                        # fit the GP titer model

# Calibrate a 90% interval on a held-out set (split conformal):
mc, sdc = gp.predict(U[ca])
q90 = split_conformal_multiplier(y[ca], mc, sdc, level=0.90)

mean, sd = gp.predict(U[te])                     # forecast: mean ± q90*sd is a 90% PI
X_next, m_next, sd_next, ei = recommend_batch(gp, float(y[tr].max()), k=8)
print("recommended next runs (physical units):\n", unit_to_physical(X_next))
print("titer drivers (ARD):", np.round(ard_importance(gp), 2))

Running this in a loop? recommend_batch draws a fresh candidate pool on each call, because seed defaults to None (ADR 0011). Pass seed=<int> when you want a bit-reproducible recommendation — but pass a different one each round, not a fixed one, or every round searches the same fixed set of candidate points and the campaign converges to the best point in that set rather than the best design.

Full end-to-end demo (writes plots, a DoE CSV, and a DoE round-reduction memo):

python examples/run_demo.py

What's in the box

Module What it does
engin_core.simulator Fed-batch Monod/Luedeking-Piret bioreactor with product inhibition — a non-monotonic titer landscape with a real interior optimum. Bespoke equations, integrated by scipy solve_ivp (piecewise across the feed/induction switches). 5 knobs: feed_rate, feed_start, Sf, induction_time, S0.
engin_core.gp scikit-learn ARD-RBF Gaussian Process + split-conformal (heteroscedastic, sd-scaled) and MAPIE-backed interval calibration + prob_at_least.
engin_core.recommend Expected-Improvement next-batch recommender with a diversity filter.
engin_core.sensitivity ARD inverse-lengthscale sensitivity — which knobs actually move titer.

The calibration story (why conformal)

A raw GP interval is overconfident here because a space-filling DoE is "easier" than the future query points the model is asked about (covariate shift), and the epistemic sd ignores observation noise entirely. Split-conformal calibrates the interval multiplier on a same-distribution held-out set using the finite-sample conformal quantile — distribution-free, no normality assumption. The score is the classical normalized nonconformity measure of Papadopoulos, Gammerman and Vovk — |y − ŷ| / σ, with σ taken from the model's own predictive sd — and the multiplier form keeps intervals riding the GP's per-point sd.

This is related to, but not the same as, MAPIE's ResidualNormalisedScore, which estimates σ with a separate learned model fitted to log-residuals. Normalizing by the GP's own sd needs no second model, which matters at the sample sizes this targets.

Reproduce (python benchmarks/benchmark.py, mean over 20 seeds):

90% interval built from… Coverage (target 0.90)
epistemic-only, Gaussian ×1.645 0.59 — naive, overconfident (seed-dependent; read as ~0.55–0.62)
total (model + noise), Gaussian ×1.645 0.86 — assumes normality, drifts per seed
total, split-conformal ×q90 0.96 — honest

Benchmarks

python benchmarks/benchmark.py (mean over 20 seeds, held-out):

  • Forecast: RMSE ≈ 3.8 g/L, R² ≈ 0.96.
  • Calibration: see table above.
  • Active-learning lift (best true titer of an 8-run batch vs the best true titer in the initial DoE): EI ≈ +18% vs random ≈ −23% — one recommended batch moves the frontier; a random batch does not.

The single-seed examples/run_demo.py slice: R² 0.97, RMSE ~4 g/L, feed_rate the dominant driver, and one active-learning round lifting best titer +28% (86→110 g/L).

Development

pip install -e ".[dev]"
pytest            # tests
ruff check .      # lint

License

Apache-2.0. Patent grant included, matching the BayBE/BioSTEAM ecosystem.

Metadata

Release files for engin-core 0.1.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 engin-core 0.1.1
File Size Uploaded
engin_core-0.1.1.tar.gz 126.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for engin-core 0.1.1
File Interpreter ABI Platform
engin_core-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 215.3 kB

Release files / engin_core-0.1.1.tar.gz

Download URL engin_core-0.1.1.tar.gz
Size 126.3 kB
Tags Source
SHA-256 checksum
How to use checksums
354734760ee056759a397a7afc3f5ee09740c9f88213ffe2767b64b6e3c132b0
BLAKE2b-256 checksum
How to use checksums
5a1d8856963963d2df8fe7a726e3c0f866ba63bd80d28dbb0794c2e1ffa21c8e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.

Transparency log

Release files / engin_core-0.1.1-py3-none-any.whl

Download URL engin_core-0.1.1-py3-none-any.whl
Size 88.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
eaaef8bc90976105daa62c2132338c71854cbaa0f8e67ff42d075bb28a2c6930
BLAKE2b-256 checksum
How to use checksums
377ff818f04e3fa489c9d9178d535002618f475f120cb551e2fd482424bd443d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.1 This release

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