Example #1
0
    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
Example #2
0
    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
Example #3
0
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)    
Example #4
0
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
Example #5
0
    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)
Example #6
0
    def test_diff_expr(self):
        cases = [('x', 'x'), ('+x', 'x'), ('y', 'x'), ('x+y', 'x'),
                 ('x*y', 'x'), ('x/y', 'x'), ('x**y', 'x'), ('x**x', 'x'),
                 ('y**x', 'x'), ('acos(x)', 'x'), ('asin(x)', 'x'),
                 ('atan(x)', 'x'), ('cos(x)', 'x'), ('cosh(x)', 'x'),
                 ('exp(x)', 'x'), ('log(x)', 'x'), ('log10(x)', 'x'),
                 ('sin(x)', 'x'), ('sinh(x)', 'x'), ('sqrt(x)', 'x'),
                 ('tan(x)', 'x'), ('tanh(x)', 'x'), ('pow(x, 2)', 'x'),
                 ('pow(y, x)', 'x'), ('y**2 - 4*x*z', 'x'),
                 ('(-y + sqrt(y**2 - 4*x*z))/(2*x)', 'x'),
                 ('(-y + sqrt(y**2 - 4*x*z))/(2*x)', 'y'),
                 ('(-y + sqrt(y**2 - 4*x*z))/(2*x)', 'z'),
                 ('sqrt(y - x)', 'x'), ('f(x)', 'x'),
                 ('f(x - y*x + cos(x*z))', 'x'),
                 ('g(x - y*x + cos(x*z), y, x)', 'x'),
                 ('g(x - y*x + cos(x*z), y, x)', 'y'),
                 ('g(x - y*x + cos(x*z), y**z, x - 14*z)', 'y'),
                 ('g(x - y*x + cos(x*z), y, x)', 'y'),
                 ('g(x*y, x*y**2, y)', 'z')]

        for expr, wrt in cases:
            d = ExprManip.diff_expr(expr, wrt)
            ad = eval(d)
            fd = self._num_diff(expr, wrt, x=x, y=y, z=z)
            # We test that our numeric and analytic derivatives differ by less
            #  than 0.1%
            if ad != 0:
                assert abs(fd - ad) / (0.5 * (ad + fd)) < 1e-3
            else:
                assert ad == fd
Example #7
0
    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'
Example #8
0
    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')
Example #9
0
 def get_h(self, keep1=True):
     """
     """
     coefs = self.get_coefs()
     if not keep1: 
         coefs = butil.get_submapping(coefs, f_value=lambda s: s != '1')
     subcoefids, subcoefstrs = coefs.keys(), coefs.values()
     yids = ['%s, %s, %s'%((self.polyid,)+subcoefid) 
             for subcoefid in subcoefids]
     
     senstrs = [[exprmanip.diff_expr(subcoefstr, pid)
                 for pid in self.pids] for subcoefstr in subcoefstrs]
         
     hstr = str(subcoefstrs).replace("'", "") 
     Dhstr = str(senstrs).replace("'", "") 
             
     subs0 = self.convarvals.to_dict()
     
     def h(p):
         subs = subs0.copy()
         subs.update(dict(zip(self.pids, p)))
         return np.array(eval(hstr, subs))
     
     def Dh(p):
         subs = subs0.copy()
         subs.update(dict(zip(self.pids, p)))
         return np.array(eval(Dhstr, subs))
     
     h = predict.Predict(f=h, Df=Dh, pids=self.pids, p0=self.p0, 
                         yids=yids, frepr=butil.Series(subcoefstrs, yids),
                         Dfrepr=butil.DF(senstrs, yids, self.pids)) 
     return h
    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)
Example #11
0
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
Example #12
0
    def test_expr2Tex(self):
        lines.append(r'\section{Basic expressions}')
        lines.append(r'\begin{longtable}{rl}')
        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)',
            'sqrt(x+y-sqrt(z/x))',
        ]

        for expr in cases:
            TeXed = ExprManip.expr2TeX(expr)
            line = r'{\tt %s} & $ %s $ \\' % (expr, TeXed)
            lines.append(line)

        lines.append(r'\end{longtable}')
