Exemplo n.º 1
0
    def document(self, doc: libsbml.SBMLDocument) -> Dict[str, str]:
        """Info for SBMLDocument.

        :param doc: SBMLDocument
        :return: information dictionary for SBMLDocument
        """
        d = self.sbase_dict(doc)

        packages: Dict[str, Any] = {}
        packages["document"] = {
            "level": doc.getLevel(),
            "version": doc.getVersion()
        }

        plugins: List[Dict[str, Any]] = []
        for k in range(doc.getNumPlugins()):
            plugin: libsbml.SBMLDocumentPlugin = doc.getPlugin(k)
            prefix: str = plugin.getPrefix()
            version: int = plugin.getPackageVersion()
            plugins.append({"prefix": prefix, "version": version})

        packages["plugins"] = plugins

        d["packages"] = packages
        return d
Exemplo n.º 2
0
    def toXMLString(self, enzmldoc):
        '''
        Converts EnzymeMLDocument to XML string.
        
        Args:
            EnzymeMLDocument enzmldoc: Previously created instance of an EnzymeML document
        '''
        doc = SBMLDocument()
        doc.setLevelAndVersion(enzmldoc.getLevel(), enzmldoc.getVersion())

        model = doc.createModel()
        model.setName(enzmldoc.getName())
        model.setId(enzmldoc.getName())

        # Add references
        self.__addRefs(model, enzmldoc)

        # Add units
        self.__addUnits(model, enzmldoc)

        # Add Vessel
        self.__addVessel(model, enzmldoc)

        # Add protein
        self.__addProteins(model, enzmldoc)

        # Add reactants
        self.__addReactants(model, enzmldoc)

        # Add reactions
        self.__addReactions(model, enzmldoc, csv=False)

        # Write to EnzymeML
        writer = SBMLWriter()
        return writer.writeToString(doc)
Exemplo n.º 3
0
    def toSBML(self, enzmldoc):
        '''
        Returns libSBML model.
        
        Args:
            EnzymeMLDocument enzmldoc: Previously created instance of an EnzymeML document
        '''

        doc = SBMLDocument()
        doc.setLevelAndVersion(enzmldoc.getLevel(), enzmldoc.getVersion())

        model = doc.createModel()
        model.setName(enzmldoc.getName())
        model.setId(enzmldoc.getName())

        # Add references
        self.__addRefs(model, enzmldoc)

        # Add units
        self.__addUnits(model, enzmldoc)

        # Add Vessel
        self.__addVessel(model, enzmldoc)

        # Add protein
        self.__addProteins(model, enzmldoc)

        # Add reactants
        self.__addReactants(model, enzmldoc)

        # Add reactions
        self.__addReactions(model, enzmldoc, csv=False)

        return doc
Exemplo n.º 4
0
    def __init__(self, Nc, Nf, version,
                 tissue_dict, cell_model, sim_id='core', events=None):
        """
        Initialize with the tissue information dictionary and
        the respective cell model used for creation.
        """
        self.Nc = Nc
        self.Nf = Nf
        self.version = version
        self.simId = sim_id
        self.cellModel = cell_model
        # print self.cellModel.info()

        # tissue information fields
        for key, value in tissue_dict.items():
            setattr(self, key, value)
        self.events = events

        # sbmlutils
        self.id = self.createId()
        self.doc = SBMLDocument(SBML_LEVEL, SBML_VERSION)
        self.model = self.doc.createModel()

        check(self.model.setId(self.id), 'set id')
        check(self.model.setName(self.id), 'set name')

        # add dynamical parameters
        self.pars.extend(
            [('Nc', self.Nc, '-', True),
             ('Nf', self.Nf, '-', True), ]
        )

        print '\n', '*' * 40, '\n', self.id, '\n', '*' * 40
Exemplo n.º 5
0
    def toFile(self, enzmldoc, path):
        '''
        Writes EnzymeMLDocument object to an .omex container
        
        Args:
            EnzymeMLDocument enzmldoc: Previously created instance of an EnzymeML document
            String path: EnzymeML file is written to this destination
        '''

        self.path = path + '/' + enzmldoc.getName()

        try:
            os.makedirs(self.path + '/data')
        except FileExistsError:
            pass

        doc = SBMLDocument()
        doc.setLevelAndVersion(enzmldoc.getLevel(), enzmldoc.getVersion())

        model = doc.createModel()
        model.setName(enzmldoc.getName())
        model.setId(enzmldoc.getName())

        # Add references
        self.__addRefs(model, enzmldoc)

        # Add units
        self.__addUnits(model, enzmldoc)

        # Add Vessel
        self.__addVessel(model, enzmldoc)

        # Add protein
        self.__addProteins(model, enzmldoc)

        # Add reactants
        self.__addReactants(model, enzmldoc)

        # Add reactions
        self.__addReactions(model, enzmldoc)

        # Write to EnzymeML
        writer = SBMLWriter()
        writer.writeSBMLToFile(doc, self.path + '/experiment.xml')

        # Write to OMEX
        self.__createArchive(enzmldoc, doc)

        os.remove(self.path + '/experiment.xml')
        os.remove(self.path + '/data/data.csv')
        os.rmdir(self.path + '/data')
Exemplo n.º 6
0
def get_submodel_frameworks(doc: libsbml.SBMLDocument) -> Dict[str, Any]:
    """Read the SBO terms of the submodels.

    These are used to distinguish the different frameworks of the submodels.
    :param doc: SBMLDocument
    :return:
    """
    frameworks = {}
    # get list of submodels
    model = doc.getModel()
    mplugin = model.getPlugin("comp")

    # model.setSBOTerm(comp.SBO.CONTINOUS_FRAMEWORK)
    submodel: libsbml.Submodel
    for submodel in mplugin.getListOfSubmodels():
        sid = submodel.getId()
        sbo = None
        if submodel.isSetSBOTerm():
            # This is the sbo which is set on the submodel element
            # not the SBO which is set on the model in listOfModels or
            # listOfExternalModels
            sbo = submodel.getSBOTerm()
        frameworks[sid] = {
            "sid": sid,
            "modelRef": submodel.getModelRef(),
            "sbo": sbo
        }

    return frameworks
Exemplo n.º 7
0
def save_sbml_model(model, filename, flavor=None):
    """ Save a model to an SBML file.
    
    Arguments:
        model (Model): model
        filename (str): file path
        flavor (str): adapt to different modeling conventions (optional, currently available: 'cobra', 'fbc2')
    """

    document = SBMLDocument(DEFAULT_SBML_LEVEL, DEFAULT_SBML_VERSION)
    sbml_model = document.createModel(model.id)

    if flavor in {Flavor.BIGG, Flavor.FBC2}:
        document.enablePackage(FbcExtension.getXmlnsL3V1V2(), 'fbc', True)
        fbc_model = sbml_model.getPlugin('fbc')
        fbc_model.setStrict(True)
        document.setPackageRequired('fbc', False)
    _save_compartments(model, sbml_model)
    _save_metabolites(model, sbml_model, flavor)
    _save_reactions(model, sbml_model)
    if isinstance(model, CBModel):
        _save_cb_parameters(model, sbml_model, flavor)
        _save_gpr_associations(model, sbml_model, flavor)
    if isinstance(model, ODEModel):
        _save_concentrations(model, sbml_model)
        _save_global_parameters(model, sbml_model)
        _save_kineticlaws(model, sbml_model)
        _save_assignment_rules(model, sbml_model)
    _save_metadata(model, sbml_model)
    writer = SBMLWriter()
    writer.writeSBML(document, filename)
