diff --git a/src/sbmlsim/_deprecated/__init__.py b/src/sbmlsim/_deprecated/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/src/sbmlsim/_deprecated/pk/__init__.py b/src/sbmlsim/_deprecated/pk/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/src/sbmlsim/_deprecated/pk/pkpd.py b/src/sbmlsim/_deprecated/pk/pkpd.py deleted file mode 100644 index 9792fa2c..00000000 --- a/src/sbmlsim/_deprecated/pk/pkpd.py +++ /dev/null @@ -1,82 +0,0 @@ -"""Methods specific to pkdb models.""" -import re -from typing import Dict - -import roadrunner -from sbmlutils import log - - -logger = log.get_logger(__name__) - -# ------------------------------------------------------------------------------------------------- -# Initial values -# ------------------------------------------------------------------------------------------------- -# Helper functions for setting initial values in the model. -# Substances which are transported in the body can hereby be initialized in all -# tissues to identical values (which removes the distribution kinetics). -# ------------------------------------------------------------------------------------------------- - - -def init_concentrations_changes(r: roadrunner.RoadRunner, skey, value: float): - """Get changes to set initial concentrations for skey.""" - return _set_initial_values(r, skey, value, method="concentration") - - -def init_amounts_changes(r: roadrunner.RoadRunner, skey, value): - """Set initial amounts for skey.""" - return _set_initial_values(r, skey, value, method="amount") - - -def _set_initial_values( - r: roadrunner.RoadRunner, sid, value, method="concentration" -) -> Dict: - """Set the initial concentration of a distributing substance. - - Takes care of all the compartment values so starting close/in steady state. - Units are in model units - - return: changeset for model - """ - if method not in ["amount", "concentration"]: - raise ValueError - - species_ids = r.model.getFloatingSpeciesIds() + r.model.getBoundarySpeciesIds() - species_keys = get_species_keys(sid, species_ids) - changeset = {} - - for key in species_keys: - - if method == "concentration": - rkey = f"[{key}]" - - if "urine" in rkey: - logger.debug("urinary values are not set") - continue - - changeset[rkey] = value - - return changeset - - -def get_species_keys(skey, species_ids): - """Get keys of substance in given list of ids. - - Relies on naming patterns of ids. This does not get the species ids of the submodels, - but only of the top model. - - :param skey: substance key - :param species_ids: list of species ids to filter from - :return: - """ - keys = [] - for species_id in species_ids: - # use regular expression to find ids - # This pattern is not very robust !!! FIXME (e.g. blood vs. plasma) - pattern = r"^[AC][a-z]+(_plasma)*\_{}$".format(skey) - - match = re.search(pattern, species_id) - if match: - # print("match:", species_id) - keys.append(species_id) - - return keys diff --git a/src/sbmlsim/_deprecated/tesedml.py b/src/sbmlsim/_deprecated/tesedml.py deleted file mode 100644 index 484feec0..00000000 --- a/src/sbmlsim/_deprecated/tesedml.py +++ /dev/null @@ -1,2315 +0,0 @@ -""" -Tellurium SED-ML support. - -This module implements SED-ML support for tellurium. - ----------------- -Overview SED-ML ----------------- -SED-ML is build of main classes - the Model Class, - the Simulation Class, - the Task Class, - the DataGenerator Class, - and the Output Class. - -The Model Class - The Model class is used to reference the models used in the simulation experiment. - SED-ML itself is independent of the model encoding underlying the models. The only - requirement is that the model needs to be referenced by using an unambiguous identifier - which allows for finding it, for example using a MIRIAM URI. To specify the language in - which the model is encoded, a set of predefined language URNs is provided. - The SED-ML Change class allows the application of changes to the referenced models, - including changes on the XML attributes, e.g. changing the value of an observable, - computing the change of a value using mathematics, or general changes on any XML element - of the model representation that is addressable by XPath expressions, e.g. substituting - a piece of XML by an updated one. - -TODO: DATA CLASS - - -The Simulation Class - The Simulation class defines the simulation settings and the steps taken during simulation. - These include the particular type of simulation and the algorithm used for the execution of - the simulation; preferably an unambiguous reference to such an algorithm should be given, - using a controlled vocabulary, or ontologies. One example for an ontology of simulation - algorithms is the Kinetic Simulation Algorithm Ontology KiSAO. Further information encodable - in the Simulation class includes the step size, simulation duration, and other - simulation-type dependent information. - -The Task Class - SED-ML makes use of the notion of a Task class to combine a defined model (from the Model class) - and a defined simulation setting (from the Simulation class). A task always holds one reference each. - To refer to a specific model and to a specific simulation, the corresponding IDs are used. - -The DataGenerator Class - The raw simulation result sometimes does not correspond to the desired output of the simulation, - e.g. one might want to normalise a plot before output, or apply post-processing like mean-value calculation. - The DataGenerator class allows for the encoding of such post-processings which need to be applied to the - simulation result before output. To define data generators, any addressable variable or parameter - of any defined model (from instances of the Model class) may be referenced, and new entities might - be specified using MathML definitions. - -The Output Class - The Output class defines the output of the simulation, in the sense that it specifies what shall be - plotted in the output. To do so, an output type is defined, e.g. 2D-plot, 3D-plot or data table, - and the according axes or columns are all assigned to one of the formerly specified instances - of the DataGenerator class. - -For information about SED-ML please refer to http://www.sed-ml.org/ -and the SED-ML specification. - ------------------------------------- -SED-ML in tellurium: Implementation ------------------------------------- -SED-ML support in tellurium is based on Combine Archives. -The SED-ML files in the Archive can be executed and stored with results. - ----------------------------------------- -SED-ML in tellurium: Supported Features ----------------------------------------- -Tellurium supports SED-ML L1V3 with SBML as model format. - -SBML models are fully supported, whereas for CellML models only basic support -is implemented (when additional support is requested it be implemented). -CellML models are transformed to SBML models which results in different XPath expressions, -so that targets, selections cannot be easily resolved in the CellMl-SBML. - -Supported input for SED-ML are either SED-ML files ('.sedml' extension), -SED-ML XML strings or combine archives ('.sedx'|'.omex' extension). -Executable python code is generated from the SED-ML which allows the -execution of the defined simulation experiment. - - In the current implementation all SED-ML constructs with exception of - XML transformation changes of the model - - Change.RemoveXML - - Change.AddXML - - Change.ChangeXML - are supported. - -------- -Notice -------- -The main maintainer for SED-ML support is Matthias König. -Please let changes to this file be reviewed and make sure that all SED-ML related tests are working. -""" -from __future__ import absolute_import, division, print_function - -import datetime -import importlib -import os.path -import platform -import re -import shutil -import sys -import tempfile -import traceback -import warnings -import zipfile -from collections import namedtuple - -import jinja2 -import libsedml -import numpy as np - - -importlib.reload(libsedml) - - -import tellurium as te -from tellurium.utils import omex - -from sbmlsim.oven.mathml import evaluableMathML - - -try: - # required imports in generated python code - import matplotlib.pyplot as plt - import mpl_toolkits.mplot3d - import pandas -except ImportError: - warnings.warn("Dependencies for SEDML code execution not fulfilled.") - print(traceback.format_exc()) - -###################################################################################################################### -# KISAO MAPPINGS -###################################################################################################################### - -KISAOS_CVODE = [ # 'cvode' - "KISAO:0000019", # CVODE - "KISAO:0000433", # CVODE-like method - "KISAO:0000407", - "KISAO:0000099", - "KISAO:0000035", - "KISAO:0000071", - "KISAO:0000288", # "BDF" cvode, stiff=true - "KISAO:0000280", # "Adams-Moulton" cvode, stiff=false -] - -KISAOS_RK4 = [ # 'rk4' - "KISAO:0000032", # RK4 explicit fourth-order Runge-Kutta method - "KISAO:0000064", # Runge-Kutta based method -] - -KISAOS_RK45 = [ # 'rk45' - "KISAO:0000086", # RKF45 embedded Runge-Kutta-Fehlberg 5(4) method -] - -KISAOS_LSODA = [ # 'lsoda' - "KISAO:0000088", # roadrunner doesn't have an lsoda solver so use cvode -] - -KISAOS_GILLESPIE = [ # 'gillespie' - "KISAO:0000241", # Gillespie-like method - "KISAO:0000029", - "KISAO:0000319", - "KISAO:0000274", - "KISAO:0000333", - "KISAO:0000329", - "KISAO:0000323", - "KISAO:0000331", - "KISAO:0000027", - "KISAO:0000082", - "KISAO:0000324", - "KISAO:0000350", - "KISAO:0000330", - "KISAO:0000028", - "KISAO:0000038", - "KISAO:0000039", - "KISAO:0000048", - "KISAO:0000074", - "KISAO:0000081", - "KISAO:0000045", - "KISAO:0000351", - "KISAO:0000084", - "KISAO:0000040", - "KISAO:0000046", - "KISAO:0000003", - "KISAO:0000051", - "KISAO:0000335", - "KISAO:0000336", - "KISAO:0000095", - "KISAO:0000022", - "KISAO:0000076", - "KISAO:0000015", - "KISAO:0000075", - "KISAO:0000278", -] - -KISAOS_NLEQ = [ # 'nleq' - "KISAO:0000099", - "KISAO:0000274", - "KISAO:0000282", - "KISAO:0000283", - "KISAO:0000355", - "KISAO:0000356", - "KISAO:0000407", - "KISAO:0000408", - "KISAO:0000409", - "KISAO:0000410", - "KISAO:0000411", - "KISAO:0000412", - "KISAO:0000413", - "KISAO:0000432", - "KISAO:0000437", -] - -# allowed algorithms for simulation type -KISAOS_STEADYSTATE = KISAOS_NLEQ -KISAOS_UNIFORMTIMECOURSE = ( - KISAOS_CVODE + KISAOS_RK4 + KISAOS_RK45 + KISAOS_GILLESPIE + KISAOS_LSODA -) -KISAOS_ONESTEP = KISAOS_UNIFORMTIMECOURSE - -# supported algorithm parameters -KISAOS_ALGORITHMPARAMETERS = { - "KISAO:0000209": ("relative_tolerance", float), # the relative tolerance - "KISAO:0000211": ("absolute_tolerance", float), # the absolute tolerance - "KISAO:0000220": ("maximum_bdf_order", int), # the maximum BDF (stiff) order - "KISAO:0000219": ( - "maximum_adams_order", - int, - ), # the maximum Adams (non-stiff) order - "KISAO:0000415": ( - "maximum_num_steps", - int, - ), # the maximum number of steps that can be taken before exiting - "KISAO:0000467": ( - "maximum_time_step", - float, - ), # the maximum time step that can be taken - "KISAO:0000485": ( - "minimum_time_step", - float, - ), # the minimum time step that can be taken - "KISAO:0000332": ( - "initial_time_step", - float, - ), # the initial value of the time step for algorithms that change this value - "KISAO:0000107": ( - "variable_step_size", - bool, - ), # whether or not the algorithm proceeds with an adaptive step size or not - "KISAO:0000486": ( - "maximum_iterations", - int, - ), # [nleq] the maximum number of iterations the algorithm should take before exiting - "KISAO:0000487": ("minimum_damping", float), # [nleq] minimum damping value - "KISAO:0000488": ("seed", int), # the seed for stochastic runs of the algorithm -} - - -###################################################################################################################### -# Interface functions -###################################################################################################################### -# The functions listed in this section are the only functions one should interact with this module. -# We try to keep these back-wards compatible and keep the function signatures. -# -# All other function and class signatures can change. -###################################################################################################################### - - -def sedmlToPython(inputStr, workingDir=None): - """Convert sedml file to python code. - - :param inputStr: full path name to SedML model or SED-ML string - :type inputStr: path - :return: generated python code - """ - factory = SEDMLCodeFactory(inputStr, workingDir=workingDir) - return factory.toPython() - - -def executeSEDML(inputStr, workingDir=None): - """Run a SED-ML file or combine archive with results. - - If a workingDir is provided the files and results are written in the workingDir. - - :param inputStr: - :type inputStr: - :return: - :rtype: - """ - # execute the sedml - factory = SEDMLCodeFactory(inputStr, workingDir=workingDir) - factory.executePython() - - -def combineArchiveToPython(omexPath): - """All python code generated from given combine archive. - - :param omexPath: - :return: dictionary of { sedml_location: pycode } - """ - tmp_dir = tempfile.mkdtemp() - pycode = {} - try: - omex.extract_combine_archive(omexPath, directory=tmp_dir, method="zip") - locations = omex.locations_by_format(omexPath, "sed-ml") - sedml_files = [os.path.join(tmp_dir, loc) for loc in locations] - - for k, sedml_file in enumerate(sedml_files): - pystr = sedmlToPython(sedml_file) - pycode[locations[k]] = pystr - - finally: - shutil.rmtree(tmp_dir) - return pycode - - -def executeCombineArchive( - omexPath, - workingDir=None, - printPython=False, - createOutputs=True, - saveOutputs=False, - outputDir=None, - plottingEngine=None, -): - """Run all SED-ML simulations in given COMBINE archive. - - If no workingDir is provided execution is performed in temporary directory - which is cleaned afterwards. - The executed code can be printed via the 'printPython' flag. - - :param omexPath: OMEX Combine archive - :param workingDir: directory to extract archive to - :param printPython: boolean switch to print executed python code - :param createOutputs: boolean flag if outputs should be created, i.e. report and plots - :param saveOutputs: flag if the outputs should be saved to file - :param outputDir: directory where the outputs should be written - :param plottingEngin: string of which plotting engine to use; uses set plotting engine otherwise - :return dictionary of sedmlFile:data generators - """ - - # combine archives are zip format - if zipfile.is_zipfile(omexPath): - try: - tmp_dir = tempfile.mkdtemp() - if workingDir is None: - extractDir = tmp_dir - else: - if not os.path.exists(workingDir): - raise IOError( - "workingDir does not exist, make sure to create the directoy: '{}'".format( - workingDir - ) - ) - extractDir = workingDir - - # extract - omex.extract_combine_archive(omex_path=omexPath, directory=extractDir) - - # get sedml locations by omex - sedml_locations = omex.locations_by_format( - omex_path=omexPath, format_key="sed-ml", method="omex" - ) - if len(sedml_locations) == 0: - - # falling back to zip archive - sedml_locations = omex.locations_by_format( - omex_path=omexPath, format_key="sed-ml", method="zip" - ) - warnings.warn( - "No SED-ML files in COMBINE archive based on manifest '{}'; Guessed SED-ML {}".format( - omexPath, sedml_locations - ) - ) - - # run all sedml files - results = {} - sedml_paths = [os.path.join(extractDir, loc) for loc in sedml_locations] - for sedmlFile in sedml_paths: - factory = SEDMLCodeFactory( - sedmlFile, - workingDir=os.path.dirname(sedmlFile), - createOutputs=createOutputs, - saveOutputs=saveOutputs, - outputDir=outputDir, - plottingEngine=plottingEngine, - ) - if printPython: - code = factory.toPython() - print(code) - - results[sedmlFile] = factory.executePython() - - return results - finally: - shutil.rmtree(tmp_dir) - else: - if not os.path.exists(omexPath): - raise FileNotFoundError("File does not exist: {}".format(omexPath)) - else: - raise IOError( - "File is not an OMEX Combine Archive in zip format: {}".format(omexPath) - ) - - -###################################################################################################################### - - -class SEDMLCodeFactory(object): - """Code Factory generating executable code.""" - - # template location - TEMPLATE_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "templates") - - def __init__( - self, - inputStr, - workingDir=None, - createOutputs=True, - saveOutputs=False, - outputDir=None, - plottingEngine=None, - ): - """Create CodeFactory for given input. - - :param inputStr: - :param workingDir: - :param createOutputs: if outputs should be created - - :return: - :rtype: - """ - self.inputStr = inputStr - self.workingDir = workingDir - self.python = sys.version - self.platform = platform.platform() - self.createOutputs = createOutputs - self.saveOutputs = saveOutputs - self.outputDir = outputDir - self.plotFormat = "pdf" - self.reportFormat = "csv" - - if not plottingEngine: - plottingEngine = te.getPlottingEngine() - self.plottingEngine = plottingEngine - - if self.outputDir: - if not os.path.exists(outputDir): - raise IOError("outputDir does not exist: {}".format(outputDir)) - - info = SEDMLTools.readSEDMLDocument(inputStr, workingDir) - self.doc = info["doc"] - self.inputType = info["inputType"] - self.workingDir = info["workingDir"] - - # parse the models (resolve the source models & the applied changes for all models) - model_sources, model_changes = SEDMLTools.resolveModelChanges(self.doc) - self.model_sources = model_sources - self.model_changes = model_changes - - def __str__(self): - """Print. - - :return: - :rtype: - """ - lines = [ - "{}".format(self.__class__), - "doc: {}".format(self.doc), - "workingDir: {}".format(self.workingDir), - "inputType: {}".format(self.inputType), - ] - if self.inputType != SEDMLTools.INPUT_TYPE_STR: - lines.append("input: {}".format(self.inputStr)) - return "\n".join(lines) - - def sedmlString(self): - """Get the SEDML XML string of the current document. - - :return: SED-ML XML - :rtype: str - """ - return libsedml.writeSedMLToString(self.doc) - - def toPython(self, python_template="tesedml_template.template"): - """Create python code by rendering the python template. - Uses the information in the SED-ML document to create - python code - - Renders the respective template. - - :return: returns the rendered template - :rtype: str - """ - # template environment - env = jinja2.Environment( - loader=jinja2.FileSystemLoader(self.TEMPLATE_DIR), - extensions=[], - trim_blocks=True, - lstrip_blocks=True, - ) - - # additional filters - # for key in sedmlfilters.filters: - # env.filters[key] = getattr(sedmlfilters, key) - template = env.get_template(python_template) - env.globals["modelToPython"] = self.modelToPython - env.globals["dataDescriptionToPython"] = self.dataDescriptionToPython - env.globals["taskToPython"] = self.taskToPython - env.globals["dataGeneratorToPython"] = self.dataGeneratorToPython - env.globals["outputToPython"] = self.outputToPython - - # timestamp - time = datetime.datetime.now() - timestamp = time.strftime("%Y-%m-%dT%H:%M:%S") - - # Context - c = { - "version": te.getTelluriumVersion(), - "timestamp": timestamp, - "factory": self, - "doc": self.doc, - "model_sources": self.model_sources, - "model_changes": self.model_changes, - } - pysedml = template.render(c) - - return pysedml - - def executePython(self): - """Executes python code. - - The python code is created during the function call. - See :func:`createpython` - - :return: returns dictionary of information with keys - """ - result = {} - code = self.toPython() - result["code"] = code - result["platform"] = platform.platform() - - # FIXME: better solution for exec traceback - filename = os.path.join(tempfile.gettempdir(), "te-generated-sedml.py") - - try: - # Use of exec carries the usual security warnings - symbols = {} - exec(compile(code, filename, "exec"), symbols) - - # read information from exec symbols - dg_data = {} - for dg in self.doc.getListOfDataGenerators(): - dg_id = dg.getId() - dg_data[dg_id] = symbols[dg_id] - result["dataGenerators"] = dg_data - return result - - except: - # leak this tempfile just so we can see a full stack trace. freaking python. - with open(filename, "w") as f: - f.write(code) - raise - - def modelToPython(self, model): - """Python code for SedModel. - - :param model: SedModel instance - :type model: SedModel - :return: python str - :rtype: str - """ - lines = [] - mid = model.getId() - language = model.getLanguage() - source = self.model_sources[mid] - - if not language: - warnings.warn( - "No model language specified, defaulting to SBML for: {}".format(source) - ) - - def isUrn(): - return source.startswith("urn") or source.startswith("URN") - - def isHttp(): - return source.startswith("http") or source.startswith("HTTP") - - # read SBML - if "sbml" in language or len(language) == 0: - if isUrn(): - lines.append("import tellurium.temiriam as temiriam") - lines.append( - "__{}_sbml = temiriam.getSBMLFromBiomodelsURN('{}')".format( - mid, source - ) - ) - lines.append("{} = te.loadSBMLModel(__{}_sbml)".format(mid, mid)) - elif isHttp(): - lines.append("{} = te.loadSBMLModel('{}')".format(mid, source)) - else: - lines.append( - "{} = te.loadSBMLModel(os.path.join(workingDir, '{}'))".format( - mid, source - ) - ) - # read CellML - elif "cellml" in language: - warnings.warn( - "CellML model encountered. Tellurium CellML support is very limited.".format( - language - ) - ) - if isHttp(): - lines.append("{} = te.loadCellMLModel('{}')".format(mid, source)) - else: - lines.append( - "{} = te.loadCellMLModel(os.path.join(workingDir, '{}'))".format( - mid, self.model_sources[mid] - ) - ) - # other - else: - warnings.warn("Unsupported model language: '{}'.".format(language)) - - # apply model changes - for change in self.model_changes[mid]: - lines.extend(SEDMLCodeFactory.modelChangeToPython(model, change)) - - return "\n".join(lines) - - @staticmethod - def modelChangeToPython(model, change): - """Creates the apply change python string for given model and change. - - Currently only a very limited subset of model changes is supported. - Namely changes of parameters and concentrations within a SedChangeAttribute. - - :param model: given model - :type model: SedModel - :param change: model change - :type change: SedChange - :return: - :rtype: str - """ - lines = [] - mid = model.getId() - xpath = change.getTarget() - - if change.getTypeCode() == libsedml.SEDML_CHANGE_ATTRIBUTE: - # resolve target change - value = change.getNewValue() - lines.append("# {} {}".format(xpath, value)) - lines.append(SEDMLCodeFactory.targetToPython(xpath, value, modelId=mid)) - - elif change.getTypeCode() == libsedml.SEDML_CHANGE_COMPUTECHANGE: - variables = {} - for par in change.getListOfParameters(): - variables[par.getId()] = par.getValue() - for var in change.getListOfVariables(): - vid = var.getId() - selection = SEDMLCodeFactory.selectionFromVariable(var, mid) - expr = selection.id - if selection.type == "concentration": - expr = "init([{}])".format(selection.id) - elif selection.type == "amount": - expr = "init({})".format(selection.id) - lines.append("__var__{} = {}['{}']".format(vid, mid, expr)) - variables[vid] = "__var__{}".format(vid) - - # value is calculated with the current state of model - value = evaluableMathML(change.getMath(), variables=variables) - lines.append(SEDMLCodeFactory.targetToPython(xpath, value, modelId=mid)) - - elif change.getTypeCode() in [ - libsedml.SEDML_CHANGE_REMOVEXML, - libsedml.SEDML_CHANGE_ADDXML, - libsedml.SEDML_CHANGE_CHANGEXML, - ]: - lines.append("# Unsupported change: {}".format(change.getElementName())) - warnings.warn("Unsupported change: {}".format(change.getElementName())) - else: - lines.append("# Unsupported change: {}".format(change.getElementName())) - warnings.warn("Unsupported change: {}".format(change.getElementName())) - - return lines - - def dataDescriptionToPython(self, dataDescription): - """Python code for DataDescription. - - :param dataDescription: SedModel instance - :type dataDescription: DataDescription - :return: python str - :rtype: str - """ - lines = [] - - from tellurium.sedml.data import DataDescriptionParser - - data_sources = DataDescriptionParser.parse(dataDescription, self.workingDir) - - def data_to_string(data): - info = np.array2string(data) - # cleaner string and NaN handling - info = info.replace("\n", ", ").replace("\r", "").replace("nan", "np.nan") - return info - - for sid, data in data_sources.items(): - # handle the 1D shapes - if len(data.shape) == 1: - data = np.reshape(data.values, (data.shape[0], 1)) - - array_str = data_to_string(data) - lines.append("{} = np.array({})".format(sid, array_str)) - - return "\n".join(lines) - - ################################################################################################ - # Here the main work is done, - # transformation of tasks to python code - ################################################################################################ - @staticmethod - def taskToPython(doc, task): - """Create python for arbitrary task (repeated or simple). - - :param doc: - :type doc: - :param task: - :type task: - :return: - :rtype: - """ - # If no DataGenerator references the task, no execution is necessary - dgs = SEDMLCodeFactory.getDataGeneratorsForTask(doc, task) - if len(dgs) == 0: - return "# not part of any DataGenerator: {}".format(task.getId()) - - # tasks contain other subtasks, which can contain subtasks. This - # results in a tree of task dependencies where the - # simple tasks are the node leaves. These tree has to be resolved to - # generate code for more complex task dependencies. - - # resolve task tree (order & dependency of tasks) & generate code - taskTree = SEDMLCodeFactory.createTaskTree(doc, rootTask=task) - return SEDMLCodeFactory.taskTreeToPython(doc, tree=taskTree) - - class TaskNode(object): - """Tree implementation of task tree.""" - - def __init__(self, task, depth): - self.task = task - self.depth = depth - self.children = [] - self.parent = None - - def add_child(self, obj): - obj.parent = self - self.children.append(obj) - - def is_leaf(self): - return len(self.children) == 0 - - def __str__(self): - lines = [ - "<[{}] {} ({})>".format( - self.depth, self.task.getId(), self.task.getElementName() - ) - ] - for child in self.children: - child_str = child.__str__() - lines.extend(["\t{}".format(line) for line in child_str.split("\n")]) - return "\n".join(lines) - - def info(self): - return "<[{}] {} ({})>".format( - self.depth, self.task.getId(), self.task.getElementName() - ) - - def __iter__(self): - """Depth-first iterator which yields TaskNodes.""" - yield self - for child in self.children: - for node in child: - yield node - - class Stack(object): - """Stack implementation for nodes.""" - - def __init__(self): - self.items = [] - - def isEmpty(self): - return self.items == [] - - def push(self, item): - self.items.append(item) - - def pop(self): - return self.items.pop() - - def peek(self): - return self.items[len(self.items) - 1] - - def size(self): - return len(self.items) - - def __str__(self): - return "stack: " + str([item.info() for item in self.items]) - - @staticmethod - def createTaskTree(doc, rootTask): - """Creates the task tree. - Required for resolution of order of all simulations. - """ - - def add_children(node): - typeCode = node.task_id.getTypeCode() - if typeCode == libsedml.SEDML_TASK: - return # no children - elif typeCode == libsedml.SEDML_TASK_REPEATEDTASK: - # add the ordered list of subtasks as children - subtasks = SEDMLCodeFactory.getOrderedSubtasks(node.task_id) - for st in subtasks: - # get real task for subtask - t = doc.getTask(st.getTask()) - child = SEDMLCodeFactory.TaskNode(t, depth=node.depth + 1) - node.add_child(child) - # recursive adding of children - add_children(child) - else: - raise IOError( - "Unsupported task type: {}".format(node.task_id.getElementName()) - ) - - # create root - root = SEDMLCodeFactory.TaskNode(rootTask, depth=0) - # recursive adding of children - add_children(root) - return root - - @staticmethod - def getOrderedSubtasks(task): - """Ordered list of subtasks for task.""" - subtasks = task.getListOfSubTasks() - subtaskOrder = [st.getOrder() for st in subtasks] - # sort by order, if all subtasks have order (not required) - if all(subtaskOrder) != None: - subtasks = [st for (stOrder, st) in sorted(zip(subtaskOrder, subtasks))] - return subtasks - - @staticmethod - def taskTreeToPython(doc, tree): - """Python code generation from task tree.""" - - # go forward through task tree - lines = [] - nodeStack = SEDMLCodeFactory.Stack() - treeNodes = [n for n in tree] - - # iterate over the tree - for kn, node in enumerate(treeNodes): - taskType = node.task_id.getTypeCode() - - # Create information for task - # We are going down in the tree - if taskType == libsedml.SEDML_TASK_REPEATEDTASK: - taskLines = SEDMLCodeFactory.repeatedTaskToPython(doc, node=node) - - elif taskType == libsedml.SEDML_TASK: - tid = node.task_id.getId() - taskLines = SEDMLCodeFactory.simpleTaskToPython(doc=doc, node=node) - else: - lines.append("# Unsupported task: {}".format(taskType)) - warnings.warn("Unsupported task: {}".format(taskType)) - - lines.extend([" " * node.depth + line for line in taskLines]) - - ''' - @staticmethod - def simpleTaskToPython(doc, task): - """ Create python for simple task. """ - for ksub, subtask in enumerate(subtasks): - t = doc.getTask(subtask.getTask()) - - resultVariable = "__subtask__".format(t.getId()) - selections = SEDMLCodeFactory.selectionsForTask(doc=doc, task=task) - if t.getTypeCode() == libsedml.SEDML_TASK: - forLines.extend(SEDMLCodeFactory.subtaskToPython(doc, task=t, - selections=selections, - resultVariable=resultVariable)) - forLines.append("{}.extend([__subtask__])".format(task.getId())) - - elif t.getTypeCode() == libsedml.SEDML_TASK_REPEATEDTASK: - forLines.extend(SEDMLCodeFactory.repeatedTaskToPython(doc, task=t)) - forLines.append("{}.extend({})".format(task.getId(), t.getId())) - ''' - - # Collect information - # We have to go back up - # Look at next node in the treeNodes (this is the next one to write) - if kn == (len(treeNodes) - 1): - nextNode = None - else: - nextNode = treeNodes[kn + 1] - - # The next node is further up in the tree, or there is no next node - # and still nodes on the stack - if (nextNode is None) or (nextNode.depth < node.depth): - - # necessary to pop nodes from the stack and close the code - test = True - while test is True: - # stack is empty - if nodeStack.size() == 0: - test = False - continue - # try to pop next one - peek = nodeStack.peek() - if (nextNode is None) or (peek.depth > nextNode.depth): - # TODO: reset evaluation has to be defined here - # determine if it's steady state - # if taskType == libsedml.SEDML_TASK_REPEATEDTASK: - # print('task {}'.format(node.task.getId())) - # print(' peek {}'.format(peek.task.getId())) - if ( - node.task_id.getTypeCode() - == libsedml.SEDML_TASK_REPEATEDTASK - ): - # if peek.task.getTypeCode() == libsedml.SEDML_TASK_REPEATEDTASK: - # sid = task.getSimulationReference() - # simulation = doc.getSimulation(sid) - # simType = simulation.getTypeCode() - # if simType is libsedml.SEDML_SIMULATION_STEADYSTATE: - terminator = "terminate_trace({})".format( - node.task_id.getId() - ) - else: - terminator = "{}".format(node.task_id.getId()) - - lines.extend( - [ - "", - # " "*node.depth + "{}.extend({})".format(peek.task.getId(), terminator), - " " * node.depth - + "{}.extend({})".format( - peek.task_id.getId(), node.task_id.getId() - ), - ] - ) - node = nodeStack.pop() - - else: - test = False - else: - # we are going done or next subtask -> put node on stack - nodeStack.push(node) - - return "\n".join(lines) - - @staticmethod - def simpleTaskToPython(doc, node): - """Creates the simulation python code for a given taskNode. - - The taskNodes are required to handle the relationships between - RepeatedTasks, SubTasks and SimpleTasks (Task). - - :param doc: sedml document - :type doc: SEDDocument - :param node: taskNode of the current task - :type node: TaskNode - :return: - :rtype: - """ - lines = [] - task = node.task_id - lines.append("# Task: <{}>".format(task.getId())) - lines.append("{} = [None]".format(task.getId())) - - mid = task.getModelReference() - sid = task.getSimulationReference() - simulation = doc.getSimulation(sid) - - simType = simulation.getTypeCode() - algorithm = simulation.getAlgorithm() - if algorithm is None: - warnings.warn( - "Algorithm missing on simulation, defaulting to 'cvode: KISAO:0000019'" - ) - algorithm = simulation.createAlgorithm() - algorithm.setKisaoID("KISAO:0000019") - kisao = algorithm.getKisaoID() - - # is supported algorithm - if not SEDMLCodeFactory.isSupportedAlgorithmForSimulationType( - kisao=kisao, simType=simType - ): - warnings.warn( - "Algorithm {} unsupported for simulation {} type {} in task {}".format( - kisao, simulation.getId(), simType, task.getId() - ) - ) - lines.append( - "# Unsupported Algorithm {} for SimulationType {}".format( - kisao, simulation.getElementName() - ) - ) - return lines - - # set integrator/solver - integratorName = SEDMLCodeFactory.getIntegratorNameForKisaoID(kisao) - if not integratorName: - warnings.warn("No integrator exists for {} in roadrunner".format(kisao)) - return lines - - if simType is libsedml.SEDML_SIMULATION_STEADYSTATE: - lines.append("{}.setSteadyStateSolver('{}')".format(mid, integratorName)) - else: - lines.append("{}.setIntegrator('{}')".format(mid, integratorName)) - - # use fixed step by default for stochastic sims - if integratorName == "gillespie": - lines.append( - "{}.integrator.setValue('{}', {})".format( - mid, "variable_step_size", False - ) - ) - - if kisao == "KISAO:0000288": # BDF - lines.append("{}.integrator.setValue('{}', {})".format(mid, "stiff", True)) - elif kisao == "KISAO:0000280": # Adams-Moulton - lines.append("{}.integrator.setValue('{}', {})".format(mid, "stiff", False)) - - # integrator/solver settings (AlgorithmParameters) - for par in algorithm.getListOfAlgorithmParameters(): - pkey = SEDMLCodeFactory.algorithmParameterToParameterKey(par) - # only set supported algorithm paramters - if pkey: - if pkey.dtype is str: - value = "'{}'".format(pkey.value) - else: - value = pkey.value - - if value == str("inf") or pkey.value == float("inf"): - value = "float('inf')" - else: - pass - - if simType is libsedml.SEDML_SIMULATION_STEADYSTATE: - lines.append( - "{}.steadyStateSolver.setValue('{}', {})".format( - mid, pkey.key, value - ) - ) - else: - lines.append( - "{}.integrator.setValue('{}', {})".format(mid, pkey.key, value) - ) - - if simType is libsedml.SEDML_SIMULATION_STEADYSTATE: - lines.append( - "if {model}.conservedMoietyAnalysis == False: {model}.conservedMoietyAnalysis = True".format( - model=mid - ) - ) - else: - lines.append( - "if {model}.conservedMoietyAnalysis == True: {model}.conservedMoietyAnalysis = False".format( - model=mid - ) - ) - - # get parents - parents = [] - parent = node.parent - while parent is not None: - parents.append(parent) - parent = parent.parent - - # of all parents - # --------------------------- - selections = SEDMLCodeFactory.selectionsForTask(doc=doc, task=node.task_id) - for p in parents: - selections.update( - SEDMLCodeFactory.selectionsForTask(doc=doc, task=p.task_id) - ) - - # of all parents - # --------------------------- - # apply changes based on current variables, parameters and range variables - for parent in reversed(parents): - rangeId = parent.task_id.getRangeId() - helperRanges = {} - for r in parent.task_id.getListOfRanges(): - if r.getId() != rangeId: - helperRanges[r.getId()] = r - - for setValue in parent.task_id.getListOfTaskChanges(): - variables = {} - # range variables - variables[rangeId] = "__value__{}".format(rangeId) - for key in helperRanges.keys(): - variables[key] = "__value__{}".format(key) - # parameters - for par in setValue.getListOfParameters(): - variables[par.getId()] = par.getValue() - for var in setValue.getListOfVariables(): - vid = var.getId() - mid = var.getModelReference() - selection = SEDMLCodeFactory.selectionFromVariable(var, mid) - expr = selection.id - if selection.type == "concentration": - expr = "init([{}])".format(selection.id) - elif selection.type == "amount": - expr = "init({})".format(selection.id) - - # create variable - lines.append("__value__{} = {}['{}']".format(vid, mid, expr)) - # variable for replacement - variables[vid] = "__value__{}".format(vid) - - # value is calculated with the current state of model - lines.append( - SEDMLCodeFactory.targetToPython( - xpath=setValue.getTarget(), - value=evaluableMathML(setValue.getMath(), variables=variables), - modelId=setValue.getModelReference(), - ) - ) - - # handle result variable - resultVariable = "{}[0]".format(task.getId()) - - # ------------------------------------------------------------------------- - # - # ------------------------------------------------------------------------- - if simType == libsedml.SEDML_SIMULATION_UNIFORMTIMECOURSE: - lines.append("{}.timeCourseSelections = {}".format(mid, list(selections))) - - initialTime = simulation.getInitialTime() - outputStartTime = simulation.getOutputStartTime() - outputEndTime = simulation.getOutputEndTime() - numberOfPoints = simulation.getNumberOfPoints() - - # reset before simulation (see https://github.com/sys-bio/tellurium/issues/193) - lines.append("{}.reset()".format(mid)) - - # throw some points away - if abs(outputStartTime - initialTime) > 1e-6: - lines.append( - "{}.simulate(start={}, end={}, points=2)".format( - mid, initialTime, outputStartTime - ) - ) - # real simulation - lines.append( - "{} = {}.simulate(start={}, end={}, steps={})".format( - resultVariable, mid, outputStartTime, outputEndTime, numberOfPoints - ) - ) - # ------------------------------------------------------------------------- - # - # ------------------------------------------------------------------------- - elif simType == libsedml.SEDML_SIMULATION_ONESTEP: - lines.append("{}.timeCourseSelections = {}".format(mid, list(selections))) - step = simulation.getStep() - lines.append( - "{} = {}.simulate(start={}, end={}, points=2)".format( - resultVariable, mid, 0.0, step - ) - ) - - # ------------------------------------------------------------------------- - # - # ------------------------------------------------------------------------- - elif simType == libsedml.SEDML_SIMULATION_STEADYSTATE: - lines.append( - "{}.steadyStateSolver.setValue('{}', {})".format( - mid, "allow_presimulation", False - ) - ) - lines.append("{}.steadyStateSelections = {}".format(mid, list(selections))) - lines.append( - "{}.simulate()".format(mid) - ) # for stability of the steady state solver - lines.append("{} = {}.steadyStateNamedArray()".format(resultVariable, mid)) - # no need to turn this off because it will be checked before the next simulation - # lines.append("{}.conservedMoietyAnalysis = False".format(mid)) - - # ------------------------------------------------------------------------- - # - # ------------------------------------------------------------------------- - else: - lines.append("# Unsupported simulation: {}".format(simType)) - - return lines - - @staticmethod - def repeatedTaskToPython(doc, node): - """Create python for RepeatedTask. - - Must create - - the ranges (Ranges) - - apply all changes (SetValues) - """ - # storage of results - task = node.task_id - lines = ["", "{} = []".format(task.getId())] - - # - # master range - rangeId = task.getRangeId() - masterRange = task.getRange(rangeId) - if masterRange.getTypeCode() == libsedml.SEDML_RANGE_UNIFORMRANGE: - lines.extend(SEDMLCodeFactory.uniformRangeToPython(masterRange)) - elif masterRange.getTypeCode() == libsedml.SEDML_RANGE_VECTORRANGE: - lines.extend(SEDMLCodeFactory.vectorRangeToPython(masterRange)) - elif masterRange.getTypeCode() == libsedml.SEDML_RANGE_FUNCTIONALRANGE: - warnings.warn("FunctionalRange for master range not supported in task.") - # lock-in ranges - for r in task.getListOfRanges(): - if r.getId() != rangeId: - if r.getTypeCode() == libsedml.SEDML_RANGE_UNIFORMRANGE: - lines.extend(SEDMLCodeFactory.uniformRangeToPython(r)) - elif r.getTypeCode() == libsedml.SEDML_RANGE_VECTORRANGE: - lines.extend(SEDMLCodeFactory.vectorRangeToPython(r)) - - # - # iterate master range - lines.append( - "for __k__{}, __value__{} in enumerate(__range__{}):".format( - rangeId, rangeId, rangeId - ) - ) - - # Everything from now on is done in every iteration of the range - # We have to collect & intent all lines in the loop) - forLines = [] - - # definition of lock-in ranges - helperRanges = {} - for r in task.getListOfRanges(): - if r.getId() != rangeId: - helperRanges[r.getId()] = r - if r.getTypeCode() in [ - libsedml.SEDML_RANGE_UNIFORMRANGE, - libsedml.SEDML_RANGE_VECTORRANGE, - ]: - forLines.append( - "__value__{} = __range__{}[__k__{}]".format( - r.getId(), r.getId(), rangeId - ) - ) - - # - if r.getTypeCode() == libsedml.SEDML_RANGE_FUNCTIONALRANGE: - variables = {} - # range variables - variables[rangeId] = "__value__{}".format(rangeId) - for key in helperRanges.keys(): - variables[key] = "__value__{}".format(key) - # parameters - for par in r.getListOfParameters(): - variables[par.getId()] = par.getValue() - for var in r.getListOfVariables(): - vid = var.getId() - mid = var.getModelReference() - selection = SEDMLCodeFactory.selectionFromVariable(var, mid) - expr = selection.id - if selection.type == "concentration": - expr = "[{}]".format(selection.id) - lines.append("__value__{} = {}['{}']".format(vid, mid, expr)) - variables[vid] = "__value__{}".format(vid) - - # value is calculated with the current state of model - value = evaluableMathML(r.getMath(), variables=variables) - forLines.append("__value__{} = {}".format(r.getId(), value)) - - # - # models to reset via task tree below node - mids = set([]) - for child in node: - t = child.task_id - if t.getTypeCode() == libsedml.SEDML_TASK: - mids.add(t.getModelReference()) - # reset models referenced in tree below task - for mid in mids: - if task.getResetModel(): - # reset before every iteration - forLines.append("{}.reset()".format(mid)) - else: - # reset before first iteration - forLines.append("if __k__{} == 0:".format(rangeId)) - forLines.append(" {}.reset()".format(mid)) - - # add lines - lines.extend(" " + line for line in forLines) - - return lines - - ################################################################################################ - - @staticmethod - def getDataGeneratorsForTask(doc, task): - """Get the DataGenerators which reference the given task. - - :param doc: - :type doc: - :param task: - :type task: - :return: - :rtype: - """ - dgs = [] - for dg in doc.getListOfDataGenerators(): - for var in dg.getListOfVariables(): - if var.getTaskReference() == task.getId(): - dgs.append(dg) - break # the DataGenerator is added, no need to look at rest of variables - return dgs - - @staticmethod - def selectionsForTask(doc, task): - """Populate variable lists from the data generators for the given task. - - These are the timeCourseSelections and steadyStateSelections - in RoadRunner. - - Search all data generators for variables which have to be part of the simulation. - """ - modelId = task.getModelReference() - selections = set() - for dg in doc.getListOfDataGenerators(): - for var in dg.getListOfVariables(): - if var.getTaskReference() == task.getId(): - selection = SEDMLCodeFactory.selectionFromVariable(var, modelId) - expr = selection.id - if selection.type == "concentration": - expr = "[{}]".format(selection.id) - selections.add(expr) - - return selections - - @staticmethod - def uniformRangeToPython(r): - """Create python lines for uniform range. - :param r: - :type r: - :return: - :rtype: - """ - lines = [] - rId = r.getId() - rStart = r.getStart() - rEnd = r.getEnd() - rPoints = r.getNumberOfPoints() + 1 # One point more than number of points - rType = r.getType() - if rType in ["Linear", "linear"]: - lines.append( - "__range__{} = np.linspace(start={}, stop={}, num={})".format( - rId, rStart, rEnd, rPoints - ) - ) - elif rType in ["Log", "log"]: - lines.append( - "__range__{} = np.logspace(start={}, stop={}, num={})".format( - rId, rStart, rEnd, rPoints - ) - ) - else: - warnings.warn("Unsupported range type in UniformRange: {}".format(rType)) - return lines - - @staticmethod - def vectorRangeToPython(r): - lines = [] - __range = np.zeros(shape=[r.getNumValues()]) - for k, v in enumerate(r.getValues()): - __range[k] = v - lines.append("__range__{} = {}".format(r.getId(), list(__range))) - return lines - - @staticmethod - def isSupportedAlgorithmForSimulationType(kisao, simType): - """Check Algorithm Kisao Id is supported for simulation. - - :return: is supported - :rtype: bool - """ - supported = [] - if simType == libsedml.SEDML_SIMULATION_UNIFORMTIMECOURSE: - supported = KISAOS_UNIFORMTIMECOURSE - elif simType == libsedml.SEDML_SIMULATION_ONESTEP: - supported = KISAOS_ONESTEP - elif simType == libsedml.SEDML_SIMULATION_STEADYSTATE: - supported = KISAOS_STEADYSTATE - return kisao in supported - - @staticmethod - def getIntegratorNameForKisaoID(kid): - """RoadRunner integrator name for algorithm KisaoID. - - :param kid: KisaoID - :type kid: str - :return: RoadRunner integrator name. - :rtype: str - """ - if kid in KISAOS_NLEQ: - return "nleq2" - if kid in KISAOS_CVODE: - return "cvode" - if kid in KISAOS_GILLESPIE: - return "gillespie" - if kid in KISAOS_RK4: - return "rk4" - if kid in KISAOS_RK45: - return "rk45" - if kid in KISAOS_LSODA: - warnings.warn("Tellurium does not support LSODA. Using CVODE instead.") - return "cvode" # just use cvode - return None - - @staticmethod - def algorithmParameterToParameterKey(par): - """Resolve the mapping between parameter keys and roadrunner integrator keys.""" - ParameterKey = namedtuple("ParameterKey", "key value dtype") - kid = par.getKisaoID() - value = par.getValue() - - if kid in KISAOS_ALGORITHMPARAMETERS: - # algorithm parameter is in the list of parameters - key, dtype = KISAOS_ALGORITHMPARAMETERS[kid] - if dtype is bool: - # transform manually ! (otherwise all strings give True) - if value == "true": - value = True - elif value == "false": - value = False - else: - # cast to data type of parameter - value = dtype(value) - return ParameterKey(key, value, dtype) - else: - # algorithm parameter not supported - warnings.warn("Unsupported AlgorithmParameter: {} = {})".format(kid, value)) - return None - - @staticmethod - def targetToPython(xpath, value, modelId): - """Creates python line for given xpath target and value. - :param xpath: - :type xpath: - :param value: - :type value: - :return: - :rtype: - """ - target = SEDMLCodeFactory._resolveXPath(xpath, modelId) - if target: - # initial concentration - if target.type == "concentration": - expr = "init([{}])".format(target.id) - # initial amount - elif target.type == "amount": - expr = "init({})".format(target.id) - # other (parameter, flux, ...) - else: - expr = target.id - line = "{}['{}'] = {}".format(modelId, expr, value) - else: - line = "# Unsupported target xpath: {}".format(xpath) - - return line - - @staticmethod - def selectionFromVariable(var, modelId): - """Resolves the selection for the given variable. - - First checks if the variable is a symbol and returns the symbol. - If no symbol is set the xpath of the target is resolved - and used in the selection - - :param var: variable to resolve - :type var: SedVariable - :return: a single selection - :rtype: Selection (namedtuple: id type) - """ - Selection = namedtuple("Selection", "id type") - - # parse symbol expression - if var.isSetSymbol(): - cvs = var.getSymbol() - astr = cvs.rsplit("symbol:") - sid = astr[1] - return Selection(sid, "symbol") - # use xpath - elif var.isSetTarget(): - xpath = var.getTarget() - target = SEDMLCodeFactory._resolveXPath(xpath, modelId) - return Selection(target.id, target.type) - - else: - warnings.warn("Unrecognized Selection in variable") - return None - - @staticmethod - def _resolveXPath(xpath, modelId): - """Resolve the target from the xpath expression. - - A single target in the model corresponding to the modelId is resolved. - Currently, the model is not used for xpath resolution. - - :param xpath: xpath expression. - :type xpath: str - :param modelId: id of model in which xpath should be resolved - :type modelId: str - :return: single target of xpath expression - :rtype: Target (namedtuple: id type) - """ - # TODO: via better xpath expression - # get type from the SBML document for the given id. - # The xpath expression can be very general and does not need to contain the full - # xml path - # For instance: - # /sbml:sbml/sbml:model/descendant::*[@id='S1'] - # has to resolve to species. - # TODO: figure out concentration or amount (from SBML document) - # FIXME: getting of sids, pids not very robust, handle more cases (rules, reactions, ...) - - Target = namedtuple("Target", "id type") - - def getId(xpath): - xpath = xpath.replace('"', "'") - match = re.findall(r"id='(.*?)'", xpath) - if (match is None) or (len(match) is 0): - warnings.warn("Xpath could not be resolved: {}".format(xpath)) - return match[0] - - # parameter value change - if ("model" in xpath) and ("parameter" in xpath): - return Target(getId(xpath), "parameter") - # species concentration change - elif ("model" in xpath) and ("species" in xpath): - return Target(getId(xpath), "concentration") - # other - elif ("model" in xpath) and ("id" in xpath): - return Target(getId(xpath), "other") - # cannot be parsed - else: - raise ValueError("Unsupported target in xpath: {}".format(xpath)) - - @staticmethod - def dataGeneratorToPython(doc, generator): - """Create variable from the data generators and the simulation results and data sources. - - The data of repeatedTasks is handled differently depending - on if reset=True or reset=False. - reset=True: - every repeat is a single curve, i.e. the data is a list of data - reset=False: - all curves belong to a single simulation and are concatenated to one dataset - """ - lines = [] - gid = generator.getId() - mathml = generator.getMath() - - # create variables - variables = {} - for par in generator.getListOfParameters(): - variables[par.getId()] = par.getValue() - for var in generator.getListOfVariables(): - varId = var.getId() - variables[varId] = "__var__{}".format(varId) - - # create python for variables - for var in generator.getListOfVariables(): - varId = var.getId() - taskId = var.getTaskReference() - task = doc.getTask(taskId) - - # simulation data - if task is not None: - modelId = task.getModelReference() - - selection = SEDMLCodeFactory.selectionFromVariable(var, modelId) - isTime = False - if selection.type == "symbol" and selection.id == "time": - isTime = True - - resetModel = True - if task.getTypeCode() == libsedml.SEDML_TASK_REPEATEDTASK: - resetModel = task.getResetModel() - - sid = selection.id - if selection.type == "concentration": - sid = "[{}]".format(selection.id) - - # Series of curves - if resetModel is True: - # If each entry in the task consists of a single point (e.g. steady state scan) - # , concatenate the points. Otherwise, plot as separate curves. - import os - - if "PROCESS_TRACE" in os.environ and os.environ["PROCESS_TRACE"]: - lines.append( - "__var__{} = np.concatenate([process_trace(sim['{}']) for sim in {}])".format( - varId, sid, taskId - ) - ) - else: - lines.append( - "__var__{} = np.concatenate([sim['{}'] for sim in {}])".format( - varId, sid, taskId - ) - ) - else: - # One curve via time adjusted concatenate - if isTime is True: - lines.append( - "__offsets__{} = np.cumsum(np.array([sim['{}'][-1] for sim in {}]))".format( - taskId, sid, taskId - ) - ) - lines.append( - "__offsets__{} = np.insert(__offsets__{}, 0, 0)".format( - taskId, taskId - ) - ) - lines.append( - "__var__{} = np.transpose(np.array([sim['{}']+__offsets__{}[k] for k, sim in enumerate({})]))".format( - varId, sid, taskId, taskId - ) - ) - lines.append( - "__var__{} = np.concatenate(np.transpose(__var__{}))".format( - varId, varId - ) - ) - else: - lines.append( - "__var__{} = np.transpose(np.array([sim['{}'] for sim in {}]))".format( - varId, sid, taskId - ) - ) - lines.append( - "__var__{} = np.concatenate(np.transpose(__var__{}))".format( - varId, varId - ) - ) - lines.append("if len(__var__{}.shape) == 1:".format(varId)) - lines.append(" __var__{}.shape += (1,)".format(varId)) - - # check for data sources - else: - target = var.getTarget() - if target.startswith("#"): - sid = target[1:] - lines.append("__var__{} = {}".format(varId, sid)) - else: - warnings.warn( - "Unknown target in variable, no reference to SId: {}".format( - target - ) - ) - - # calculate data generator - value = evaluableMathML(mathml, variables=variables, array=True) - lines.append("{} = {}".format(gid, value)) - - return "\n".join(lines) - - def outputToPython(self, doc, output): - """Create output""" - lines = [] - typeCode = output.getTypeCode() - if typeCode == libsedml.SEDML_OUTPUT_REPORT: - lines.extend(SEDMLCodeFactory.outputReportToPython(self, doc, output)) - elif typeCode == libsedml.SEDML_OUTPUT_PLOT2D: - lines.extend(SEDMLCodeFactory.outputPlot2DToPython(self, doc, output)) - elif typeCode == libsedml.SEDML_OUTPUT_PLOT3D: - lines.extend(SEDMLCodeFactory.outputPlot3DToPython(self, doc, output)) - else: - warnings.warn( - "# Unsupported output type '{}' in output {}".format( - output.getElementName(), output.getId() - ) - ) - return "\n".join(lines) - - def outputReportToPython(self, doc, output): - """OutputReport - - :param doc: - :type doc: SedDocument - :param output: - :type output: SedOutputReport - :return: list of python lines - :rtype: list(str) - """ - lines = [] - headers = [] - dgIds = [] - columns = [] - for dataSet in output.getListOfDataSets(): - # these are the columns - headers.append(dataSet.getLabel()) - # data generator (the id is the id of the data in python) - dgId = dataSet.getDataReference() - dgIds.append(dgId) - columns.append("{}[:,k]".format(dgId)) - # create data frames for the repeats - lines.append("__dfs__{} = []".format(output.getId())) - lines.append("for k in range({}.shape[1]):".format(dgIds[0])) - lines.append( - " __df__k = pandas.DataFrame(np.column_stack(" - + str(columns).replace("'", "") - + "), \n columns=" - + str(headers) - + ")" - ) - lines.append(" __dfs__{}.append(__df__k)".format(output.getId())) - # save as variable in Tellurium - lines.append(" te.setLastReport(__df__k)".format(output.getId())) - if self.saveOutputs and self.createOutputs: - - lines.append( - " filename = os.path.join('{}', '{}.{}')".format( - self.outputDir, output.getId(), self.reportFormat - ) - ) - lines.append( - " __df__k.to_csv(filename, sep=',', index=False)".format( - output.getId() - ) - ) - lines.append( - " print('Report {}: {{}}'.format(filename))".format(output.getId()) - ) - return lines - - @staticmethod - def outputPlotSettings(): - """Settings for all plot types. - - :return: - :rtype: - """ - PlotSettings = namedtuple( - "PlotSettings", - "colors, figsize, dpi, facecolor, edgecolor, linewidth, marker, markersize, alpha", - ) - - # all lines of same cuve have same color - settings = PlotSettings( - colors=[ - u"#1f77b4", - u"#ff7f0e", - u"#2ca02c", - u"#d62728", - u"#9467bd", - u"#8c564b", - u"#e377c2", - u"#7f7f7f", - u"#bcbd22", - u"#17becf", - ], - figsize=(9, 5), - dpi=80, - facecolor="w", - edgecolor="k", - linewidth=1.5, - marker="", - markersize=3.0, - alpha=1.0, - ) - return settings - - def outputPlot2DToPython(self, doc, output): - """OutputReport - - If workingDir is provided the plot is saved in the workingDir. - :param doc: - :type doc: SedDocument - :param output: - :type output: SedOutputReport - :return: list of python lines - :rtype: list(str) - """ - - # TODO: logX and logY not applied - lines = [] - settings = SEDMLCodeFactory.outputPlotSettings() - - # figure title - title = output.getId() - if output.isSetName(): - title = "{}".format(output.getName()) - - # xtitle - oneXLabel = True - allXLabel = None - for kc, curve in enumerate(output.getListOfCurves()): - xId = curve.getXDataReference() - dgx = doc.getDataGenerator(xId) - xLabel = xId - if dgx.isSetName(): - xLabel = "{}".format(dgx.getName()) - - # do all curves have the same xLabel - if kc == 0: - allXLabel = xLabel - elif xLabel != allXLabel: - oneXLabel = False - xtitle = "" - if oneXLabel: - xtitle = allXLabel - - lines.append("_stacked = False") - # stacking, currently disabled - # lines.append("_stacked = False") - # lines.append("_engine = te.getPlottingEngine()") - # for kc, curve in enumerate(output.getListOfCurves()): - # xId = curve.getXDataReference() - # lines.append("if {}.shape[1] > 1 and te.getDefaultPlottingEngine() == 'plotly':".format(xId)) - # lines.append(" stacked=True") - lines.append("if _stacked:") - lines.append( - " tefig = te.getPlottingEngine().newStackedFigure(title='{}', xtitle='{}')".format( - title, xtitle - ) - ) - lines.append("else:") - lines.append( - " tefig = te.nextFigure(title='{}', xtitle='{}')\n".format(title, xtitle) - ) - - for kc, curve in enumerate(output.getListOfCurves()): - logX = curve.getLogX() - logY = curve.getLogY() - xId = curve.getXDataReference() - yId = curve.getYDataReference() - dgx = doc.getDataGenerator(xId) - dgy = doc.getDataGenerator(yId) - color = settings.colors[kc % len(settings.colors)] - tag = "tag{}".format(kc) - - yLabel = yId - if curve.isSetName(): - yLabel = "{}".format(curve.getName()) - elif dgy.isSetName(): - yLabel = "{}".format(dgy.getName()) - - # FIXME: add all the additional information to the plot, i.e. the settings and styles for a given curve - - lines.append("for k in range({}.shape[1]):".format(xId)) - lines.append(" extra_args = {}") - lines.append(" if k == 0:") - lines.append(" extra_args['name'] = '{}'".format(yLabel)) - lines.append( - " tefig.addXYDataset({xarr}[:,k], {yarr}[:,k], color='{color}', tag='{tag}', logx={logx}, logy={logy}, **extra_args)".format( - xarr=xId, yarr=yId, color=color, tag=tag, logx=logX, logy=logY - ) - ) - - # FIXME: endpoints must be handled via plotting functions - # lines.append(" fix_endpoints({}[:,k], {}[:,k], color='{}', tag='{}', fig=tefig)".format(xId, yId, color, tag)) - lines.append("if te.tiledFigure():\n") - lines.append(" if te.tiledFigure().renderIfExhausted():\n") - lines.append(" te.clearTiledFigure()\n") - lines.append("else:\n") - lines.append(" fig = tefig.render()\n") - - if self.saveOutputs and self.createOutputs: - # FIXME: only working for matplotlib - lines.append( - "if str(te.getPlottingEngine()) == '':".format( - self.outputDir, output.getId(), self.plotFormat - ) - ) - lines.append( - " filename = os.path.join('{}', '{}.{}')".format( - self.outputDir, output.getId(), self.plotFormat - ) - ) - lines.append( - " fig.savefig(filename, format='{}', bbox_inches='tight')".format( - self.plotFormat - ) - ) - lines.append( - " print('Figure {}: {{}}'.format(filename))".format(output.getId()) - ) - lines.append("") - return lines - - def outputPlot3DToPython(self, doc, output): - """OutputPlot3D - - :param doc: - :type doc: SedDocument - :param output: - :type output: SedOutputPlot3D - :return: list of python lines - :rtype: list(str) - """ - # TODO: handle mix of log and linear axis - settings = SEDMLCodeFactory.outputPlotSettings() - lines = [] - lines.append("from mpl_toolkits.mplot3d import Axes3D") - lines.append( - "fig = plt.figure(num=None, figsize={}, dpi={}, facecolor='{}', edgecolor='{}')".format( - settings.figsize, settings.dpi, settings.facecolor, settings.edgecolor - ) - ) - lines.append("from matplotlib import gridspec") - lines.append("__gs = gridspec.GridSpec(1, 2, width_ratios=[3, 1])") - lines.append("ax = plt.subplot(__gs[0], projection='3d')") - # lines.append("ax = fig.gca(projection='3d')") - - title = output.getId() - if output.isSetName(): - title = output.getName() - - oneXLabel = True - oneYLabel = True - allXLabel = None - allYLabel = None - - for kc, surf in enumerate(output.getListOfSurfaces()): - logX = surf.getLogX() - logY = surf.getLogY() - logZ = surf.getLogZ() - xId = surf.getXDataReference() - yId = surf.getYDataReference() - zId = surf.getZDataReference() - dgx = doc.getDataGenerator(xId) - dgy = doc.getDataGenerator(yId) - dgz = doc.getDataGenerator(zId) - color = settings.colors[kc % len(settings.colors)] - - zLabel = zId - if surf.isSetName(): - zLabel = surf.getName() - elif dgy.isSetName(): - zLabel = dgz.getName() - - xLabel = xId - if dgx.isSetName(): - xLabel = dgx.getName() - yLabel = yId - if dgy.isSetName(): - yLabel = dgy.getName() - - # do all curves have the same xLabel & yLabel - if kc == 0: - allXLabel = xLabel - allYLabel = yLabel - if xLabel != allXLabel: - oneXLabel = False - if yLabel != allYLabel: - oneYLabel = False - - lines.append("for k in range({}.shape[1]):".format(xId)) - lines.append(" if k == 0:") - lines.append( - " ax.plot({}[:,k], {}[:,k], {}[:,k], marker = '{}', color='{}', linewidth={}, markersize={}, alpha={}, label='{}')".format( - xId, - yId, - zId, - settings.marker, - color, - settings.linewidth, - settings.markersize, - settings.alpha, - zLabel, - ) - ) - lines.append(" else:") - lines.append( - " ax.plot({}[:,k], {}[:,k], {}[:,k], marker = '{}', color='{}', linewidth={}, markersize={}, alpha={})".format( - xId, - yId, - zId, - settings.marker, - color, - settings.linewidth, - settings.markersize, - settings.alpha, - ) - ) - - lines.append("ax.set_title('{}', fontweight='bold')".format(title)) - if oneXLabel: - lines.append("ax.set_xlabel('{}', fontweight='bold')".format(xLabel)) - if oneYLabel: - lines.append("ax.set_ylabel('{}', fontweight='bold')".format(yLabel)) - if len(output.getListOfSurfaces()) == 1: - lines.append("ax.set_zlabel('{}', fontweight='bold')".format(zLabel)) - - lines.append( - "__lg = plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)" - ) - lines.append("__lg.draw_frame(False)") - lines.append("plt.setp(__lg.get_texts(), fontsize='small')") - lines.append("plt.setp(__lg.get_texts(), fontweight='bold')") - lines.append("plt.tick_params(axis='both', which='major', labelsize=10)") - lines.append("plt.tick_params(axis='both', which='minor', labelsize=8)") - lines.append( - "plt.savefig(os.path.join(workingDir, '{}.png'), dpi=100)".format( - output.getId() - ) - ) - lines.append("plt.show()".format(title)) - - return lines - - -################################################################################################## -class SEDMLTools(object): - """Helper functions to work with sedml.""" - - INPUT_TYPE_STR = "SEDML_STRING" - INPUT_TYPE_FILE_SEDML = "SEDML_FILE" - INPUT_TYPE_FILE_COMBINE = "COMBINE_FILE" # includes .sedx archives - - @classmethod - def checkSEDMLDocument(cls, doc): - """Checks the SedDocument for errors. - Raises IOError if error exists. - :param doc: - :type doc: - """ - errorlog = doc.getErrorLog() - msg = errorlog.toString() - if doc.getErrorLog().getNumFailsWithSeverity(libsedml.LIBSEDML_SEV_ERROR) > 0: - # FIXME: workaround for https://github.com/fbergmann/libSEDML/issues/47 - warnings.warn(msg) - # raise IOError(msg) - if errorlog.getNumFailsWithSeverity(libsedml.LIBSEDML_SEV_FATAL) > 0: - # raise IOError(msg) - warnings.warn(msg) - if errorlog.getNumFailsWithSeverity(libsedml.LIBSEDML_SEV_WARNING) > 0: - warnings.warn(msg) - if errorlog.getNumFailsWithSeverity(libsedml.LIBSEDML_SEV_SCHEMA_ERROR) > 0: - warnings.warn(msg) - if errorlog.getNumFailsWithSeverity(libsedml.LIBSEDML_SEV_GENERAL_WARNING) > 0: - warnings.warn(msg) - - @classmethod - def readSEDMLDocument(cls, inputStr, workingDir): - """Parses SedMLDocument from given input. - - :return: dictionary of SedDocument, inputType and working directory. - :rtype: {doc, inputType, workingDir} - """ - - # SEDML-String - if not os.path.exists(inputStr): - try: - from xml.etree import ElementTree - - x = ElementTree.fromstring(inputStr) - # is parsable xml string - doc = libsedml.readSedMLFromString(inputStr) - inputType = cls.INPUT_TYPE_STR - if workingDir is None: - workingDir = os.getcwd() - - except ElementTree.ParseError: - if not os.path.exists(inputStr): - raise IOError("SED-ML String is not valid XML:", inputStr) - - # SEDML-File - else: - filename, extension = os.path.splitext(os.path.basename(inputStr)) - - # Archive - if zipfile.is_zipfile(inputStr): - omexPath = inputStr - inputType = cls.INPUT_TYPE_FILE_COMBINE - - # in case of sedx and combine a working directory is created - # in which the files are extracted - if workingDir is None: - extractDir = os.path.join( - os.path.dirname(os.path.realpath(omexPath)), - "_te_{}".format(filename), - ) - else: - extractDir = workingDir - - # TODO: refactor this - # extract the archive to working directory - CombineArchive.extractArchive(omexPath, extractDir) - # get SEDML files from archive - sedmlFiles = CombineArchive.filePathsFromExtractedArchive( - extractDir, filetype="sed-ml" - ) - - if len(sedmlFiles) == 0: - raise IOError("No SEDML files found in archive.") - - # FIXME: there could be multiple SEDML files in archive (currently only first used) - # analogue to executeOMEX - if len(sedmlFiles) > 1: - warnings.warn( - "More than one sedml file in archive, only processing first one." - ) - - sedmlFile = sedmlFiles[0] - doc = libsedml.readSedMLFromFile(sedmlFile) - # we have to work relative to the SED-ML file - workingDir = os.path.dirname(sedmlFile) - - cls.checkSEDMLDocument(doc) - - # SEDML single file - elif os.path.isfile(inputStr): - if extension not in [".sedml", ".xml"]: - raise IOError( - "SEDML file should have [.sedml|.xml] extension:", inputStr - ) - inputType = cls.INPUT_TYPE_FILE_SEDML - doc = libsedml.readSedMLFromFile(inputStr) - cls.checkSEDMLDocument(doc) - # working directory is where the sedml file is - if workingDir is None: - workingDir = os.path.dirname(os.path.realpath(inputStr)) - - return {"doc": doc, "inputType": inputType, "workingDir": workingDir} - - @staticmethod - def resolveModelChanges(doc): - """Resolves the original source model and full change lists for models. - - Going through the tree of model upwards until root is reached and - collecting changes on the way (example models m* and changes c*) - m1 (source) -> m2 (c1, c2) -> m3 (c3, c4) - resolves to - m1 (source) [] - m2 (source) [c1,c2] - m3 (source) [c1,c2,c3,c4] - The order of changes is important (at least between nodes on different - levels of hierarchies), because later changes of derived models could - reverse earlier changes. - - Uses recursive search strategy, which should be okay as long as the model tree hierarchy is - not getting to big. - """ - # initial dicts (handle source & change information for single node) - model_sources = {} - model_changes = {} - - for m in doc.getListOfModels(): - mid = m.getId() - source = m.getSource() - model_sources[mid] = source - changes = [] - # store the changes unique for this model - for c in m.getListOfChanges(): - changes.append(c) - model_changes[mid] = changes - - # recursive search for original model and store the - # changes which have to be applied in the list of changes - def findSource(mid, changes): - # mid is node above - if mid in model_sources and not model_sources[mid] == mid: - # add changes for node - for c in model_changes[mid]: - changes.append(c) - # keep looking deeper - return findSource(model_sources[mid], changes) - # the source is no longer a key in the sources, it is the source - return mid, changes - - all_changes = {} - - mids = [m.getId() for m in doc.getListOfModels()] - for mid in mids: - source, changes = findSource(mid, changes=list()) - model_sources[mid] = source - all_changes[mid] = changes[::-1] - - return model_sources, all_changes - - -def process_trace(trace): - """If each entry in the task consists of a single point - (e.g. steady state scan), concatenate the points. - Otherwise, plot as separate curves.""" - if trace.size > 1: - if len(trace.shape) == 1: - return np.concatenate((np.atleast_1d(trace), np.atleast_1d(np.nan))) - elif len(trace.shape) == 2: - result = np.vstack( - (np.atleast_1d(trace), np.full((1, trace.shape[-1]), np.nan)) - ) - return result - else: - return np.atleast_1d(trace) - - -def terminate_trace(trace): - """If each entry in the task consists of a single point - (e.g. steady state scan), concatenate the points. - Otherwise, plot as separate curves.""" - warnings.warn("don't use this", DeprecationWarning) - - if isinstance(trace, list): - if ( - len(trace) > 0 - and not isinstance(trace[-1], list) - and not isinstance(trace[-1], dict) - ): - # if len(trace) > 2 and isinstance(trace[-1], dict): - # e = np.array(trace[-1], copy=True) - e = {} - for name in trace[-1].colnames: - e[name] = np.atleast_1d(np.nan) - # print('e:') - # print(e) - return trace + [e] - return trace - - -def fix_endpoints(x, y, color, tag, fig): - """Adds endpoint markers wherever there is a discontinuity in the data.""" - warnings.warn("don't use this", DeprecationWarning) - # expect x and y to be 1d - if len(x.shape) > 1: - raise RuntimeError("Expected x to be 1d") - if len(y.shape) > 1: - raise RuntimeError("Expected y to be 1d") - x_aug = np.concatenate( - (np.atleast_1d(np.nan), np.atleast_1d(x), np.atleast_1d(np.nan)) - ) - y_aug = np.concatenate( - (np.atleast_1d(np.nan), np.atleast_1d(y), np.atleast_1d(np.nan)) - ) - w = np.argwhere(np.isnan(x_aug)) - - endpoints_x = [] - endpoints_y = [] - - for begin, end in ((int(w[k] + 1), int(w[k + 1])) for k in range(w.shape[0] - 1)): - if begin != end: - # print('begin {}, end {}'.format(begin, end)) - x_values = x_aug[begin:end] - x_identical = np.all(x_values == x_values[0]) - y_values = y_aug[begin:end] - y_identical = np.all(y_values == y_values[0]) - # print('x_values') - # print(x_values) - # print('x identical? {}'.format(x_identical)) - # print('y_values') - # print(y_values) - # print('y identical? {}'.format(y_identical)) - - if x_identical and y_identical: - # get the coords for the new markers - x_begin = x_values[0] - x_end = x_values[-1] - y_begin = y_values[0] - y_end = y_values[-1] - - # append to the lists - endpoints_x += [x_begin, x_end] - endpoints_y += [y_begin, y_end] - - if endpoints_x: - fig.addXYDataset( - np.array(endpoints_x), - np.array(endpoints_y), - color=color, - tag=tag, - mode="markers", - ) - - -################################################################################################## -if __name__ == "__main__": - import os - - from tellurium.tests.testdata import OMEX_TEST_DIR, SEDML_TEST_DIR - - def testInput(sedmlInput): - """Test function run on inputStr.""" - print("\n", "*" * 100) - print(sedmlInput) - print("*" * 100) - factory = SEDMLCodeFactory(sedmlInput) - - # create python file - python_str = factory.toPython() - realPath = os.path.realpath(sedmlInput) - with open(sedmlInput + ".py", "w") as f: - f.write(python_str) - - # execute python - factory.executePython() - - # testInput(os.path.join(sedmlDir, "sedMLBIOM21.sedml")) - - # Check sed-ml files - for fname in sorted(os.listdir(SEDML_TEST_DIR)): - if fname.endswith(".sedml"): - testInput(os.path.join(SEDML_TEST_DIR, fname)) - - # Check sedx archives - for fname in sorted(os.listdir(OMEX_TEST_DIR)): - if fname.endswith(".sedx"): - testInput(os.path.join(OMEX_TEST_DIR, fname)) diff --git a/src/sbmlsim/experiment/experiment.py b/src/sbmlsim/experiment/experiment.py index 595b4e26..f591935f 100644 --- a/src/sbmlsim/experiment/experiment.py +++ b/src/sbmlsim/experiment/experiment.py @@ -451,7 +451,7 @@ def _run_tasks(self, simulator, reduced_selections: bool = True): # load model in simulator model: AbstractModel = self._models[model_id] - logger.info(f"set model: {type(model)}: {model=}") + # logger.info(f"set model: {type(model)}: {model=}") simulator.set_model(model=model) logger.info("set selections") @@ -471,7 +471,7 @@ def _run_tasks(self, simulator, reduced_selections: bool = True): # use the complete selection simulator.set_timecourse_selections(selections=None) - logger.info("normalize changes") + logger.debug("normalize changes") # normalize model changes (these must be set in simulation!) model.normalize(uinfo=model.uinfo) @@ -490,7 +490,7 @@ def _run_tasks(self, simulator, reduced_selections: bool = True): sim = deepcopy(sim) sim.add_model_changes(model.changes) - logger.info("running timecourse simulation") + logger.debug("running timecourse simulation") if isinstance(sim, TimecourseSim): self._results[task_key] = simulator.run_timecourse(sim) elif isinstance(sim, ScanSim): diff --git a/src/sbmlsim/experiment/runner.py b/src/sbmlsim/experiment/runner.py index ce8e02b1..7ca1b3fa 100644 --- a/src/sbmlsim/experiment/runner.py +++ b/src/sbmlsim/experiment/runner.py @@ -12,6 +12,7 @@ from typing import Dict, List, Optional, Tuple, Type, Union, Set from sbmlutils import log +from sbmlutils.console import console from sbmlsim.experiment import ExperimentResult, SimulationExperiment from sbmlsim.model import RoadrunnerSBMLModel @@ -130,7 +131,8 @@ def run_experiments( exp_results = [] experiment: SimulationExperiment for sid, experiment in self.experiments.items(): - logger.info(f"Running SimulationExperiment: {sid}") + console.rule(style="white") + logger.info(f"Running SimulationExperiment: '{sid}'") # ExperimentResult used to create report result = experiment.run( diff --git a/src/sbmlsim/model/model_roadrunner.py b/src/sbmlsim/model/model_roadrunner.py index 6d8da532..31a6874c 100644 --- a/src/sbmlsim/model/model_roadrunner.py +++ b/src/sbmlsim/model/model_roadrunner.py @@ -54,17 +54,20 @@ def __init__( raise ValueError(f"language_type not supported '{self.language_type}'.") # load model - self.state_path: Path = self.get_state_path() + # logger.info("load model") self.r: Optional[roadrunner.RoadRunner] = self.load_roadrunner_model( - source=self.source, state_path=self.state_path + source=self.source ) + # logger.info(self.r) # set selections + # logger.info("set selections") self.selections = self.set_timecourse_selections( self.r, selections=self.selections ) # set integrator settings + # logger.info("set integrator settings") if settings: RoadrunnerSBMLModel.set_integrator_settings(self.r, **settings) @@ -97,20 +100,9 @@ def from_abstract_model( settings=settings, ) - def get_state_path(self) -> Optional[Path]: - """Get path of the state file. - - The state file is a binary file which allows fast model loading. - """ - if self.source.is_path(): - md5 = md5_for_path(self.source.path) - return Path(f"{self.source.path}_rr{roadrunner.__version__}_{md5}.state") - else: - return None - @classmethod def load_roadrunner_model( - cls, source: Source, state_path: Path = None + cls, source: Source, ) -> roadrunner.RoadRunner: """Load model from given source. @@ -123,31 +115,47 @@ def load_roadrunner_model( # load model if source.is_path(): - if state_path and state_path.exists(): - logger.debug(f"Load model from state: '{state_path}'") - r = roadrunner.RoadRunner() - r.loadState(str(state_path)) - logger.debug(f"Model loaded from state: '{state_path}'") - else: - logger.info(f"Load model from SBML: '{source.path.resolve()}'") - r = roadrunner.RoadRunner(str(source.path)) - # save state path - if state_path: - r.saveState(str(state_path)) - logger.info(f"Save state: '{state_path}'") + + sbml_path: Path = source.path + state_path: Path = RoadrunnerSBMLModel.get_state_path( + sbml_path=sbml_path + ) + + r = roadrunner.RoadRunner(str(sbml_path)) + # FIXME: see https://github.com/sys-bio/roadrunner/issues/963 + # if state_path.exists(): + # logger.debug(f"Load model from state: '{state_path}'") + # r = roadrunner.RoadRunner() + # r.loadState(str(state_path)) + # # with open(state_path, "rb") as fin: + # # r.loadStateS(fin.read()) + # logger.debug(f"Model loaded from state: '{state_path}'") + # else: + # logger.info(f"Load model from SBML: '{sbml_path}'") + # r = roadrunner.RoadRunner(str(sbml_path)) + # # save state + # r.saveState(str(state_path)) + # # with open(state_path, "wb") as fout: + # # fout.write(r.saveStateS(opt="b")) + # logger.info(f"Save state: '{state_path}'") elif source.is_content(): r = roadrunner.RoadRunner(str(source.content)) return r - @classmethod - def copy_roadrunner_model(cls, r: roadrunner.RoadRunner) -> roadrunner.RoadRunner: - """Copy roadrunner model by using the state. + @staticmethod + def get_state_path(sbml_path: Path) -> Optional[Path]: + """Get path of the state file. - :param r: - :return: + The state file is a binary file which allows fast model loading. """ + md5 = md5_for_path(sbml_path) + return Path(f"{sbml_path}_rr{roadrunner.__version__}_{md5}.state") + + @classmethod + def copy_roadrunner_model(cls, r: roadrunner.RoadRunner) -> roadrunner.RoadRunner: + """Copy roadrunner model by using the state.""" ftmp = tempfile.NamedTemporaryFile() filename = ftmp.name r.saveState(filename) diff --git a/src/sbmlsim/oven/model_nan.py b/src/sbmlsim/oven/model_nan.py deleted file mode 100644 index 53af1ec1..00000000 --- a/src/sbmlsim/oven/model_nan.py +++ /dev/null @@ -1,89 +0,0 @@ -"""Model with NaN example.""" -from pathlib import Path - -from sbmlutils.cytoscape import visualize_sbml -from sbmlutils.factory import * -from sbmlutils.metadata import * -from sbmlutils.examples.templates import terms_of_use - - -class U(Units): - mmole = UnitDefinition("mmole", "mmole") - min = UnitDefinition("min", "min") - mmole_per_min = UnitDefinition("mmole_per_min", "mmole/min") - mM = UnitDefinition("mM", "mmole/liter") - - -_m = Model( - "nan_species", - name="NaN species example", - notes=terms_of_use, - units=U, - model_units=ModelUnits( - time=U.min, - substance=U.mmole, - extent=U.mmole, - volume=U.liter, - ), -) - - -_m.compartments = [ - Compartment( - "Vext", - value=NaN, - name="plasma", - sboTerm=SBO.PHYSICAL_COMPARTMENT, - unit=U.liter, - ), -] - -_m.species = [ - Species( - "dex_ext", - initialConcentration=0.0, - name="dextromethorphan (plasma)", - compartment="Vext", - substanceUnit=U.mmole, - hasOnlySubstanceUnits=False, - sboTerm=SBO.SIMPLE_CHEMICAL, - ), -] - -_m.reactions = [ - Reaction( - "DEXEX", - name="DEX export", - equation="dex_ext ->", - sboTerm=SBO.TRANSPORT_REACTION, - rules=[ - ], - pars=[ - Parameter( - "DEXEX_Vmax", - 1, - unit=U.mmole_per_min, - sboTerm=SBO.MAXIMAL_VELOCITY, - ), - Parameter( - "DEXEX_Km_dex", - 0.1, - unit=U.mM, - sboTerm=SBO.MICHAELIS_CONSTANT, - ), - ], - formula=( - "DEXEX_Vmax * dex_ext/(DEXEX_Km_dex + dex_ext)", - U.mmole_per_min, - ), - ), -] - -model_nan = _m - -if __name__ == "__main__": - - result: FactoryResult = create_model( - output_dir=Path(".").parent, models=model_nan - ) - diff --git a/src/sbmlsim/oven/model_state.py b/src/sbmlsim/oven/model_state.py new file mode 100644 index 00000000..bed8e2c2 --- /dev/null +++ b/src/sbmlsim/oven/model_state.py @@ -0,0 +1,44 @@ +import hashlib +from pathlib import Path +from typing import Optional + +import roadrunner +print(f"roadrunner version: {roadrunner.__version__}") + +def md5_for_path(path): + """Calculate MD5 of file content.""" + + # Open,close, read file and calculate MD5 on its contents + with open(path, "rb") as f_check: + # read contents of the file + data = f_check.read() + # pipe contents of the file through + return hashlib.md5(data).hexdigest() + +def get_state_path(sbml_path: Path) -> Optional[Path]: + """Get path of the state file. + + The state file is a binary file which allows fast model loading. + """ + md5 = md5_for_path(sbml_path) + return Path(f"{sbml_path}_rr{roadrunner.__version__}_{md5}.state") + + +sbml_path = "omeprazole_body_flat.xml" +state_path = get_state_path(sbml_path) + +# state saving and loading +r = roadrunner.RoadRunner() + +if state_path.exists(): + r.loadState(str(state_path)) + print(f"Model loaded from state: '{state_path}'") +else: + print(f"Load model from SBML: '{sbml_path}'") + r = roadrunner.RoadRunner(str(sbml_path)) + # save state + r.saveState(str(state_path)) + +print(f"Load from state: '{state_path}'") +r.loadState(str(state_path)) +print(f"Model loaded from state: '{state_path}'") diff --git a/src/sbmlsim/oven/nan_species.xml b/src/sbmlsim/oven/nan_species.xml deleted file mode 100644 index 49481bfc..00000000 --- a/src/sbmlsim/oven/nan_species.xml +++ /dev/null @@ -1,158 +0,0 @@ - - - - -