Example #13
0
    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 test_var_args_subs(self):
        subbed = ExprManip.sub_for_func('or_func(x,y,z)', 'or_func', '*',
                                        'a or b')
        x, y, z = True, False, False
        assert eval(subbed)
        x, y, z = False, False, False
        assert not eval(subbed)

        self.assertRaises(ValueError, ExprManip.sub_for_func, 'or_func(x,y,z)',
                          'or_func', '*', 'a + b')
Example #15
0
    def test_extract_comps(self):
        cases = [('x == 3', ['x == 3']),
                 ('x == 3 and y == 4', ['x == 3', 'y == 4']),
                 ('x < 3 and not y > 4', ['x < 3', 'y > 4']),
                 ('x < 3 + (y > 4)', ['x < (3 + (y > 4))', 'y > 4']),
                 ]

        for expr, comps in cases:
            result = ExprManip.extract_comps(expr) 
            assert result == sets.Set(comps)
Example #16
0
    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()))
Example #17
0
def get_Ex_str(net):
    """
    """
    Ex = []
    for rxnid in net.rxnids:
        ratelaw = net.rxns[rxnid].kineticLaw
        Ex_rxn = []
        for xid in net.xids:
            Ex_rxn.append(expr.diff_expr(ratelaw, xid))  # diff also simplifies
        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
Example #18
0
def get_Ep_str(net):
    """
    """
    Ep = []
    for rxnid in net.rxnids:
        ratelaw = net.rxns[rxnid].kineticLaw
        Ep_rxn = []
        for pid in net.pids:
            Ep_rxn.append(expr.diff_expr(ratelaw, pid))  # diff also simplifies
        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 test_sub_for_var(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)'),
            ('g(x, y, f(z)) != y+2 and z == y', 'z', 'y',
             '(g(x, y, f(y)) != (y + 2)) and (y == y)'),
        ]

        for expr, out_var, in_expr, answer in cases:
            subbed = ExprManip.sub_for_var(expr, out_var, in_expr)
            assert eval(answer) == eval(subbed)
Example #20
0
    def test_name_dict(self):
        name_dict = {'alpha': r'\alpha',
                   'beta': r'\beta',
                   'betarho': r'\beta\rho',
                   'chi': r'\lambda',
                   'tau': r'\tau'
                   }
        cases = ['alpha',
                 'alpha**beta',
                 'chi(betarho, tau)',
                 'sqrt(4+sqrt(alpha))',
                 ]

        for expr in cases: 
            TeXed = ExprManip.expr2TeX(expr, name_dict)
Example #21
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 test_sub_for_func(self):
        cases = [
            ('f(x)', 'f', 'y', 'y+1', 'x+1'),
            ('f(x)**2', 'f', 'y', 'y+1', '(x+1)**2'),
            ('f(g(x, y, z))**2', 'f', 'y', 'y+1', '(g(x,y,z)+1)**2'),
            ('g(f(x), y, z)**2', 'f', 'y', 'y+1', 'g(x+1,y,z)**2'),
            ('g(f(x), p[0], z)**2', 'f', 'y', 'y+1', 'g(x+1,p[0],z)**2'),
            ('g(z, y, f(x)) == y+2 and f(x) + f(y) != f(x)', 'g',
             ('x', 'y', 'z'), 'f(x + y/z)',
             '(f(z + y/f(x)) == (y + 2)) and (f(x) + f(y) != f(x))'),
        ]

        for expr, func_name, func_vars, func_expr, answer in cases:
            subbed = ExprManip.sub_for_func(expr, func_name, func_vars,
                                            func_expr)
            assert eval(answer) == eval(subbed)
Example #23
0
 def test_extract_funcs(self):
     cases = [('g(x)', [('g', 1)]), ('f(g(x))', [('f', 1), ('g', 1)]),
              ('f(g(x)/2, a, b(x, y))', [('f', 3), ('g', 1), ('b', 2)]),
              ('a + g(x)', [('g', 1)]),
              ('a + g(x) + (a + f(x))', [('f', 1), ('g', 1)]),
              ('f(g(1 + h(a))/2) + j(q**k(x)) + q.r[1] + s[1]', [('f', 1),
                                                                 ('g', 1),
                                                                 ('h', 1),
                                                                 ('j', 1),
                                                                 ('k', 1)]),
              ('(g(x) + 2)**f(y)', [('f', 1), ('g', 1)]),
              ('g(x)**f(y)', [('f', 1), ('g', 1)]),
              ('g(x) > f(y)', [('f', 1), ('g', 1)]),
              ('g(x) and f(y)', [('f', 1), ('g', 1)]),
              ('g(x) and not f(y)', [('f', 1), ('g', 1)])]
     for expr, funcs in cases:
         assert ExprManip.extract_funcs(expr) == set(funcs)
