def get_h(self, keep1=True): """ c = h(p) """ hs = [poly.get_h(keep1=keep1) for poly in self] yids = butil.flatten([h_.yids for h_ in hs]) coefstrs = butil.flatten([h_.frepr.tolist() for h_ in hs]) senstrs = [[exprmanip.simplify_expr(exprmanip.diff_expr(coefstr, pid)) for pid in self.pids] for coefstr in coefstrs] hstr = str(coefstrs).replace("'", "") Dhstr = str(senstrs).replace("'", "") subs0 = dict(butil.flatten([poly.convarvals.items() for poly in self], depth=1)) def f(p): subs = subs0.copy() subs.update(dict(zip(self.pids, p))) return np.array(eval(hstr, subs)) def Df(p): subs = subs0.copy() subs.update(dict(zip(self.pids, p))) return np.array(eval(Dhstr, subs)) h = predict.Predict(f=f, Df=Df, pids=self.pids, p0=self.p0, yids=yids, frepr=butil.Series(coefstrs, yids), Dfrepr=butil.DF(senstrs, yids, self.pids)) return h
def solve_path2(s1, s2): """ Input: s1 and s2: strs of ratelaws; variable is 'X' solve_for: 'X' or 'J' #idx_root: 0 or 1, since there can be two roots (if v1 - v2 == 0 # is a quadratic equation) Output: A tuple of (X string, J string) """ if 'inf' in s1 and 'inf' in s2: raise ValueError elif 'inf' in s1: Xstr = str(sympy.solve(s1.replace('inf', '1'), 'X', simplify=True)[0]) Jstr = exprmanip.simplify_expr(exprmanip.sub_for_var(s2, 'X', Xstr)) elif 'inf' in s2: Xstr = str(sympy.solve(s2.replace('inf', '1'), 'X', simplify=True)[0]) Jstr = exprmanip.simplify_expr(exprmanip.sub_for_var(s1, 'X', Xstr)) else: eqn = '(%s) - (%s)' % (s1, s2) roots = sympy.solve(eqn, 'X', simplify=True) if len(roots) == 2: # choose the positive root (can be the 1st or the 2nd of the two) bools = ['+ sqrt' in str(sympy.expand(root)) for root in roots] idx = bools.index(True) Xstr = str(roots[idx]) else: Xstr = str(roots[0]) Jstr = exprmanip.simplify_expr(exprmanip.sub_for_var(s1, 'X', Xstr)) """ try: xsol = str(roots[1]) varids = list(exprmanip.extract_vars(xsol)) tests = [] for i in range(10): subs = dict(zip(varids, np.random.lognormal(size=len(varids)))) subs['sqrt'] = np.sqrt tests.append(eval(xsol, subs) > 0) if not all(tests): raise ValueError except (IndexError, ValueError): xsol = str(roots[0]) """ return Xstr, Jstr
def list2predict2(l, pids, uids=None, us=None, yids=None, c=None, p0=None): """ pred = list2predict(['exp(-p1*1)+exp(-p2*1)', 'exp(-p1*2)+exp(-p2*2)', 'exp(-p1*1)-exp(-p2*1)'], pids=['p1','p2'], p0=None) pred = list2predict(['(k1f*C1-k1r*X1)-(k2f*X1-k2r*X2)', '(k2f*X1-k2r*X2)-(k3f*X2-k3r*C2)'], uids=['X1','X2'], us=butil.get_product([1,2,3],[1,2,3]), pids=['k1f','k1r','k2f','k2r','k3f','k3r'], c={'C1':2,'C2':1}) Input: c: a mapping """ if c is not None: l = [exprmanip.sub_for_vars(s, c) for s in l] ystr = str(l).replace("'", "") ycode = compile(ystr, '', 'eval') def f(p): return np.array(eval(ycode, dict(zip(pids, p)), mathsubs)) jaclist = [] for s in l: jacrow = [exprmanip.simplify_expr(exprmanip.diff_expr(s, pid)) for pid in pids] jaclist.append(jacrow) if us is not None: jaclist = [[[exprmanip.sub_for_vars(jacentry, dict(zip(uids, u))) for jacentry in jacrow] for jacrow in jaclist] for u in us] jaclist = butil.flatten(jaclist, depth=1) jacstr = str(jaclist).replace("'", "") jaccode = compile(jacstr, '', 'eval') def Df(p): return np.array(eval(jaccode, dict(zip(pids, p)), mathsubs)) if p0 is None: p0 = [1] * len(pids) if yids is None: yids = ['y%d'%i for i in range(1, len(l)+1)] if us is not None: uids = ['u%d'%i for i in range(1, len(us)+1)] yids = butil.get_product(yids, uids) return Predict(f=f, Df=Df, p0=p0, pids=pids, yids=yids)
def get_Ep_str(net): """ """ Ep = [] for rxnid in net.rxnids: ratelaw = exprmanip.sub_for_vars(net.rxns[rxnid].kineticLaw, net.asgrules.to_od()) Ep_rxn = [] for pid in net.pids: Ep_rxn.append(exprmanip.simplify_expr(exprmanip.diff_expr(ratelaw, pid))) Ep.append(Ep_rxn) Ep_str = str(Ep).replace("'", "") Ep_code = compile(Ep_str, '', 'eval') # compile to code object net.Ep_str, net.Ep_code = Ep_str, Ep_code return Ep_str, Ep_code
def get_concentration_elasticity_string(net): """ """ Ex = [] for rxnid in net.rxnids: ratelaw = exprmanip.sub_for_vars(net.rxns[rxnid].kineticLaw, net.asgrules.to_dict()) Ex_rxn = [] for xid in net.xids: Ex_rxn.append( exprmanip.simplify_expr(exprmanip.diff_expr(ratelaw, xid))) Ex.append(Ex_rxn) Ex_str = str(Ex).replace("'", "") Ex_code = compile(Ex_str, '', 'eval') # compile to code object net.Ex_str, net.Ex_code = Ex_str, Ex_code return Ex_str, Ex_code
def test_simplify_expr(self): cases = [ 'x', 'x+y', 'x-y', 'x*y', 'x/y', 'x**y', '-x', 'x**-y', 'x**(-y + z)', 'f(x)', 'g(x,y,z)', 'x**(y**z)', '(x**y)**z', 'x**y**z', 'x - (x+y)', '(x+y) - z', 'g(x-0+2, y**2 - 0**0, z*y + x/1)', 'x/x', 'x/y', '(x-x)/z', 'x**2 - y/z', 'x+1-1+2-3-x', '0+1*1', 'x-x+y', '(-2)**2', '-2**2', 'x/y == x/y', 'not True', 'x/x + y/y == 2', '3 + 4 > 6', '3 + (4 > 6)', ] cases1 = ['x**(-y + z)'] # cases = ['-y + z'] for expr in cases: simplified = ExprManip.simplify_expr(expr) orig = eval(expr) simp = eval(simplified) if orig != 0: assert old_div(abs(orig - simp), (0.5 * (orig + simp))) < 1e-6 else: assert simp == 0
def str2predict(s, pids, uids, us, c=None, p0=None, yids=None): """ Input: us: a list of u's where each u has the same length as uids and has the same order c: if given, a mapping from convarid to convarval """ if c is not None: s = exprmanip.sub_for_vars(s, c) ystr = str([exprmanip.sub_for_vars(s, dict(zip(uids, u))) for u in us]).\ replace("'", "") ycode = compile(ystr, '', 'eval') def f(p): return np.array(eval(ycode, dict(zip(pids, p)), mathsubs)) jaclist = [] for u in us: s_u = exprmanip.sub_for_vars(s, dict(zip(uids, u))) jacrow = [exprmanip.simplify_expr(exprmanip.diff_expr(s_u, pid)) for pid in pids] jaclist.append(jacrow) jacstr = str(jaclist).replace("'", "") jaccode = compile(jacstr, '', 'eval') def Df(p): return np.array(eval(jaccode, dict(zip(pids, p)), mathsubs)) if p0 is None: p0 = [1] * len(pids) if yids is None: yids = ['u=%s'%str(list(u)) for u in us] return Predict(f=f, Df=Df, p0=p0, pids=pids, yids=yids)
def fromSBMLString(sbmlStr, id=None, duplicate_rxn_params=False): r = libsbml.SBMLReader() d = r.readSBMLFromString(sbmlStr) if d.getNumErrors(): message = 'libSBML reported errors in SBML file. Try running file '\ 'through the online validator: '\ 'http://www.sbml.org/Facilities/Validator . Specific errors '\ 'noted are: ' errors = [] for ii in range(d.getNumErrors()): pm = d.getError(ii) errors.append(pm.getMessage()) print(message + '; '.join(errors)) m = d.getModel() modelId = m.getId() if (id is None) and (modelId == ''): raise ValueError('Network id not specified in SBML or passed in.') elif id is not None: modelId = id rn = Network_mod.Network(id=modelId, name=m.getName()) for f in m.getListOfFunctionDefinitions(): id, name = f.getId(), f.getName() math = f.getMath() variables = [] for ii in range(math.getNumChildren() - 1): variables.append(formula_to_py(math.getChild(ii))) math = formula_to_py(math.getRightChild()) rn.addFunctionDefinition(id, variables, math) for c in m.getListOfCompartments(): id, name = c.getId(), c.getName() size = c.getSize() isConstant = c.getConstant() rn.addCompartment(id=id, size=size, isConstant=isConstant, name=name) for s in m.getListOfSpecies(): id, name = s.getId(), s.getName() compartment = s.getCompartment() if s.isSetInitialConcentration(): iC = s.getInitialConcentration() elif s.isSetInitialAmount(): iC = s.getInitialAmount() else: iC = 1 isBC, isConstant = s.getBoundaryCondition(), s.getConstant() xml_text = s.toSBML() uniprot_ids = set([ entry[1:].split('"')[0] for entry in xml_text.split('uniprot')[1:] ]) rn.addSpecies(id=id, compartment=compartment, initialConcentration=iC, isConstant=isConstant, is_boundary_condition=isBC, name=name, uniprot_ids=uniprot_ids) for p in m.getListOfParameters(): parameter = createNetworkParameter(p) rn.addVariable(parameter) for rxn in m.getListOfReactions(): id, name = rxn.getId(), rxn.getName() kL = rxn.getKineticLaw() kLFormula = kL.getFormula() substitution_dict = {} # Deal with parameters defined within reactions for p in kL.getListOfParameters(): parameter = createNetworkParameter(p) # If a parameter with this name already exists, **and it has a # different value than this parameter** we rename this parameter # instance by prefixing it with the rxn name so there isn't a # clash. if parameter.id in list(rn.variables.keys()): logger.warn('Parameter %s appears in two different reactions ' 'in SBML file.' % parameter.id) if parameter.value != rn.variables.get(parameter.id).value or\ duplicate_rxn_params: oldId = parameter.id parameter.id = id + '_' + parameter.id substitution_dict[oldId] = parameter.id logger.warn('It has different values in the two positions ' 'so we are creating a new parameter %s.' % (parameter.id)) else: logger.warn('It has the same value in the two positions ' 'so we are only defining one parameter %s. ' 'This behavior can be changed with the option ' 'duplicate_rxn_params = True' % (parameter.id)) if parameter.id not in list(rn.variables.keys()): rn.addVariable(parameter) kLFormula = ExprManip.sub_for_vars(kLFormula, substitution_dict) # Assemble the stoichiometry. SBML has the annoying trait that # species can appear as both products and reactants and 'cancel out' # For each species appearing in the reaction, we build up a string # representing the stoichiometry. Then we'll simplify that string and # see whether we ended up with a float value in the end. stoichiometry = {} reactant_stoichiometry = {} product_stoichiometry = {} for reactant in rxn.getListOfReactants(): species = reactant.getSpecies() stoichiometry.setdefault(species, '0') stoich = reactant.getStoichiometryMath() stoich = stoichToString(reactant, stoich) stoichiometry[species] += '-(%s)' % stoich if species in reactant_stoichiometry: reactant_stoichiometry[species].append(stoich) else: reactant_stoichiometry[species] = [stoich] for product in rxn.getListOfProducts(): species = product.getSpecies() stoichiometry.setdefault(species, '0') stoich = product.getStoichiometryMath() stoich = stoichToString(product, stoich) stoichiometry[species] += '+(%s)' % stoich if species in product_stoichiometry: product_stoichiometry[species].append(stoich) else: product_stoichiometry[species] = [stoich] for species, stoich in list(stoichiometry.items()): stoich = ExprManip.simplify_expr(stoich) try: # Try converting the string to a float. stoich = float(stoich) except ValueError: pass stoichiometry[species] = stoich for modifier in rxn.getListOfModifiers(): stoichiometry.setdefault(modifier.getSpecies(), 0) rn.addReaction(id=id, stoichiometry=stoichiometry, kineticLaw=kLFormula, reactant_stoichiometry=reactant_stoichiometry, product_stoichiometry=product_stoichiometry) for ii, r in enumerate(m.getListOfRules()): if r.getTypeCode() == libsbml.SBML_ALGEBRAIC_RULE: math = formula_to_py(r.getMath()) rn.add_algebraic_rule(math) else: variable = r.getVariable() math = formula_to_py(r.getMath()) if r.getTypeCode() == libsbml.SBML_ASSIGNMENT_RULE: rn.addAssignmentRule(variable, math) elif r.getTypeCode() == libsbml.SBML_RATE_RULE: rn.addRateRule(variable, math) for ii, e in enumerate(m.getListOfEvents()): id, name = e.getId(), e.getName() if id == '': id = 'event%i' % ii try: # For libSBML 3.0 trigger_math = e.getTrigger().getMath() except AttributeError: # For older versions trigger_math = e.getTrigger() trigger = formula_to_py(trigger_math) if e.getDelay() is not None: try: # For libSBML 3.0 delay_math = e.getDelay().getMath() except AttributeError: # For older versions delay_math = e.getDelay() delay = formula_to_py(delay_math) else: delay = 0 timeUnits = e.getTimeUnits() eaDict = KeyedList() for ea in e.getListOfEventAssignments(): ea_formula = formula_to_py(ea.getMath()) ea_formula = ea_formula.replace('or(', 'or_func(') ea_formula = ea_formula.replace('and(', 'and_func(') eaDict.set(ea.getVariable(), ea_formula) rn.addEvent(id=id, trigger=trigger, eventAssignments=eaDict, delay=delay, name=name) for ii, con in enumerate(m.getListOfConstraints()): id, name = con.getId(), con.getName() if id == '': id = 'constraint%i' % ii trigger_math = con.getMath() trigger = formula_to_py(trigger_math) if con.isSetMessage(): message = con.getMessage() else: message = None rn.addConstraint(id=id, trigger=trigger, message=message, name=name) return rn
def fromSBMLString(sbmlStr, id = None, duplicate_rxn_params=False): r = libsbml.SBMLReader() d = r.readSBMLFromString(sbmlStr) if d.getNumErrors(): message = 'libSBML reported errors in SBML file. Try running file '\ 'through the online validator: '\ 'http://www.sbml.org/Facilities/Validator . Specific errors '\ 'noted are: ' errors = [] for ii in range(d.getNumErrors()): pm = d.getError(ii) errors.append(pm.getMessage()) raise ValueError(message + '; '.join(errors)) m = d.getModel() modelId = m.getId() if (id == None) and (modelId == ''): raise ValueError('Network id not specified in SBML or passed in.') elif id is not None: modelId = id rn = Network_mod.Network(id = modelId, name = m.getName()) for f in m.getListOfFunctionDefinitions(): id, name = f.getId(), f.getName() math = f.getMath() variables = [] for ii in range(math.getNumChildren() - 1): variables.append(libsbml.formulaToString(math.getChild(ii))) math = libsbml.formulaToString(math.getRightChild()) rn.addFunctionDefinition(id, variables, math) for c in m.getListOfCompartments(): id, name = c.getId(), c.getName() size = c.getSize() isConstant = c.getConstant() rn.addCompartment(id = id, size = size, isConstant = isConstant, name = name) for s in m.getListOfSpecies(): id, name = s.getId(), s.getName() compartment = s.getCompartment() if s.isSetInitialConcentration(): iC = s.getInitialConcentration() elif s.isSetInitialAmount(): iC = s.getInitialAmount() else: iC = 1 isBC, isConstant = s.getBoundaryCondition(), s.getConstant() xml_text = s.toSBML() uniprot_ids = set([entry[1:].split('"')[0] for entry in xml_text.split('uniprot')[1:]]) rn.addSpecies(id = id, compartment = compartment, initialConcentration = iC, isConstant = isConstant, is_boundary_condition = isBC, name = name, uniprot_ids = uniprot_ids) for p in m.getListOfParameters(): parameter = createNetworkParameter(p) rn.addVariable(parameter) for rxn in m.getListOfReactions(): id, name = rxn.getId(), rxn.getName() kL = rxn.getKineticLaw() kLFormula = kL.getFormula() substitution_dict = {} # Deal with parameters defined within reactions for p in kL.getListOfParameters(): parameter = createNetworkParameter(p) # If a parameter with this name already exists, **and it has a # different value than this parameter** we rename this parameter # instance by prefixing it with the rxn name so there isn't a # clash. if parameter.id in rn.variables.keys(): logger.warn('Parameter %s appears in two different reactions ' 'in SBML file.' % parameter.id) if parameter.value != rn.variables.get(parameter.id).value or\ duplicate_rxn_params: oldId = parameter.id parameter.id = id + '_' + parameter.id substitution_dict[oldId] = parameter.id logger.warn('It has different values in the two positions ' 'so we are creating a new parameter %s.' % (parameter.id)) else: logger.warn('It has the same value in the two positions ' 'so we are only defining one parameter %s. ' 'This behavior can be changed with the option ' 'duplicate_rxn_params = True' % (parameter.id)) if parameter.id not in rn.variables.keys(): rn.addVariable(parameter) kLFormula = ExprManip.sub_for_vars(kLFormula, substitution_dict) # Assemble the stoichiometry. SBML has the annoying trait that # species can appear as both products and reactants and 'cancel out' # For each species appearing in the reaction, we build up a string # representing the stoichiometry. Then we'll simplify that string and # see whether we ended up with a float value in the end. stoichiometry = {} reactant_stoichiometry = {} product_stoichiometry = {} for reactant in rxn.getListOfReactants(): species = reactant.getSpecies() stoichiometry.setdefault(species, '0') stoich = reactant.getStoichiometryMath() stoich = stoichToString(reactant, stoich) stoichiometry[species] += '-(%s)' % stoich if species in reactant_stoichiometry: reactant_stoichiometry[species].append(stoich) else: reactant_stoichiometry[species] = [stoich] for product in rxn.getListOfProducts(): species = product.getSpecies() stoichiometry.setdefault(species, '0') stoich = product.getStoichiometryMath() stoich = stoichToString(product, stoich) stoichiometry[species] += '+(%s)' % stoich if species in product_stoichiometry: product_stoichiometry[species].append(stoich) else: product_stoichiometry[species] = [stoich] for species, stoich in stoichiometry.items(): stoich = ExprManip.simplify_expr(stoich) try: # Try converting the string to a float. stoich = float(stoich) except ValueError: pass stoichiometry[species] = stoich for modifier in rxn.getListOfModifiers(): stoichiometry.setdefault(modifier.getSpecies(), 0) rn.addReaction(id = id, stoichiometry = stoichiometry, kineticLaw = kLFormula, reactant_stoichiometry = reactant_stoichiometry, product_stoichiometry = product_stoichiometry) for ii, r in enumerate(m.getListOfRules()): if r.getTypeCode() == libsbml.SBML_ALGEBRAIC_RULE: math = libsbml.formulaToString(r.getMath()) rn.add_algebraic_rule(math) else: variable = r.getVariable() math = libsbml.formulaToString(r.getMath()) if r.getTypeCode() == libsbml.SBML_ASSIGNMENT_RULE: rn.addAssignmentRule(variable, math) elif r.getTypeCode() == libsbml.SBML_RATE_RULE: rn.addRateRule(variable, math) for ii, e in enumerate(m.getListOfEvents()): id, name = e.getId(), e.getName() if id == '': id = 'event%i' % ii try: # For libSBML 3.0 trigger_math = e.getTrigger().getMath() except AttributeError: # For older versions trigger_math = e.getTrigger() trigger = libsbml.formulaToString(trigger_math) trigger = trigger.replace('or(','or_func(') trigger = trigger.replace('and(','and_func(') if e.getDelay() is not None: try: # For libSBML 3.0 delay_math = e.getDelay().getMath() except AttributeError: # For older versions delay_math = e.getDelay() delay = libsbml.formulaToString(delay_math) else: delay = 0 timeUnits = e.getTimeUnits() eaDict = KeyedList() for ea in e.getListOfEventAssignments(): ea_formula = libsbml.formulaToString(ea.getMath()) ea_formula = ea_formula.replace('or(','or_func(') ea_formula = ea_formula.replace('and(','and_func(') eaDict.set(ea.getVariable(), ea_formula) rn.addEvent(id = id, trigger = trigger, eventAssignments = eaDict, delay = delay, name = name) for ii, con in enumerate(m.getListOfConstraints()): id, name = con.getId(), con.getName() if id == '': id = 'constraint%i' % ii trigger_math = con.getMath() trigger = libsbml.formulaToString(trigger_math) if con.isSetMessage(): message = con.getMessage() else: message = None rn.addConstraint(id = id, trigger = trigger, message = message, name = name) return rn