Created with https://github.com/matthiaskoenig/sbmlutils. - - DOI

- -
- - - -

Terms of use

-

The content of this model has been carefully created in a manual research effort. -This file has been created by Matthias König -using - sbmlutils - . -For questions contact koenigmx@hu-berlin.de.

- - - -Copyright © 2021 Matthias König. - - Creative Commons License -
This work is licensed under a Creative Commons Attribution 4.0 International License. -

Redistribution and use of any part of this model, with or without modification, -are permitted provided that the following conditions are met:

-
    -
  1. Redistributions of this SBML file must retain the above copyright notice, this -list of conditions and the following disclaimer.
  2. -
  3. Redistributions in a different form must reproduce the above copyright notice, -this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution.
  4. -
-

This model is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE.

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DEXEX_Vmax - dex_ext - - - - DEXEX_Km_dex - dex_ext - - - - - - -
-
diff --git a/src/sbmlsim/oven/nan_species.zip b/src/sbmlsim/oven/nan_species.zip deleted file mode 100644 index 8ff09568..00000000 Binary files a/src/sbmlsim/oven/nan_species.zip and /dev/null differ diff --git a/src/sbmlsim/oven/nan_species_roadrunner.py b/src/sbmlsim/oven/nan_species_roadrunner.py deleted file mode 100644 index 457e5583..00000000 --- a/src/sbmlsim/oven/nan_species_roadrunner.py +++ /dev/null @@ -1,23 +0,0 @@ -import roadrunner - -r: roadrunner.RoadRunner = roadrunner.RoadRunner("nan_species.xml") - -# setting a valid volume, now the model is completely specified and can be -# numerically integrated -r.setValue("Vext", 1.0) - -# setting the initial value -r.setValue("init(Vext)", 1.0) -r.resetAll() - -# Instead of `initialConcentration="0.0" defined in the model there is an -# incorrect `initialAmount="NaN"` on the `dex_ext` species probably due to some -# pre-processing steps of the model -sbml_str = r.getCurrentSBML() -print("-" * 80) -print(sbml_str) -print("-" * 80) - -# As a consequence the model does not integrate -s = r.simulate(start=0, end=10, steps=10) - diff --git a/src/sbmlsim/oven/omeprazole_body_flat.xml b/src/sbmlsim/oven/omeprazole_body_flat.xml new file mode 100644 index 00000000..647fcf62 --- /dev/null +++ b/src/sbmlsim/oven/omeprazole_body_flat.xml @@ -0,0 +1,7993 @@ + + + + +

