From 0c46b6a37d6e10a80e5a3654bc32da3d5f48a369 Mon Sep 17 00:00:00 2001 From: heenasaqib Date: Wed, 22 Jul 2026 14:24:04 -0700 Subject: [PATCH 1/3] make configurable change to define reaction flux bounds in metabolism.py --- ecoli/processes/metabolism.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ecoli/processes/metabolism.py b/ecoli/processes/metabolism.py index 4a1c653f5..140cfa367 100644 --- a/ecoli/processes/metabolism.py +++ b/ecoli/processes/metabolism.py @@ -95,6 +95,7 @@ class Metabolism(Step): "linked_metabolites": None, "aa_exchange_names": [], "removed_aa_uptake": [], + "set_reaction_bounds": {}, # In form: {RXN_ID:[lb,ub]} "seed": 0, # TODO: For testing, remove later (perhaps after modifying sim data) "reduce_murein_objective": False, @@ -532,6 +533,16 @@ def next_update(self, timestep, states): catalyst_counts, counts_to_molar, coefficient, translation_gtp ) + # Set reaction limits from config options + self.set_reaction_bounds = self.parameters["set_reaction_bounds"] + for rxn, bounds in self.set_reaction_bounds.items(): + if rxn not in self.fba_reaction_ids: + print(f"Reaction {rxn} not found in fba reaction ids") + continue + self.model.fba.setReactionFluxBounds( + rxn, lowerBounds=bounds[0], upperBounds=bounds[1] + ) + # Constrain reactions based on targets targets, upper_targets, lower_targets = self.model.set_reaction_targets( kinetic_enzyme_counts, From 4efcb04e4a495ee3b2508d37a383c60e1be37722 Mon Sep 17 00:00:00 2001 From: Haina Saqibo <67342672+heenasaqib@users.noreply.github.com> Date: Wed, 22 Jul 2026 14:50:08 -0700 Subject: [PATCH 2/3] Fix copilot comment - robust handling of config option Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- ecoli/processes/metabolism.py | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/ecoli/processes/metabolism.py b/ecoli/processes/metabolism.py index 140cfa367..324bcfa19 100644 --- a/ecoli/processes/metabolism.py +++ b/ecoli/processes/metabolism.py @@ -534,13 +534,24 @@ def next_update(self, timestep, states): ) # Set reaction limits from config options - self.set_reaction_bounds = self.parameters["set_reaction_bounds"] - for rxn, bounds in self.set_reaction_bounds.items(): + 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: - print(f"Reaction {rxn} not found in fba reaction ids") - continue + 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=bounds[0], upperBounds=bounds[1] + rxn, lowerBounds=lower_bound, upperBounds=upper_bound ) # Constrain reactions based on targets From 1dda65df21834c0785ab3ccea8b9dda7f7b5c312 Mon Sep 17 00:00:00 2001 From: heenasaqib Date: Wed, 22 Jul 2026 15:11:47 -0700 Subject: [PATCH 3/3] Added pytest for new configuration option --- ecoli/processes/metabolism.py | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/ecoli/processes/metabolism.py b/ecoli/processes/metabolism.py index 324bcfa19..44c01b761 100644 --- a/ecoli/processes/metabolism.py +++ b/ecoli/processes/metabolism.py @@ -95,7 +95,7 @@ class Metabolism(Step): "linked_metabolites": None, "aa_exchange_names": [], "removed_aa_uptake": [], - "set_reaction_bounds": {}, # In form: {RXN_ID:[lb,ub]} + "set_reaction_bounds": {}, # In form: {FBA_RXN_ID:[lb,ub]} (reaction must match FBA basis) "seed": 0, # TODO: For testing, remove later (perhaps after modifying sim data) "reduce_murein_objective": False, @@ -1171,5 +1171,31 @@ def test_metabolism_listener(): assert isinstance(reaction_fluxes[1], list) +def test_set_reaction_bounds_config(): + from ecoli.experiments.ecoli_master_sim import EcoliSim + import pytest + + 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) + + if __name__ == "__main__": test_metabolism_listener()