Make configurable change to define reaction flux bounds in metabolism.py#438
Make configurable change to define reaction flux bounds in metabolism.py#438heenasaqib wants to merge 3 commits into
Conversation
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
There was a problem hiding this comment.
Pull request overview
This PR adds a configuration hook to the Metabolism process so simulations/tests can override specific FBA reaction flux bounds from the process config, enabling targeted constraint experiments without modifying code.
Changes:
- Added a new
set_reaction_boundsconfig field inMetabolism.PARAMETERS. - Applied config-provided reaction flux bounds during
Metabolism.next_update()by callingfba.setReactionFluxBounds(...).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "linked_metabolites": None, | ||
| "aa_exchange_names": [], | ||
| "removed_aa_uptake": [], | ||
| "set_reaction_bounds": {}, # In form: {RXN_ID:[lb,ub]} |
🔍 Vulnerabilities of
|
| digest | sha256:62998ad36772672e64adc54b007f61ce71ce0aa83797c00b9f849d0ce8f8361d |
| vulnerabilities | |
| platform | linux/amd64 |
| size | 975 MB |
| packages | 904 |
📦 Base Image debian:13-slim
| also known as |
|
| digest | sha256:486b1c3d3a6a836d2518d5ac1a7b522050a034ae83b47c063fd45d550b2b9dbf |
| vulnerabilities |
Description
Description
Description
Description
Description
Description
Description
Description
Description
Description
Description
Description
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
Description
Description
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
Description
Description
Description
Description
Description
Description
Description
Description
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
Description
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
|
Robotato
left a comment
There was a problem hiding this comment.
Agreed with the Copilot comments, otherwise LGTM!
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
ecoli/processes/metabolism.py:98
- The inline config doc for
set_reaction_boundsis ambiguous about what reaction IDs and bound values are valid. In this codebase,FluxBalanceAnalysis.setReactionFluxBoundsrejects negative bounds, and reversible reactions are represented as separate forward/reverse reaction IDs, so callers need that guidance to avoid confusing runtime errors.
"set_reaction_bounds": {}, # In form: {RXN_ID:[lb,ub]}
ecoli/processes/metabolism.py:538
set_reaction_boundsis used as a mapping without validating its type; if a user sets it tonull/Noneor another non-mapping value, this will raise an unhelpful AttributeError at.items(). Also,FluxBalanceAnalysis.setReactionFluxBoundsrejects negative bounds; validating here lets you raise a clearer error that includes the reaction ID and the provided bounds.
# Set reaction limits from config options
config_reaction_bounds = self.parameters.get("set_reaction_bounds", {})
for rxn, bounds in config_reaction_bounds.items():
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
ecoli/processes/metabolism.py:98
- The config comment for
set_reaction_boundsdoesn’t specify the expected units/constraints. In this FBA implementation, flux bounds are non-negative (forward/reverse handled separately) and are in the same units passed tosetReactionFluxBounds(CONC_UNITS). Clarifying this here will help prevent misconfigured bounds.
"set_reaction_bounds": {}, # In form: {FBA_RXN_ID:[lb,ub]} (reaction must match FBA basis)
| sim = EcoliSim.from_file() | ||
| sim.max_duration = 2 | ||
| sim.build_ecoli() | ||
|
|
||
| metabolism = sim.ecoli.processes["agents"]["0"]["ecoli-metabolism"] | ||
|
|
||
| # test invalid configuration: reaction not in FBA reaction IDs | ||
| metabolism.parameters["set_reaction_bounds"] = {"NOT-A-REAL-RXN": [0, 1]} | ||
| with pytest.raises(ValueError, match="not found in FBA reaction IDs"): | ||
| sim.run() | ||
|
|
||
| # test valid configuration | ||
| rxn_id = metabolism.fba_reaction_ids[0] | ||
| metabolism.parameters["set_reaction_bounds"] = {rxn_id: [0.0, 0.0]} | ||
| sim.run() | ||
| data = sim.query() | ||
| reaction_fluxes = data["agents"]["0"]["listeners"]["fba_results"]["reaction_fluxes"] | ||
| rxn_idx = metabolism.fba_reaction_ids.index(rxn_id) | ||
| for fluxes_at_t in reaction_fluxes: | ||
| assert fluxes_at_t[rxn_idx] == pytest.approx(0.0, abs=1e-6) |
| # Set reaction limits from config options | ||
| config_reaction_bounds = self.parameters.get("set_reaction_bounds", {}) | ||
| for rxn, bounds in config_reaction_bounds.items(): | ||
| if rxn not in self.fba_reaction_ids: | ||
| raise ValueError( | ||
| f"set_reaction_bounds: reaction '{rxn}' not found in FBA reaction IDs" | ||
| ) | ||
| try: | ||
| lower_bound, upper_bound = bounds | ||
| except (TypeError, ValueError) as e: | ||
| raise ValueError( | ||
| f"set_reaction_bounds for '{rxn}' must be a 2-item sequence [lower, upper], got: {bounds!r}" | ||
| ) from e | ||
| if lower_bound > upper_bound: | ||
| raise ValueError( | ||
| f"set_reaction_bounds for '{rxn}' has lower_bound > upper_bound ({lower_bound} > {upper_bound})" | ||
| ) | ||
| self.model.fba.setReactionFluxBounds( | ||
| rxn, lowerBounds=lower_bound, upperBounds=upper_bound | ||
| ) |
This pull request introduces a new feature to the
Metabolismprocess, allowing users to set custom flux bounds for specific reactions via configuration. This makes it easier to test metabolic reaction constraints directly from the config.Configuration and reaction bound setting:
set_reaction_boundsfield to theMetabolismprocess configuration, enabling users to specify custom lower and upper bounds for reaction fluxes (ecoli/processes/metabolism.py).Example config option