Created with https://github.com/matthiaskoenig/sbmlutils. + + DOI

+ +
+ + + +

Model for omeprazole distribution and elimination

+

Terms of use

+

The content of this model has been carefully created in a manual research effort. +This file has been created by Matthias König +using sbmlutils. +For questions contact koenigmx@hu-berlin.de. Copyright © 2024 Matthias König.

+ + Creative Commons License + +
This work is licensed under a Creative Commons Attribution 4.0 International License. +

Redistribution and use of any part of this model, with or without modification, +are permitted provided that the following conditions are met:

+
    +
  1. Redistributions of this SBML file must retain the above copyright notice, this +list of conditions and the following disclaimer.
  2. +
  3. Redistributions in a different form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution.
  4. +
+

This model is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE.

+
+ + + + + + + + Leal Pujol + Helen + + lepujolh@hu-berlin.de + Humboldt-University Berlin, Institute for Theoretical Biology + + + + Balci + Sükrü + + balcisue@hu-berlin.de + Humboldt-University Berlin, Institute for Theoretical Biology + + + + König + Matthias + + koenigmx@hu-berlin.de + Humboldt-University Berlin, Institute for Theoretical Biology + + + + + 1900-01-01T00:00:00Z + + + 1900-01-01T00:00:00Z + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Urinary species are in amounts.

