diff --git a/biosimulators_utils/sedml/utils.py b/biosimulators_utils/sedml/utils.py
index df22e7dc..7703f77c 100644
--- a/biosimulators_utils/sedml/utils.py
+++ b/biosimulators_utils/sedml/utils.py
@@ -559,7 +559,9 @@ def apply_changes_to_xml_model(model, model_etree, sed_doc=None, working_dir=Non
attribute.set("size", change.new_value)
elif type_suffix == "parameter" and attribute.get("value") is not None:
attribute.set("value", change.new_value)
- elif (type_suffix == "reaction" and second_type_suffix == "parameter"
+ elif (type_suffix == "reaction" and
+ (second_type_suffix == "parameter" # SBML L1, L2
+ or second_type_suffix == "localParameter") # SBML L3+
and attribute.get("value") is not None): # Reaction parameter change
attribute.set("value", change.new_value)
else:
diff --git a/tests/fixtures/sbml-list-of-species.xml b/tests/fixtures/sbml-list-of-species-lvl-2.xml
similarity index 57%
rename from tests/fixtures/sbml-list-of-species.xml
rename to tests/fixtures/sbml-list-of-species-lvl-2.xml
index 03471f8f..ea467476 100644
--- a/tests/fixtures/sbml-list-of-species.xml
+++ b/tests/fixtures/sbml-list-of-species-lvl-2.xml
@@ -18,5 +18,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/fixtures/sbml-list-of-species-lvl-3.xml b/tests/fixtures/sbml-list-of-species-lvl-3.xml
new file mode 100644
index 00000000..fb1b81ac
--- /dev/null
+++ b/tests/fixtures/sbml-list-of-species-lvl-3.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/model_lang/sbml/test_sbml_validation.py b/tests/model_lang/sbml/test_sbml_validation.py
index 6016f0ea..8b505ca9 100644
--- a/tests/model_lang/sbml/test_sbml_validation.py
+++ b/tests/model_lang/sbml/test_sbml_validation.py
@@ -8,7 +8,7 @@ class ValidationTestCase(unittest.TestCase):
FIXTURE_DIR = os.path.join(os.path.dirname(__file__), '..', '..', 'fixtures')
def test(self):
- errors, warnings, _ = validate_model(os.path.join(self.FIXTURE_DIR, 'sbml-list-of-species.xml'))
+ errors, warnings, _ = validate_model(os.path.join(self.FIXTURE_DIR, 'sbml-list-of-species-lvl-2.xml'))
self.assertEqual(errors, [])
self.assertEqual(warnings, [])
diff --git a/tests/sedml/test_sedml_utils.py b/tests/sedml/test_sedml_utils.py
index c616625d..3413cf6e 100644
--- a/tests/sedml/test_sedml_utils.py
+++ b/tests/sedml/test_sedml_utils.py
@@ -231,7 +231,8 @@ def test_get_variables_for_task(self):
class ApplyModelChangesTestCase(unittest.TestCase):
- FIXTURE_FILENAME = os.path.join(os.path.dirname(__file__), '../fixtures/sbml-list-of-species.xml')
+ FIXTURE_FILENAME = os.path.join(os.path.dirname(__file__), '../fixtures/sbml-list-of-species-lvl-2.xml')
+ FIXTURE_FILENAME_2 = os.path.join(os.path.dirname(__file__), '../fixtures/sbml-list-of-species-lvl-3.xml')
def setUp(self):
self.tmp_dir = tempfile.mkdtemp()
@@ -668,7 +669,7 @@ def test_errors(self):
target="/sbml:sbml/sbml:model/sbml:listOfSpecies/sbml:spesies[@id='Trim']/initialConcentration",
target_namespaces={'sbml': 'http://www.sbml.org/sbml/level2/version4'},
new_value='1.9')
- self._attempt_change(change, self.FIXTURE_FILENAME, NotImplementedError)
+ self._attempt_change(change, self.FIXTURE_FILENAME, ValueError)
change = data_model.ModelAttributeChange(
target="/sbml:sbml/sbml:model/sbml:listOfSpecies/sbml:spesies[@id='Trim']",
@@ -746,6 +747,21 @@ def test_errors(self):
new_value='1.9')
self._attempt_change(change, self.FIXTURE_FILENAME)
+ change = data_model.ModelAttributeChange(
+ target="/sbml:sbml/sbml:model/sbml:listOfReactions/sbml:reaction[@id='lumen']/sbml:kineticLaw"
+ "/sbml:listOfParameters/sbml:parameter[@id='k1']",
+ target_namespaces={'sbml': 'http://www.sbml.org/sbml/level2/version4'},
+ new_value='1.9')
+ self._attempt_change(change, self.FIXTURE_FILENAME)
+
+ change = data_model.ModelAttributeChange(
+ target="/sbml:sbml/sbml:model/sbml:listOfReactions/sbml:reaction[@id='lumen']/sbml:kineticLaw"
+ "/sbml:listOfLocalParameters/sbml:localParameter[@id='k1']/@value",
+ target_namespaces={'sbml': 'http://www.sbml.org/sbml/level3/version1'},
+ new_value='1.9')
+ self._attempt_change(change, self.FIXTURE_FILENAME_2)
+
+
def _attempt_change(self, change: data_model.ModelChange, sbml_path: str,
expected_exception: "type[BaseException] | tuple[type[BaseException], ...]" = None):
et = etree.parse(sbml_path)
diff --git a/tests/sedml/test_sedml_validation.py b/tests/sedml/test_sedml_validation.py
index 3ef4c4b1..bc7eb9a9 100644
--- a/tests/sedml/test_sedml_validation.py
+++ b/tests/sedml/test_sedml_validation.py
@@ -828,7 +828,7 @@ def _validate_task(self, task, variables):
return (errors, warnings)
def test_validate_model_source_with_abs_path(self):
- filename = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'fixtures', 'sbml-list-of-species.xml'))
+ filename = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'fixtures', 'sbml-list-of-species-lvl-2.xml'))
errors, warnings = validation.validate_model_source(data_model.Model(
source=filename, language=data_model.ModelLanguage.SBML), [], None, validate_models_with_languages=False)
self.assertEqual(errors, [])
@@ -851,7 +851,7 @@ def test_validate_model_source_with_url(self):
def test_validate_model_with_language(self):
# SBML
- filename = os.path.join(os.path.dirname(__file__), '..', 'fixtures', 'sbml-list-of-species.xml')
+ filename = os.path.join(os.path.dirname(__file__), '..', 'fixtures', 'sbml-list-of-species-lvl-2.xml')
validation.validate_model_with_language(filename, data_model.ModelLanguage.SBML)
errors, warnings, _ = validation.validate_model_with_language(filename, '--not-supported--')