-
Notifications
You must be signed in to change notification settings - Fork 0
Closed
Description
the load_vcml_file function seems to only recognize some types of parameters (ModelParameters and Kinetics). My VCML model has an "ApplicationParameter" that isn't recognized. I was able to patch this with the following code, but I'm not sure if this is the best way to do it because it's not clear to me with the ApplicationParameters are; the ones that my file has are output by my patch:
Skipped parameters: [{'name': 'appParm0', 'parent_tag': 'ApplicationParameters', 'text': '1.0'}, {'name': 'appParm1', 'parent_tag': 'ApplicationParameters', 'text': '1.0'}, {'name': 'appParm2', 'parent_tag': 'ApplicationParameters', 'text': '1.0'}, {'name': 'appParm3', 'parent_tag': 'ApplicationParameters', 'text': '1.0'}]
import pyvcell.vcml as vc
from lxml.etree import _Element
import pyvcell.vcml as vc
from lxml import etree
from pathlib import Path
def load_vcml_file_patched(vcml_file: str | Path) -> vc.Biomodel:
"""
Load a VCML file using PatchedBiomodelVisitor.
Logs skipped parameters in the visitor.
"""
vcml_file = Path(vcml_file)
with open(vcml_file, "r", encoding="utf-8") as f:
vcml_str = f.read()
document = vc.VCMLDocument()
visitor = PatchedBiomodelVisitor(document)
root = etree.fromstring(vcml_str.encode("utf-8"))
visitor.visit(root, document)
if visitor.skipped_parameters:
print("Skipped parameters:", visitor.skipped_parameters)
if visitor.document.biomodel is None:
raise ValueError("No biomodel found in VCML file.")
return visitor.document.biomodel
class PatchedBiomodelVisitor(vc.vcml_reader.BiomodelVisitor):
def __init__(self, document):
super().__init__(document)
self.skipped_parameters = [] # store skipped parameters
def visit_Parameter(self, element: _Element, node: vc.Model | vc.Kinetics | vc.Application) -> None:
parent: _Element | None = element.getparent()
if parent is None:
raise ValueError("Parameter element has no parent")
text: str = element.text or ""
value: str | float = vc.vcml_reader.float_or_formula(text)
name: str = element.get("Name", default="unnamed")
role = element.get("Role", default="user defined")
unit = element.get("Unit", default="tbd")
parameter = None
parent_tag = vc.vcml_reader.strip_namespace(parent.tag)
if parent_tag == "ModelParameters":
model: vc.Model = node # type: ignore
model_parameter = vc.ModelParameter(
name=name, value=value, role=role, unit=unit)
model.model_parameters.append(model_parameter)
parameter = model_parameter
elif parent_tag == "Kinetics":
kinetics: vc.Kinetics = node # type: ignore
reaction_node = parent.getparent()
if reaction_node is None:
raise ValueError("Kinetics element has no parent")
reaction_name = reaction_node.get("Name", default="unknown")
kinetics_parameter = vc.KineticsParameter(
name=name, value=value, role=role, unit=unit, reaction_name=reaction_name
)
kinetics.kinetics_parameters.append(kinetics_parameter)
parameter = kinetics_parameter
else:
# Log skipped parameters
self.skipped_parameters.append({
"name": name,
"parent_tag": parent_tag,
"text": text
})
# Do not raise an error; just skip
return
self.generic_visit(element, parameter)
Metadata
Metadata
Assignees
Labels
No labels