+ +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Typical stomach pH of: pH = 1-3; pH=2.0 +Calculation of proton concentration as:

+
+              pH = -log10(H+) => H+ = 10^-pH = 10^-2 = 0.01 [mole/litre] = 10 [mmole/l] 
+   = 10 [mM]
+
+            
+ +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Parameter controls the health state/renal function +(1.0 reference function, < 1.0 reduced function, > 1.0 increased function)

+ +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

loss of stomach fluid to intestine

+ +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +

Fraction absorbed, i.e., only a fraction of the S-omeprazole in the intestinal lumen +is absorbed. This parameter determines how much of the S-omeprazole is excreted in the feces.

+

+ F_some_abs of dose is absorbed. (1-F_some_abs) is excreted in feces.

+ +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Fast application to shift applied dose in the stomach.

+ +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Fraction absorbed, i.e., only a fraction of the R-omeprazole in the intestinal lumen +is absorbed. This parameter determines how much of the R-omeprazole is excreted in the feces.

+

+ F_rome_abs of dose is absorbed. (1-F_rome_abs) is excreted in feces.

+ +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Fast application to shift applied dose in the stomach.

+ +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + Cve_some + Cve_rome + + + + + + +

Used to compare to total metabolites in plasma often based on radioactive assay.

+ +
+ + + + Cve_some + Cve_rome + Cve_omeoh + Cve_omesul + + +
+ + + + + 1 + + + FVgu + FVki + FVli + FVlu + FVsp + FVpa + FVve + FVar + + + + + + + + + 1 + + + FQki + FQh + + + + + + + + + 0.024265 + + + + + BW + 1 + + 0.5378 + + + + + + HEIGHT + 1 + + 0.3964 + + + + + + + + + + + BW + COBW + + + + + + + + HR + HRrest + + COHRI + + 60 + + + + + + + + + + + CO + 1000 + + 60 + + + + + + + + BW + FVgu + + + + + + + + BW + FVki + + + + + + + + BW + FVli + + + + + + + + BW + FVlu + + + + + + + + BW + FVsp + + + + + + + + BW + FVpa + + + + + + + + BW + FVre + + + + + + + + + + 1 + HCT + + + + + + BW + FVve + + + + + + FVve + + + FVar + FVve + FVpo + FVhv + + + BW + Fblood + + + 1 + + + FVar + FVve + FVpo + FVhv + + + + + + + + + + + + + + 1 + HCT + + + + + + BW + FVar + + + + + + FVar + + + FVar + FVve + FVpo + FVhv + + + BW + Fblood + + + 1 + + + FVar + FVve + FVpo + FVhv + + + + + + + + + + + + + + 1 + HCT + + + + + + BW + FVpo + + + + + + FVpo + + + FVar + FVve + FVpo + FVhv + + + BW + Fblood + + + 1 + + + FVar + FVve + FVpo + FVhv + + + + + + + + + + + + + + 1 + HCT + + + + + + BW + FVhv + + + + + + FVhv + + + FVar + FVve + FVpo + FVhv + + + BW + Fblood + + + 1 + + + FVar + FVve + FVpo + FVhv + + + + + + + + + + + + QC + FQgu + + + + + + + + QC + FQki + + + + + + + + QC + FQh + + + + + + + + + + + + Qh + Qgu + + Qsp + + Qpa + + + + + + + + QC + FQlu + + + + + + + + QC + FQsp + + + + + + + + QC + FQpa + + + + + + + + QC + FQre + + + + + + + + Qsp + Qpa + Qgu + + + + + + + + Vgu + Fblood + + + 1 + HCT + + + + + + + + + Vki + Fblood + + + 1 + HCT + + + + + + + + + Vli + Fblood + + + 1 + HCT + + + + + + + + + Vlu + Fblood + + + 1 + HCT + + + + + + + + + Vpa + Fblood + + + 1 + HCT + + + + + + + + + Vsp + Fblood + + + 1 + HCT + + + + + + + + + Vre + Fblood + + + 1 + HCT + + + + + + + +

