From 0bfa14d4d6132c932368760f4fece59d0efb9a6c Mon Sep 17 00:00:00 2001 From: Jan Range <30547301+JR-1991@users.noreply.github.com> Date: Mon, 22 Sep 2025 13:28:05 +0200 Subject: [PATCH 1/4] Update specs submodule to latest commit Advanced the specs submodule pointer from 95b520a to c5dc877 to incorporate the latest changes from the specs repository. --- specs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs b/specs index 95b520a..c5dc877 160000 --- a/specs +++ b/specs @@ -1 +1 @@ -Subproject commit 95b520a9d7144f23584e4f84dfd25ae94167efb2 +Subproject commit c5dc877bdbc4d99ce1b57009583cfe3dc97163fb From 85c29e4bea61f389e47a8d2a5f1dc12db7d35fd6 Mon Sep 17 00:00:00 2001 From: Jan Range <30547301+JR-1991@users.noreply.github.com> Date: Mon, 22 Sep 2025 13:28:13 +0200 Subject: [PATCH 2/4] Add 'fit' parameter to Parameter model and context Introduces an optional 'fit' boolean to the Parameter model and related method, indicating if a parameter should be varied during optimization. Also reorders the '@context' dictionary entries for consistency across multiple classes. --- pyenzyme/versions/v2.py | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/pyenzyme/versions/v2.py b/pyenzyme/versions/v2.py index 802bf8a..4734074 100644 --- a/pyenzyme/versions/v2.py +++ b/pyenzyme/versions/v2.py @@ -201,8 +201,8 @@ class EnzymeMLDocument(BaseModel): serialization_alias="@context", default_factory=lambda: { "enzml": "http://www.enzymeml.org/v2/", - "schema": "https://schema.org/", "OBO": "http://purl.obolibrary.org/obo/", + "schema": "https://schema.org/", "name": "schema:title", "created": "schema:dateCreated", "modified": "schema:dateModified", @@ -603,6 +603,7 @@ def add_to_parameters( initial_value: Optional[float] = None, upper_bound: Optional[float] = None, lower_bound: Optional[float] = None, + fit: Optional[bool] = True, stderr: Optional[float] = None, constant: Optional[bool] = True, **kwargs, @@ -616,6 +617,7 @@ def add_to_parameters( "initial_value": initial_value, "upper_bound": upper_bound, "lower_bound": lower_bound, + "fit": fit, "stderr": stderr, "constant": constant, } @@ -659,8 +661,8 @@ class Creator(BaseModel): serialization_alias="@context", default_factory=lambda: { "enzml": "http://www.enzymeml.org/v2/", - "schema": "https://schema.org/", "OBO": "http://purl.obolibrary.org/obo/", + "schema": "https://schema.org/", "given_name": "schema:givenName", "family_name": "schema:familyName", "mail": "schema:email", @@ -773,8 +775,8 @@ class Vessel(BaseModel): serialization_alias="@context", default_factory=lambda: { "enzml": "http://www.enzymeml.org/v2/", - "schema": "https://schema.org/", "OBO": "http://purl.obolibrary.org/obo/", + "schema": "https://schema.org/", "id": { "@id": "schema:identifier", "@type": "@id", @@ -911,8 +913,8 @@ class Protein(BaseModel): serialization_alias="@context", default_factory=lambda: { "enzml": "http://www.enzymeml.org/v2/", - "schema": "https://schema.org/", "OBO": "http://purl.obolibrary.org/obo/", + "schema": "https://schema.org/", "id": { "@id": "schema:identifier", "@type": "@id", @@ -1044,8 +1046,8 @@ class Complex(BaseModel): serialization_alias="@context", default_factory=lambda: { "enzml": "http://www.enzymeml.org/v2/", - "schema": "https://schema.org/", "OBO": "http://purl.obolibrary.org/obo/", + "schema": "https://schema.org/", "id": { "@id": "schema:identifier", "@type": "@id", @@ -1195,8 +1197,8 @@ class SmallMolecule(BaseModel): serialization_alias="@context", default_factory=lambda: { "enzml": "http://www.enzymeml.org/v2/", - "schema": "https://schema.org/", "OBO": "http://purl.obolibrary.org/obo/", + "schema": "https://schema.org/", "id": { "@id": "schema:identifier", "@type": "@id", @@ -1330,8 +1332,8 @@ class Reaction(BaseModel): serialization_alias="@context", default_factory=lambda: { "enzml": "http://www.enzymeml.org/v2/", - "schema": "https://schema.org/", "OBO": "http://purl.obolibrary.org/obo/", + "schema": "https://schema.org/", "id": { "@id": "schema:identifier", "@type": "@id", @@ -1517,8 +1519,8 @@ class ReactionElement(BaseModel): serialization_alias="@context", default_factory=lambda: { "enzml": "http://www.enzymeml.org/v2/", - "schema": "https://schema.org/", "OBO": "http://purl.obolibrary.org/obo/", + "schema": "https://schema.org/", "species_id": { "@id": "schema:identifier", "@type": "@id", @@ -1622,8 +1624,8 @@ class ModifierElement(BaseModel): serialization_alias="@context", default_factory=lambda: { "enzml": "http://www.enzymeml.org/v2/", - "schema": "https://schema.org/", "OBO": "http://purl.obolibrary.org/obo/", + "schema": "https://schema.org/", "species_id": { "@id": "schema:identifier", "@type": "@id", @@ -1738,8 +1740,8 @@ class Equation(BaseModel): serialization_alias="@context", default_factory=lambda: { "enzml": "http://www.enzymeml.org/v2/", - "schema": "https://schema.org/", "OBO": "http://purl.obolibrary.org/obo/", + "schema": "https://schema.org/", "species_id": { "@id": "schema:identifier", "@type": "@id", @@ -1874,8 +1876,8 @@ class Variable(BaseModel): serialization_alias="@context", default_factory=lambda: { "enzml": "http://www.enzymeml.org/v2/", - "schema": "https://schema.org/", "OBO": "http://purl.obolibrary.org/obo/", + "schema": "https://schema.org/", "id": { "@id": "schema:identifier", "@type": "@id", @@ -1989,6 +1991,11 @@ class Parameter(BaseModel): description="""Lower bound for the parameter value that was used for the parameter estimation""", ) + fit: Optional[bool] = Field( + default=True, + description="""Whether this parameter should be varied or not in + the context of an optimization.""", + ) stderr: Optional[float] = Field( default=None, description="""Standard error of the estimated parameter.""", @@ -2014,8 +2021,8 @@ class Parameter(BaseModel): serialization_alias="@context", default_factory=lambda: { "enzml": "http://www.enzymeml.org/v2/", - "schema": "https://schema.org/", "OBO": "http://purl.obolibrary.org/obo/", + "schema": "https://schema.org/", "id": { "@id": "schema:identifier", "@type": "@id", @@ -2141,8 +2148,8 @@ class Measurement(BaseModel): serialization_alias="@context", default_factory=lambda: { "enzml": "http://www.enzymeml.org/v2/", - "schema": "https://schema.org/", "OBO": "http://purl.obolibrary.org/obo/", + "schema": "https://schema.org/", "id": { "@id": "schema:identifier", "@type": "@id", @@ -2330,8 +2337,8 @@ class MeasurementData(BaseModel): serialization_alias="@context", default_factory=lambda: { "enzml": "http://www.enzymeml.org/v2/", - "schema": "https://schema.org/", "OBO": "http://purl.obolibrary.org/obo/", + "schema": "https://schema.org/", "species_id": { "@type": "@id", }, From 71a7a86f1a79d7b88a2537890cf2e5f5a8a0f09b Mon Sep 17 00:00:00 2001 From: JM Rohwer Date: Mon, 22 Sep 2025 17:53:40 +0200 Subject: [PATCH 3/4] Handle non-fitted parameters, including pre-defined standard errors --- pyenzyme/thinlayers/psyces.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/pyenzyme/thinlayers/psyces.py b/pyenzyme/thinlayers/psyces.py index 14a75a8..a634c04 100644 --- a/pyenzyme/thinlayers/psyces.py +++ b/pyenzyme/thinlayers/psyces.py @@ -232,7 +232,16 @@ def optimize(self, method="leastsq"): self.parameters = parameters - return self.minimizer.minimize(method=method) + result = self.minimizer.minimize(method=method) + # add standard error if available in enzmldoc and if param.fit=False + # (e.g. if parameter was fitted before) + for param in self.enzmldoc.parameters: + if not param.fit and param.stderr is not None: + if param.symbol in result.params: + result.params[param.symbol].stderr = param.stderr + + return result + def write(self) -> v2.EnzymeMLDocument: """ @@ -286,8 +295,9 @@ def _initialize_parameters(self): for param in self.enzmldoc.parameters: # Build kwargs dictionary with conditional assignments kwargs = { - **({"min": param.lower_bound} if param.lower_bound is not None else {}), - **({"max": param.upper_bound} if param.upper_bound is not None else {}), + **({'min': param.lower_bound} if param.lower_bound is not None else {}), + **({'max': param.upper_bound} if param.upper_bound is not None else {}), + **({'vary': param.fit}), } # Determine parameter value From d64745db3445b5774719449eceb5282579b9d7fa Mon Sep 17 00:00:00 2001 From: JM Rohwer Date: Mon, 22 Sep 2025 17:56:59 +0200 Subject: [PATCH 4/4] Write standard error back to enzymeml doc after fitting --- pyenzyme/thinlayers/psyces.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pyenzyme/thinlayers/psyces.py b/pyenzyme/thinlayers/psyces.py index a634c04..f7d2115 100644 --- a/pyenzyme/thinlayers/psyces.py +++ b/pyenzyme/thinlayers/psyces.py @@ -264,16 +264,18 @@ def write(self) -> v2.EnzymeMLDocument: >>> pe.write_enzymeml(optimized_doc, "optimized_model.json") """ nu_enzmldoc = self.enzmldoc.model_copy(deep=True) - results = self.minimizer.result.params.valuesdict() # type: ignore + results = self.minimizer.result.params # type: ignore - for name, value in results.items(): + for name in results: query = nu_enzmldoc.filter_parameters(symbol=name) if len(query) == 0: raise ValueError(f"Parameter {name} not found") parameter = query[0] - parameter.value = value + parameter.value = results[name].value + if results[name].stderr is not None: + parameter.stderr = results[name].stderr return nu_enzmldoc