From a65b4054fcb0a233ff298d813b9fd78371555c38 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Mon, 21 Sep 2026 19:29:35 +0200 Subject: [PATCH] get_model_for_condition: don't remove rate rules for condition-table overrides `get_model_for_condition` removed *any* SBML rule (including rate rules) for a species/compartment/parameter overridden in the condition table. For rate-rule targets, this turned dynamic species into constants instead of just setting their initial value. Only assignment rules are removed now; rate rules are left in place. Fixes #197 Co-Authored-By: Claude Sonnet 5 --- petab/v1/sbml.py | 10 +++++++++- tests/v1/test_sbml.py | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/petab/v1/sbml.py b/petab/v1/sbml.py index e8ed10aa..dc6f594b 100644 --- a/petab/v1/sbml.py +++ b/petab/v1/sbml.py @@ -307,7 +307,15 @@ def get_param_value(parameter_id: str): ] def remove_rules(target_id: str): - if sbml_model.removeRuleByVariable(target_id): + """Remove any assignment rule and initial assignment for + ``target_id`` so that its initial value can be set explicitly. + """ + rule = sbml_model.getRuleByVariable(target_id) + if ( + rule is not None + and rule.getTypeCode() == libsbml.SBML_ASSIGNMENT_RULE + ): + sbml_model.removeRuleByVariable(target_id) warn( "An SBML rule was removed to set the component " f"{target_id} to a constant value.", diff --git a/tests/v1/test_sbml.py b/tests/v1/test_sbml.py index 5cbb1568..469524c5 100644 --- a/tests/v1/test_sbml.py +++ b/tests/v1/test_sbml.py @@ -17,9 +17,10 @@ def create_test_data(): "\n".join( [ "compartment compartment_1 = 1", - *(f"species species_{i} = 10 * {i}" for i in range(1, 5)), + *(f"species species_{i} = 10 * {i}" for i in range(1, 6)), *(f"parameter_{i} = {i}" for i in range(1, 4)), "species_2 := 25", + "species_5' = 1", ] ) ) @@ -32,6 +33,7 @@ def create_test_data(): "species_2": [25], "species_3": ["parameter_1"], "species_4": ["not_a_model_parameter"], + "species_5": [55], "compartment_1": [2], } ) @@ -85,6 +87,12 @@ def check_model(condition_model): condition_model.getSpecies("species_4").getInitialConcentration() == 3.25 ) + assert ( + condition_model.getSpecies("species_5").getInitialConcentration() == 55 + ) + assert condition_model.getRuleByVariable("species_5") is not None, ( + "RateRule was removed although it should have been kept" + ) assert len(condition_model.getListOfInitialAssignments()) == 0, ( "InitialAssignment not removed" )