log(2) ~ 0.693 used for conversion of half-life injection time to +injection rate.

+ +
+ + + + + + 0.693 + ti_some + + 60 + + +
+ + + + + Cgu_plasma_some + Vgu_plasma + + + + + + + + Cgu_plasma_some + fup_some + + + + + + + + Agu_plasma_some + Mr_some + + + + + + + + + + Agu_plasma_some + Vgu_plasma + + Mr_some + + + + + + + + Cki_plasma_some + Vki_plasma + + + + + + + + Cki_plasma_some + fup_some + + + + + + + + Aki_plasma_some + Mr_some + + + + + + + + + + Aki_plasma_some + Vki_plasma + + Mr_some + + + + + + + + Cli_plasma_some + Vli_plasma + + + + + + + + Cli_plasma_some + fup_some + + + + + + + + Ali_plasma_some + Mr_some + + + + + + + + + + Ali_plasma_some + Vli_plasma + + Mr_some + + + + + + + + Clu_plasma_some + Vlu_plasma + + + + + + + + Clu_plasma_some + fup_some + + + + + + + + Alu_plasma_some + Mr_some + + + + + + + + + + Alu_plasma_some + Vlu_plasma + + Mr_some + + + + + + + + Cpa_plasma_some + Vpa_plasma + + + + + + + + Cpa_plasma_some + fup_some + + + + + + + + Apa_plasma_some + Mr_some + + + + + + + + + + Apa_plasma_some + Vpa_plasma + + Mr_some + + + + + + + + Csp_plasma_some + Vsp_plasma + + + + + + + + Csp_plasma_some + fup_some + + + + + + + + Asp_plasma_some + Mr_some + + + + + + + + + + Asp_plasma_some + Vsp_plasma + + Mr_some + + + + + + + + Cre_plasma_some + Vre_plasma + + + + + + + + Cre_plasma_some + fup_some + + + + + + + + Are_plasma_some + Mr_some + + + + + + + + + + Are_plasma_some + Vre_plasma + + Mr_some + + + + + + + + Car_some + Var + + + + + + + + Car_some + fup_some + + + + + + + + Aar_some + Mr_some + + + + + + + + + + Aar_some + Var + + Mr_some + + + + + + + + Cve_some + Vve + + + + + + + + Cve_some + fup_some + + + + + + + + Ave_some + Mr_some + + + + + + + + + + Ave_some + Vve + + Mr_some + + + + + + + + Cpo_some + Vpo + + + + + + + + Cpo_some + fup_some + + + + + + + + Apo_some + Mr_some + + + + + + + + + + Apo_some + Vpo + + Mr_some + + + + + + + + Chv_some + Vhv + + + + + + + + Chv_some + fup_some + + + + + + + + Ahv_some + Mr_some + + + + + + + + + + Ahv_some + Vhv + + Mr_some + + + + + + +