Exemplo n.º 8
0
    def info_document(self, doc: libsbml.SBMLDocument) -> Dict[str, str]:
        """Info dictionary for SBaseRef.

        :param doc: SBMLDocument
        :return: information dictionary for SBMLDocument
        """
        info = self.info_sbase(doc)
        packages = [
            f'<span class="package">L{doc.getLevel()}V{doc.getVersion()}</span>'
        ]

        for k in range(doc.getNumPlugins()):
            plugin = doc.getPlugin(k)
            prefix = plugin.getPrefix()
            version = plugin.getPackageVersion()
            packages.append(
                f'<span class="package">{prefix}-V{version}</span>')
        info["packages"] = " ".join(packages)
        return info
Exemplo n.º 9
0
def _check_consistency(doc: libsbml.SBMLDocument, internalConsistency=False, show_errors=True):
    Nerr = 0  # error count
    Nwarn = 0  # warning count
    if internalConsistency:
        Nall = doc.checkInternalConsistency()
    else:
        Nall = doc.checkConsistency()

    if Nall > 0:
        for i in range(Nall):
            severity = doc.getError(i).getSeverity()
            if (severity == libsbml.LIBSBML_SEV_ERROR) or (severity == libsbml.LIBSBML_SEV_FATAL):
                Nerr += 1
            else:
                Nwarn += 1

        doc.printErrors()

    return Nall, Nerr, Nwarn
Exemplo n.º 10
0
def no_boundary_conditions(doc: libsbml.SBMLDocument) -> None:
    """Set all boundaryCondition to False in the model.

    :param doc: libsbml.SBMLDocument
    :return:
    """
    model = doc.getModel()
    for s in model.species:
        if s.boundary_condition:
            warnings.warn(f"boundaryCondition changed {s}", UserWarning)
            s.setBoundaryCondition(False)
Exemplo n.º 11
0
def save_sbml_model(model, filename):
    """ Save a model to an SBML file.
    
    Arguments:
        model : StoichiometricModel (or any subclass) -- Stoichiometric model (or subclass)
        filename : String -- SBML file path
    """

    document = SBMLDocument(DEFAULT_SBML_LEVEL, DEFAULT_SBML_VERSION)
    sbml_model = document.createModel(model.id)
    _save_compartments(model, sbml_model)
    _save_metabolites(model, sbml_model)
    _save_reactions(model, sbml_model)
    _save_stoichiometry(model, sbml_model)
    if isinstance(model, ConstraintBasedModel):
        _save_cb_parameters(model, sbml_model)
    if isinstance(model, GPRConstrainedModel):
        _save_gpr(model, sbml_model)
    writer = SBMLWriter()
    writer.writeSBML(document, filename)
Exemplo n.º 12
0
def is_sbml_consistent(sbml_document: libsbml.SBMLDocument, check_units=False):
    """Check for SBML validity / consistency

    Arguments:
        sbml_document: SBML document to check
        check_units: Also check for unit-related issues
    Returns:
        False if problems were detected, otherwise True
    """

    if not check_units:
        sbml_document.setConsistencyChecks(
            libsbml.LIBSBML_CAT_UNITS_CONSISTENCY, False)

    has_problems = sbml_document.checkConsistency()
    if has_problems:
        log_sbml_errors(sbml_document)
        logger.warning(
            'WARNING: Generated invalid SBML model. Check messages above.')

    return not has_problems
Exemplo n.º 13
0
def log_sbml_errors(sbml_document: libsbml.SBMLDocument,
                    minimum_severity=libsbml.LIBSBML_SEV_WARNING) -> None:
    """Log libsbml errors

    Arguments:
        sbml_document: SBML document to check
        minimum_severity: Minimum severity level to report (see libsbml)
    """

    for error_idx in range(sbml_document.getNumErrors()):
        error = sbml_document.getError(error_idx)
        if error.getSeverity() >= minimum_severity:
            category = error.getCategoryAsString()
            severity = error.getSeverityAsString()
            message = error.getMessage()
            if severity == libsbml.LIBSBML_SEV_INFO:
                logger.info(f'libSBML {severity} ({category}): {message}')
            elif severity == libsbml.LIBSBML_SEV_WARNING:
                logger.warning(f'libSBML {severity} ({category}): {message}')
            else:
                logger.error(f'libSBML {severity} ({category}): {message}')
Exemplo n.º 14
0
def save_sbml_model(model, filename, flavor=None):
    """ Save a model to an SBML file.
    
    Arguments:
        model (Model): model
        filename (str): file path
        flavor (str): adapt to different modeling conventions (optional, currently available: 'cobra', 'fbc2')
    """

    document = SBMLDocument(DEFAULT_SBML_LEVEL, DEFAULT_SBML_VERSION)
    sbml_model = document.createModel(model.id)

    if flavor in {Flavor.BIGG, Flavor.FBC2}:
        document.enablePackage(FbcExtension.getXmlnsL3V1V2(), 'fbc', True)
        fbc_model = sbml_model.getPlugin('fbc')
        fbc_model.setStrict(True)
        document.setPackageRequired('fbc', False)
    _save_compartments(model, sbml_model)
    _save_metabolites(model, sbml_model, flavor)
    _save_reactions(model, sbml_model)
    if isinstance(model, CBModel):
        _save_cb_parameters(model, sbml_model, flavor)
        _save_gpr_associations(model, sbml_model, flavor)
    if isinstance(model, ODEModel):
        _save_concentrations(model, sbml_model)
        _save_global_parameters(model, sbml_model)
        _save_kineticlaws(model, sbml_model)
        _save_assignment_rules(model, sbml_model)
    _save_metadata(model, sbml_model)
    writer = SBMLWriter()
    writer.writeSBML(document, filename)
Exemplo n.º 15
0
def _create_html(
    doc: libsbml.SBMLDocument,
    basename: str,
    html_template: str = "report.html",
    math_type: str = "cmathml",
    offline: bool = True,
) -> str:
    """Create HTML from SBML.

    :param doc: SBML document for creating HTML report
    :param basename: basename of SBML file path
    :param html_template: which template file to use for rendering
    :param math_type: specifies the math rendering mode for the report
    :param offline: to specify offline report generation for appropriate linking of
                    stylesheet and script files

    :return: rendered HTML report template for the SBML document
    """
    # template environment
    env = jinja2.Environment(
        loader=jinja2.FileSystemLoader(TEMPLATE_DIR),
        extensions=["jinja2.ext.autoescape"],
        trim_blocks=True,
        lstrip_blocks=True,
    )
    # additional SBML filters
    for key in sbmlfilters.filters:
        env.filters[key] = getattr(sbmlfilters, key)

    model = doc.getModel()
    context: Dict[str, Any] = {
        "offline": offline,
        "basename": basename,
    }
    if model is not None:
        try:
            template = env.get_template(html_template)
        except TemplateNotFound as err:
            logger.error(
                f"TemplateNotFound: {TEMPLATE_DIR} / {html_template}; {err}")

        model_info = SBMLModelInfo(doc=doc, model=model, math_render=math_type)
        context.update(model_info.info)
    else:
        # no model exists
        logging.error(
            f"No model in SBML file when creating model report: {doc}")
        template = env.get_template("report_no_model.html")
        context.update({
            "doc": doc,
        })
    return template.render(context)
Exemplo n.º 16
0
    def __init__(self, doc: libsbml.SBMLDocument,
                 annotations: Iterable[ExternalAnnotation]):
        """Constructor.

        :param doc: SBMLDocument
        :param annotations: iterable of ModelAnnotation
        """
        self.doc = doc
        self.model = doc.getModel()
        self.annotations = annotations

        # prepare dictionary for lookup of ids
        self.id_dict = self._get_ids_from_model()
