Linear-programming–based optimization of microbial growth media under elemental stoichiometric constraints.
Project description
OptiThor
OptiThor is a Python package for linear-programming–based optimization of microbial growth media under elemental stoichiometric constraints.
Given:
- a set of candidate compounds (identified by PubChem CIDs),
- elemental growth requirements (e.g. C, N, P, S),
- and a target biomass yield,
OptiThor computes the optimal compound concentrations that satisfy elemental requirements while minimizing total compound mass.
The package ships with a pre-built compound database derived from PubChem, so no external data preparation is required for most use cases.
Installation
pip install optithor
Python requirement: ≥ 3.10
Quick start (minimal example)
from optithor import CompoundDb, optimize_medium
from optithor.types import ElementRequirement, MediumOptimizationInput
repo = CompoundDb()
compound_cids = [
"57429219",
"5284359",
"24643",
"61482",
]
required_elements = {
"C": ElementRequirement(reference_yield_g_cdw_per_g=1.0, excess_factor=1.0),
"N": ElementRequirement(reference_yield_g_cdw_per_g=8.0, excess_factor=3.0),
"P": ElementRequirement(reference_yield_g_cdw_per_g=33.0, excess_factor=5.0),
}
medium_input = MediumOptimizationInput(
compound_cids=compound_cids,
required_elements=required_elements,
max_dry_biomass_g_per_l=10.0,
)
result = optimize_medium(
medium_input=medium_input,
compound_repository=repo,
)
if not result.success:
raise RuntimeError(result.message)
print(result.solution)
Understanding the results
Running the basic example produces three main outputs:
(1) selected compounds, (2) optimized compound concentrations, and (3) elemental validation.
Selected compounds
The first table lists the compounds found in the local database:
- Confirms that all requested PubChem CIDs exist in the database
- Shows the molecular formula and molar mass used internally
- If a CID is missing, it is reported explicitly
Compounds results table
The compounds results table shows the optimized medium composition.
Key columns:
- Obtained Compound Concentration: the optimal amount of each compound
- Unit: concentrations are automatically reported in sensible units (g/L, mg/L, µg/L)
- Values satisfy all elemental constraints while minimizing total compound mass
Important notes:
- Some compounds appear at very low concentrations because they supply trace elements
- Major nutrients (e.g. carbon or nitrogen sources) appear at higher concentrations
- The solution is a mathematical optimum, not a validated experimental recipe
Element validation table
The element validation table verifies that elemental requirements are met.
Key columns:
- Reference Elemental Growth Yield: biological assumption (g CDW per g element)
- Excess Factor: safety margin applied to the requirement
- Required Element Mass: target elemental amount after applying excess
- Obtained Element Mass: elemental mass supplied by the optimized medium
- Match (%): agreement between required and obtained values
A match of 100% indicates that the solver satisfied the constraint exactly (within numerical tolerance).
Core concepts
Compound database
OptiThor ships with a pre-generated compound database containing molecular formulas, molar masses, elemental composition, and hydrate handling.
The database is accessed via:
from optithor import CompoundDb
repo = CompoundDb()
Cache behavior
- On first use, the packaged database (shipped in the wheel) is copied into a user-writable local cache
- Subsequent runs read from this local cache
- No network access occurs by default
If needed, the local cache can be reset to the packaged database:
repo.load(force_reload=True)
This overwrites the local cache using the database shipped in the installed wheel.
PubChem CIDs
Compounds are referenced using PubChem Compound IDs (CIDs) provided as strings:
compound_cids = ["5793", "4873", "62640"]
Elemental requirements
Elemental constraints are defined using ElementRequirement:
ElementRequirement(
reference_yield_g_cdw_per_g=..., # grams CDW per gram of element
excess_factor=..., # oversupply safety factor
)
These parameters are biological assumptions and must be adapted to the organism and growth model.
Optimization model
The optimization problem is solved using linear programming and aims to:
- satisfy elemental requirements,
- respect compound availability,
- minimize total compound mass.
Solver behavior can be customized, but default settings are suitable for most use cases.
Inspecting compound availability
To see which requested compounds exist in the local database:
from optithor.reports import build_selected_cids_table
df = build_selected_cids_table(
compound_repository=repo,
compound_cids=compound_cids,
force_reload=False,
)
print(df)
This operation is offline and uses the local cache.
Advanced usage
Fetching missing compounds from PubChem
To explicitly allow network access and fetch missing compounds from PubChem:
df = repo.get_compounds_by_cids(
compound_cids,
fetch_missing=True,
update_cache=True,
)
Fetched compounds are optionally written back into the local cache.
⚠️ PubChem is never accessed unless explicitly requested.
Diagnostics and reporting tables
from optithor.reports import build_optimization_tables
tables = build_optimization_tables(
medium_input=medium_input,
result=result,
compound_repository=repo,
decimals=2,
)
tables.compounds
tables.elements
Returned objects are Pandas DataFrames and can be exported or plotted.
Assumptions and limitations
- Elemental formulas are parsed using simplified chemical rules
- Hydrates are handled via an anhydrous-equivalent representation
- Optimization assumes linear, additive stoichiometry
- Biological yield parameters must be provided by the user
OptiThor is intended as a design and exploration tool, not a substitute for experimental validation.
Project structure
src/optithor/ # Core OptiThor package (runtime code)
resources/ # Packaged compound database (Parquet)
examples/ # Usage examples (basic + advanced)
tests/ # Test suite (pytest)
compound_db_builder/ # Database construction pipeline (for transparency)
pyproject.toml
README.md
LICENSE
The compound_db_builder/ directory documents how the packaged compound
database was generated and curated. It is not required for normal usage
of OptiThor and is not used at runtime, but is included for transparency
and reproducibility.
Contributing
Contributions are welcome.
If you would like to:
- report a bug,
- suggest an improvement,
- add new features,
- improve documentation or examples,
please open an issue or a pull request on GitHub.
Before contributing code, please read the contribution guidelines: https://github.com/harounbensaadi/optithor/blob/main/CONTRIBUTING.md
License
MIT License
Project details
Release history Release notifications | RSS feed
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 optithor-0.1.0.tar.gz.
File metadata
- Download URL: optithor-0.1.0.tar.gz
- Upload date:
- Size: 33.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
78741f9489f194ef61fdd5ffb52ef0010a3a70f8102a6b35f8045a96d2b2c219
|
|
| MD5 |
eff4f4db092ab4060f450bf53197f269
|
|
| BLAKE2b-256 |
abae8a747e0b23097f832be06c56d50831e324ea6587c0587c077d255e2f464e
|
File details
Details for the file optithor-0.1.0-py3-none-any.whl.
File metadata
- Download URL: optithor-0.1.0-py3-none-any.whl
- Upload date:
- Size: 36.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
934ead031f29c03336b70483576ee2b220375a16ff22b553f576232143ddc759
|
|
| MD5 |
2b3a3aa61c4ba9ec26aeeb02c5576a36
|
|
| BLAKE2b-256 |
b4de37232e26a888b22797492f739da34d4441776e7ebbc4433c367250facf44
|