def id_html(item: libsbml.SBase) -> str: """Create info from id and metaid. :param item: SBML object for which info is to be generated :return: HTML code fragment enclosing info for item """ sid = item.getId() meta = metaid_html(item) if sid: display_sid = sid if isinstance(item, libsbml.RateRule) and item.isSetVariable(): display_sid = "d {}/dt".format(item.getVariable()) info = f""" <td id="{sid}" class="active"> <span class="package">{display_sid}</span> {meta} """ else: if meta: info = f'<td class="active">{meta}' else: info = f'<td class="active">{empty_html()}' # create modal information info += xml_modal(item) return info
def annotation_to_html(item: libsbml.SBase) -> str: """Render HTML representation of given annotation. :param item: SBase instance """ lines = [] for kcv in range(item.getNumCVTerms()): cv = item.getCVTerm(kcv) q_type = cv.getQualifierType() if q_type == 0: qualifier = miriam.ModelQualifierType[cv.getModelQualifierType()] elif q_type == 1: qualifier = miriam.BiologicalQualifierType[ cv.getBiologicalQualifierType()] lines.append("".join( ['<span class="collection">', qualifier, "</span>"])) items = [] for k in range(cv.getNumResources()): uri = cv.getResourceURI(k) tokens = uri.split("/") resource_id = tokens[-1] link = "".join( ['<a href="', uri, '" target="_blank">', resource_id, "</a>"]) items.append(link) lines.append("; ".join(items)) res = "<br />".join(lines) return res
def annotate_sbase(sbase: libsbml.SBase, annotation: Annotation): """ Annotate SBase based on given annotation data :param sbase: libsbml.SBase :param annotation: Annotation :return: """ qualifier, resource = annotation.qualifier.value, annotation.resource cv = libsbml.CVTerm() # type: libsbml.CVTerm # set correct type of qualifier if qualifier.startswith("BQB"): cv.setQualifierType(libsbml.BIOLOGICAL_QUALIFIER) sbml_qualifier = ModelAnnotator.get_SBMLQualifier(qualifier) cv.setBiologicalQualifierType(sbml_qualifier) elif qualifier.startswith('BQM'): cv.setQualifierType(libsbml.MODEL_QUALIFIER) sbml_qualifier = ModelAnnotator.get_SBMLQualifier(qualifier) cv.setModelQualifierType(sbml_qualifier) else: LOGGER.error('Unsupported qualifier: {}'.format(qualifier)) cv.addResource(resource) # meta id has to be set if not sbase.isSetMetaId(): sbase.setMetaId(utils.create_metaid(sbase)) success = sbase.addCVTerm(cv) if success != 0: LOGGER.error("RDF not written: ", success) LOGGER.error(libsbml.OperationReturnValue_toString(success)) LOGGER.error("{}, {}, {}".format(object, qualifier, resource))
def _create_hash_id(sbase: libsbml.SBase) -> str: if sbase and hasattr(sbase, "getId") and sbase.isSetId(): hash_key = sbase.getId() else: # hash the xml_node xml_node = sbase.toXMLNode() # type: libsbml.XMLNode xml_str = xml_node.toString().encode("utf-8") hash_key = hashlib.md5(xml_str).hexdigest() return hash_key
def annotate_sbase(sbase: libsbml.SBase, annotation: Annotation) -> None: """Annotate SBase based on given annotation data. :param sbase: libsbml.SBase :param annotation: Annotation :return: """ qualifier, resource = annotation.qualifier.value, annotation.resource cv: libsbml.CVTerm = libsbml.CVTerm() # set correct type of qualifier if isinstance(qualifier, str): if qualifier.startswith("BQB"): cv.setQualifierType(libsbml.BIOLOGICAL_QUALIFIER) sbml_qualifier = ModelAnnotator.get_SBMLQualifier(qualifier) success = check( cv.setBiologicalQualifierType(str(sbml_qualifier)), f"Set biological qualifier: '{sbml_qualifier}'", ) if success != 0: logger.error( f"Could not set biological qualifier: {qualifier}") elif qualifier.startswith("BQM"): cv.setQualifierType(libsbml.MODEL_QUALIFIER) sbml_qualifier = ModelAnnotator.get_SBMLQualifier(qualifier) success = check( cv.setModelQualifierType(str(sbml_qualifier)), f"Set model qualifier: '{sbml_qualifier}'", ) if success != 0: logger.error(f"Could not set model qualifier: {qualifier}") else: logger.error(f"Unsupported qualifier: '{qualifier}'") else: msg = (f"qualifier is not a string, but: '{qualifier}' of type " f"'{type(qualifier)}'.") logger.error(msg) raise ValueError(msg) success = check(cv.addResource(resource), f"Add resource: '{resource}'") if success != 0: logger.error(f"Could not add resource: {resource}") # meta id has to be set if not sbase.isSetMetaId(): sbase.setMetaId(utils.create_metaid(sbase)) success = sbase.addCVTerm(cv) if success != 0: logger.error( f"Annotation RDF for CVTerm could not be written: {cv}") logger.error(libsbml.OperationReturnValue_toString(success)) logger.error(f"{sbase}, {qualifier}, {resource}")
def set_fields(self, obj: libsbml.SBase): if self.sid is not None: if not libsbml.SyntaxChecker.isValidSBMLSId(self.sid): logging.error( "The id `{self.sid}` is not a valid SBML SId on `{obj}`. " "The SId syntax is defined as:" "\tletter ::= 'a'..'z','A'..'Z'" "\tdigit ::= '0'..'9'" "\tidChar ::= letter | digit | '_'" "\tSId ::= ( letter | '_' ) idChar*" ) obj.setId(self.sid) if self.name is not None: obj.setName(self.name) if self.sboTerm is not None: obj.setSBOTerm(self.sboTerm) if self.metaId is not None: obj.setMetaId(self.metaId) if self.annotations: for a_tuple in self.annotations: ModelAnnotator.annotate_sbase( sbase=obj, annotation=Annotation.from_tuple(a_tuple) ) self.create_uncertainties(obj)
def notes_to_string(sbase: libsbml.SBase) -> str: """Render notes to string. :param sbase: SBase instance :return string rendering of the notes in the SBase instance """ return str(sbase.getNotesString())
def create_sbml(self, sbase: libsbml.SBase, model: libsbml.Model) -> libsbml.ReplacedBy: """Create SBML ReplacedBy.""" sbase_comp = sbase.getPlugin("comp") # type: libsbml.CompSBasePlugin rby = sbase_comp.createReplacedBy() # type: libsbml.ReplacedBy self._set_fields(rby, model) return rby
def cvterms(cls, sbase: libsbml.SBase) -> Optional[List]: """Parse CVTerms information. :param sbase: SBase instance """ if not sbase.isSetAnnotation(): return None cvterms = [] for kcv in range(sbase.getNumCVTerms()): cv: libsbml.CVTerm = sbase.getCVTerm(kcv) # qualifier q_type = cv.getQualifierType() if q_type == libsbml.MODEL_QUALIFIER: qualifier = ModelQualifierType[cv.getModelQualifierType()] elif q_type == libsbml.BIOLOGICAL_QUALIFIER: qualifier = BiologicalQualifierType[ cv.getBiologicalQualifierType()] else: raise ValueError(f"Unsupported qualifier type: '{q_type}'") resources = [ cv.getResourceURI(k) for k in range(cv.getNumResources()) ] cvterms.append({ "qualifier": qualifier, "resources": resources, }) # add SBO term as CVTerm if sbase.isSetSBOTerm(): sbo = sbase.getSBOTermID() sbo_in_cvs: bool = False for cv in cvterms: for resource in cv["resources"]: if sbo in resource: sbo_in_cvs = True break if not sbo_in_cvs: cvterms = [{ "qualifier": "BQB_IS", "resources": [f"https://identifiers.org/{sbo}"], }] + cvterms return cvterms
def notes(item: libsbml.SBase) -> str: """Convert the SBML object's notes subelement to formatted string. :param item: SBML object containing the notes subelement :return: formatted string for the notes subelement of the item """ if item.isSetNotes(): return notes_to_string(item) return ""
def cvterm(item: libsbml.SBase) -> str: """Create HTML code fragment enclosing cvterm data for the item. :param item: SBML object for which cvterm data has to be displayed :return: HTML code fragment enclosing cvterm data for the item """ if item.isSetAnnotation(): return f'<div class="cvterm">{annotation_to_html(item)}</div>' return ""
def annotation_xml(item: libsbml.SBase) -> str: """Create Annotation string for the item. :param item: SBML object for which MathML content is to be generated :return: Annotation string for the item """ if item.isSetAnnotation(): return f"<pre>{item.getAnnotationString().decode('utf-8')}</pre>" return ""
def annotation_html(item: libsbml.SBase) -> str: """Create annotation HTML content for the item. :param item: SBML object for which annotation HTML content is to be generated :return: HTML code fragment enclosing annotation for item """ info = '<div class="cvterm">' if item.getSBOTerm() != -1: info += f""" <a href="{item.getSBOTermAsURL()}" target="_blank"> {item.getSBOTermID()} </a><br /> """ if item.isSetAnnotation(): info += annotation_to_html(item) info += "</div>" return info
def metaid_html(item: libsbml.SBase) -> str: """Create metaid data for the item. :param item: SBML object for which metaid data has to be generated :return: HTML code fragment enclosing metaid data for item """ if item.isSetMetaId(): return f"<code>{item.getMetaId()}</code>" return ""
def set_fields(self, obj: libsbml.SBase): if self.sid is not None: obj.setId(self.sid) if self.name is not None: obj.setName(self.name) if self.sboTerm is not None: obj.setSBOTerm(self.sboTerm) if self.metaId is not None: obj.setMetaId(self.metaId) self.create_uncertainties(obj)
def derived_units(item: libsbml.SBase) -> str: """Create formatted string for Unit definition object. :param item: SBML object from which Unit Definition string is to be created :return: formatted string for Unit Definition derived from the item """ if item: return formula_to_mathml( unitDefinitionToString(item.getDerivedUnitDefinition())) return ""
def sbo(item: libsbml.SBase) -> str: """Create HTML code fragment enclosing SBOTerm data for the item. :param item: SBML object for which SBOTerm data has to be displayed :return: HTML code fragment enclosing SBOTerm data for the item """ if item.getSBOTerm() != -1: return f"""<div class="cvterm"> <a href="{item.getSBOTermAsURL()}" target="_blank"> {item.getSBOTermID()} </a> </div> """ return ""
def model_history(cls, sbase: libsbml.SBase) -> Optional[Dict]: """Parse model history information. :return """ if sbase.isSetModelHistory(): history: libsbml.ModelHistory = sbase.getModelHistory() else: return None creators = [] for kc in range(history.getNumCreators()): c: libsbml.ModelCreator = history.getCreator(kc) creators.append({ "givenName": c.getGivenName() if c.isSetGivenName() else None, "familyName": c.getFamilyName() if c.isSetFamilyName() else None, "organization": c.getOrganization() if c.isSetOrganization() else None, "email": c.getEmail() if c.isSetEmail() else None, }) created_date = (history.getCreatedDate().getDateAsString() if history.isSetCreatedDate() else None) modified_dates = [] for km in range(history.getNumModifiedDates()): modified_dates.append( history.getModifiedDate(km).getDateAsString()) return { "creators": creators, "createdDate": created_date, "modifiedDates": modified_dates, }
def _get_pk(sbase: libsbml.SBase) -> str: """Calculate primary key.""" if not hasattr(sbase, "pk"): pk: str = f"{SBMLDocumentInfo._sbml_type(sbase)}:" if sbase.isSetId(): pk += sbase.getId() elif sbase.isSetMetaId(): pk += sbase.getMetaId() else: xml = sbase.toSBML() pk += SBMLDocumentInfo._uuid(xml) sbase.pk = pk return pk
def math(item: libsbml.SBase, math_type: str = "cmathml") -> str: """Create MathML content for the item. :param item: SBML object for which MathML content is to be generated :param math_type: specifies which math rendering mode to use :return: formatted MathML content for the item """ if item: if not isinstance(item, libsbml.ASTNode): astnode = item.getMath() else: astnode = item if math_type == "cmathml": return astnode_to_mathml(astnode) elif math_type == "pmathml": cmathml = astnode_to_mathml(astnode) return mathml.cmathml_to_pmathml(cmathml) elif math_type == "latex": latex_str = mathml.astnode_to_latex(astnode) return f"$${latex_str}$$" return empty_html()
def create_sbml(self, sbase: libsbml.SBase): """Create libsbml Uncertainty. :param model: :return: """ logger.debug(f"Create uncertainty for object: {sbase}") sbase_distrib = sbase.getPlugin( "distrib") # type: libsbml.DistribSBasePlugin uncertainty = sbase_distrib.createUncertainty( ) # type: libsbml.Uncertainty self.set_fields(uncertainty) for uncertParameter in self.uncertParameters: up = None if uncertParameter.type in [ libsbml.DISTRIB_UNCERTTYPE_INTERQUARTILERANGE, libsbml.DISTRIB_UNCERTTYPE_CREDIBLEINTERVAL, libsbml.DISTRIB_UNCERTTYPE_CONFIDENCEINTERVAL, libsbml.DISTRIB_UNCERTTYPE_RANGE, ]: up = uncertainty.createUncertSpan() # type: libsbml.UncertSpan up.setType(uncertParameter.type) if uncertParameter.valueLower is not None: up.setValueLower(uncertParameter.valueLower) if uncertParameter.valueUpper is not None: up.setValueUpper(uncertParameter.valueUpper) if uncertParameter.varLower is not None: up.setVarLower(uncertParameter.varLower) if uncertParameter.varUpper is not None: up.setValueLower(uncertParameter.varUpper) elif uncertParameter.type in [ libsbml.DISTRIB_UNCERTTYPE_COEFFIENTOFVARIATION, libsbml.DISTRIB_UNCERTTYPE_KURTOSIS, libsbml.DISTRIB_UNCERTTYPE_MEAN, libsbml.DISTRIB_UNCERTTYPE_MEDIAN, libsbml.DISTRIB_UNCERTTYPE_MODE, libsbml.DISTRIB_UNCERTTYPE_SAMPLESIZE, libsbml.DISTRIB_UNCERTTYPE_SKEWNESS, libsbml.DISTRIB_UNCERTTYPE_STANDARDDEVIATION, libsbml.DISTRIB_UNCERTTYPE_STANDARDERROR, libsbml.DISTRIB_UNCERTTYPE_VARIANCE, ]: up = (uncertainty.createUncertParameter() ) # type: libsbml.UncertParameter up.setType(uncertParameter.type) if uncertParameter.value is not None: up.setValue(uncertParameter.value) if uncertParameter.var is not None: up.setValue(uncertParameter.var) else: logger.error( "Unsupported UncertParameter or UncertSpan type: %s", uncertParameter.type, ) if up and uncertParameter.unit: up.setUnits(Unit.get_unit_string(uncertParameter.unit)) # create a distribution uncertainty if self.formula: model = sbase.getModel() up = uncertainty.createUncertParameter( ) # type: libsbml.UncertParameter up.setType(libsbml.DISTRIB_UNCERTTYPE_DISTRIBUTION) for key in [ "normal", "uniform", "bernoulli", "binomial", "cauchy", "chisquare", "exponential", "gamma", "laplace", "lognormal", "poisson", "raleigh", ]: if key in self.formula: up.setDefinitionURL( "http://www.sbml.org/sbml/symbols/distrib/{}".format( key)) ast = libsbml.parseL3FormulaWithModel(self.formula, model) if ast is None: logger.error(libsbml.getLastParseL3Error()) else: check(up.setMath(ast), "set math in distrib formula") return uncertainty
def notes_to_string(sbase: libsbml.SBase) -> str: """Notes to string.""" return sbase.getNotesString()
def info_sbase(sbase: libsbml.SBase) -> Dict[str, Any]: """Info dictionary for SBase. :param sbase: SBase instance for which info dictionary is to be created :return info dictionary for item """ info = { "object": sbase, "id": sbase.getId(), "metaId": metaid_html(sbase), "sbo": sbo(sbase), "cvterm": cvterm(sbase), "notes": notes(sbase), "annotation": annotation_html(sbase), } if sbase.isSetName(): name = sbase.name else: name = empty_html() info["name"] = name info["id_html"] = id_html(sbase) # comp item_comp = sbase.getPlugin("comp") if item_comp and type(item_comp) == libsbml.CompSBasePlugin: # ReplacedBy if item_comp.isSetReplacedBy(): replaced_by = item_comp.getReplacedBy() submodel_ref = replaced_by.getSubmodelRef() info["replaced_by"] = f""" <br /><i class="fa fa-arrow-circle-right" aria-hidden="true"></i> <code>ReplacedBy {submodel_ref}:{sbaseref(replaced_by)}</code> """ # ListOfReplacedElements if item_comp.getNumReplacedElements() > 0: replaced_elements = [] for rep_el in item_comp.getListOfReplacedElements(): submodel_ref = rep_el.getSubmodelRef() replaced_elements.append(f""" <br /><i class="fa fa-arrow-circle-left" aria-hidden="true"></i> <code>ReplacedElement {submodel_ref}:{sbaseref(rep_el)}</code> """) if len(replaced_elements) == 0: replaced_elements_combined = "" else: replaced_elements_combined = "".join(replaced_elements) info["replaced_elements"] = replaced_elements_combined # distrib sbml_distrib: libsbml.DistribSBasePlugin = sbase.getPlugin("distrib") if sbml_distrib and isinstance(sbml_distrib, libsbml.DistribSBasePlugin): info["uncertainties"] = [] info["uncert_strings"] = [] for uncertainty in sbml_distrib.getListOfUncertainties(): u_dict = SBMLModelInfo.info_sbase(uncertainty) u_dict["uncert_parameters"] = [] u_dict["uncert_params_strings"] = [] upar: libsbml.UncertParameter for upar in uncertainty.getListOfUncertParameters(): param_dict = {} param_str = "" if upar.isSetVar(): param_dict["var"] = upar.getVar() param_str += f"{param_dict['var']}, " if upar.isSetValue(): param_dict["value"] = upar.getValue() param_str += f"{param_dict['value']}, " if upar.isSetUnits(): param_dict["units"] = upar.getUnits() param_str += f"{param_dict['units']}, " if upar.isSetType(): param_dict["type"] = upar.getTypeAsString() param_str += f"{param_dict['type']}, " if upar.isSetDefinitionURL(): param_dict["definition_url"] = f""" <a href='{upar.getDefinitionURL()}'> {upar.getDefinitionURL()}</a> """ param_str += param_dict["definition_url"] if upar.isSetMath(): param_dict["math"] = formating.math(upar.getMath()) param_str += f"{param_dict['math']}, " # create param info string param_str = "<li>" for key in param_dict.keys(): param_str += f"{key}:{param_dict.get(key, '')}, " param_str += "</li>" u_dict["uncert_parameters"].append(param_dict) u_dict["uncert_params_strings"].append(param_str) info["uncertainties"].append(u_dict) return info
def sbase_dict(cls, sbase: libsbml.SBase) -> Dict[str, Any]: """Info dictionary for SBase. :param sbase: SBase instance for which info dictionary is to be created :return info dictionary for item """ pk = cls._get_pk(sbase) d = { "pk": pk, "sbmlType": cls._sbml_type(sbase), "id": sbase.getId() if sbase.isSetId() else None, "metaId": sbase.getMetaId() if sbase.isSetMetaId() else None, "name": sbase.getName() if sbase.isSetName() else None, "sbo": sbase.getSBOTermID() if sbase.isSetSBOTerm() else None, "cvterms": cls.cvterms(sbase), "history": cls.model_history(sbase), "notes": sbase.getNotesString() if sbase.isSetNotes() else None, } # TODO: add the ports information if sbase.getTypeCode() in {libsbml.SBML_DOCUMENT, libsbml.SBML_MODEL}: d["xml"] = None else: d["xml"] = sbase.toSBML() # comp item_comp = sbase.getPlugin("comp") if item_comp and type(item_comp) == libsbml.CompSBasePlugin: # ReplacedBy if item_comp.isSetReplacedBy(): replaced_by = item_comp.getReplacedBy() submodel_ref = replaced_by.getSubmodelRef() d["replacedBy"] = { "submodelRef": submodel_ref, "replacedBySbaseref": cls._sbaseref(replaced_by), } else: d["replacedBy"] = None # ListOfReplacedElements if item_comp.getNumReplacedElements() > 0: replaced_elements = [] for rep_el in item_comp.getListOfReplacedElements(): submodel_ref = rep_el.getSubmodelRef() replaced_elements.append({ "submodelRef": submodel_ref, "replacedElementSbaseref": cls._sbaseref(rep_el), }) d["replacedElements"] = replaced_elements else: d["replacedElements"] = None # distrib sbml_distrib: libsbml.DistribSBasePlugin = sbase.getPlugin("distrib") if sbml_distrib and isinstance(sbml_distrib, libsbml.DistribSBasePlugin): d["uncertainties"] = [] for uncertainty in sbml_distrib.getListOfUncertainties(): u_dict = SBMLDocumentInfo.sbase_dict(uncertainty) u_dict["uncertaintyParameters"] = [] upar: libsbml.UncertParameter for upar in uncertainty.getListOfUncertParameters(): param_dict = { "var": upar.getVar() if upar.isSetVar() else None, "value": upar.getValue() if upar.isSetValue() else None, "units": upar.getUnits() if upar.isSetUnits() else None, "type": upar.getTypeAsString() if upar.isSetType() else None, "definitionURL": upar.getDefinitionURL() if upar.isSetDefinitionURL() else None, "math": astnode_to_latex(upar.getMath()) if upar.isSetMath() else None, } u_dict["uncertaintyParameters"].append(param_dict) d["uncertainties"].append(u_dict) return d