Exemplo n.º 17
0
def promote_local_variables(doc: libsbml.SBMLDocument,
                            suffix: str = "_promoted") -> libsbml.SBMLDocument:
    """Promotes local variables in SBMLDocument.

    Manipulates SBMLDocument in place!

    :param doc: SBMLDocument
    :param suffix: str suffix for promoted SBML
    :return: SBMLDocument with promoted parameters
    """
    model: libsbml.Model = doc.getModel()
    model.setId(f"{model.id}{suffix}")

    # promote local parameters
    props = libsbml.ConversionProperties()
    props.addOption("promoteLocalParameters", True,
                    "Promotes all Local Parameters to Global ones")

    if doc.convert(props) != libsbml.LIBSBML_OPERATION_SUCCESS:
        logger.error(f"Promotion of local parameters failed: {doc}")
    else:
        logger.info(f"Promotion of local paramters successful: {doc}")
    return doc
Exemplo n.º 18
0
def add_default_flux_bounds(doc: libsbml.SBMLDocument,
                            lower: float = -100.0,
                            upper: float = 100.0) -> None:
    """Add default flux bounds to SBMLDocument.

    :param doc: SBMLDocument
    :param lower: lower flux bound
    :param upper: upper flux bound
    :return:
    """
    model = doc.getModel()

    def create_bound(sid: str, value: float) -> libsbml.Parameter:
        """Create flux bound parameter with given value.

        :param sid: id of parameter
        :param value: flux bound
        :return:
        """
        p = model.createParameter()
        p.setId(sid)
        p.setValue(value)
        p.setName("{} flux bound".format(sid))
        p.setSBOTerm("SBO:0000626")  # default flux bound
        p.setConstant(True)
        return p

    # FIXME: overwrites lower/upper parameter (you should check if existing in model)
    create_bound(sid="lower", value=lower)
    create_bound(sid="upper", value=upper)

    for r in model.reactions:
        rfbc = r.getPlugin("fbc")
        if not rfbc.isSetLowerFluxBound():
            rfbc.setLowerFluxBound("lower")
        if not rfbc.isSetUpperFluxBound():
            rfbc.setUpperFluxBound("upper")
Exemplo n.º 19
0
def flatten_external_model_definitions(
        doc: libsbml.SBMLDocument,
        validate: bool = False) -> libsbml.SBMLDocument:
    """Converts all ExternalModelDefinitions to ModelDefinitions.

    I.e. the definition of models in external files are read
    and directly included in the top model. The resulting
    comp model consists than only of a single file.

    The model refs in the submodel do not change in the process,
    so no need to update the submodels.

    :param doc: SBMLDocument
    :param validate: validation flag
    :return: SBMLDocument with ExternalModelDefinitions replaced
    """
    logger.debug("* flattenExternalModelDefinitions")

    # FIXME: handle multiple levels of hierarchies. Recursively to handle the ExternalModelDefinitions of submodels
    logger.warning(
        "flattenExternalModelDefinitions is experimental and does not work recursively!"
    )

    comp_doc = doc.getPlugin("comp")
    if comp_doc is None:
        logger.warning(
            "Model is not a comp model, no ExternalModelDefinitions")
        return doc
    emd_list = comp_doc.getListOfExternalModelDefinitions()
    if (emd_list is None) or (len(emd_list) == 0):
        # no ExternalModelDefinitions
        logger.warning("Model does not contain any ExternalModelDefinitions")
        return doc
    else:
        emd_ids = []
        for emd in emd_list:
            logger.debug(emd)
            emd_ids.append(emd.getId())

            # get the model definition from the model
            ref_model = emd.getReferencedModel()

            ref_doc = ref_model.getSBMLDocument()
            # print(ref_model)
            for k in range(ref_doc.getNumPlugins()):
                plugin = ref_doc.getPlugin(k)
                # print(k, plugin)

                # enable the package on the main SBMLDocument
                uri = plugin.getURI()
                prefix = plugin.getPrefix()
                doc.enablePackage(uri, prefix, True)

            # print("\n")

            # add model definition for model
            md = libsbml.ModelDefinition(ref_model)
            comp_doc.addModelDefinition(md)

        # remove the emds afterwards
        for emd_id in emd_ids:
            # remove the emd from the model
            comp_doc.removeExternalModelDefinition(emd_id)

    # validate
    if validate:
        validate_doc(doc)
    return doc
Exemplo n.º 20
0
def save_sbml(model, filename):
    """docstring for save_model"""

    sbml_document = SBMLDocument(2, 1)
    sbml_model    = sbml_document.createModel(model.id)

    sbml_model.getNamespaces().add("http://www.w3.org/1999/xhtml", "html")

    if model.name:
        sbml_model.setName(model.name)

    for compartment in model.compartments():
        sbml_compartment = sbml_model.createCompartment()
        sbml_compartment.setId(compartment.id)
        sbml_compartment.setName(compartment.name)

    for unit_definition in model.unit_definitions():
        sbml_unitDefinition = sbml_model.createUnitDefinition()
        sbml_unitDefinition.setId(unit_definition.id)
        for unit in unit_definition.units:
            sbml_unit = sbml_unitDefinition.createUnit()
            sbml_unit.setKind(UnitKind_forName(unit.kind))
            sbml_unit.setMultiplier(unit.multiplier)
            sbml_unit.setOffset(unit.offset)
            sbml_unit.setExponent(unit.exponent)
            sbml_unit.setScale(unit.scale)

    for metabolite in model.metabolites():
        species = sbml_model.createSpecies()
        species.setId(metabolite.id)
        species.setName(metabolite.name)
        if metabolite.charge:
            species.setCharge(metabolite.charge)
        species.setCompartment(metabolite.compartment)
        species.setBoundaryCondition(metabolite.boundaryCondition)
        if metabolite.notes:
            for (key, value) in metabolite.notes.items():
                species.appendNotes('\n<html:p>%s: %s</html:p>' % (key, value))
            species.appendNotes('\n')

    for reaction in model.reactions():
        sbml_reaction = sbml_model.createReaction()
        sbml_reaction.setId(reaction.id)
        sbml_reaction.setName(reaction.name)
        sbml_reaction.setReversible(reaction.reversible)

        for (key, value) in reaction.notes.items():
            sbml_reaction.appendNotes('\n<html:p>%s: %s</html:p>' % (key, value))
        sbml_reaction.appendNotes('\n')

        kineticLaw = sbml_reaction.createKineticLaw()
        kineticLaw.setFormula('FLUX_VALUE')

        sbml_lower = kineticLaw.createParameter()
        sbml_lower.setId('LOWER_BOUND')
        sbml_lower.setValue(reaction.lower_bound)

        sbml_upper = kineticLaw.createParameter()
        sbml_upper.setId('UPPER_BOUND')
        sbml_upper.setValue(reaction.upper_bound)

        sbml_upper = kineticLaw.createParameter()
        sbml_upper.setId('OBJECTIVE_COEFFICIENT')
        sbml_upper.setValue(reaction.objective_coefficient)

        if reaction.flux_value:
            sbml_upper = kineticLaw.createParameter()
            sbml_upper.setId('FLUX_VALUE')
            sbml_upper.setValue(reaction.flux_value)

        for (metabolite, coefficient) in reaction.participants.items():
            if coefficient < 0:
                speciesReference = sbml_reaction.createReactant()
                coefficient      = abs(coefficient)
            else:
                speciesReference = sbml_reaction.createProduct()
            speciesReference.setSpecies(metabolite.id)
            speciesReference.setStoichiometry(float(coefficient))

    writer = SBMLWriter()
    writer.writeSBML(sbml_document, filename)
