Source code for pymixef.interoperability.sedml

"""SED-ML uniform-time-course subset."""

from __future__ import annotations

import xml.etree.ElementTree as ET
from collections.abc import Mapping
from pathlib import Path
from typing import Any

from .._contracts import CompatibilityIssue
from .base import CompatibilityReport, InterchangeResult


def _local(tag: str) -> str:
    return tag.rsplit("}", 1)[-1]


[docs] def import_sedml(path: str | Path) -> InterchangeResult[dict[str, Any]]: """Import uniform-time-course simulations from a SED-ML document. The result captures output grids and KiSAO algorithm identifiers. One-step, steady-state, repeated-task, and functional-range constructs are reported as ``unsupported``; call :meth:`InterchangeResult.require_supported` to reject a partial translation. """ source = Path(path) root = ET.parse(source).getroot() simulations: list[dict[str, Any]] = [] unsupported: set[str] = set() for element in root.iter(): kind = _local(element.tag) if kind == "uniformTimeCourse": simulations.append( { "id": element.attrib.get("id"), "initial_time": float(element.attrib.get("initialTime", 0)), "output_start_time": float(element.attrib.get("outputStartTime", 0)), "output_end_time": float(element.attrib["outputEndTime"]), "number_of_points": int(element.attrib["numberOfPoints"]), "algorithm": next( ( child.attrib.get("kisaoID") for child in element if _local(child.tag) == "algorithm" ), None, ), } ) elif kind in { "oneStep", "steadyState", "repeatedTask", "functionalRange", }: unsupported.add(kind) found = [ CompatibilityIssue( "uniformTimeCourse", "transformed", f"Imported {len(simulations)} uniform time-course simulation(s).", ) ] found.extend( CompatibilityIssue( name, "unsupported", "This SED-ML experiment construct is outside the initial subset.", ) for name in sorted(unsupported) ) return InterchangeResult( {"simulations": simulations, "source": str(source)}, CompatibilityReport("SED-ML", "PyMixEF simulation design", tuple(found)), )
[docs] def export_sedml(design: Mapping[str, Any], path: str | Path) -> InterchangeResult[Path]: """Export one uniform-time-course design as SED-ML Level 1 Version 4. ``output_end_time`` and ``number_of_points`` are required. The export records the deterministic output grid and KiSAO identifier; richer SED-ML tasks and ranges are outside this function's supported subset. """ namespace = "http://sed-ml.org/sed-ml/level1/version4" ET.register_namespace("", namespace) root = ET.Element( f"{{{namespace}}}sedML", {"level": "1", "version": "4"}, ) simulations = ET.SubElement(root, f"{{{namespace}}}listOfSimulations") simulation = ET.SubElement( simulations, f"{{{namespace}}}uniformTimeCourse", { "id": str(design.get("id", "simulation")), "initialTime": str(design.get("initial_time", 0.0)), "outputStartTime": str(design.get("output_start_time", 0.0)), "outputEndTime": str(design["output_end_time"]), "numberOfPoints": str(design["number_of_points"]), }, ) ET.SubElement( simulation, f"{{{namespace}}}algorithm", {"kisaoID": str(design.get("algorithm", "KISAO:0000019"))}, ) destination = Path(path) destination.parent.mkdir(parents=True, exist_ok=True) ET.ElementTree(root).write(destination, encoding="utf-8", xml_declaration=True) return InterchangeResult( destination, CompatibilityReport( "PyMixEF simulation design", "SED-ML", ( CompatibilityIssue( "uniformTimeCourse", "exact", "Exported deterministic output grid and KiSAO algorithm identifier.", ), ), ), )