def addProtein(self, protein_id, n=300, txn_rate="we*a/(thetax + a)", modifiers=["a"], deg_rate="0"): self.addSpecies('[' + protein_id + ']', 0, "cell"); self.addSpecies('[m' + protein_id + ']', 0, "cell"); self.addSpecies('[rm' + protein_id + ']', 0, "cell"); self.getModel().getAssignmentRule("ttrate").getMath().getChild(0).prependChild( \ libsbml.parseL3Formula("rm" + protein_id)); self.getModel().getAssignmentRule("fr").getMath().getChild(0).getChild(1). \ prependChild(libsbml.parseL3Formula("rm" + protein_id)); self.getModel().getAssignmentRule("fr").getMath().getChild(1).getChild(0). \ getChild(1).prependChild(libsbml.parseL3Formula("rm" + protein_id)); self.getModel().getAssignmentRule("fr").getMath().getChild(1).getChild(1). \ getChild(1).prependChild(libsbml.parseL3Formula(protein_id)); self.addParameter("n" + protein_id, n, "cell"); v = self.addReaction([], ['m' + protein_id], txn_rate); for s in modifiers: m = v.createModifier(); m.setSpecies(s); self.addReaction(['m' + protein_id, "r"], ['rm' + protein_id], "kb * r * m" + protein_id); self.addReaction(['rm' + protein_id], ['r', 'm' + protein_id], "ku * rm" + protein_id); self.addReaction(['rm' + protein_id], ['r', 'm' + protein_id, protein_id], \ "gamma * rm" + protein_id + " / n" + protein_id); self.addReaction(['m' + protein_id], [], 'lam * m' + protein_id); self.addReaction(['rm' + protein_id], [], 'lam * rm' + protein_id); self.addReaction([protein_id], [], 'lam * ' + protein_id); self.addReaction(['m' + protein_id], [], 'dm * m' + protein_id); self.addReaction([protein_id], [], deg_rate + " * " + protein_id);
def create_sbml_model( initial_assignments, parameters, rate_rules, species, to_file: str = None, ): """Create an SBML model from simple definitions. See the model definitions and usage in :py:func:`model` for example input. The default initial concentration of species is `1.0`. This can currently be changed by specifying an initial assignment. """ document = libsbml.SBMLDocument(3, 1) model = document.createModel() compartment = model.createCompartment() compartment.setId('compartment') compartment.setConstant(True) compartment.setSize(1) compartment.setSpatialDimensions(3) compartment.setUnits('dimensionless') for species_id in species: species = model.createSpecies() species.setId(species_id) species.setCompartment('compartment') species.setConstant(False) species.setSubstanceUnits('dimensionless') species.setBoundaryCondition(False) species.setHasOnlySubstanceUnits(False) species.setInitialConcentration(1.0) for target, formula in initial_assignments.items(): initial_assignment = model.createInitialAssignment() initial_assignment.setSymbol(target) initial_assignment.setMath(libsbml.parseL3Formula(formula)) for target, formula in rate_rules.items(): rate_rule = model.createRateRule() rate_rule.setVariable(target) rate_rule.setMath(libsbml.parseL3Formula(formula)) for parameter_id, parameter_value in parameters.items(): parameter = model.createParameter() parameter.setId(parameter_id) parameter.setConstant(True) parameter.setValue(parameter_value) parameter.setUnits('dimensionless') if to_file: libsbml.writeSBMLToFile( document, str(to_file), ) # Need to return document, else AMICI throws an error. # (possibly due to garbage collection?) return document, model
def DefineFunctions (Model): # Define all functions to be used # Distribution Function Func1 = Model.createFunctionDefinition() Func1.setId('uniform') Func1Math = libsbml.parseL3Formula('lambda(a,b,(a+b)/2)') Check(Func1Math,'Check Math') Func1.setMath(Func1Math) UniformDistrAnnotation = """<annotation> <distribution xmlns="http://sbml.org/annotations/distribution" definition="http://en.wikipedia.org/wiki/Uniform_distribution_(continuous)"/> </annotation>""" Func1.appendAnnotation(UniformDistrAnnotation) DistribPlugin1 = Func1.getPlugin("distrib") DrawFromDistrib = DistribPlugin1.createDrawFromDistribution() InputA = DrawFromDistrib.createDistribInput() InputA.setId('a') InputA.setIndex(0) InputB = DrawFromDistrib.createDistribInput() InputB.setId('b') InputB.setIndex(1) Uncert = libsbml.UncertMLNode_createDistributionNode("UniformDistribution", "minimum, maximum", "a,b"); DrawFromDistrib.setUncertML(Uncert) Func2 = Model.createFunctionDefinition() Func2.setId('min') Func2Math = libsbml.parseL3Formula('lambda(a,b,piecewise(a, a < b, b))') Check(Func2Math,'Check Math') Func2.setMath(Func2Math) return Func1, Func2
def addEvent(self, trigger, delay, var, value, persistent=True, \ initial_value=False, priority=0, event_id=''): e1 = self.model.createEvent(); self.check(e1, 'create event'); if len(event_id) == 0: event_id = 'e' + str(self.model.getNumEvents()); self.check(e1.setId(event_id), 'add id to event'); tri = e1.createTrigger(); self.check(tri, 'add trigger to event'); self.check(tri.setPersistent(persistent), 'set persistence of trigger'); self.check(tri.setInitialValue(initial_value), 'set initial value of trigger'); tri_ast = libsbml.parseL3Formula(trigger); self.check(tri.setMath(tri_ast), 'add formula to trigger'); de = e1.createDelay(); k = self.addParameter(event_id+'Delay', delay, self.model.getTimeUnits()); self.check(de, 'add delay to event'); delay_ast = libsbml.parseL3Formula(k.getId()); self.check(de.setMath(delay_ast), 'set formula for delay'); for v in var: assign = e1.createEventAssignment(); self.check(assign, 'add event assignment to event'); self.check(assign.setVariable(v), 'add variable to event assignment'); val_ast = libsbml.parseL3Formula(str(value[var.index(v)])); self.check(assign.setMath(val_ast), 'add value to event assignment'); pri = e1.createPriority(); pri_ast = libsbml.parseL3Formula(str(priority)); self.check(pri.setMath(pri_ast), 'add priority to event'); return e1
def addInitialAssignment(self, symbol, math): a = self.model.createInitialAssignment() self.check(a, 'create initial assignment a') self.check(a.setSymbol(symbol), 'set initial assignment a symbol') math_ast = libsbml.parseL3Formula(math); self.check(a.setMath(math_ast), 'set initial assignment a math') return a
def model_from_reacts(reactions, level=3, version=1): """Create an SBML model from a list of reactions, with one compartment. Return model, document and list of species.""" # Create the list of species from the # reactants and products species = sorted( list( set([s for r in reactions for s in r.reactant] + [s for r in reactions for s in r.product]))) # Create an empty SBMLDocument # level 3, version 1 document = libsbml.SBMLDocument(level, version) # Create the model model = document.createModel() # Create compartment c1 = model.createCompartment() c1.setId('c1') c1.setConstant(True) # Create the species for sid in species: s = model.createSpecies() s.setId(sid) s.setCompartment('c1') s.setConstant(False) s.setInitialAmount(0) s.setBoundaryCondition(False) s.setHasOnlySubstanceUnits(False) # Create the reactions for reaction in reactions: r = model.createReaction() r.setId(reaction.reactionid) r.setReversible(False) r.setFast(False) for s in sorted(reaction.reactant): react_species = r.createReactant() react_species.setSpecies(s) react_species.setStoichiometry(int(reaction.reactant[s])) react_species.setConstant(True) for s in sorted(reaction.product): prod_species = r.createProduct() prod_species.setSpecies(s) prod_species.setStoichiometry(int(reaction.product[s])) prod_species.setConstant(True) math_ast = libsbml.parseL3Formula( str(reaction.rate).replace('**', '^')) kinetic_law = r.createKineticLaw() kinetic_law.setMath(math_ast) promote_params(model, document) return model, document, list(species)
def addRateRule(self, var, math): r = self.model.createRateRule() self.check(r, 'create rate rule r') self.check(r.setVariable(var), 'set rate rule variable') math_ast = libsbml.parseL3Formula(math) self.check(r.setMath(math_ast), 'set rate rule equation') return r
def addReaction(self, reactants, products, expression, rxn_id=''): r1 = self.model.createReaction() self.check(r1, 'create reaction') if len(rxn_id) == 0: rxn_id = 'v' + str(self.model.getNumReactions()); self.check(r1.setId(rxn_id), 'set reaction id') self.check(r1.setReversible(False), 'set reaction reversibility flag') self.check(r1.setFast(False), 'set reaction "fast" attribute') for re in reactants: s1 = self.model.getSpecies(re); species_ref1 = r1.createReactant() self.check(species_ref1, 'create reactant') self.check(species_ref1.setSpecies(str(s1)[9:len(str(s1))-1]), \ 'assign reactant species') self.check(species_ref1.setConstant(True), \ 'set "constant" on species ref 1') for pro in products: s2 = self.model.getSpecies(pro); species_ref2 = r1.createProduct() self.check(species_ref2, 'create product') self.check(species_ref2.setSpecies(str(s2)[9:len(str(s2))-1]), \ 'assign product species') self.check(species_ref2.setConstant(True), \ 'set "constant" on species ref 2') math_ast = libsbml.parseL3Formula(expression); self.check(math_ast, 'create AST for rate expression') kinetic_law = r1.createKineticLaw() self.check(kinetic_law, 'create kinetic law') self.check(kinetic_law.setMath(math_ast), 'set math on kinetic law') return r1
def addInitialAssignment(self, symbol, math): a = self.model.createInitialAssignment() self.check(a, 'create initial assignment a') self.check(a.setSymbol(symbol), 'set initial assignment a symbol') math_ast = libsbml.parseL3Formula(math) self.check(a.setMath(math_ast), 'set initial assignment a math') return a
def create_equation(sbml_reaction, reaction, reactants): kin_law = sbml_reaction.createKineticLaw() rate = reaction['rate'] if not reaction['propensity']: if len(reactants) == 0: equation = "{0}".format(rate['name']) elif len(reactants) == 1: name = list(reactants.keys())[0] ratio = reactants[name] equation = '{0} * {1}'.format(rate['name'], name) if ratio == 2: equation += " * {0}".format(name) else: name0, name1 = list(reactants.keys()) equation = "{0} * {1} * {2}".format(rate['name'], name0, name1) else: equation = reaction['propensity'].replace("and", "&&").replace("or", "||") try: kin_law.setMath(libsbml.parseL3Formula(equation)) except Exception: raise ImporperMathMLFormatError( 'libsbml threw an error when parsing rate equation "{0}" \ for reaction "{1}"'.format(equation, reaction['name']), traceback.format_exc())
def create_reaction(model, reaction_id, reactants, products, formula, reversible=False, fast=False): """Add reaction to SBML model""" r = model.createReaction() r.setId(reaction_id) r.setReversible(reversible) r.setFast(fast) for (coeff, name) in reactants: species_ref = r.createReactant() species_ref.setSpecies(name) species_ref.setConstant(True) # TODO ? species_ref.setStoichiometry(coeff) for (coeff, name) in products: species_ref = r.createProduct() species_ref.setSpecies(name) species_ref.setConstant(True) # TODO ? species_ref.setStoichiometry(coeff) math_ast = libsbml.parseL3Formula(formula) kinetic_law = r.createKineticLaw() kinetic_law.setMath(math_ast) return r
def addReaction(self, reactants, products, expression, rxn_id=''): r1 = self.model.createReaction() self.check(r1, 'create reaction') if len(rxn_id) == 0: rxn_id = 'v' + str(self.model.getNumReactions()) self.check(r1.setId(rxn_id), 'set reaction id') self.check(r1.setReversible(False), 'set reaction reversibility flag') self.check(r1.setFast(False), 'set reaction "fast" attribute') for re in reactants: s1 = self.model.getSpecies(re) species_ref1 = r1.createReactant() self.check(species_ref1, 'create reactant') self.check(species_ref1.setSpecies(str(s1)[9:len(str(s1))-1]), \ 'assign reactant species') self.check(species_ref1.setConstant(True), \ 'set "constant" on species ref 1') for pro in products: s2 = self.model.getSpecies(pro) species_ref2 = r1.createProduct() self.check(species_ref2, 'create product') self.check(species_ref2.setSpecies(str(s2)[9:len(str(s2))-1]), \ 'assign product species') self.check(species_ref2.setConstant(True), \ 'set "constant" on species ref 2') math_ast = libsbml.parseL3Formula(expression) self.check(math_ast, 'create AST for rate expression') kinetic_law = r1.createKineticLaw() self.check(kinetic_law, 'create kinetic law') self.check(kinetic_law.setMath(math_ast), 'set math on kinetic law') return r1
def _create_species(model: sbml.Model, species_id: str, initial_amount: str): """ Creates a species and adds it to the given SBML model. Units are set as dimensionless by default. Arguments: model: the SBML model to which the species will be added. species_id: the species ID initial_amount: the species initial amount Returns: s: the SBML species Raises: """ s = model.createSpecies() s.setId(species_id) try: s.setInitialAmount(float(initial_amount)) except ValueError: init = model.createInitialAssignment() init.setId('init_' + species_id) init.setSymbol(species_id) init.setMath(sbml.parseL3Formula(initial_amount)) s.setConstant(False) s.setBoundaryCondition(False) s.setHasOnlySubstanceUnits(False) s.setCompartment('Compartment') s.setSubstanceUnits('dimensionless') return s
def addRateRule(self, var, math): r = self.model.createRateRule() self.check(r, 'create rate rule r') self.check(r.setVariable(var), 'set rate rule variable') math_ast = libsbml.parseL3Formula(math); self.check(r.setMath(math_ast), 'set rate rule equation') return r
def addEvent(self, trigger, assignments, persistent=True, \ initial_value=False, priority=0, delay=0, event_id=''): e1 = self.model.createEvent() self.check(e1, 'create event') if len(event_id) == 0: event_id = 'e' + str(self.model.getNumEvents()) self.check(e1.setId(event_id), 'add id to event') if self.document.getLevel()==3 or (self.document.getLevel()==2 \ and self.document.getVersion()==4): self.check(e1.setUseValuesFromTriggerTime(True), 'set use values from trigger time') tri = e1.createTrigger() self.check(tri, 'add trigger to event') tri_ast = libsbml.parseL3Formula(trigger) self.check(tri.setMath(tri_ast), 'add formula to trigger') if self.document.getLevel() == 3: self.check(tri.setPersistent(persistent), 'set persistence of trigger') self.check(tri.setInitialValue(initial_value), 'set initial value of trigger') de = e1.createDelay() if self.document.getLevel() == 3: k = self.addParameter(event_id + 'Delay', delay, self.model.getTimeUnits()) else: k = self.addParameter(event_id + 'Delay', delay, 'time') self.check(de, 'add delay to event') delay_ast = libsbml.parseL3Formula(k.getId()) self.check(de.setMath(delay_ast), 'set formula for delay') for a in assignments.keys(): assign = e1.createEventAssignment() self.check(assign, 'add event assignment to event') self.check(assign.setVariable(a), 'add variable to event assignment') val_ast = libsbml.parseL3Formula(assignments.get(a)) self.check(assign.setMath(val_ast), 'add value to event assignment') if self.document.getLevel() == 3: pri = e1.createPriority() pri_ast = libsbml.parseL3Formula(str(priority)) self.check(pri.setMath(pri_ast), 'add priority to event') return e1
def DefineIndex(Container, DimEnum, ReferencedAttribute, MathExpr): "Create an index to a container" Index = Container.getPlugin("arrays").createIndex() Index.setArrayDimension(DimEnum) Index.setReferencedAttribute(ReferencedAttribute) Index1Math = libsbml.parseL3Formula(MathExpr) Check(Index1Math,'Check Math') Index.setMath(Index1Math) return Index
def formula_to_mathml(string: str) -> str: """Parse formula string. :param string: formula string :return string rendering of parsed formula in the formula string """ astnode = libsbml.parseL3Formula(str(string)) mathml = libsbml.writeMathMLToString(astnode) return str(mathml)
def create_kinetic_law(self, model, sbml_reaction, stochastic, reverse_reaction=False, **kwargs): if 'crn_reaction' in kwargs: crn_reaction = kwargs['crn_reaction'] else: raise ValueError( 'crn_reaction reference is needed for Massaction kinetics!') # create a kinetic law for the sbml_reaction ratelaw = sbml_reaction.createKineticLaw() # translate the internal representation of a propensity to SBML format propensity_dict_in_sbml = self._translate_propensity_dict_to_sbml( model=model, ratelaw=ratelaw) # set up the forward sbml_reaction if not reverse_reaction: reactant_species = {} for w_species in crn_reaction.inputs: species_id = getSpeciesByName(model, str(w_species.species)).getId() reactant_species[species_id] = w_species param = propensity_dict_in_sbml['parameters']['k_forward'] propensity_dict_in_sbml['parameters'].pop( 'k_reverse', None) #remove the other parameter from the propensities ratelaw.removeLocalParameter( "k_reverse") #if k_reverse is a local parameter, remove it # set up a reverse reaction elif reverse_reaction: reactant_species = {} for w_species in crn_reaction.outputs: species_id = getSpeciesByName(model, str(w_species.species)).getId() reactant_species[species_id] = w_species param = propensity_dict_in_sbml['parameters']['k_reverse'] propensity_dict_in_sbml['parameters'].pop( 'k_forward', None) #remove the other parameter from the propensities ratelaw.removeLocalParameter( "k_forward") #if k_forward is a local parameter, remove it rate_formula = self._get_rate_formula(param, stochastic, reactant_species) # Set the ratelaw to the rateformula math_ast = libsbml.parseL3Formula(rate_formula) ratelaw.setMath(math_ast) annotation_string = self._create_annotation( model, propensity_dict_in_sbml=propensity_dict_in_sbml, **kwargs) sbml_reaction.appendAnnotation(annotation_string) return ratelaw
def addInitialAssignment(self, symbol, math): if self.document.getLevel() == 2 and self.document.getVersion() == 1: raise SystemExit('Error: InitialAssignment does not exist for \ this level and version.') a = self.model.createInitialAssignment() self.check(a, 'create initial assignment a') self.check(a.setSymbol(symbol), 'set initial assignment a symbol') math_ast = libsbml.parseL3Formula(math); self.check(a.setMath(math_ast), 'set initial assignment a math') return a
def addInitialAssignment(self, symbol, math): if self.document.getLevel() == 2 and self.document.getVersion() == 1: raise SystemExit('Error: InitialAssignment does not exist for \ this level and version.') a = self.model.createInitialAssignment() self.check(a, 'create initial assignment a') self.check(a.setSymbol(symbol), 'set initial assignment a symbol') math_ast = libsbml.parseL3Formula(math) self.check(a.setMath(math_ast), 'set initial assignment a math') return a
def convert_events(sbml_model, events): for event in events: evt = sbml_model.createEvent() evt.setId(event['name']) evt.setUseValuesFromTriggerTime(event['useValuesFromTriggerTime']) if event['delay']: delay = event['delay'].replace('and', '&&').replace('or', '||') dly = evt.createDelay() try: dly.setMath(libsbml.parseL3Formula(delay)) except Exception: raise ImporperMathMLFormatError( 'libsbml threw an error when parsing \ delay equation "{0}" for event "{1}"'.format( delay, event['name']), traceback.format_exc()) priority = event['priority'].replace('and', '&&').replace('or', '||') prior = evt.createPriority() try: prior.setMath(libsbml.parseL3Formula(priority)) except Exception: raise ImporperMathMLFormatError( 'libsbml threw an error when parsing priority \ equation "{0}" for event "{1}"'.format( priority, event['name']), traceback.format_exc()) trigger_expression = event['triggerExpression'].replace('and', '&&').replace( 'or', '||') trig = evt.createTrigger() try: trig.setMath(libsbml.parseL3Formula(trigger_expression)) except Exception: raise ImporperMathMLFormatError( 'libsbml threw an error when parsing trigger \ equation "{0}" for event "{1}"'.format( trigger_expression, event['name']), traceback.format_exc()) trig.setInitialValue(event['initialValue']) trig.setPersistent(event['persistent']) assignments = event['eventAssignments'] convert_event_assignments(event['name'], evt, assignments)
def to_formula( ast_dict: Dict[str, Union[libsbml.ASTNode, str]], replace_symbols: bool = True, ) -> Dict[str, Union[libsbml.ASTNode, str]]: """Replace all symbols in given astnode dictionary. :param replace_symbols: :param ast_dict: :return: """ d: Dict[str, Union[libsbml.ASTNode, str]] = dict() for key in ast_dict: astnode = ast_dict[key] if not isinstance(astnode, libsbml.ASTNode): # already a formula d[key] = astnode continue if replace_symbols: astnode = astnode.deepCopy() # replace parameters (p) for key_rep, index in pids_idx.items(): ast_rep = libsbml.parseL3Formula( "p__{}__".format(index)) astnode.replaceArgument(key_rep, ast_rep) # replace states (x) for key_rep, index in dxids_idx.items(): ast_rep = libsbml.parseL3Formula( "x__{}__".format(index)) astnode.replaceArgument(key_rep, ast_rep) formula = evaluableMathML(astnode) if replace_symbols: formula = re.sub("p__", "p[", formula) formula = re.sub("x__", "x[", formula) formula = re.sub("y__", "y[", formula) formula = re.sub("__", "]", formula) d[key] = formula return d
def createMath(self, formulaString): ''' Creates a new math AST_Node using the formulaString given and returns it ''' if type(formulaString) is not str: raise ValueError( 'The formulaString argument must be a string in the appropriate format' ) math_ast = libsbml.parseL3Formula(formulaString) check(math_ast, 'create AST for rate expression') return math_ast
def formula_to_astnode(formula: str) -> libsbml.ASTNode: """Convert formula string to ASTNode. :param formula: SBML formula string :return: libsbml.ASTNode """ astnode = libsbml.parseL3Formula(formula) if not astnode: logging.error(f"Formula could not be parsed: '{formula}'") logging.error(libsbml.getLastParseL3Error()) return astnode
def createNewEvent(self, id, trigger_persistent, trigger_initialValue, trigger_formula, variable_id, assignment_formula, delay_formula = '', priority_formula = '', useValuesFromTriggerTime = True, name = ''): ''' Creates a new Event in the Model and returns a pointer to the libSBML object created ''' if (type(id) is not str) or (type(trigger_persistent) is not bool) or (type(trigger_initialValue) is not bool) or (type(trigger_formula) is not str) or (type(variable_id) is not str) or (type(assignment_formula) is not str) or (type(delay_formula) is not str) or (type(priority_formula) is not str) or (type(useValuesFromTriggerTime) is not bool) or (type(name) is not str): raise ValueError('The arguments are not of expected type.') model = self.getModel() check(model,'retreived model object') e = model.createEvent() check(e,'creating new event in the model') check(e.setId(id), 'setting ID of the event created') if name != '': check(e.setName(name),'setting name of the event created') eTrig = e.createTrigger() check(eTrig,'creating trigger inside the event') check(eTrig.setPersistent(trigger_persistent), 'setting persistent value to the trigger') check(eTrig.setInitialValue(trigger_initialValue), 'setting initial value to the trigger') trig_math = libsbml.parseL3Formula(trigger_formula) check(eTrig.setMath(trig_math), 'setting math to the trigger') eA = e.createEventAssignment() check(eA, 'creating event assignment inside the event') check(eA.setVariable(variable_id), 'setting variable in the event assignment') asmt_math = libsbml.parseL3Formula(assignment_formula) check(eA.setMath(asmt_math), 'setting math to the event assignment') if delay_formula != '': eDel = e.createDelay() check(eDel, 'creating a new delay inside the event') del_math = libsbml.parseL3Formula(delay_formula) check(eDel.setMath(del_math), 'setting the math to the delay') if priority_formula != '': eP = e.createPriority() check(eP, 'creating a new priority inside the event') prio_math = libsbml.parseL3Formula(priority_formula) check(eP.setMath(prio_math), 'setting the math to the priority') e.setUseValuesFromTriggerTime(useValuesFromTriggerTime) return e
def addEvent(self, trigger, assignments, persistent=True, \ initial_value=False, priority=0, delay=0, event_id=''): e1 = self.model.createEvent(); self.check(e1, 'create event'); if len(event_id) == 0: event_id = 'e' + str(self.model.getNumEvents()); self.check(e1.setId(event_id), 'add id to event'); if self.document.getLevel()==3 or (self.document.getLevel()==2 \ and self.document.getVersion()==4): self.check(e1.setUseValuesFromTriggerTime(True), 'set use values from trigger time'); tri = e1.createTrigger(); self.check(tri, 'add trigger to event'); tri_ast = libsbml.parseL3Formula(trigger); self.check(tri.setMath(tri_ast), 'add formula to trigger'); if self.document.getLevel() == 3: self.check(tri.setPersistent(persistent), 'set persistence of trigger'); self.check(tri.setInitialValue(initial_value), 'set initial value of trigger'); de = e1.createDelay(); if self.document.getLevel() == 3: k = self.addParameter(event_id+'Delay', delay, self.model.getTimeUnits()); else: k = self.addParameter(event_id+'Delay', delay, 'time'); self.check(de, 'add delay to event'); delay_ast = libsbml.parseL3Formula(k.getId()); self.check(de.setMath(delay_ast), 'set formula for delay'); for a in assignments.keys(): assign = e1.createEventAssignment(); self.check(assign, 'add event assignment to event'); self.check(assign.setVariable(a), 'add variable to event assignment'); val_ast = libsbml.parseL3Formula(assignments.get(a)); self.check(assign.setMath(val_ast), 'add value to event assignment'); if self.document.getLevel() == 3: pri = e1.createPriority(); pri_ast = libsbml.parseL3Formula(str(priority)); self.check(pri.setMath(pri_ast), 'add priority to event'); return e1
def add_event( sbml_model: libsbml.Model, event_id: str, trigger_formula: str, event_assignments: Dict[str, Union[float, int, str]], ): """Add an event to an SBML model instance. The model is modified in-place. Parameters ---------- sbml_model: The SBML model instance. event_id: The ID of the event. trigger_formula: The formula that describes when the event is triggered. event_assignments: A dictionary of assignments that occur when the event is triggered. Each key is an assignment target, and the corresponding value is value that the assignment target takes when the event is triggered. """ event = sbml_model.createEvent() event.setId(event_id) event.setUseValuesFromTriggerTime(True) trigger = event.createTrigger() trigger.setInitialValue(True) trigger.setPersistent(True) trigger_math = libsbml.parseL3Formula(trigger_formula) trigger.setMath(trigger_math) for variable, event_assignment_formula in event_assignments.items(): event_assignment = event.createEventAssignment() event_assignment.setVariable(variable) event_assignment_math = \ libsbml.parseL3Formula(str(event_assignment_formula)) event_assignment.setMath(event_assignment_math)
def parse_expr(s): """Try to convert a string to a sympy expression, reading the string using the SBML formula parser first, and converting the libSBML AST to a sympy expression. """ if not s: return None s = s.replace('**', '^') ast_tree = libsbml.parseL3Formula(s) if ast_tree: return ast_to_sympy_expr(ast_tree) else: raise ValueError("Could not parse expression.")
def createNewInitialAssignment(self, symbol, initialAssignment_formula): ''' Creates a new InitialAssignment in the Model and returns a pointer to the libSBML object created ''' if type(symbol) is not str or type(initialAssignment_formula) is not str: raise ValueError('The arguments are not of expected type.') model = self.getModel() check(model,'retreived model object') init_asmt = model.createInitialAssignment() check(init_asmt,'creating new initial assignment inside the model') check(init_asmt.setSymbol(symbol),'setting the symbol to the initial assignment') initAsmt_math = libsbml.parseL3Formula(initialAssignment_formula) check(init_asmt.setMath(initAsmt_math),'setting math to the initial assignment') return
def addReaction(self, reactants, products, expression, local_params={}, rxn_id=''): r1 = self.model.createReaction() self.check(r1, 'create reaction') if len(rxn_id) == 0: rxn_id = 'v' + str(self.model.getNumReactions()) self.check(r1.setId(rxn_id), 'set reaction id') self.check(r1.setReversible(False), 'set reaction reversibility flag') self.check(r1.setFast(False), 'set reaction "fast" attribute') for re in reactants: s1 = self.model.getSpecies(re) species_ref1 = r1.createReactant() self.check(species_ref1, 'create reactant') self.check(species_ref1.setSpecies(str(s1)[9:len(str(s1))-1]), \ 'assign reactant species') self.check(species_ref1.setConstant(True), \ 'set "constant" on species ref 1') self.check(species_ref1.setStoichiometry(1.), \ 'set "stoichiometry" on reactant') for pro in products: s2 = self.model.getSpecies(pro) species_ref2 = r1.createProduct() self.check(species_ref2, 'create product') self.check(species_ref2.setSpecies(str(s2)[9:len(str(s2))-1]), \ 'assign product species') self.check(species_ref2.setConstant(True), \ 'set "constant" on species ref 2') self.check(species_ref2.setStoichiometry(1.), \ 'set "stoichiometry" on product') math_ast = libsbml.parseL3Formula(expression) self.check(math_ast, 'create AST for rate expression') kinetic_law = r1.createKineticLaw() self.check(kinetic_law, 'create kinetic law') self.check(kinetic_law.setMath(math_ast), 'set math on kinetic law') for param in local_params.keys(): val = local_params.get(param) p = kinetic_law.createLocalParameter() self.check(p, 'create local parameter') self.check(p.setId(param), 'set id of local parameter') self.check(p.setValue(val), 'set value of local parameter') return r1
def convert_assignment_rules(sbml_model, rules): for rule in rules: variable = rule['variable'] a_rule = sbml_model.createAssignmentRule() a_rule.setId(rule['name']) a_rule.setVariable(variable['name']) equation = rule['expression'].replace("and", "&&").replace("or", "||") try: a_rule.setMath(libsbml.parseL3Formula(equation)) except: raise ImporperMathMLFormatError( 'libsbml threw an error when parsing assignment \ equation "{0}" for assignment rule "{1}"'.format( equation, rule['name']), traceback.format_exc())
def to_formula(ast_dict, replace_symbols=True): """ Replaces all symbols in given astnode dictionary. :param ast_dict: :return: """ d = dict() for key in ast_dict: astnode = ast_dict[key] if not isinstance(astnode, libsbml.ASTNode): # already a formula d[key] = astnode continue if replace_symbols: astnode = astnode.deepCopy() # replace parameters (p) for key_rep, index in pids_idx.items(): ast_rep = libsbml.parseL3Formula('p__{}__'.format(index)) astnode.replaceArgument(key_rep, ast_rep) # replace states (x) for key_rep, index in dxids_idx.items(): ast_rep = libsbml.parseL3Formula('x__{}__'.format(index)) astnode.replaceArgument(key_rep, ast_rep) formula = evaluableMathML(astnode) if replace_symbols: formula = re.sub("p__", "p[", formula) formula = re.sub("x__", "x[", formula) formula = re.sub("y__", "y[", formula) formula = re.sub("__", "]", formula) d[key] = formula return d
def addEvent(self, trigger, delay, var, value, persistent=True, \ initial_value=False, priority=0, event_id=''): e1 = self.model.createEvent() self.check(e1, 'create event') if len(event_id) == 0: event_id = 'e' + str(self.model.getNumEvents()) self.check(e1.setId(event_id), 'add id to event') tri = e1.createTrigger() self.check(tri, 'add trigger to event') self.check(tri.setPersistent(persistent), 'set persistence of trigger') self.check(tri.setInitialValue(initial_value), 'set initial value of trigger') tri_ast = libsbml.parseL3Formula(trigger) self.check(tri.setMath(tri_ast), 'add formula to trigger') de = e1.createDelay() k = self.addParameter(event_id + 'Delay', delay, self.model.getTimeUnits()) self.check(de, 'add delay to event') delay_ast = libsbml.parseL3Formula(k.getId()) self.check(de.setMath(delay_ast), 'set formula for delay') for v in var: assign = e1.createEventAssignment() self.check(assign, 'add event assignment to event') self.check(assign.setVariable(v), 'add variable to event assignment') val_ast = libsbml.parseL3Formula(str(value[var.index(v)])) self.check(assign.setMath(val_ast), 'add value to event assignment') pri = e1.createPriority() pri_ast = libsbml.parseL3Formula(str(priority)) self.check(pri.setMath(pri_ast), 'add priority to event') return e1
def addReaction(self, reactants, products, expression, local_params={}, rxn_id=''): r1 = self.model.createReaction() self.check(r1, 'create reaction') if len(rxn_id) == 0: rxn_id = 'v' + str(self.model.getNumReactions()); self.check(r1.setId(rxn_id), 'set reaction id') self.check(r1.setReversible(False), 'set reaction reversibility flag') self.check(r1.setFast(False), 'set reaction "fast" attribute') for re in reactants: if re is not None and '$' in re: re.translate(None, '$') s1 = self.model.getSpecies(re); species_ref1 = r1.createReactant() self.check(species_ref1, 'create reactant') self.check(species_ref1.setSpecies(str(s1)[9:len(str(s1))-1]), \ 'assign reactant species') self.check(species_ref1.setConstant(True), \ 'set "constant" on species ref 1') self.check(species_ref1.setStoichiometry(1.), \ 'set "stoichiometry" on reactant') for pro in products: if pro is not None and '$' in pro: pro.translate(None, '$') s2 = self.model.getSpecies(pro); species_ref2 = r1.createProduct() self.check(species_ref2, 'create product') self.check(species_ref2.setSpecies(str(s2)[9:len(str(s2))-1]), \ 'assign product species') self.check(species_ref2.setConstant(True), \ 'set "constant" on species ref 2') self.check(species_ref2.setStoichiometry(1.), \ 'set "stoichiometry" on product') math_ast = libsbml.parseL3Formula(expression); self.check(math_ast, 'create AST for rate expression') kinetic_law = r1.createKineticLaw() self.check(kinetic_law, 'create kinetic law') self.check(kinetic_law.setMath(math_ast), 'set math on kinetic law') for param in local_params.keys(): val = local_params.get(param); p = kinetic_law.createLocalParameter() self.check(p, 'create local parameter') self.check(p.setId(param), 'set id of local parameter') self.check(p.setValue(val), 'set value of local parameter') return r1
def ruleSBtab(self): ''' Extracts the information from the Rule SBtab and writes it to the model. ''' sbtab = self.type2sbtab['Rule'] for row in sbtab.value_rows: if row[sbtab.columns_dict['!Name']] == 'assignmentRule': rule = self.new_model.createAssignmentRule() elif row[sbtab.columns_dict['!Name']] == 'algebraicRule': rule = self.new_model.createAlgebraicRule() elif row[sbtab.columns_dict['!Name']] == 'rateRule': rule = self.new_model.createRateRule() else: continue rule.setMetaId(row[sbtab.columns_dict['!Rule']] + '_meta') try: rule.setName(row[sbtab.columns_dict['!Name']]) except: pass try: rule.setUnits(row[sbtab.columns_dict['!Unit']]) except: pass try: if row[sbtab.columns_dict['!Formula']] != '': asses = row[sbtab.columns_dict['!Formula']] var = asses.split('=')[0].strip() val = asses.split('=')[1].strip() rule.setMath(libsbml.parseL3Formula(val)) rule.setVariable(var) except: pass for column in sbtab.columns_dict.keys(): if "Identifiers" in column: annot = row[sbtab.columns_dict[column]] if annot == '': continue for pattern in urns: if pattern in column: urn = pattern try: cv_term = self.set_annotation(event, annot, urn, 'Biological') rule.addCVTerm(cv_term) except: print( 'There was an annotation that I could not assign properly: ', rule.getId(), annot)
def add_assignment(model, parameter_id, formula): #type: (libsbml.Model, str, str) """ this function adds an assignment rule to the given parameter """ if not model.getParameter(parameter_id): raise ValueError('the model has no parameter %s' % parameter_id) rule = model.createAssignmentRule() rule.setVariable(parameter_id) math = libsbml.parseL3Formula(formula) if not math: raise ValueError('the formula could not be parsed') rule.setMath(math)
def add_function_defintion(model, id, function): #type: (libsbml.Model, str, str) """ this function adds a new function definition to the given sbml model """ if model.getFunctionDefinition(id): raise ValueError( 'the model already has a function definition with id %s' % id) fun = model.createFunctionDefinition() fun.setId(id) math = libsbml.parseL3Formula(function) if not math: raise ValueError('the formula could not be parsed') fun.setMath(math)
def convert_function_definitions(sbml_model, function_definitions): for function_definition in function_definitions: func_def = sbml_model.createFunctionDefinition() func_def.setId(function_definition['name']) function = (function_definition['function'].replace( "and", "&&").replace("or", "||").replace("**", "^")) try: node = libsbml.parseL3Formula(function) func_def.setMath(node) except: raise ImporperMathMLFormatError( 'libsbml threw an error when parsing function "{0}" \ for function definition "{1}"'.format( function, function_definition['name']), traceback.format_exc())
def convertToSBML(filename, model): try: document = libsbml.SBMLDocument(2, 1) except ValueError: raise SystemExit('Could not create SBMLDocumention object') sbmlModel = document.createModel() sbmlModel.setName(str(model.name)) c = sbmlModel.createCompartment() c.setId('c') c.setConstant(True) c.setSize(1) c.setSpatialDimensions(3) species = model.species for specie in species: s = sbmlModel.createSpecies() s.setCompartment('c') s.setId(removeUnicode(specie['name'])) s.setInitialAmount(removeUnicode(specie['initialCondition'])) dParameters = {} parameters = model.parameters for parameter in parameters: p = sbmlModel.createParameter() dParameters[parameter['name']] = parameter['value'] p.setId(removeUnicode(parameter['name'])) value = removeUnicode(parameter['value']) try: value = float(value) except Exception as e: raise Exception("Python threw an error when casting parameter {0} to float (decimal float required for this functionality)".format(parameter['name'])) p.setValue(value) reactions = model.reactions for reaction in reactions: r = sbmlModel.createReaction() r.setId(removeUnicode(reaction['name'])) reactants = {} for reactant in reaction['reactants']: if reactant['specie'] not in reactants: reactants[reactant['specie']] = 0 reactants[reactant['specie']] += reactant['stoichiometry'] for reactantName, stoichiometry in reactants.items(): r2 = r.createReactant() r2.setSpecies(removeUnicode(reactantName)) r2.setStoichiometry(removeUnicode(stoichiometry)) products = {} for product in reaction['products']: if product['specie'] not in products: products[product['specie']] = 0 products[product['specie']] += product['stoichiometry'] for productName, stoichiometry in products.items(): p = r.createProduct() p.setSpecies(removeUnicode(productName)) p.setStoichiometry(removeUnicode(stoichiometry)) k = r.createKineticLaw() if reaction['type'] != 'custom': if len(reactants) == 0: equation = "{0}".format(reaction['rate']) elif len(reactants) == 1: reactantName, stoichiometry = reactants.items()[0] if stoichiometry == 1: equation = "{0} * {1}".format(reaction['rate'], reactantName) elif stoichiometry == 2: equation = "{0} * {1} * {1}".format(reaction['rate'], reactantName) else: raise Exception("Failed to export SBML. Reaction '{0}' is marked as mass action but reactant '{1}' has stoichiometry '{2}' (impossible)".format(reaction['name'], reactantName, stoichiometry)) elif len(reactants) == 2: reactantName0, stoichiometry0 = reactants.items()[0] reactantName1, stoichiometry1 = reactants.items()[1] if stoichiometry0 == 1 and stoichiometry1 == 1: equation = "{0} * {1} * {2}".format(reaction['rate'], reactantName0, reactantName1) else: raise Exception("Failed to export SBML. Reaction '{0}' is marked as mass action but total stoichiometry of reactants exceeds 2 (impossible)".format(reaction['name'])) else: raise Exception("Failed to export SBML. Reaction '{0}' is marked as mass action but has {1} reactants (impossible)".format(reaction['name'], len(reactants))) else: equation = reaction['equation'] try: k.setMath(libsbml.parseL3Formula(removeUnicode(equation))) except Exception as e: traceback.print_exc() raise Exception('libsbml threw an error when parsing rate equation "{0}" for reaction "{1}"'.format(equation, reaction['name'])) writer = libsbml.SBMLWriter() with open(filename, 'w') as f: f.write(writer.writeSBMLToString(document))
def export_sbml(model, y0={}, volume=1.0): """ Export a model as a SBMLDocument. Parameters ---------- model : NetworkModel or ODENetworkModel y0 : dict Initial condition. volume : Real or Real3, optional A size of the simulation volume. """ import libsbml document = libsbml.SBMLDocument(3, 1) # ns = libsbml.XMLNamespaces() # ns.add("http://www.ecell.org/ns/ecell4", "ecell4") #XXX: DUMMY URI # document.setNamespaces(ns) m = document.createModel() comp1 = m.createCompartment() comp1.setId('world') comp1.setConstant(True) if isinstance(volume, ecell4.Real3): comp1.setSize(volume[0] * volume[1] * volume[2]) else: comp1.setSize(volume) comp1.setSpatialDimensions(3) species_list = [] for rr in model.reaction_rules(): for sp in itertools.chain(rr.reactants(), rr.products()): species_list.append(sp) species_list = list(set(species_list)) species_list.sort() sid_map = {} for cnt, sp in enumerate(species_list): sid_map[sp.serial()] = "s{:d}".format(cnt) for sp in species_list: sid = sid_map[sp.serial()] s1 = m.createSpecies() s1.setId(sid) s1.setName(sp.serial()) s1.setCompartment('world') s1.setConstant(False) if sp.serial() in y0.keys(): s1.setInitialAmount(y0[sp.serial()]) else: s1.setInitialAmount(0) s1.setBoundaryCondition(False) s1.setHasOnlySubstanceUnits(False) # s1.appendAnnotation('<annotation><ecell4:extension><ecell4:species serial="{:s}"/></ecell4:extension></annotation>'.format(sp.serial())) if isinstance(model, (ecell4.NetworkModel, ecell4.Model)): for cnt, rr in enumerate(model.reaction_rules()): r1 = m.createReaction() r1.setId("r{:d}".format(cnt)) r1.setReversible(False) r1.setFast(False) kinetic_law = r1.createKineticLaw() # p1 = kinetic_law.createLocalParameter() # p1.setId("k") p1 = m.createParameter() p1.setId("k{:d}".format(cnt)) p1.setConstant(True) p1.setValue(rr.k()) species_coef_map = {} for sp in rr.reactants(): if sp not in species_coef_map.keys(): species_coef_map[sp] = 1 else: species_coef_map[sp] += 1 # math_exp = "k" math_exp = "k{:d}".format(cnt) for sp, coef in species_coef_map.items(): sid = sid_map[sp.serial()] s1 = r1.createReactant() s1.setSpecies(sid) s1.setConstant(False) s1.setStoichiometry(coef) if coef == 1: math_exp += "*{:s}".format(sid) else: math_exp += "*pow({:s},{:g})".format(sid, coef) species_coef_map = {} for sp in rr.products(): if sp not in species_coef_map.keys(): species_coef_map[sp] = 1 else: species_coef_map[sp] += 1 for sp, coef in species_coef_map.items(): sid = sid_map[sp.serial()] s1 = r1.createProduct() s1.setSpecies(sid) s1.setConstant(False) s1.setStoichiometry(coef) math_ast = libsbml.parseL3Formula(math_exp) kinetic_law.setMath(math_ast) elif isinstance(model, ecell4.ode.ODENetworkModel): for cnt, rr in enumerate(model.reaction_rules()): r1 = m.createReaction() r1.setId("r{:d}".format(cnt)) r1.setReversible(True) r1.setFast(False) kinetic_law = r1.createKineticLaw() species_coef_map = {} for sp, coef in zip(rr.reactants(), rr.reactants_coefficients()): if sp not in species_coef_map.keys(): species_coef_map[sp] = coef else: species_coef_map[sp] += coef if rr.is_massaction(): p1 = m.createParameter() p1.setId("k{:d}".format(cnt)) # p1 = kinetic_law.createLocalParameter() # p1.setId("k") p1.setConstant(True) p1.setValue(rr.k()) # math_exp = "k" math_exp = "k{:d}".format(cnt) for sp, coef in species_coef_map.items(): sid = sid_map[sp.serial()] if coef == 1.0: math_exp += "*{:s}".format(sid) else: math_exp += "*pow({:s},{:g})".format(sid, coef) else: math_exp = rr.get_ratelaw().as_string() if math_exp in ('', '<lambda>'): warnings.warn( "The given ODEReactionRule [{:s}] might be invalid.".format( rr.as_string())) math_exp = replace_parseobj(math_exp, sid_map) for sp, coef in species_coef_map.items(): sid = sid_map[sp.serial()] s1 = r1.createReactant() s1.setSpecies(sid) s1.setConstant(False) s1.setStoichiometry(coef) species_coef_map = {} for sp, coef in zip(rr.products(), rr.products_coefficients()): if sp not in species_coef_map.keys(): species_coef_map[sp] = coef else: species_coef_map[sp] += coef for sp, coef in species_coef_map.items(): sid = sid_map[sp.serial()] s1 = r1.createProduct() s1.setSpecies(sid) s1.setConstant(False) s1.setStoichiometry(coef) math_ast = libsbml.parseL3Formula(math_exp) kinetic_law.setMath(math_ast) else: raise ValueError( "The invalid type of a Model was given [{:s}].".format(str(model)) + " NetworkModel or ODENetworkModel must be given.") document.validateSBML() num_errors = (document.getNumErrors(libsbml.LIBSBML_SEV_ERROR) + document.getNumErrors(libsbml.LIBSBML_SEV_FATAL)) if num_errors > 0: messages = "The generated document is not valid." messages += " {} errors were found:\n".format(num_errors) for i in range(document.getNumErrors(libsbml.LIBSBML_SEV_ERROR)): err = document.getErrorWithSeverity(i, libsbml.LIBSBML_SEV_ERROR) messages += "{}: {}\n".format(err.getSeverityAsString(), err.getShortMessage()) for i in range(document.getNumErrors(libsbml.LIBSBML_SEV_FATAL)): err = document.getErrorWithSeverity(i, libsbml.LIBSBML_SEV_FATAL) messages += "{}: {}\n".format(err.getSeverityAsString(), err.getShortMessage()) raise RuntimeError(messages) return document
def addReaction(self, reactants, products, expression, local_params={}, rxn_id=''): r1 = self.model.createReaction() self.check(r1, 'create reaction') if len(rxn_id) == 0: rxn_id = 'v' + str(self.model.getNumReactions()); self.check(r1.setId(rxn_id), 'set reaction id') self.check(r1.setReversible(False), 'set reaction reversibility flag') self.check(r1.setFast(False), 'set reaction "fast" attribute') for re in reactants: if re is not None and '$' in re: re.translate(None, '$') re_split = re.split(); if len(re_split) == 1: sto = 1.0; re_id = re; elif len(re_split) == 2 and re_split[0].isdigit(): sto = float(re_split[0]); re_id = re_split[1]; else: err_msg = 'Error: reactants must be listed in format \'S\' or \'(float)\' S\''; raise SystemExit(err_msg) s1 = self.model.getSpecies(re_id); species_ref1 = r1.createReactant() self.check(species_ref1, 'create reactant') self.check(species_ref1.setSpecies(str(s1)[9:len(str(s1))-1]), \ 'assign reactant species') self.check(species_ref1.setStoichiometry(sto), \ 'assign reactant stoichiometry') if self.document.getLevel() == 3: self.check(species_ref1.setConstant(True), \ 'set "constant" on species ref 1') for pro in products: if pro is not None and '$' in pro: pro.translate(None, '$') pro_split = pro.split(); if len(pro_split) == 1: sto = 1.0; pro_id = pro; elif len(pro_split) == 2: sto = float(pro_split[0]); pro_id = pro_split[1]; else: err_msg = 'Error: products must be listed in format \'S\' or \'(float)\' S\''; raise SystemExit(err_msg) s2 = self.model.getSpecies(pro_id); species_ref2 = r1.createProduct() self.check(species_ref2, 'create product') self.check(species_ref2.setSpecies(str(s2)[9:len(str(s2))-1]), \ 'assign product species') self.check(species_ref2.setStoichiometry(sto), \ 'set product stoichiometry') if self.document.getLevel() == 3: self.check(species_ref2.setConstant(True), \ 'set "constant" on species ref 2') math_ast = libsbml.parseL3Formula(expression); self.check(math_ast, 'create AST for rate expression') kinetic_law = r1.createKineticLaw() self.check(kinetic_law, 'create kinetic law') self.check(kinetic_law.setMath(math_ast), 'set math on kinetic law') for param in local_params.keys(): val = local_params.get(param); if self.document.getLevel() == 3: p = kinetic_law.createLocalParameter() else: p = kinetic_law.createParameter() self.check(p, 'create local parameter') self.check(p.setId(param), 'set id of local parameter') self.check(p.setValue(val), 'set value of local parameter') return r1
def export_sbml(model, y0=None, volume=1.0, is_valid=True): """ Export a model as a SBMLDocument. Parameters ---------- model : NetworkModel y0 : dict Initial condition. volume : Real or Real3, optional A size of the simulation volume. 1 as a default. is_valid : bool, optional Check if the generated model is valid. True as a default. """ y0 = y0 or {} import libsbml document = libsbml.SBMLDocument(3, 1) # ns = libsbml.XMLNamespaces() # ns.add("http://www.ecell.org/ns/ecell4", "ecell4") #XXX: DUMMY URI # document.setNamespaces(ns) m = document.createModel() comp1 = m.createCompartment() comp1.setId('world') comp1.setConstant(True) if unit.HAS_PINT: if isinstance(volume, unit._Quantity): if unit.STRICT: if isinstance(volume.magnitude, ecell4_base.core.Real3) and not unit.check_dimensionality(volume, '[length]'): raise ValueError("Cannot convert [volume] from '{}' ({}) to '[length]'".format( volume.dimensionality, volume.u)) elif not unit.check_dimensionality(volume, '[volume]'): raise ValueError("Cannot convert [volume] from '{}' ({}) to '[volume]'".format( volume.dimensionality, volume.u)) volume = volume.to_base_units().magnitude y0 = y0.copy() for key, value in y0.items(): if isinstance(value, unit._Quantity): if not unit.STRICT: y0[key] = value.to_base_units().magnitude elif unit.check_dimensionality(value, '[substance]'): y0[key] = value.to_base_units().magnitude elif unit.check_dimensionality(value, '[concentration]'): volume = w.volume() if not isinstance(w, ecell4_base.spatiocyte.SpatiocyteWorld) else w.actual_volume() y0[key] = value.to_base_units().magnitude * volume else: raise ValueError( "Cannot convert a quantity for [{}] from '{}' ({}) to '[substance]'".format( key, value.dimensionality, value.u)) if isinstance(volume, ecell4_base.core.Real3): comp1.setSize(volume[0] * volume[1] * volume[2]) else: comp1.setSize(volume) comp1.setSpatialDimensions(3) species_list = [] for rr in model.reaction_rules(): for sp in itertools.chain(rr.reactants(), rr.products()): species_list.append(sp) species_list = list(set(species_list)) species_list.sort() sid_map = {} for cnt, sp in enumerate(species_list): sid_map[sp.serial()] = "s{:d}".format(cnt) for sp in species_list: sid = sid_map[sp.serial()] s1 = m.createSpecies() s1.setId(sid) s1.setName(sp.serial()) s1.setCompartment('world') s1.setConstant(False) if sp.serial() in y0.keys(): s1.setInitialAmount(y0[sp.serial()]) else: s1.setInitialAmount(0) s1.setBoundaryCondition(False) s1.setHasOnlySubstanceUnits(False) # s1.appendAnnotation('<annotation><ecell4:extension><ecell4:species serial="{:s}"/></ecell4:extension></annotation>'.format(sp.serial())) for cnt, rr in enumerate(model.reaction_rules()): desc = rr.get_descriptor() r1 = m.createReaction() r1.setId("r{:d}".format(cnt)) r1.setReversible(True) r1.setFast(False) kinetic_law = r1.createKineticLaw() species_coef_map = {} if desc is None: for sp in rr.reactants(): if sp not in species_coef_map.keys(): species_coef_map[sp] = 1 else: species_coef_map[sp] += 1 else: for sp, coef in zip(rr.reactants(), desc.reactant_coefficients()): if sp not in species_coef_map.keys(): species_coef_map[sp] = coef else: species_coef_map[sp] += coef if desc is None or isinstance(desc, ecell4_base.core.ReactionRuleDescriptorMassAction): p1 = m.createParameter() p1.setId("k{:d}".format(cnt)) # p1 = kinetic_law.createLocalParameter() # p1.setId("k") p1.setConstant(True) p1.setValue(rr.k() if desc is None else desc.k()) # math_exp = "k" math_exp = "k{:d}".format(cnt) for sp, coef in species_coef_map.items(): sid = sid_map[sp.serial()] if coef == 1.0: math_exp += "*{:s}".format(sid) else: math_exp += "*pow({:s},{:g})".format(sid, coef) elif isinstance(desc, ecell4_base.core.ReactionRuleDescriptorPyfunc): math_exp = desc.as_string() if math_exp in ('', '<lambda>'): warnings.warn( "The given ReactionRuleDescriptorPyfunc [{:s}] might be invalid.".format( rr.as_string())) math_exp = replace_parseobj(math_exp, sid_map) else: raise RuntimeError('Unknown derived type of ReactionRuleDescriptor was given [{}].'.format(type(desc))) for sp, coef in species_coef_map.items(): sid = sid_map[sp.serial()] s1 = r1.createReactant() s1.setSpecies(sid) s1.setConstant(False) s1.setStoichiometry(coef) if desc is None: for sp in rr.products(): if sp not in species_coef_map.keys(): species_coef_map[sp] = 1 else: species_coef_map[sp] += 1 else: species_coef_map = {} for sp, coef in zip(rr.products(), desc.product_coefficients()): if sp not in species_coef_map.keys(): species_coef_map[sp] = coef else: species_coef_map[sp] += coef for sp, coef in species_coef_map.items(): sid = sid_map[sp.serial()] s1 = r1.createProduct() s1.setSpecies(sid) s1.setConstant(False) s1.setStoichiometry(coef) math_ast = libsbml.parseL3Formula(math_exp) kinetic_law.setMath(math_ast) if is_valid: document.validateSBML() num_errors = (document.getNumErrors(libsbml.LIBSBML_SEV_ERROR) + document.getNumErrors(libsbml.LIBSBML_SEV_FATAL)) if num_errors > 0: messages = "The generated document is not valid." messages += " {} errors were found:\n".format(num_errors) for i in range(document.getNumErrors(libsbml.LIBSBML_SEV_ERROR)): err = document.getErrorWithSeverity(i, libsbml.LIBSBML_SEV_ERROR) messages += "{}: {}\n".format(err.getSeverityAsString(), err.getShortMessage()) for i in range(document.getNumErrors(libsbml.LIBSBML_SEV_FATAL)): err = document.getErrorWithSeverity(i, libsbml.LIBSBML_SEV_FATAL) messages += "{}: {}\n".format(err.getSeverityAsString(), err.getShortMessage()) raise RuntimeError(messages) return document
def stringToMathML(string): """Parses formula string. """ astnode = libsbml.parseL3Formula(str(string)) mathml = libsbml.writeMathMLToString(astnode) return mathml
pstack = [] for i, c in enumerate(s): if c == '(': pstack.append(i) elif c == ')': if len(pstack) == 0: return toret toret[pstack.pop()] = i return toret if __name__ == "__main__": # parse ast formula = "abar / (1 + k1 * exp(-2 * d1 * 96.485 * Vm / 8.313424 / (310)) / c)" ast = libsbml.parseL3Formula(formula) # print info ast_info(ast) # iterate the ast names = find_names_in_ast(ast) print(names) print(libsbml.AST_NAME) print('------------------------') # s = "vtest(v(a, b, c), x(a, b, c), d)*(abc)" s = 'hv(t-1,sharpness) - hv(t-2,sharpness) + (hv(t-5,sharpness) - hv(t-6,sharpness)))' toret = bracket_stack(s) print(toret)