Exemplo n.º 21
0
def write_cobra_model_to_sbml_file(cobra_model, sbml_filename,
                                   sbml_level=2, sbml_version=1,
                                   print_time=False):
    """Write a cobra.Model object to an SBML XML file.

    cobra_model:  A cobra.Model object

    sbml_filename:  The file to write the SBML XML to.

    sbml_level:  2 is the only level supported at the moment.

    sbml_version: 1 is the only version supported at the moment.

    print_time:  Boolean.  Print the time requirements for different sections

    TODO: Update the NOTES to match the SBML standard and provide support for
    Level 2 Version 4
    
    """
    #Add in the common compartment abbreviations.  If there are additional compartments
    #they also need to be added.
    note_start_tag, note_end_tag = '<p>', '</p>'
    if sbml_level > 2 or (sbml_level == 2 and sbml_version == 4):
        note_start_tag, note_end_tag = '<html:p>', '</html:p>'
        
    if not hasattr(cobra_model, 'compartments'):
        cobra_model.compartments = {'c': 'cytosol',
                                    'p': 'periplasm',
                                    'e': 'extracellular'}
    
    sbml_doc = SBMLDocument(sbml_level, sbml_version)
    sbml_model = sbml_doc.createModel(cobra_model.description.split('.')[0])
    #Note need to set units
    reaction_units = 'mmol_per_gDW_per_hr'
    model_units = sbml_model.createUnitDefinition()
    model_units.setId(reaction_units)
    sbml_unit = model_units.createUnit()
    sbml_unit.setKind(UNIT_KIND_MOLE)
    sbml_unit.setScale(-3)
    sbml_unit = model_units.createUnit()
    sbml_unit.setKind(UNIT_KIND_GRAM)
    sbml_unit.setExponent(-1)
    sbml_unit = model_units.createUnit()
    sbml_unit.setKind(UNIT_KIND_SECOND)
    sbml_unit.setMultiplier(1.0/60/60)
    sbml_unit.setExponent(-1)

    
    for the_key in cobra_model.compartments.keys():
        sbml_comp = sbml_model.createCompartment()
        sbml_comp.setId(the_key)
        sbml_comp.setName(cobra_model.compartments[the_key])
        sbml_comp.setSize(1) #Just to get rid of warnings

    if print_time:
        start_time = time()
    #Use this dict to allow for fast look up of species id
    #for references created in the reaction section.
    metabolite_dict = {}

    for cobra_metabolite in cobra_model.metabolites:
        metabolite_dict[cobra_metabolite.id] =  add_sbml_species(sbml_model,
                                                                 cobra_metabolite,
                                                                 note_start_tag=note_start_tag,
                                                                 note_end_tag=note_end_tag)

    if print_time:
        print 'Adding %s took %1.2f seconds'%('metabolites',
                                              time()-start_time)
    if print_time:
        start_time = time()
    for the_reaction in cobra_model.reactions:
        #This is probably the culprit.  Including cobra.Reaction
        #objects explicitly in cobra.Model will speed this up.
        sbml_reaction = sbml_model.createReaction()
        #Need to remove - for proper SBML.  Replace with __
        the_reaction_id = 'R_' + the_reaction.id.replace('-','__' )
        sbml_reaction.setId(the_reaction_id)
        if the_reaction.reversibility == 1:
            sbml_reaction.setReversible(True)
        else:
            sbml_reaction.setReversible(False)
        if the_reaction.name:
            sbml_reaction.setName(the_reaction.name)
        else:
            sbml_reaction.setName(the_reaction.id)
        #Add in the reactant/product references
        for the_metabolite, the_coefficient in the_reaction._metabolites.items():
            sbml_stoichiometry = the_coefficient
            metabolite_id = str(metabolite_dict[the_metabolite.id])
            #Each SpeciesReference must have a unique id
            if sbml_stoichiometry < 0:
                species_reference = sbml_reaction.createReactant()
            else:
                species_reference = sbml_reaction.createProduct()
            species_reference.setId(metabolite_id + '_' + the_reaction_id)
            species_reference.setSpecies(metabolite_id)
            species_reference.setStoichiometry(abs(sbml_stoichiometry))
        #Deal with the case where the reaction is a boundary reaction
        if len(the_reaction._metabolites) == 1:
            the_metabolite, the_coefficient = the_reaction._metabolites.items()[0]
            the_metabolite = the_metabolite.copy()
            metabolite_id = add_sbml_species(sbml_model, the_metabolite,
                                             note_start_tag=note_start_tag,
                                             note_end_tag=note_end_tag,
                                             boundary_metabolite=True)
            the_coefficient *= -1
            #Each SpeciesReference must have a unique id
            if sbml_stoichiometry < 0:
                species_reference = sbml_reaction.createReactant()
            else:
                species_reference = sbml_reaction.createProduct()
            species_reference.setId(metabolite_id + '_' + the_reaction_id)
            species_reference.setSpecies(metabolite_id)
            species_reference.setStoichiometry(abs(sbml_stoichiometry))
            
        #Add in the kineticLaw
        sbml_law = KineticLaw(sbml_level, sbml_version)
        sbml_law.setId('FLUX_VALUE')
        sbml_law.setFormula('FLUX_VALUE')
        reaction_parameter_dict = {'LOWER_BOUND': [the_reaction.lower_bound, reaction_units],
                                   'UPPER_BOUND': [the_reaction.upper_bound, reaction_units],
                                   'FLUX_VALUE': [0, reaction_units],
                                   'OBJECTIVE_COEFFICIENT': [the_reaction.objective_coefficient,
                                                             'dimensionless']}
        for k, v in reaction_parameter_dict.items():
            sbml_parameter = Parameter(sbml_level, sbml_version)
            sbml_parameter.setId(k)
            if hasattr(v, '__iter__'):
                sbml_parameter.setValue(v[0])
                sbml_parameter.setUnits(v[1])
            else:
                sbml_parameter.setValue(v)
            sbml_law.addParameter(sbml_parameter)
        sbml_reaction.setKineticLaw(sbml_law)
        sbml_reaction.setNotes('<html xmlns="http://www.w3.org/1999/xhtml">%sGENE_ASSOCIATION: %s%s%sSUBSYSTEM: %s%s</html>'%(note_start_tag,
                                                                 the_reaction.gene_reaction_rule,
                                                                 note_end_tag,
                                                                 note_start_tag,
                                                                 the_reaction.subsystem,
                                                                 note_end_tag))

    if print_time:
       print 'Adding %s took %1.2f seconds'%('reactions',
                                             time()-start_time)

    writeSBML(sbml_doc, sbml_filename)
