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 _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 test_sub_for_vars(self): cases = [ ('x', { 'x': 'y' }, 'y'), ('x + 1', { 'x': 'y' }, 'y + 1'), ('f(x)**2 - y + z', { 'x': 'y*z/(x-2)' }, 'f(y*z/(x-2))**2 - y + z'), ('x**2', { 'x': 'y+2' }, '(y+2)**2'), ('p[0]**x', { 'x': 'y+2' }, 'p[0]**(y+2)'), # In these cases substituting one-by-one will fail ('x*y', { 'x': 'y', 'y': 'z' }, 'y*z'), ('z*y', { 'z': 'y', 'y': 'z' }, 'y*z'), ] for expr, mapping, answer in cases: subbed = ExprManip.sub_for_vars(expr, mapping) assert eval(answer) == eval(subbed)
def doKwargsSubstitution(self, kwargs): oldStoichiometry = self.stoichiometry self.stoichiometry = {} for base in oldStoichiometry: self.stoichiometry[kwargs[base]] = oldStoichiometry[base] self.kineticLaw = ExprManip.sub_for_vars(self.kineticLaw, kwargs)
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 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 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 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