Example #24
0
 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
Example #25
0
    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()))
Example #26
0
    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)
Example #27
0
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 test_sub_for_comps(self):
     cases = [
         ('not x < 3 and True', {
             'x < 3': 'True'
         }, False),
         ('not x < 3 and x < 3', {
             'x < 3': 'True'
         }, False),
         ('x < 3 and x < 3', {
             'x < 3': 'True'
         }, True),
         ('x < 3 and y > 4', {
             'x < 3': 'True',
             'y > 4': 'False'
         }, False),
         ('x < 3 and not y > 4', {
             'x < 3': 'True',
             'y > 4': 'False'
         }, True),
     ]
     for expr, mapping, result in cases:
         subbed = ExprManip.sub_for_comps(expr, mapping)
         assert eval(subbed) == result
Example #29
0
    def replace_varid(self, varid_old, varid_new, only_expr=False):
        """Change id of reaction, species, or parameter.
        
        :param only_expr: bool; if True, only replace varid in expressions 
            such as reaction ratelaws or assignment rules but not variable ids; 
            useful when varid_new == 'varid_old * r'
        """
        if only_expr:
            f = lambda varid: varid
        else:
            f = lambda varid: varid_new if varid == varid_old else varid

        netid_new = f(self.id)
        net_new = self.__class__(netid_new)

        for var in self.variables:
            var_new = copy.deepcopy(var)
            var_new.id = f(var.id)
            net_new.variables.set(var_new.id, var_new)

        for rxn in self.reactions:
            rxn_new = copy.deepcopy(rxn)
            rxn_new.id = f(rxn.id)
            rxn_new.stoichiometry = OD(
                zip(map(f, rxn.stoichiometry.keys()),
                    rxn.stoichiometry.values()))
            try:
                rxn_new.reactant_stoichiometry =\
                    OD(zip(map(f, rxn.reactant_stoichiometry.keys()),
                           rxn.reactant_stoichiometry.values()))
                rxn_new.product_stoichiometry =\
                    OD(zip(map(f, rxn.product_stoichiometry.keys()),
                           rxn.product_stoichiometry.values()))
            except AttributeError:  # some rxns have no reactant/product stoich
                pass

            rxn_new.parameters = set(map(f, rxn.parameters))
            rxn_new.kineticLaw = exprmanip.sub_for_var(rxn.kineticLaw,
                                                       varid_old, varid_new)
            net_new.reactions.set(rxn_new.id, rxn_new)

        for varid, rule in self.assignmentRules.items():
            net_new.assignmentRules.set(
                f(varid), exprmanip.sub_for_var(rule, varid_old, varid_new))

        for varid, rule in self.algebraicRules.items():
            net_new.algebraicRules.set(
                exprmanip.sub_for_var(varid, varid_old, varid_new),
                exprmanip.sub_for_var(rule, varid_old, varid_new))

        for varid, rule in self.rateRules.items():
            net_new.rateRules.set(
                f(varid), exprmanip.sub_for_var(rule, varid_old, varid_new))

        for eid, event in self.events.items():
            eid_new = f(eid)
            trigger_new = exprmanip.sub_for_var(event.trigger, varid_old,
                                                varid_new)
            assignments_new = OD(
                zip(map(f, event.event_assignments.keys()),
                    event.event_assignments.values()))
            net_new.add_event(eid_new, trigger_new, assignments_new)

        net_new.functionDefinitions = self.functionDefinitions.copy()
        for fid, f in net_new.functionDefinitions.items():
            fstr = 'lambda %s: %s' % (','.join(f.variables), f.math)
            net_new.namespace[fid] = eval(fstr, net_new.namespace)

        # _makeCrossReferences will take care of at least the following
        # attributes:
        # assignedVars, constantVars, optimizableVars, dynamicVars,
        # algebraicVars
        net_new._makeCrossReferences()
        return net_new