Exemplo n.º 22
0
    def export_en_sbml(self,
                       file_path,
                       gemtractor,
                       model_id,
                       model_name=None,
                       filter_species=None,
                       filter_reactions=None,
                       filter_genes=None,
                       filter_gene_complexes=None,
                       remove_reaction_enzymes_removed=True,
                       remove_ghost_species=False,
                       discard_fake_enzymes=False,
                       remove_reaction_missing_species=False,
                       removing_enzyme_removes_complex=True):
        """
    export the enzyme-centric network in SBML format
    
    will attach the trimming-settings as SBML note
    
    writes the document using the `libsbml:SBMLWriter <http://sbml.org/Special/Software/libSBML/docs/python-api/class_s_b_m_l_writer.html>` -- returns the result of `libsbml:SBMLWriter.writeSBML <http://sbml.org/Special/Software/libSBML/docs/python-api/class_s_b_m_l_writer.html#a02d1998aee7656d7b9c3ac69d62bb66f>`_
    
    :param file_path: where to store the exported format?
    :param model_id: the model's identifier, will be postfixed with a greeting from us
    :param model_name: the model's name, will be prefixed with a greeting from us
    :param filter_species: species identifiers to get rid of
    :param filter_reactions: reaction identifiers to get rid of
    :param filter_genes: enzyme identifiers to get rid of
    :param filter_gene_complexes: enzyme-complex identifiers to get rid of, every list-item should be of format: 'A + B + gene42'
    :param remove_reaction_enzymes_removed: should we remove a reaction if all it's genes were removed?
    :param remove_ghost_species: should species be removed, that do not participate in any reaction anymore - even though they might be required in other entities?
    :param discard_fake_enzymes: should fake enzymes (implicitly assumes enzymes, if no enzymes are annotated to a reaction) be removed?
    :param remove_reaction_missing_species: remove a reaction if one of the participating genes was removed?
    :param removing_enzyme_removes_complex: if an enzyme is removed, should also all enzyme complexes be removed in which it participates?
    
    :type file_path: str
    :type model_id: str
    :type model_name: str
    :type filter_species: list of str
    :type filter_reactions: list of str
    :type filter_genes: list of str
    :type filter_gene_complexes: list of str
    :type remove_reaction_enzymes_removed: bool
    :type remove_ghost_species: bool
    :type discard_fake_enzymes: bool
    :type remove_reaction_missing_species: bool
    :type removing_enzyme_removes_complex: bool
    
    :return: true on success, otherwise false
    :rtype: bool
    """
        if not self.have_gene_net:
            self.calc_genenet()

        sbml = SBMLDocument()
        model = sbml.createModel()
        #TODO dc modified?
        if model is None:
            self.__logger.error("could not create model...")
            return False
        model.setId(model_id + "_GEMtracted_EnzymeNetwork")
        if model_name is None:
            model_name = model_id
        model.setName("GEMtracted EnzymeNetwork of " + model_name)

        # print ("adding note to en sbml")
        Utils.add_model_note(model, filter_species, filter_reactions,
                             filter_genes, filter_gene_complexes,
                             remove_reaction_enzymes_removed,
                             remove_ghost_species, discard_fake_enzymes,
                             remove_reaction_missing_species,
                             removing_enzyme_removes_complex)

        nodemap = {}

        compartment = model.createCompartment()
        compartment.setId('compartment')
        compartment.setConstant(True)

        num = 0
        for gene in self.genes:
            num += 1
            nodemap[gene] = self.__create_sbml_gene(model, 'g' + str(num),
                                                    gene, compartment,
                                                    gemtractor)
            # TODO: add other information if available

        for gene in self.gene_complexes:
            num += 1
            nodemap[gene] = self.__create_sbml_gene_complex(
                model, 'gc' + str(num), gene, compartment, gemtractor,
                self.gene_complexes[gene].genes, nodemap)
            # TODO: add other information if available

        num = 0
        for gene in self.genes:
            for associated in self.genes[gene].links["g"]:
                num += 1
                Network.create_sbml_reaction(model, 'r' + str(num),
                                             nodemap[gene],
                                             nodemap[associated.identifier])
            for associated in self.genes[gene].links["gc"]:
                num += 1
                Network.create_sbml_reaction(model, 'r' + str(num),
                                             nodemap[gene],
                                             nodemap[associated.identifier])
        for gene in self.gene_complexes:
            for associated in self.gene_complexes[gene].links["g"]:
                num += 1
                Network.create_sbml_reaction(model, 'r' + str(num),
                                             nodemap[gene],
                                             nodemap[associated.identifier])
            for associated in self.gene_complexes[gene].links["gc"]:
                num += 1
                Network.create_sbml_reaction(model, 'r' + str(num),
                                             nodemap[gene],
                                             nodemap[associated.identifier])

        return SBMLWriter().writeSBML(sbml, file_path)
