def is_complex_assembly(reaction: libsbml.Reaction, model: libsbml.Model): """ Returns true iff 'reaction' can be classified as a biomolecular complex assembly. Rules: - The reaction must have at least two reactants and exactly one product - The product must be annotated with the same non-empty set of identifiers as the full set of identifiers for all reactants. (This is assumed to mean that the product contains all and consists only of the specified reactants, so the reaction is a complex assembly.) :param reaction: libSBML Reaction object to classify as a transport. :param model: libsbml Model containing the 'reaction' object. :rtype: bool """ if len(reaction.getListOfReactants()) < 2 or len( reaction.getListOfProducts()) != 1: return False reactant_identifiers = set() for reactant in reaction.getListOfReactants(): reactant_species = model.getSpecies( reactant.toXMLNode().getAttrValue('species')) reactant_identifiers.update( extract_annotation_identifiers( reactant_species.getAnnotationString())) product = reaction.getListOfProducts()[0] product_species = model.getSpecies( product.toXMLNode().getAttrValue('species')) product_identifiers = set( extract_annotation_identifiers(product_species.getAnnotationString())) return len(reactant_identifiers ) > 0 and reactant_identifiers == product_identifiers
def equationStringFromReaction( reaction: libsbml.Reaction, sep_reversible: str = "⇆", sep_irreversible: str = "➞", modifiers: bool = False, ) -> str: """Create equation for reaction. :param reaction: SBML reaction instance for which equation is to be generated :param sep_reversible: escape sequence for reversible equation (<=>) separator :param sep_irreversible: escape sequence for irreversible equation (=>) separator :param modifiers: boolean flag to use modifiers :return equation string generated for the reaction """ left = _halfEquation(reaction.getListOfReactants()) right = _halfEquation(reaction.getListOfProducts()) if reaction.getReversible(): # '<=>' sep = sep_reversible else: # '=>' sep = sep_irreversible if modifiers: mods = _modifierEquation(reaction.getListOfModifiers()) if mods is None: return " ".join([left, sep, right]) else: return " ".join([left, sep, right, mods]) return " ".join([left, sep, right])
def _reaction_id_format( reaction: libsbml.Reaction, logger: Logger = getLogger(__name__)) -> str: if pd.isna(reaction) or \ not isinstance(reaction, libsbml.Reaction): return np.nan return _f_reaction(reaction.getIdAttribute())
def boundsStringFromReaction(reaction: libsbml.Reaction, model: libsbml.Model) -> str: """Render string of bounds from the reaction. :param reaction: SBML reaction instance :param model: SBML model instance :return: String of bounds extracted from the reaction """ bounds = "" rfbc = reaction.getPlugin("fbc") if rfbc is not None: # get values for bounds lb_id, ub_id = None, None lb_value, ub_value = None, None if rfbc.isSetLowerFluxBound(): lb_id = rfbc.getLowerFluxBound() lb_p = model.getParameter(lb_id) if lb_p.isSetValue(): lb_value = lb_p.getValue() if rfbc.isSetUpperFluxBound(): ub_id = rfbc.getUpperFluxBound() ub_p = model.getParameter(ub_id) if ub_p.isSetValue(): ub_value = ub_p.getValue() if (lb_value is not None) or (ub_value is not None): bounds = f""" <code>[{lb_value} <i class="fa fa-sort fa-rotate-90" aria-hidden="true"></i> {ub_value}] </code> """ return bounds
def get_reactant_species_ids(reaction: libsbml.Reaction, model: libsbml.Model): product = reaction.getListOfProducts()[0] product_species = model.getSpecies( product.toXMLNode().getAttrValue('species')) product_identifiers = set( extract_annotation_identifiers(product_species.getAnnotationString())) return product_identifiers
def __init__(self, reaction: libsbml.Reaction): super().__init__(reaction) # references, not actual species self.reactants = list(reaction.getListOfReactants()) self.products = list(reaction.getListOfProducts()) # inhibitors / activators self.modifiers = list(reaction.getListOfModifiers()) self.reversible: bool = reaction.getReversible() self.kl = reaction.getKineticLaw() self.unit = libsbml.UnitDefinition.printUnits( self.kl.getDerivedUnitDefinition()) self.regex = re.compile( "(" + "|".join([p.id for p in self.kl.getListOfParameters()]) + ")", re.VERBOSE, ) self.text_formula = self.regex.sub(f"{self.id}_\\1", self.kl.formula) self.formula = compile(self.text_formula, "<string>", "eval")
def is_transport(reaction: libsbml.Reaction, model: libsbml.Model): """ Returns true iff 'reaction' can be classified as a biological transport. Rules: - The reaction must have exactly one reactant and one product - The reactant and product must be annotated with the same non-empty set of identifiers (if they are annotated with the same identifiers, they are assumed to refer to the same biological object) - The reactant and product must reside in different compartments. :param reaction: libSBML Reaction object to classify as a transport. :param model: libsbml Model containing the 'reaction' object. :rtype: bool """ if len(reaction.getListOfReactants()) != 1 or len( reaction.getListOfProducts()) != 1: return False reactant, product = reaction.getListOfReactants( )[0], reaction.getListOfProducts()[0] reactant_species = model.getSpecies( reactant.toXMLNode().getAttrValue('species')) product_species = model.getSpecies( product.toXMLNode().getAttrValue('species')) reactant_compartment = model.getCompartment( reactant_species.getCompartment()) product_compartment = model.getCompartment( product_species.getCompartment()) reactant_identifiers = set( extract_annotation_identifiers(reactant_species.getAnnotationString())) product_identifiers = set( extract_annotation_identifiers(product_species.getAnnotationString())) return (len(reactant_identifiers) > 0 and reactant_identifiers.intersection(product_identifiers) and reactant_compartment != product_compartment)
def _gene_product_association_from_reaction( reaction: libsbml.Reaction, ) -> Optional[str]: """Render string representation of the GeneProductAssociation for given reaction. :param reaction: SBML reaction instance :return: string representation of GeneProductAssociation """ rfbc = reaction.getPlugin("fbc") gpa = (str(rfbc.getGeneProductAssociation().getAssociation().toInfix()) if (rfbc and rfbc.isSetGeneProductAssociation()) else None) return gpa
def geneProductAssociationStringFromReaction( reaction: libsbml.Reaction) -> str: """Render string representation of the GeneProductAssociation for given reaction. :param reaction: SBML reaction instance :return: string representation of GeneProductAssociation """ info = "" rfbc = reaction.getPlugin("fbc") if rfbc and rfbc.isSetGeneProductAssociation(): gpa = rfbc.getGeneProductAssociation() association = gpa.getAssociation() info = association.toInfix() return info
def _bounds_dict_from_reaction(reaction: libsbml.Reaction, model: libsbml.Model) -> Optional[Dict]: """Render string of bounds from the reaction. :param reaction: SBML reaction instance :param model: SBML model instance :return: String of bounds extracted from the reaction """ bounds: Optional[Dict] rfbc = reaction.getPlugin("fbc") if rfbc is not None: # get values for bounds lb_id: Optional[str] = None ub_id: Optional[str] = None lb_value: Optional[float] = None ub_value: Optional[float] = None if rfbc.isSetLowerFluxBound(): lb_id = rfbc.getLowerFluxBound() lb_p: libsbml.Parameter = model.getParameter(lb_id) if lb_p.isSetValue(): lb_value = lb_p.getValue() if rfbc.isSetUpperFluxBound(): ub_id = rfbc.getUpperFluxBound() ub_p: libsbml.Parameter = model.getParameter(ub_id) if ub_p.isSetValue(): ub_value = ub_p.getValue() bounds = { "lowerFluxBound": { "id": lb_id, "value": lb_value, }, "upperFluxBound": { "id": ub_id, "value": ub_value, }, } else: bounds = None return bounds
def set_flux_bounds(reaction: libsbml.Reaction, lb: float, ub: float) -> None: """Set flux bounds on given reaction.""" rplugin = reaction.getPlugin("fbc") rplugin.setLowerFluxBound(lb) rplugin.setUpperFluxBound(ub)