log(2) ~ 0.693 used for conversion of half-life injection time to +injection rate.

+ +
+ + + + + + 0.693 + ti_rome + + 60 + + +
+ + + + + Cgu_plasma_rome + Vgu_plasma + + + + + + + + Cgu_plasma_rome + fup_rome + + + + + + + + Agu_plasma_rome + Mr_rome + + + + + + + + + + Agu_plasma_rome + Vgu_plasma + + Mr_rome + + + + + + + + Cki_plasma_rome + Vki_plasma + + + + + + + + Cki_plasma_rome + fup_rome + + + + + + + + Aki_plasma_rome + Mr_rome + + + + + + + + + + Aki_plasma_rome + Vki_plasma + + Mr_rome + + + + + + + + Cli_plasma_rome + Vli_plasma + + + + + + + + Cli_plasma_rome + fup_rome + + + + + + + + Ali_plasma_rome + Mr_rome + + + + + + + + + + Ali_plasma_rome + Vli_plasma + + Mr_rome + + + + + + + + Clu_plasma_rome + Vlu_plasma + + + + + + + + Clu_plasma_rome + fup_rome + + + + + + + + Alu_plasma_rome + Mr_rome + + + + + + + + + + Alu_plasma_rome + Vlu_plasma + + Mr_rome + + + + + + + + Cpa_plasma_rome + Vpa_plasma + + + + + + + + Cpa_plasma_rome + fup_rome + + + + + + + + Apa_plasma_rome + Mr_rome + + + + + + + + + + Apa_plasma_rome + Vpa_plasma + + Mr_rome + + + + + + + + Csp_plasma_rome + Vsp_plasma + + + + + + + + Csp_plasma_rome + fup_rome + + + + + + + + Asp_plasma_rome + Mr_rome + + + + + + + + + + Asp_plasma_rome + Vsp_plasma + + Mr_rome + + + + + + + + Cre_plasma_rome + Vre_plasma + + + + + + + + Cre_plasma_rome + fup_rome + + + + + + + + Are_plasma_rome + Mr_rome + + + + + + + + + + Are_plasma_rome + Vre_plasma + + Mr_rome + + + + + + + + Car_rome + Var + + + + + + + + Car_rome + fup_rome + + + + + + + + Aar_rome + Mr_rome + + + + + + + + + + Aar_rome + Var + + Mr_rome + + + + + + + + Cve_rome + Vve + + + + + + + + Cve_rome + fup_rome + + + + + + + + Ave_rome + Mr_rome + + + + + + + + + + Ave_rome + Vve + + Mr_rome + + + + + + + + Cpo_rome + Vpo + + + + + + + + Cpo_rome + fup_rome + + + + + + + + Apo_rome + Mr_rome + + + + + + + + + + Apo_rome + Vpo + + Mr_rome + + + + + + + + Chv_rome + Vhv + + + + + + + + Chv_rome + fup_rome + + + + + + + + Ahv_rome + Mr_rome + + + + + + + + + + Ahv_rome + Vhv + + Mr_rome + + + + + + + + Cgu_plasma_omeoh + Vgu_plasma + + + + + + + + Cgu_plasma_omeoh + fup_omeoh + + + + + + + + Agu_plasma_omeoh + Mr_omeoh + + + + + + + + + + Agu_plasma_omeoh + Vgu_plasma + + Mr_omeoh + + + + + + + + Cki_plasma_omeoh + Vki_plasma + + + + + + + + Cki_plasma_omeoh + fup_omeoh + + + + + + + + Aki_plasma_omeoh + Mr_omeoh + + + + + + + + + + Aki_plasma_omeoh + Vki_plasma + + Mr_omeoh + + + + + + + + Cli_plasma_omeoh + Vli_plasma + + + + + + + + Cli_plasma_omeoh + fup_omeoh + + + + + + + + Ali_plasma_omeoh + Mr_omeoh + + + + + + + + + + Ali_plasma_omeoh + Vli_plasma + + Mr_omeoh + + + + + + + + Clu_plasma_omeoh + Vlu_plasma + + + + + + + + Clu_plasma_omeoh + fup_omeoh + + + + + + + + Alu_plasma_omeoh + Mr_omeoh + + + + + + + + + + Alu_plasma_omeoh + Vlu_plasma + + Mr_omeoh + + + + + + + + Cpa_plasma_omeoh + Vpa_plasma + + + + + + + + Cpa_plasma_omeoh + fup_omeoh + + + + + + + + Apa_plasma_omeoh + Mr_omeoh + + + + + + + + + + Apa_plasma_omeoh + Vpa_plasma + + Mr_omeoh + + + + + + + + Csp_plasma_omeoh + Vsp_plasma + + + + + + + + Csp_plasma_omeoh + fup_omeoh + + + + + + + + Asp_plasma_omeoh + Mr_omeoh + + + + + + + + + + Asp_plasma_omeoh + Vsp_plasma + + Mr_omeoh + + + + + + + + Cre_plasma_omeoh + Vre_plasma + + + + + + + + Cre_plasma_omeoh + fup_omeoh + + + + + + + + Are_plasma_omeoh + Mr_omeoh + + + + + + + + + + Are_plasma_omeoh + Vre_plasma + + Mr_omeoh + + + + + + + + Car_omeoh + Var + + + + + + + + Car_omeoh + fup_omeoh + + + + + + + + Aar_omeoh + Mr_omeoh + + + + + + + + + + Aar_omeoh + Var + + Mr_omeoh + + + + + + + + Cve_omeoh + Vve + + + + + + + + Cve_omeoh + fup_omeoh + + + + + + + + Ave_omeoh + Mr_omeoh + + + + + + + + + + Ave_omeoh + Vve + + Mr_omeoh + + + + + + + + Cpo_omeoh + Vpo + + + + + + + + Cpo_omeoh + fup_omeoh + + + + + + + + Apo_omeoh + Mr_omeoh + + + + + + + + + + Apo_omeoh + Vpo + + Mr_omeoh + + + + + + + + Chv_omeoh + Vhv + + + + + + + + Chv_omeoh + fup_omeoh + + + + + + + + Ahv_omeoh + Mr_omeoh + + + + + + + + + + Ahv_omeoh + Vhv + + Mr_omeoh + + + + + + + + Cgu_plasma_omesul + Vgu_plasma + + + + + + + + Cgu_plasma_omesul + fup_omesul + + + + + + + + Agu_plasma_omesul + Mr_omesul + + + + + + + + + + Agu_plasma_omesul + Vgu_plasma + + Mr_omesul + + + + + + + + Cki_plasma_omesul + Vki_plasma + + + + + + + + Cki_plasma_omesul + fup_omesul + + + + + + + + Aki_plasma_omesul + Mr_omesul + + + + + + + + + + Aki_plasma_omesul + Vki_plasma + + Mr_omesul + + + + + + + + Cli_plasma_omesul + Vli_plasma + + + + + + + + Cli_plasma_omesul + fup_omesul + + + + + + + + Ali_plasma_omesul + Mr_omesul + + + + + + + + + + Ali_plasma_omesul + Vli_plasma + + Mr_omesul + + + + + + + + Clu_plasma_omesul + Vlu_plasma + + + + + + + + Clu_plasma_omesul + fup_omesul + + + + + + + + Alu_plasma_omesul + Mr_omesul + + + + + + + + + + Alu_plasma_omesul + Vlu_plasma + + Mr_omesul + + + + + + + + Cpa_plasma_omesul + Vpa_plasma + + + + + + + + Cpa_plasma_omesul + fup_omesul + + + + + + + + Apa_plasma_omesul + Mr_omesul + + + + + + + + + + Apa_plasma_omesul + Vpa_plasma + + Mr_omesul + + + + + + + + Csp_plasma_omesul + Vsp_plasma + + + + + + + + Csp_plasma_omesul + fup_omesul + + + + + + + + Asp_plasma_omesul + Mr_omesul + + + + + + + + + + Asp_plasma_omesul + Vsp_plasma + + Mr_omesul + + + + + + + + Cre_plasma_omesul + Vre_plasma + + + + + + + + Cre_plasma_omesul + fup_omesul + + + + + + + + Are_plasma_omesul + Mr_omesul + + + + + + + + + + Are_plasma_omesul + Vre_plasma + + Mr_omesul + + + + + + + + Car_omesul + Var + + + + + + + + Car_omesul + fup_omesul + + + + + + + + Aar_omesul + Mr_omesul + + + + + + + + + + Aar_omesul + Var + + Mr_omesul + + + + + + + + Cve_omesul + Vve + + + + + + + + Cve_omesul + fup_omesul + + + + + + + + Ave_omesul + Mr_omesul + + + + + + + + + + Ave_omesul + Vve + + Mr_omesul + + + + + + + + Cpo_omesul + Vpo + + + + + + + + Cpo_omesul + fup_omesul + + + + + + + + Apo_omesul + Mr_omesul + + + + + + + + + + Apo_omesul + Vpo + + Mr_omesul + + + + + + + + Chv_omesul + Vhv + + + + + + + + Chv_omesul + fup_omesul + + + + + + + + Ahv_omesul + Mr_omesul + + + + + + + + + + Ahv_omesul + Vhv + + Mr_omesul + + + + + + + + + + + + iv_some + + Mr_some + + Ri_some + + + + + + Ri_some + + + + + + + + + + + iv_rome + + Mr_rome + + Ri_rome + + + + + + Ri_rome + + + + + + + LI__cyp2c19_ac + + + LI__cyp2c19_allele1 + + + 1 + + + + + LI__cyp2c19_a0 + + + LI__cyp2c19_allele1 + 0 + + + + LI__cyp2c19_a1 + + + LI__cyp2c19_allele1 + 1 + + + + LI__cyp2c19_a2 + + + LI__cyp2c19_allele1 + 2 + + + + LI__cyp2c19_a3 + + + LI__cyp2c19_allele1 + 3 + + + + LI__cyp2c19_a4 + + + LI__cyp2c19_allele1 + 4 + + + + LI__cyp2c19_a5 + + + LI__cyp2c19_allele1 + 5 + + + + LI__cyp2c19_ac + + + + + + + + + LI__cyp2c19_ac + + + LI__cyp2c19_allele2 + + + 1 + + + + + LI__cyp2c19_a0 + + + LI__cyp2c19_allele2 + 0 + + + + LI__cyp2c19_a1 + + + LI__cyp2c19_allele2 + 1 + + + + LI__cyp2c19_a2 + + + LI__cyp2c19_allele2 + 2 + + + + LI__cyp2c19_a3 + + + LI__cyp2c19_allele2 + 3 + + + + LI__cyp2c19_a4 + + + LI__cyp2c19_allele2 + 4 + + + + LI__cyp2c19_a5 + + + LI__cyp2c19_allele2 + 5 + + + + LI__cyp2c19_ac + + + + + + + + + + + LI__cyp2c19_activity1 + LI__cyp2c19_activity2 + + 2 + + + + + + +