Exemplo n.º 23
0
class TissueModel(object):
    """
    The SBML model is created from the tissue information
    and the single cell models.
    """
    _keys = ['main_units', 'units', 'names',
             'pars', 'external', 'assignments', 'rules']

    def __init__(self, Nc, Nf, version,
                 tissue_dict, cell_model, sim_id='core', events=None):
        """
        Initialize with the tissue information dictionary and
        the respective cell model used for creation.
        """
        self.Nc = Nc
        self.Nf = Nf
        self.version = version
        self.simId = sim_id
        self.cellModel = cell_model
        # print self.cellModel.info()

        # tissue information fields
        for key, value in tissue_dict.items():
            setattr(self, key, value)
        self.events = events

        # sbmlutils
        self.id = self.createId()
        self.doc = SBMLDocument(SBML_LEVEL, SBML_VERSION)
        self.model = self.doc.createModel()

        check(self.model.setId(self.id), 'set id')
        check(self.model.setName(self.id), 'set name')

        # add dynamical parameters
        self.pars.extend(
            [('Nc', self.Nc, '-', True),
             ('Nf', self.Nf, '-', True), ]
        )

        print '\n', '*' * 40, '\n', self.id, '\n', '*' * 40

    @staticmethod
    def createTissueDict(module_names):
        """
        Creates one information dictionary from various modules by combining the information.
        Information in earlier modules if overwritten by information in later modules.
        """
        import copy
        cdict = dict()
        for name in module_names:
            mdict = TissueModel._createDict(name)
            for key, value in mdict.items():
                if type(value) is list:
                    # create new list
                    if not cdict.has_key(key):
                        cdict[key] = []
                    # now add the elements by copy
                    cdict[key].extend(copy.deepcopy(value))

                elif type(value) is dict:
                    # create new dict
                    if not cdict.has_key(key):
                        cdict[key] = dict()
                    # now add the elements by copy
                    old_value = cdict.get(key)
                    for k, v in value.items():
                        old_value[k] = copy.deepcopy(v)
        return cdict

    @staticmethod
    def _createDict(module_name):
        """
        A module which encodes a cell model is given and
        used to create the instance of the CellModel from
        the given global variables of the module.

        TODO: some quality control of the model structure.
        """
        # dynamically import module
        # tissue_module = __import__(module_name)
        import importlib
        module = importlib.import_module(module_name)

        # get attributes from the class
        print '\n***', module_name, '***'
        print module
        print dir(module)

        mdict = dict()
        for key in TissueModel._keys:
            if hasattr(module, key):
                # print 'set:', key
                mdict[key] = getattr(module, key)
            else:
                print 'missing:', key

        return mdict

    def createId(self):
        if self.simId:
            mid = '{}_v{}_Nc{}_{}'.format(self.cellModel.mid, self.version, self.Nc, self.simId)
        else:
            mid = '{}_v{}_Nc{}'.format(self.cellModel.mid, self.version, self.Nc)
        return mid

    def cell_range(self):
        return range(1, self.Nc + 1)

    def comp_range(self):
        return range(1, self.Nc * self.Nf + 1)

    def info(self):
        for key in TissueModel._keys:
            print key, ' : ', getattr(self, key)

    def createModel(self):
        # sinusoidal unit model
        self.createUnits()
        self.createExternalParameters()
        self.createInitialAssignments()
        self.createExternalCompartments()
        self.createExternalSpecies()
        self.createAssignmentRules()
        self.createTransportReactions()
        self.createBoundaryConditions()
        # cell model
        self.createCellCompartments()
        self.createCellSpecies()
        self.createCellParameters()
        self.createCellInitialAssignments()
        self.createCellAssignmentRules()
        self.createCellReactions()
        # events
        self.createCellEvents()
        self.createSimulationEvents()

    #########################################################################
    # External Compartments
    ##########################################################################
    # id, name, spatialDimension, unit, constant, assignment/value
    def createExternalCompartmentsDict(self):
        comps = dict()
        # periportal
        comps[getPPId()] = (getPPName(), 3, 'm3', False, 'Vol_pp')
        # sinusoid
        for k in self.comp_range():
            comps[getSinusoidId(k)] = (getSinusoidName(k), 3, 'm3', False, 'Vol_sin')
        # disse
        for k in self.comp_range():
            comps[getDisseId(k)] = (getDisseName(k), 3, 'm3', False, 'Vol_dis')
        # perivenious
        comps[getPVId()] = (getPVName(), 3, 'm3', False, 'Vol_pv')
        return comps

    ##########################################################################
    # Cell compartments
    ##########################################################################
    def createCellCompartmentsDict(self):
        comps = dict()
        # hepatocyte compartments
        for k in self.cell_range():
            comps[getHepatocyteId(k)] = (getHepatocyteName(k), 3, 'm3', False, 'Vol_cell')
            comps[getCytosolId(k)] = (getCytosolName(k), 3, 'm3', False, 'Vol_cyto')
        return comps

    ##########################################################################
    # Species
    ##########################################################################
    def createExternalSpeciesDict(self):
        """
        All species which are defined external are generated in all
        external compartments, i.e. PP, PV, sinusoid and disse space.
        """
        sdict = dict()
        for data in self.external:
            (sid, init, units, boundaryCondition) = self.getItemsFromSpeciesData(data)
            name = self.names[sid]
            # PP
            sdict[getPPSpeciesId(sid)] = (getPPSpeciesName(name), init, units, getPPId(), boundaryCondition)
            for k in self.comp_range():
                sdict[getSinusoidSpeciesId(sid, k)] = (
                    getSinusoidSpeciesName(name, k), init, units, getSinusoidId(k), boundaryCondition)
                sdict[getDisseSpeciesId(sid, k)] = (
                    getDisseSpeciesName(name, k), init, units, getDisseId(k), boundaryCondition)
            # PV
            sdict[getPVSpeciesId(sid)] = (getPVSpeciesName(name), init, units, getPVId(), boundaryCondition)
        return sdict

    def createCellSpeciesDict(self):
        sdict = dict()
        for data in self.cellModel.species:
            (full_id, init, units, boundaryCondition) = self.getItemsFromSpeciesData(data)

            tokens = full_id.split('__')
            sid = tokens[1]
            name = self.names[sid]
            for k in self.cell_range():
                # TODO: only covers species in cytosol (has to work with arbitrary number of compartments)
                # necessary to have a mapping of the compartments to the functions which generate id and names
                if full_id.startswith('h__'):
                    sdict[getHepatocyteSpeciesId(sid, k)] = (getHepatocyteSpeciesName(name, k), init, units,
                                                             getHepatocyteId(k), boundaryCondition)
                if full_id.startswith('c__'):
                    sdict[getCytosolSpeciesId(sid, k)] = (getCytosolSpeciesName(name, k), init, units,
                                                          getCytosolId(k), boundaryCondition)
        return sdict

    def getItemsFromSpeciesData(self, data):
        sid, init, units = data[0], data[1], data[2]
        # handle the constant species
        if len(data) == 4:
            boundaryCondition = data[3]
        else:
            boundaryCondition = False
        return sid, init, units, boundaryCondition

    ##########################################################################
    # Diffusion
    ##########################################################################
    def createDiffusionAssignments(self):
        """ Create the geometrical diffusion constants
            based on the external substances.
            For the diffusion between sinusoid and space of Disse,
            diffusion through fenestrations is handled via pore theory.
        """
        # get the fenestration radius
        r_fen = None
        for p in self.pars:
            if p[0] == 'r_fen':
                r_fen = p[1]
                break
        if not r_fen:
            raise TissueModelException('Fenestration radius not defined.')

        diffusion_assignments = []
        for data in self.external:
            sid = data[0]
            # id, assignment, unit
            diffusion_assignments.extend([
                ('Dx_sin_{}'.format(sid), 'D{}/x_sin * A_sin'.format(sid), "m3_per_s"),
                ('Dx_dis_{}'.format(sid), 'D{}/x_sin * A_dis'.format(sid), "m3_per_s"),
                # ('Dy_sindis_{}'.format(sid), 'D{}/y_dis * f_fen * A_sindis'.format(sid), "m3_per_s")
                # check the pore size
            ])
            # test if substance larger than fenestration radius
            r_sid = None
            for p in self.pars:
                if p[0] == 'r_{}'.format(sid):
                    r_sid = p[1]
                    break
            if r_sid > r_fen:
                diffusion_assignments.extend([('Dy_sindis_{}'.format(sid), '0 m3_per_s', "m3_per_s")])
            else:
                diffusion_assignments.extend([('Dy_sindis_{}'.format(sid),
                                               'D{}/y_dis * f_fen * A_sindis * (1 dimensionless - r_{}/r_fen)^2 * (1 dimensionless - 2.104 dimensionless*r_{}/r_fen + 2.09 dimensionless *(r_{}/r_fen)^3 - 0.95 dimensionless *(r_{}/r_fen)^5)'.format(
                                                   sid, sid, sid, sid, sid),
                                               "m3_per_s")])
        return diffusion_assignments

    def createDiffusionRules(self):
        return self.createDiffusionAssignments()

    # Parameters
    def createParametersDict(self, pars):
        pdict = dict()
        for pdata in pars:
            pid = pdata[0]
            # id, name, value, unit, constant
            pdict[pid] = [pid, self.names.get(pid, None),
                          pdata[1], pdata[2], pdata[3]]
        return pdict

    # Units
    def createUnits(self):
        # creates all the individual unit definitions
        for key, value in self.units.iteritems():
            createUnitDefinition(self.model, key, value)
        # sets the main units of model
        setMainUnits(self.model, self.main_units)

    # Compartments
    def createExternalCompartments(self):
        comps = self.createExternalCompartmentsDict()
        createCompartments(self.model, comps)

    def createCellCompartments(self):
        comps = self.createCellCompartmentsDict()
        createCompartments(self.model, comps)

    # Species
    def createExternalSpecies(self):
        species = self.createExternalSpeciesDict()
        createSpecies(self.model, species)

    def createCellSpecies(self):
        species = self.createCellSpeciesDict()
        createSpecies(self.model, species)

    # Parameters
    def createExternalParameters(self):
        parameters = self.createParametersDict(self.pars)
        createParameters(self.model, parameters)

    def createCellParameters(self):
        parameters = self.createParametersDict(self.cellModel.pars)
        createParameters(self.model, parameters)

    # InitialAssignments
    def createInitialAssignments(self):
        createInitialAssignments(self.model, self.assignments, self.names)
        # diffusion
        # dif_assignments = self.createDiffusionAssignments()
        # createInitialAssignments(self.model, dif_assignments, self.names)

    def createCellInitialAssignments(self):
        createInitialAssignments(self.model, self.cellModel.assignments, self.names)

    # Assignment Rules
    def createAssignmentRules(self):
        createAssignmentRules(self.model, self.rules, self.names)

        # diffusion
        dif_rules = self.createDiffusionRules()
        createAssignmentRules(self.model, dif_rules, self.names)

    def createCellAssignmentRules(self):
        rules = []
        rep_dicts = self.createCellExtReplacementDicts()
        for rule in self.cellModel.rules:
            for d in rep_dicts:
                r_new = [initString(rpart, d) for rpart in rule]
                rules.append(r_new)
        createAssignmentRules(self.model, rules, self.names)

    def createCellReplacementDicts(self):
        """ Definition of replacement information for initialization of the cell ids.
            Creates all possible combinations.
        """
        init_data = []
        for k in self.cell_range():
            d = dict()
            d['h__'] = '{}__'.format(getHepatocyteId(k))
            d['c__'] = '{}__'.format(getCytosolId(k))
            init_data.append(d)
        return init_data

    def createCellExtReplacementDicts(self):
        """ Definition of replacement information for initialization of the cell ids.
            Creates all possible combinations.
        """
        init_data = []
        for k in self.cell_range():
            for i in range((k - 1) * self.Nf + 1, k * self.Nf + 1):
                d = dict()
                d['h__'] = '{}__'.format(getHepatocyteId(k))
                d['c__'] = '{}__'.format(getCytosolId(k))
                d['e__'] = '{}__'.format(getDisseId(i))
                init_data.append(d)
        return init_data

    # Boundary Conditions
    def createBoundaryConditions(self):
        ''' Set constant in periportal. '''
        sdict = self.createExternalSpeciesDict()
        for key in sdict.keys():
            if isPPSpeciesId(key):
                s = self.model.getSpecies(key)
                s.setBoundaryCondition(True)

    # Reactions
    def createCellReactions(self):
        """ Initializes the generic compartments with the actual
            list of compartments for the given geometry.
        """
        # set the model for the template
        reaction.model = self.model

        rep_dicts = self.createCellReplacementDicts()
        for r in self.cellModel.reactions:
            # Get the right replacement dictionaries for the reactions
            if ('c__' in r.compartments) and not ('e__' in r.compartments):
                rep_dicts = self.createCellReplacementDicts()
            if ('c__' in r.compartments) and ('e__' in r.compartments):
                rep_dicts = self.createCellExtReplacementDicts()
            r.createReactions(self.model, rep_dicts)

    def createTransportReactions(self):
        self.createFlowRules()
        self.createFlowReactions()
        self.createFlowPoreReactions()
        self.createDiffusionReactions()

    def createFlowRules(self):
        """ Creates the rules for positions Si_x, pressures Si_P,
            capillary flow Si_Q and pore flow Si_q.
            These parameters are used afterwards to calculate the actual flow
            values.
        """
        rules = [
            (getPositionId(getPPId()), '0 m', 'm'),
            (getPositionId(getPVId()), 'L', 'm'),
        ]
        # position midpoint hepatocyte
        for k in range(1, self.Nc * self.Nf + 1):
            r = (getPositionId(getSinusoidId(k)), '({} dimensionless-0.5 dimensionless)*x_sin'.format(k), 'm')
            rules.append(r)
        # position in between hepatocytes
        for k in range(1, self.Nc * self.Nf):
            r = (getPositionId(getSinusoidId(k), getSinusoidId(k + 1)), '{} dimensionless*x_sin'.format(k), 'm')
            rules.append(r)

        # pressures
        P_formula = '(-(Pb-P0) + (Pa-P0)*exp(-L/lambda))/(exp(-L/lambda)-exp(L/lambda))*exp( {}/lambda)\
                 + ( (Pb-P0) - (Pa-P0)*exp( L/lambda))/(exp(-L/lambda)-exp(L/lambda))*exp(-{}/lambda) + P0'
        # PP, PV
        for vid in [getPPId(), getPVId()]:
            x_str = getPositionId(vid)
            P_str = getPressureId(vid)
            rules.append((P_str, P_formula.format(x_str, x_str), 'Pa'))
        # midpoint
        for k in self.comp_range():
            x_str = getPositionId(getSinusoidId(k))
            P_str = getPressureId(getSinusoidId(k))
            rules.append((P_str, P_formula.format(x_str, x_str), 'Pa'))

        # capillary flow
        Q_formula = '-1 dimensionless/sqrt(W*w) * ( (-(Pb-P0) + (Pa-P0)*exp(-L/lambda))/(exp(-L/lambda)-exp(L/lambda))*exp( {}/lambda)\
        - ( (Pb-P0) - (Pa-P0)*exp( L/lambda))/(exp(-L/lambda)-exp(L/lambda))*exp(-{}/lambda) )'
        # PP, PV
        for vid in [getPPId(), getPVId()]:
            x_str = getPositionId(vid)
            Q_str = getQFlowId(vid)
            rules.append((Q_str, Q_formula.format(x_str, x_str), 'm3_per_s'))
        # between locations
        for k in range(1, self.Nc * self.Nf):
            x_str = '{}{}_x'.format(getSinusoidId(k), getSinusoidId(k + 1))
            Q_str = '{}{}_Q'.format(getSinusoidId(k), getSinusoidId(k + 1))
            rules.append((Q_str, Q_formula.format(x_str, x_str), 'm3_per_s'))

        # pore flow (only along sinusoid, not in PP and PV)
        q_formula = '1 dimensionless/w  * ( (-(Pb-P0) + (Pa-P0)*exp(-L/lambda))/(exp(-L/lambda)-exp(L/lambda))*exp( {}/lambda) \
        + ( (Pb-P0) - (Pa-P0)*exp( L/lambda))/(exp(-L/lambda)-exp(L/lambda))*exp(-{}/lambda) )'

        # midpoint
        for k in self.comp_range():
            x_str = '{}_x'.format(getSinusoidId(k))
            q_str = '{}_q'.format(getSinusoidId(k))
            rules.append((q_str, q_formula.format(x_str, x_str), 'm2_per_s'))

        createAssignmentRules(self.model, rules, {})

    def createFlowReactions(self):
        """
        Creates the local flow reactions based on the local volume flows.
        The amount of substance transported via the volume flow is calculated.
        """
        # flow = 'flow_sin * A_sin'     # [m3/s] global volume flow (converts to local volume flow in pressure model)
        for data in self.external:
            sid = data[0]
            # flow PP -> S01
            Q_str = getQFlowId(getPPId())  # [m3/s] local volume flow
            createFlowReaction(self.model, sid, c_from=getPPId(), c_to=getSinusoidId(1),
                               flow=Q_str)  # [m3/s] local volume flow
            # flow S[k] -> S[k+1]
            for k in range(1, self.Nc * self.Nf):
                Q_str = getQFlowId(getSinusoidId(k), getSinusoidId(k + 1))
                createFlowReaction(self.model, sid, c_from=getSinusoidId(k), c_to=getSinusoidId(k + 1), flow=Q_str)
            # flow S[Nc*Nf] -> PV
            Q_str = getQFlowId(getPVId())
            createFlowReaction(self.model, sid, c_from=getSinusoidId(self.Nc * self.Nf), c_to=getPVId(), flow=Q_str)
            # flow PV ->
            createFlowReaction(self.model, sid, c_from=getPVId(), c_to=NONE_ID, flow=Q_str);

    def createFlowPoreReactions(self):
        """ Filtration and reabsorption reactions through pores. """
        for data in self.external:
            sid = data[0]
            if sid in ["rbcM"]:
                continue  # only create for substances fitting through pores

            # flow S[k] -> D[k]
            for k in self.comp_range():
                Q_str = getqFlowId(getSinusoidId(k)) + ' * {}'.format('x_sin')  # [m2/s] * [m] (area flow)
                createFlowReaction(self.model, sid, c_from=getSinusoidId(k), c_to=getDisseId(k), flow=Q_str)

    def createDiffusionReactions(self):
        for data in self.external:
            sid = data[0]
            # [1] sinusoid diffusion
            Dx_sin = 'Dx_sin_{}'.format(sid)
            createDiffusionReaction(self.model, sid, c_from=getPPId(), c_to=getSinusoidId(1), D=Dx_sin)

            for k in range(1, self.Nc * self.Nf):
                createDiffusionReaction(self.model, sid, c_from=getSinusoidId(k), c_to=getSinusoidId(k + 1), D=Dx_sin)
            createDiffusionReaction(self.model, sid, c_from=getSinusoidId(self.Nc * self.Nf), c_to=getPVId(), D=Dx_sin)

            # [2] disse diffusion
            Dx_dis = 'Dx_dis_{}'.format(sid)
            for k in range(1, self.Nc * self.Nf):
                createDiffusionReaction(self.model, sid, c_from=getDisseId(k), c_to=getDisseId(k + 1), D=Dx_dis)

            # [3] sinusoid - disse diffusion
            Dy_sindis = 'Dy_sindis_{}'.format(sid)
            for k in self.comp_range():
                createDiffusionReaction(self.model, sid, c_from=getSinusoidId(k), c_to=getDisseId(k), D=Dy_sindis)

    # Events
    def createCellEvents(self):
        """ Creates the additional events defined in the cell model.
            These can be metabolic deficiencies, or other defined
            parameter changes.
            TODO: make this cleaner and more general.
        """

        ddict = self.cellModel.deficiencies
        dunits = self.cellModel.deficiencies_units

        for deficiency, data in ddict.iteritems():
            e = createDeficiencyEvent(self.model, deficiency)
            # create all the event assignments for the event
            for key, value in data.iteritems():
                p = self.model.getParameter(key)
                p.setConstant(False)
                formula = '{} {}'.format(value, dunits[key])
                astnode = libsbml.parseL3FormulaWithModel(formula, self.model)
                ea = e.createEventAssignment()
                ea.setVariable(key)
                ea.setMath(astnode)

    def createSimulationEvents(self):
        """ Create the simulation timecourse events based on the
            event data.
        """
        if self.events:
            createSimulationEvents(self.model, self.events)

    def writeSBML(self, filepath=None, validate=True):
        if not filepath:
            filepath = self.sbml_default_path()

        print 'Write : {}\n'.format(self.id, filepath)
        writer = SBMLWriter()
        writer.writeSBMLToFile(self.doc, filepath)

        # validate the model with units (only for small models)
        if validate:
            validator = SBMLValidator(ucheck=(self.Nc < 4))
            validator.validate(filepath)
        return filepath

    def sbml_default_path(self):
        import os
        from multiscale import multiscale_settings

        return os.path.join(multiscale_settings.SBML_DIR, '{}.xml'.format(self.id))