Example #30
0
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
Example #31
0
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
Example #32
0
    def to_tex(self, d_tex=None, eqn=True, 
               filepath='', landscape=True, margin=2):
        """
        
        Input:
            d_tex: a mapping...
        """
        
        _repl = exprmanip.sub_for_vars
        _raisepower = lambda tu: tu[0] ** tu[1]
        
        def _2tex_pid(pid):
            if pid.startswith('Vf_') or pid.startswith('Vb_'):
                pid = '%s^{%s}' % tuple(pid.split('_'))
            if pid.count('_') == 2:
                pid = '%s^{%s}_{%s}' % tuple(pid.split('_'))
            return pid
        d_tex = dict(zip(self.pids, [_2tex_pid(pid) for pid in self.pids]) +\
                     d_tex.items())
        
        _2tex = lambda sympyexpr:\
            sympy.latex(sympyexpr, mode='plain', long_frac_ratio=10, mul_symbol='dot',
                        symbol_names=butil.chkeys(d_tex, lambda k: sympy.symbols(k))) 
        _rm1pt0 = lambda expr: re.sub('(?<![0-9])1.0\s*\\\cdot', '', expr)

        
        lines = []
        lines.append(r'\documentclass{article}') 
        lines.append(r'\usepackage{amsmath,fullpage,longtable,array,calc,mathastext,breqn,xcolor}') 
        if landscape == True:
            lines.append(r'\usepackage[a4paper,landscape,margin=1in]{geometry}')
        else:
            lines.append(r'\usepackage[a4paper,margin=%fin]{geometry}'%margin)
        lines.append(r'\begin{document}')
        
        coefs_r = []
        yids = []
        for poly in self:
            termstrs = []
            
            leadingcoef_r = sympy.Poly(poly.coeffs()[0], r).coeffs()[0]
            
            for monom_X, coef_X in poly.terms():
                coef_X = sympy.simplify(coef_X, ratio=1)
                poly_r = sympy.Poly(coef_X, r)
                
                coefs_r.extend([coef_r/leadingcoef_r for coef_r in poly_r.coeffs()])
                
                monom_X = sympy.prod(map(_raisepower, zip(X, monom_X)))
                monomstr_X = _2tex(monom_X)
                if monomstr_X == '1':
                    monomstr_X = ''
                monomstr_X = '\\textcolor{red}{%s}' % monomstr_X
                
                termstrs_r = []
                for monom_r, coef_r in poly_r.terms():
                    
                    coefstr_r = _rm1pt0(_2tex(coef_r))
                    if coef_r.is_Add:
                        coefstr_r = '\left('+ coefstr_r +'\\right)'
                    
                    monom_r = sympy.prod(map(_raisepower, zip(r, monom_r)))
                    monomstr_r = _2tex(monom_r)
                    if monomstr_r == '1':
                        monomstr_r = ''
                    monomstr_r = '\\textcolor{blue}{%s}' % monomstr_r
                        
                    termstrs_r.append(coefstr_r + '\t' + monomstr_r)
                    coefstr_X = '\\left(' + '+'.join(termstrs_r) + '\\right)'
                    
                    yids.append((ixid, str(monom_X), str(monom_r)))
                
                termstrs.append(coefstr_X + '\t' + monomstr_X)
        
            linestr = '\\begin{dmath} \n' + '+'.join(termstrs) + '=0\n\end{dmath} \n\n'
            lines.append(linestr.replace('+-', '-'))
        
        lines.append('\\end{document}') 
        
        if filepath:
            fh = file(filepath, 'w') 
            fh.write(os.linesep.join(lines)) 
            fh.close()
        
        coefs_r = [_rm1pt0(str(coef)) for coef in coefs_r]
        
        str_h = str(coefs_r).replace("'", "")
        str_Dh = str([[exprmanip.diff_expr(coef, pid) for pid in self.pids] 
                      for coef in coefs_r]).replace("'", "")
        
        def h(p):
            self.update(p=p)
            return np.array(eval(str_h, self.varvals.to_dict()))
        
        def Dh(p):
            self.update(p=p)
            return np.array(eval(str_Dh, self.varvals.to_dict()))
        
        coefs = predict.Predict(f=h, Df=Dh, pids=self.pids, p0=self.p0, 
                                yids=yids, funcform=coefs_r) 
        
        return coefs
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