def _sub_var_names(self, input): mapping_dict = {} for id in ExprManip.extract_vars(input): # convert it back to something key_column will recognize # had to use a form dynVarName__derivWRT__optParamName for the # sensitivity variable because otherwise, # extract_vars gets confused splitId = id.split('__derivWRT__') if len(splitId) == 1: idname = splitId[0] elif len(splitId) == 2: idname = tuple(splitId) else: raise 'Problem with id %s in Trajectory._sub_var_names' % id if idname in self.key_column.keys(): mapping = 'values[start:end, %i]' % self.key_column.get(idname) elif idname in self.const_var_values.keys(): # Don't substitute for constant variable names. Those will # be taken care of earlier in the method. continue elif idname == 'time': mapping = 'times[start:end]' else: raise 'Problem with idname %s in Trajectory._sub_var_names' % id mapping_dict[id] = mapping input = ExprManip.sub_for_vars(input, mapping_dict) return input
def parseTrigger(self, trigger): if '<' in trigger or '>' in trigger or '=' in trigger: raise ValueError( 'Event triggers must use the functions gt and lt, ' 'rather than the symbols > and <. For example, ' 'to trigger when B becomes less than A, use ' 'lt(B,A).') # Figures out if the event is time-triggered and parses it to niceness. # 'and' is a reserved keyword in python, so the parser will break # unless we substitute the name here. trigger = trigger.replace('and(', 'and_func(') self.trigger = trigger if ExprManip.extract_vars(trigger) == set(['time']): self.timeTriggered = True ast = ExprManip.AST.strip_parse(trigger) firstArg = ExprManip.AST.ast2str(ast.args[0]) secondArg = ExprManip.AST.ast2str(ast.args[1]) if firstArg == 'time': self.triggeringTime = eval(secondArg) elif secondArg == 'time': self.triggeringTime = eval(firstArg) else: raise NameError('Problem in time triggered events')
def parseTrigger(self, trigger): if '<' in trigger or '>' in trigger or '=' in trigger: raise ValueError('Event triggers must use the functions gt and lt, ' 'rather than the symbols > and <. For example, ' 'to trigger when B becomes less than A, use ' 'lt(B,A).') # Figures out if the event is time-triggered and parses it to niceness. # 'and' is a reserved keyword in python, so the parser will break # unless we substitute the name here. trigger = trigger.replace('and(', 'and_func(') self.trigger = trigger if ExprManip.extract_vars(trigger) == sets.Set(['time']): self.timeTriggered = True ast = ExprManip.AST.strip_parse(trigger) firstArg = ExprManip.AST.ast2str(ast.args[0]) secondArg = ExprManip.AST.ast2str(ast.args[1]) if firstArg == 'time': self.triggeringTime = eval(secondArg) elif secondArg == 'time': self.triggeringTime = eval(firstArg) else: raise 'Problem in time triggered events'
def __init__(self, id, stoichiometry, kineticLaw = '', name = '', reactant_stoichiometry = None, product_stoichiometry = None): self.id = id self.stoichiometry = stoichiometry # self.reactant_stoichiometry and self.product_stoichiometry # are defined to help repserve the stoichiometry defined in an # SBML model self.reactant_stoichiometry = reactant_stoichiometry self.product_stoichiometry = product_stoichiometry self.kineticLaw = kineticLaw self.name = name variables = ExprManip.extract_vars(kineticLaw) self.parameters = variables.difference(sets.Set(stoichiometry.keys()))
def test_extract_vars(self): cases = [('x', ['x']), ('x + y', ['x', 'y']), ('x * y', ['x', 'y']), ('x / y', ['x', 'y']), ('x**2', ['x']), ('x**y', ['x', 'y']), ('f(x)', ['x']), ('f(x, y)', ['x', 'y']), ('f(x + z/x, y)', ['x', 'y', 'z']), ('x**2 + f(y)', ['x', 'y']), ('x + y**2 + z**(a + b) + z**f.g.h(a + b + sqrt(c))', ['x', 'y', 'z', 'a', 'b', 'c']), ('x < y', ['x', 'y']), ('(x < y) and (x == 2)', ['x', 'y']), ] for expr, vars in cases: assert ExprManip.extract_vars(expr) == sets.Set(vars)
def __init__(self, id, stoichiometry, kineticLaw='', name='', reactant_stoichiometry=None, product_stoichiometry=None): self.id = id self.stoichiometry = stoichiometry # self.reactant_stoichiometry and self.product_stoichiometry # are defined to help repserve the stoichiometry defined in an # SBML model self.reactant_stoichiometry = reactant_stoichiometry self.product_stoichiometry = product_stoichiometry self.kineticLaw = kineticLaw self.name = name variables = ExprManip.extract_vars(kineticLaw) self.parameters = variables.difference(sets.Set(stoichiometry.keys()))
def toSBMLString(net): metaId = 0 try: m = libsbml.Model(net.id) except NotImplementedError: m = libsbml.Model(sbml_level, sbml_version) m.setId(net.id) m.setName(net.name) m.setMetaId('SloppyCell_{0:05d}'.format(metaId)) metaId += 1 for id, fd in list(net.functionDefinitions.items()): try: sfd = libsbml.FunctionDefinition(id) except: sfd = libsbml.FunctionDefinition(sbml_level, sbml_version) sfd.setId(id) sfd.setName(fd.name) formula = fd.math formula = formula.replace('**', '^') formula = 'lambda(%s, %s)' % (','.join(fd.variables), formula) sfd.setMath(libsbml.parseFormula(formula)) sfd.setMetaId('SloppyCell_{0:05d}'.format(metaId)) metaId += 1 m.addFunctionDefinition(sfd) for id, c in list(net.compartments.items()): try: sc = libsbml.Compartment(id) except NotImplementedError: sc = libsbml.Compartment(sbml_level, sbml_version) sc.setId(id) sc.setName(c.name) sc.setConstant(c.is_constant) sc.setSize(c.initialValue) sc.setMetaId('SloppyCell_{0:05d}'.format(metaId)) metaId += 1 m.addCompartment(sc) for id, s in list(net.species.items()): try: ss = libsbml.Species(id) except NotImplementedError: ss = libsbml.Species(sbml_level, sbml_version) ss.setId(id) ss.setName(s.name) ss.setCompartment(s.compartment) if s.initialValue is not None and not isinstance(s.initialValue, str): ss.setInitialConcentration(s.initialValue) ss.setBoundaryCondition(s.is_boundary_condition) ss.setMetaId('SloppyCell_{0:05d}'.format(metaId)) metaId += 1 m.addSpecies(ss) for id, p in list(net.parameters.items()): try: sp = libsbml.Parameter(id) except NotImplementedError: sp = libsbml.Parameter(sbml_level, sbml_version) sp.setId(id) sp.setName(p.name) if p.initialValue is not None: sp.setValue(p.initialValue) sp.setConstant(p.is_constant) sp.setMetaId('SloppyCell_{0:05d}'.format(metaId)) metaId += 1 m.addParameter(sp) for id, r in list(net.rateRules.items()): try: sr = libsbml.RateRule() except NotImplementedError: sr = libsbml.RateRule(sbml_level, sbml_version) sr.setVariable(id) formula = r.replace('**', '^') sr.setMath(libsbml.parseFormula(formula)) sr.setMetaId('SloppyCell_{0:05d}'.format(metaId)) metaId += 1 m.addRule(sr) for id, r in list(net.assignmentRules.items()): try: sr = libsbml.AssignmentRule() except NotImplementedError: sr = libsbml.AssignmentRule(sbml_level, sbml_version) sr.setVariable(id) formula = r.replace('**', '^') sr.setMath(libsbml.parseFormula(formula)) sr.setMetaId('SloppyCell_{0:05d}'.format(metaId)) metaId += 1 m.addRule(sr) for r, r in list(net.algebraicRules.items()): try: sr = libsbml.AlgebraicRule() except NotImplementedError: sr = libsbml.AlgebraicRule(sbml_level, sbml_version) formula = r.replace('**', '^') sr.setMath(libsbml.parseFormula(formula)) sr.setMetaId('SloppyCell_{0:05d}'.format(metaId)) metaId += 1 m.addRule(sr) for id, rxn in list(net.reactions.items()): # Need to identify modifiers in kinetic law and add them to # stoichiometry kl_vars = ExprManip.extract_vars(rxn.kineticLaw) species_in_kl = kl_vars.intersection(list(net.species.keys())) for s in species_in_kl: if s not in rxn.stoichiometry: rxn.stoichiometry[s] = 0 try: srxn = libsbml.Reaction(id) except NotImplementedError: srxn = libsbml.Reaction(sbml_level, sbml_version) srxn.setId(id) srxn.setName(rxn.name) # Handle the case where the model was originally read in from an # SBML file, so that the reactants and products of the Reaction # object are explicitly set. if rxn.reactant_stoichiometry != None and \ rxn.product_stoichiometry != None: for rid, stoich_list in list(rxn.reactant_stoichiometry.items()): for stoich in stoich_list: rxn_add_stoich(srxn, rid, -float(stoich), is_product=False) for rid, stoich_list in list(rxn.product_stoichiometry.items()): for stoich in stoich_list: rxn_add_stoich(srxn, rid, stoich, is_product=True) # Handle the case where the model was created using the SloppyCell # API, in which case reactants and products are inferred from their # stoichiometries else: for rid, stoich in list(rxn.stoichiometry.items()): rxn_add_stoich(srxn, rid, stoich) formula = rxn.kineticLaw.replace('**', '^') try: kl = libsbml.KineticLaw(formula) except NotImplementedError: kl = libsbml.KineticLaw(sbml_level, sbml_version) kl.setFormula(formula) srxn.setKineticLaw(kl) srxn.setMetaId('SloppyCell_{0:05d}'.format(metaId)) metaId += 1 m.addReaction(srxn) for id, e in list(net.events.items()): try: se = libsbml.Event(id) except NotImplementedError: se = libsbml.Event(sbml_level, sbml_version) se.setId(id) se.setName(e.name) formula = e.trigger.replace('**', '^') formula = formula.replace('and_func(', 'and(') formula = formula.replace('or_func(', 'or(') ast = libsbml.parseFormula(formula) if ast is None: raise ValueError('Problem parsing event trigger: %s. Problem may ' 'be use of relational operators (< and >) rather ' 'than libsbml-friendly functions lt and gt.' % formula) try: se.setTrigger(ast) except TypeError: try: trigger = libsbml.Trigger(ast) except NotImplementedError: trigger = libsbml.Trigger(sbml_level, sbml_version) trigger.setMath(ast) se.setTrigger(trigger) formula = str(e.delay).replace('**', '^') try: se.setDelay(libsbml.parseFormula(formula)) except TypeError: try: se.setDelay(libsbml.Delay(libsbml.parseFormula(formula))) except NotImplementedError: delay = libsbml.Delay(sbml_level, sbml_version) delay.setMath(libsbml.parseFormula(formula)) se.setDelay(delay) for varId, formula in list(e.event_assignments.items()): try: sea = libsbml.EventAssignment() except NotImplementedError: sea = libsbml.EventAssignment(sbml_level, sbml_version) sea.setVariable(varId) formula = str(formula).replace('**', '^') formula = formula.replace('and_func(', 'and(') formula = formula.replace('or_func(', 'or(') ast = libsbml.parseFormula(formula) replaceTime(ast) sea.setMath(ast) se.addEventAssignment(sea) se.setMetaId('SloppyCell_{0:05d}'.format(metaId)) metaId += 1 m.addEvent(se) for id, con in list(net.constraints.items()): try: scon = libsbml.Constraint() except NotImplementedError: scon = libsbml.Constraint(sbml_level, sbml_version) scon.setId(con.id) scon.setName(con.name) formula = con.trigger.replace('**', '^') ast = libsbml.parseFormula(formula) if ast is None: raise ValueError( 'Problem parsing constraint math: %s. Problem may ' 'be use of relational operators (< and >) rather ' 'than libsbml-friendly functions lt and gt.' % formula) scon.setMath(ast) se.setcon('SloppyCell_{0:05d}'.format(metaId)) metaId += 1 m.addConstraint(scon) d = libsbml.SBMLDocument(sbml_level, sbml_version) d.setModel(m) sbmlStr = libsbml.writeSBMLToString(d) return sbmlStr