Exemplo n.º 24
0
def log_sbml_errors_for_doc(doc: libsbml.SBMLDocument) -> None:
    """Log errors of current SBMLDocument."""
    for k in range(doc.getNumErrors()):
        log_sbml_error(error=doc.getError(k))
Exemplo n.º 25
0
def flatten_sbml_doc(doc: libsbml.SBMLDocument,
                     output_path: Path = None,
                     leave_ports: bool = True) -> libsbml.SBMLDocument:
    """Flatten SBMLDocument.

    Validation should be performed before the flattening and is not part
    of the flattening routine.
    If an output path is provided the file is written to the output path.

    :param doc: SBMLDocument to flatten.
    :param output_path: Path to write flattended SBMLDocument to
    :param leave_ports: flag to leave ports

    :return: SBMLDocument
    """
    error_count = doc.getNumErrors()
    if error_count > 0:
        if doc.getError(0).getErrorId() == libsbml.XMLFileUnreadable:
            # Handle case of unreadable file here.
            logger.error("SBML error in doc: libsbml.XMLFileUnreadable")
        elif doc.getError(0).getErrorId() == libsbml.XMLFileOperationError:
            # Handle case of other file error here.
            logger.error("SBML error in doc: libsbml.XMLFileOperationError")
        else:
            # Handle other error cases here.
            logger.error("SBML errors in doc, see SBMLDocument error log.")

    # converter options
    libsbml.CompFlatteningConverter
    props = libsbml.ConversionProperties()
    props.addOption("flatten comp", True)  # Invokes CompFlatteningConverter
    props.addOption("leave_ports",
                    leave_ports)  # Indicates whether to leave ports
    props.addOption("abortIfUnflattenable", "none")

    # flatten
    current = time.perf_counter()
    result = doc.convert(props)
    flattened_status = result == libsbml.LIBSBML_OPERATION_SUCCESS

    lines = [
        "",
        "-" * 120,
        str(doc),
        "{:<25}: {}".format("flattened",
                            str(flattened_status).upper()),
        "{:<25}: {:.3f}".format("flatten time (ms)",
                                time.perf_counter() - current),
        "-" * 120,
    ]
    info = bcolors.BOLD + "\n".join(lines) + bcolors.ENDC

    if flattened_status:
        logger.info(bcolors.OKGREEN + info + bcolors.ENDC)
    else:
        logger.error(bcolors.FAIL + info + bcolors.ENDC)
        raise ValueError(
            "SBML could not be flattend due to errors in the SBMLDocument.")

    if output_path is not None:
        write_sbml(doc, filepath=output_path)
        logger.info(f"Flattened model created: '{output_path}'")

    return doc