Used to compare to total metabolites in urine often based on radioactive assay. +No S-omeprazole or R-omeprazole excreted.

+ +
+ + + + Aurine_omeoh + Aurine_omesul + + +
+ + + + + KI__OMESULEX + KI__OMEOHEX + + + + + + + + + + + + + + + + + + + GU__pp_active + GU__pp_inactive + + + + + + +

pH calculation with conversion of stomach proton concentration: +[mmole/l] -> [mole/l]

+ +
+ + + + + + + + + + + + + + + + + + + 10 + + + + GU__protons_stomach + 1000 + + + + +
+ + + +

Using sigmoidal rule interpolating between F_ome_pH2 and F_ome_pH6. +Ensures non-negative values and capping at pH6.

+ +
+ + + + + + GU__F_ome_pH2 + + + + + + + GU__F_ome_pH6 + GU__F_ome_pH2 + + + + + + 0 + + + pH + 2 + + + GU__F_ome_n + + + + + + + + + 0 + + + pH + 2 + + + GU__F_ome_n + + + + GU__F_ome_KpH + GU__F_ome_n + + + + + GU__F_ome_solution + + + GU__F_ome_pH6 + + + +
+ + + + + GU__SOMEABS_k + Vgu + Cgu_some + + + + + + + + + + + + Ka_dis_some + 60 + + GU__POSTOMACH_some + + GU__Mr_some + + + + + + + + GU__ROMEABS_k + Vgu + Cgu_rome + + + + + + + + + + + + Ka_dis_rome + 60 + + GU__POSTOMACH_rome + + GU__Mr_rome + + + + + + + + Afeces_rome + Afeces_some + + + + + + + + + + GU__application_some + + GU__Mr_some + + + + + + + + + + GU__application_some + GU__dissolution_some + + GU__Mr_some + + + + + + + + + + GU__application_rome + + GU__Mr_rome + + + + + + + + + + GU__application_rome + GU__dissolution_rome + + GU__Mr_rome + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + Ki_some + IVDOSE_some + + Mr_some + + + + + + + + + + + + + + + + Qgu + Car_some + + + + + + + + + + + + + + + + Qgu + Cgu_plasma_some + BP_some + + + + + + + + + + + + + + + + Qki + Car_some + + + + + + + + + + + + + + + + Qki + Cki_plasma_some + BP_some + + + + + + + + + + + + + + + + Qha + Car_some + + + + + + + + + + + + + + + + Qpo + Cpo_some + BP_some + + + + + + + + + + + + + + + + Qh + Cli_plasma_some + BP_some + + + + + + + + + + + + + + + + Qh + Chv_some + BP_some + + + + + + + + + + + + + + + + Qlu + Cve_some + + + + + + + + + + + + + + + + Qlu + Clu_plasma_some + BP_some + + + + + + + + + + + + + + + + Qpa + Car_some + + + + + + + + + + + + + + + + Qpa + Cpa_plasma_some + BP_some + + + + + + + + + + + + + + + + Qsp + Car_some + + + + + + + + + + + + + + + + Qsp + Csp_plasma_some + BP_some + + + + + + + + + + + + + + + + Qre + Car_some + + + + + + + + + + + + + + + + Qre + Cre_plasma_some + BP_some + + + + + + + + + + + + + + + + + + + + + + + + + + + Ki_rome + IVDOSE_rome + + Mr_rome + + + + + + + + + + + + + + + + Qgu + Car_rome + + + + + + + + + + + + + + + + Qgu + Cgu_plasma_rome + BP_rome + + + + + + + + + + + + + + + + Qki + Car_rome + + + + + + + + + + + + + + + + Qki + Cki_plasma_rome + BP_rome + + + + + + + + + + + + + + + + Qha + Car_rome + + + + + + + + + + + + + + + + Qpo + Cpo_rome + BP_rome + + + + + + + + + + + + + + + + Qh + Cli_plasma_rome + BP_rome + + + + + + + + + + + + + + + + Qh + Chv_rome + BP_rome + + + + + + + + + + + + + + + + Qlu + Cve_rome + + + + + + + + + + + + + + + + Qlu + Clu_plasma_rome + BP_rome + + + + + + + + + + + + + + + + Qpa + Car_rome + + + + + + + + + + + + + + + + Qpa + Cpa_plasma_rome + BP_rome + + + + + + + + + + + + + + + + Qsp + Car_rome + + + + + + + + + + + + + + + + Qsp + Csp_plasma_rome + BP_rome + + + + + + + + + + + + + + + + Qre + Car_rome + + + + + + + + + + + + + + + + Qre + Cre_plasma_rome + BP_rome + + + + + + + + + + + + + + + + Qgu + Car_omeoh + + + + + + + + + + + + + + + + Qgu + Cgu_plasma_omeoh + BP_omeoh + + + + + + + + + + + + + + + + Qki + Car_omeoh + + + + + + + + + + + + + + + + Qki + Cki_plasma_omeoh + BP_omeoh + + + + + + + + + + + + + + + + Qha + Car_omeoh + + + + + + + + + + + + + + + + Qpo + Cpo_omeoh + BP_omeoh + + + + + + + + + + + + + + + + Qh + Cli_plasma_omeoh + BP_omeoh + + + + + + + + + + + + + + + + Qh + Chv_omeoh + BP_omeoh + + + + + + + + + + + + + + + + Qlu + Cve_omeoh + + + + + + + + + + + + + + + + Qlu + Clu_plasma_omeoh + BP_omeoh + + + + + + + + + + + + + + + + Qpa + Car_omeoh + + + + + + + + + + + + + + + + Qpa + Cpa_plasma_omeoh + BP_omeoh + + + + + + + + + + + + + + + + Qsp + Car_omeoh + + + + + + + + + + + + + + + + Qsp + Csp_plasma_omeoh + BP_omeoh + + + + + + + + + + + + + + + + Qre + Car_omeoh + + + + + + + + + + + + + + + + Qre + Cre_plasma_omeoh + BP_omeoh + + + + + + + + + + + + + + + + Qgu + Car_omesul + + + + + + + + + + + + + + + + Qgu + Cgu_plasma_omesul + BP_omesul + + + + + + + + + + + + + + + + Qki + Car_omesul + + + + + + + + + + + + + + + + Qki + Cki_plasma_omesul + BP_omesul + + + + + + + + + + + + + + + + Qha + Car_omesul + + + + + + + + + + + + + + + + Qpo + Cpo_omesul + BP_omesul + + + + + + + + + + + + + + + + Qh + Cli_plasma_omesul + BP_omesul + + + + + + + + + + + + + + + + Qh + Chv_omesul + BP_omesul + + + + + + + + + + + + + + + + Qlu + Cve_omesul + + + + + + + + + + + + + + + + Qlu + Clu_plasma_omesul + BP_omesul + + + + + + + + + + + + + + + + Qpa + Car_omesul + + + + + + + + + + + + + + + + Qpa + Cpa_plasma_omesul + BP_omesul + + + + + + + + + + + + + + + + Qsp + Car_omesul + + + + + + + + + + + + + + + + Qsp + Csp_plasma_omesul + BP_omesul + + + + + + + + + + + + + + + + Qre + Car_omesul + + + + + + + + + + + + + + + + Qre + Cre_plasma_omesul + BP_omesul + + + + + + + +