Exemplo n.º 26
0
def validate_doc(
    doc: libsbml.SBMLDocument,
    name=None,
    log_errors=True,
    units_consistency=True,
    modeling_practice=True,
    internal_consistency=True,
) -> ValidationResult:
    """Validate SBMLDocument.

    :param doc: SBMLDocument to check
    :param name: identifier or path for report
    :param log_errors: boolean flag of errors should be logged
    :param units_consistency: boolean flag units consistency
    :param modeling_practice: boolean flag modeling practise
    :param internal_consistency: boolean flag internal consistency

    :return: ValidationResult
    """
    if not name:
        name = str(doc)

    # set the unit checking, similar for the other settings
    doc.setConsistencyChecks(libsbml.LIBSBML_CAT_UNITS_CONSISTENCY,
                             units_consistency)
    doc.setConsistencyChecks(libsbml.LIBSBML_CAT_MODELING_PRACTICE,
                             modeling_practice)

    # time
    current = time.perf_counter()

    # all, error, warn
    if internal_consistency:
        results_internal = _check_consistency(doc, internal_consistency=True)
    else:
        results_internal = ValidationResult()
    results_not_internal = _check_consistency(doc, internal_consistency=False)

    # sum up
    vresults = ValidationResult.from_results(
        [results_internal, results_not_internal])

    lines = [
        "",
        "-" * 80,
        str(name),
        "{:<25}: {}".format("valid",
                            str(vresults.is_valid()).upper()),
    ]
    if not vresults.is_perfect():
        lines += [
            "{:<25}: {}".format("validation error(s)", vresults.error_count),
            "{:<25}: {}".format("validation warnings(s)",
                                vresults.warning_count),
        ]
    lines += [
        "{:<25}: {:.3f}".format("check time (s)",
                                time.perf_counter() - current),
        "-" * 80,
        "",
    ]
    info = "\n".join(lines)

    if vresults.is_valid():
        info = bcolors.OKGREEN + info + bcolors.ENDC
    else:
        info = bcolors.FAIL + info + bcolors.ENDC
    info = bcolors.BOLD + info + bcolors.ENDC

    # overall validation report
    if vresults.is_perfect():
        print(info)
    else:
        if vresults.is_valid():
            logging.warning(info)
        else:
            logging.error(info)

    # individual error and warning report
    if log_errors:
        vresults.log()

    return vresults