Irreversible transport of S-omeprazole from plasma in the liver.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + LI__OMEIM_Vmax + Vli_tissue + Cli_plasma_some + + + + LI__OMEIM_Km_ome + Cli_plasma_some + + + + +
+ + + +

Irreversible transport of R-omeprazole from plasma in the liver.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + LI__OMEIM_Vmax + Vli_tissue + Cli_plasma_rome + + + + LI__OMEIM_Km_ome + Cli_plasma_rome + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + LI__f_CYP2C19 + LI__cyp2c19_activity + LI__SOMECYP2C19_Vmax + Vli_tissue + LI__some + + + + LI__SOMECYP2C19_Km_some + LI__some + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LI__f_CYP2C19 + LI__cyp2c19_activity + LI__ROMECYP2C19_Vmax + Vli_tissue + LI__rome + + + + LI__ROMECYP2C19_Km_rome + LI__rome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LI__SOMECYP3A4_Vmax + Vli_tissue + LI__some + + + + LI__SOMECYP3A4_Km_some + LI__some + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LI__ROMECYP3A4_Vmax + Vli_tissue + LI__rome + + + + LI__ROMECYP3A4_Km_rome + LI__rome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LI__OMEOHEX_Vmax + Vli_tissue + LI__omeoh + + + + LI__OMEOHEX_Km_omeoh + LI__omeoh + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LI__OMESUL_Vmax + Vli_tissue + LI__omesul + + + + LI__OMESUL_Km_omesul + LI__omesul + + + + + + + + + + + + + + + + + + + + + + + + + + + + + KI__OMEOHEX_k + Vki_tissue + Cki_plasma_omeoh + + + + + + + + + + + + + + + + + + + + + + + + + + + + KI__OMESULEX_k + Vki_tissue + Cki_plasma_omesul + + + + + + + + + + + + + + + + + + + + + + + + + + + GU__pp_rate_k + + + 10 + + + + + + + 1.1 + + + + GU__pp_active + 0.1 + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + GU__Qstomach + GU__protons_stomach + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GU__ppi_k + GU__pp_active + + + Cgu_plasma_some + Cgu_plasma_rome + + + + + + + + +

+ steady state +

+
+              pp_synthesis = pp_active_degradation (with pp_active = 1 [dimensionless])
+pp_synthesis_k = pp_degradation_k * pp_active
+pp_active = pp_synthesis_k/pp_degradation_k
+
+            
+ +
+ + + + + + + + + + + + + + + + + GU__pp_synthesis_k + + +
+ + + + + + + + + + + + + + + + + + + + GU__pp_degradation_k + GU__pp_active + + + + + + + +

Identical kinetics to degradation of active PP.

+ +
+ + + + + + + + + + + + + + + + + + + GU__pp_degradation_k + GU__pp_inactive + + + +
+ + + + + + + + + + + + + + + + + + + + + + + GU__F_some_abs + GU__absorption_some + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + GU__F_some_abs + + GU__absorption_some + + + + + + + + + + + + + + + + + GU__Ka_application_some + 60 + + PODOSE_some + + GU__Mr_some + + + + + + + + + + + + + + + + GU__F_ome_pH + GU__dissolution_some_rate + + + + + + + + + + + + + + + + + + 1 + GU__F_ome_pH + + GU__dissolution_some_rate + + + + + + + + + + + + + + + + + + + + + + + + + + + GU__F_rome_abs + GU__absorption_rome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + GU__F_rome_abs + + GU__absorption_rome + + + + + + + + + + + + + + + + + GU__Ka_application_rome + 60 + + PODOSE_rome + + GU__Mr_rome + + + + + + + + + + + + + + + + GU__F_ome_pH + GU__dissolution_rome_rate + + + + + + + + + + + + + + + + + + 1 + GU__F_ome_pH + + GU__dissolution_rome_rate + + + + +
+
+
diff --git a/src/sbmlsim/oven/rr_tolerances_issues.py b/src/sbmlsim/oven/rr_tolerances_issues.py deleted file mode 100644 index 41e15d75..00000000 --- a/src/sbmlsim/oven/rr_tolerances_issues.py +++ /dev/null @@ -1,15 +0,0 @@ -import roadrunner -import pandas as pd - -tiny_sbml = "tiny_example_1.xml" -r = roadrunner.RoadRunner(tiny_sbml) -s = r.simulate(0, 100, steps=100) -df = pd.DataFrame(s, columns=s.colnames) -r.plot() - -r = roadrunner.RoadRunner(tiny_sbml) -r.integrator.setValue("relative_tolerance", 1E-18) -r.integrator.setValue("absolute_tolerance", 1E-18) -s = r.simulate(0, 100, steps=100) -df = pd.DataFrame(s, columns=s.colnames) -r.plot() diff --git a/src/sbmlsim/oven/tiny_example_1.png b/src/sbmlsim/oven/tiny_example_1.png deleted file mode 100644 index dea4a8e1..00000000 Binary files a/src/sbmlsim/oven/tiny_example_1.png and /dev/null differ diff --git a/src/sbmlsim/oven/tiny_example_1.xml b/src/sbmlsim/oven/tiny_example_1.xml deleted file mode 100644 index 238d5258..00000000 --- a/src/sbmlsim/oven/tiny_example_1.xml +++ /dev/null @@ -1,298 +0,0 @@ - - - - - - - - - - - - - - - - -

Description

-

A minimal example in SBML format. -

-
The content of this model has been carefully created in a manual research effort.
-
This file has been created by - SBML team.
-

Terms of use

-
Copyright © 2019 SBML team.
-
-

Redistribution and use of any part of this model, with or without modification, are permitted provided - that the following conditions are met: -

    -
  1. Redistributions of this SBML file must retain the above copyright notice, this list of conditions and - the following disclaimer.
  2. -
  3. Redistributions in a different form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided - with the distribution.
  4. -
- This model is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -

-
- -
- - - - - - - - Koenig - Matthias - - koenigmx@hu-berlin.de - - Humboldt-University Berlin, Institute for Theoretical Biology - - - - - - 2019-02-07T17:15:12Z - - - 2019-02-07T17:15:12Z - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Vmax - glc - - - - Km_glc - glc - - - atp - - - - Km_atp - atp - - - - - - -
-
diff --git a/src/sbmlsim/simulator/simulation_serial.py b/src/sbmlsim/simulator/simulation_serial.py index 2096b506..77c3e90f 100644 --- a/src/sbmlsim/simulator/simulation_serial.py +++ b/src/sbmlsim/simulator/simulation_serial.py @@ -44,22 +44,29 @@ def __init__(self, model: Union[str|Path|RoadrunnerSBMLModel|AbstractModel] = No def set_model(self, model: Union[str|Path|RoadrunnerSBMLModel|AbstractModel]): """Set model for simulator and updates the integrator settings.""" - logger.info("SimulatorSerial.set_model") + # logger.info("SimulatorSerial.set_model") self.model = None if model is not None: if isinstance(model, RoadrunnerSBMLModel): + # logger.info("SimulatorSerial.set_model from RoadrunnerSBMLModel") self.model = model elif isinstance(model, AbstractModel): + # logger.info("SimulatorSerial.set_model from AbstractModel") self.model = RoadrunnerSBMLModel.from_abstract_model( abstract_model=model ) elif isinstance(model, (str, Path)): + # logger.info("SimulatorSerial.set_model from Path") self.model = RoadrunnerSBMLModel( source=model, ) - self.r = model.r + # logger.info(f"get roadrunner instance from model: {type(self.model)}") + self.r = self.model.r + # logger.info("set integrator settings") self.set_integrator_settings(**self.integrator_settings) + # logger.info("model loading finished") + def set_integrator_settings(self, **kwargs): """Set settings in the integrator.""" @@ -192,11 +199,6 @@ def _timecourse(self, simulation: TimecourseSim) -> pd.DataFrame: self.r[key] = float(item) logger.debug(f"\t{key} = {item}") - # debug model state - # FIXME: report issue - # sbml_str = self.r.getCurrentSBML() - # with open("/home/mkoenig/git/pkdb_models/pkdb_models/models/dextromethorphan/results/debug/test.xml", "w") as f_out: - # f_out.write(sbml_str) # run simulation integrator = self.r.integrator