Пример #1
0
def test_simres_dataframe():
    """ Test SimulationResult.dataframe() """

    tspan1 = np.linspace(0, 100, 100)
    tspan2 = np.linspace(50, 100, 50)
    tspan3 = np.linspace(100, 150, 100)
    model = tyson_oscillator.model
    sim = ScipyOdeSimulator(model, integrator='lsoda')
    simres1 = sim.run(tspan=tspan1)
    # Check retrieving a single simulation dataframe
    df_single = simres1.dataframe

    # Generate multiple trajectories
    trajectories1 = simres1.species
    trajectories2 = sim.run(tspan=tspan2).species
    trajectories3 = sim.run(tspan=tspan3).species

    # Try a simulation result with two different tspan lengths
    sim = ScipyOdeSimulator(model, param_values={'k6' : [1.,1.]}, integrator='lsoda')
    simres = SimulationResult(sim, [tspan1, tspan2], [trajectories1, trajectories2])
    df = simres.dataframe

    assert df.shape == (len(tspan1) + len(tspan2),
                        len(model.species) + len(model.observables))

    # Next try a simulation result with two identical tspan lengths, stacked
    # into a single 3D array of trajectories
    simres2 = SimulationResult(sim, [tspan1, tspan3],
                               np.stack([trajectories1, trajectories3]))
    df2 = simres2.dataframe

    assert df2.shape == (len(tspan1) + len(tspan3),
                         len(model.species) + len(model.observables))
Пример #2
0
def parameter_sweep(model, sigma, ns):
    generate_equations(model)
    logp = [numpy.log10(p.value) for p in model.parameters]
    ts = numpy.linspace(0, 20 * 3600, 20 * 60)
    solver = Solver(model, ts)
    pf.set_fig_params()
    plt.figure(figsize=(1.8, 1), dpi=300)
    for i in range(ns):
        psample = sample_params(logp, 0.05)
        res = solver.run(param_values=psample)
        signal = res.observables['p53_active']
        plt.plot(signal, color=(0.7, 0.7, 0.7), alpha=0.3)
    # Highlighted
    colors = ['g', 'y', 'c']
    for c in colors:
        psample = sample_params(logp, 0.05)
        res = solver.run(param_values=psample)
        signal = res.observables['p53_active']
        plt.plot(signal, c)

    # Nominal
    solver = Solver(model, ts)
    res = solver.run()
    signal = res.observables['p53_active']
    plt.plot(signal, 'r')

    plt.xticks([])
    plt.xlabel('Time (a.u.)', fontsize=7)
    plt.ylabel('Active p53', fontsize=7)
    plt.yticks([])
    plt.ylim(ymin=0)
    pf.format_axis(plt.gca())
    plt.savefig(model.name + '_sample.pdf')
Пример #3
0
def parameter_sweep(model, sigma, ns):
    generate_equations(model)
    logp = [numpy.log10(p.value) for p in model.parameters]
    ts = numpy.linspace(0, 20*3600, 20*60)
    solver = Solver(model, ts)
    pf.set_fig_params()
    plt.figure(figsize=(1.8, 1), dpi=300)
    for i in range(ns):
        psample = sample_params(logp, 0.05)
        res = solver.run(param_values=psample)
        signal = res.observables['p53_active']
        plt.plot(signal, color=(0.7, 0.7, 0.7), alpha=0.3)
    # Highlighted
    colors = ['g', 'y', 'c']
    for c in colors:
        psample = sample_params(logp, 0.05)
        res = solver.run(param_values=psample)
        signal = res.observables['p53_active']
        plt.plot(signal, c)

    # Nominal
    solver = Solver(model, ts)
    res = solver.run()
    signal = res.observables['p53_active']
    plt.plot(signal, 'r')

    plt.xticks([])
    plt.xlabel('Time (a.u.)', fontsize=7)
    plt.ylabel('Active p53', fontsize=7)
    plt.yticks([])
    plt.ylim(ymin=0)
    pf.format_axis(plt.gca())
    plt.savefig(model.name + '_sample.pdf')
Пример #4
0
def test_simres_dataframe():
    """ Test SimulationResult.dataframe() """

    tspan1 = np.linspace(0, 100, 100)
    tspan2 = np.linspace(50, 100, 50)
    tspan3 = np.linspace(100, 150, 100)
    model = tyson_oscillator.model
    sim = ScipyOdeSimulator(model, integrator='lsoda')
    simres1 = sim.run(tspan=tspan1)
    # Check retrieving a single simulation dataframe
    df_single = simres1.dataframe

    # Generate multiple trajectories
    trajectories1 = simres1.species
    trajectories2 = sim.run(tspan=tspan2).species
    trajectories3 = sim.run(tspan=tspan3).species

    # Try a simulation result with two different tspan lengths
    sim = ScipyOdeSimulator(model, param_values={'k6' : [1.,1.]}, integrator='lsoda')
    simres = SimulationResult(sim, [tspan1, tspan2], [trajectories1, trajectories2])
    df = simres.dataframe

    assert df.shape == (len(tspan1) + len(tspan2),
                        len(model.species) + len(model.observables))

    # Next try a simulation result with two identical tspan lengths, stacked
    # into a single 3D array of trajectories
    simres2 = SimulationResult(sim, [tspan1, tspan3],
                               np.stack([trajectories1, trajectories3]))
    df2 = simres2.dataframe

    assert df2.shape == (len(tspan1) + len(tspan3),
                         len(model.species) + len(model.observables))
Пример #5
0
 def test_lsoda_jac_solver_run(self):
     """Test lsoda and analytic jacobian."""
     solver_lsoda_jac = ScipyOdeSimulator(self.model,
                                          tspan=self.time,
                                          integrator='lsoda',
                                          use_analytic_jacobian=True)
     solver_lsoda_jac.run()
Пример #6
0
    def test_vode_jac_solver_run(self):
        """Test vode and analytic jacobian."""
        args = {
            'model': self.model,
            'tspan': self.time,
            'integrator': 'vode',
            'use_analytic_jacobian': True
        }
        solver_vode_jac = ScipyOdeSimulator(**args)
        res1 = solver_vode_jac.run()
        # Test again with analytic jacobian
        if solver_vode_jac._compiler != 'python':
            sim = ScipyOdeSimulator(compiler='python', **args)
            simres = sim.run()
            assert simres.species.shape[0] == args['tspan'].shape[0]
            assert np.allclose(res1.dataframe, simres.dataframe)

        # Test again using theano
        solver = ScipyOdeSimulator(compiler='theano', **args)
        simres = solver.run()
        assert np.allclose(res1.dataframe, simres.dataframe)

        # Test again using cython (if original was not cython)
        if solver_vode_jac._compiler != 'cython':
            solver = ScipyOdeSimulator(compiler='cython', **args)
            simres = solver.run()
            assert np.allclose(res1.dataframe, simres.dataframe)
Пример #7
0
class Earm10ODESuite(object):
    def setup(self):
        self.nsims = 100
        self.timer = timeit.default_timer
        self.model = earm_1_0.model
        self.model.reset_equations()
        self.parameter_set = np.repeat(
            [[p.value for p in self.model.parameters]], self.nsims, axis=0)
        integrator_options_common = {
            'model': self.model,
            'tspan': np.linspace(0, 1000, 101),
            'atol': 1e-6,
            'rtol': 1e-6,
            'mxsteps': 20000,
            'param_values': self.parameter_set
        }

        self.sim_lsoda = ScipyOdeSimulator(integrator='lsoda',
                                           **integrator_options_common)
        self.sim_cupsoda = CupSodaSimulator(**integrator_options_common)

    def time_scipy_lsoda(self):
        self.sim_lsoda.run()

    def time_cupsoda(self):
        self.sim_cupsoda.run()
Пример #8
0
def test_earm_integration():
    """Ensure earm_1_0 model simulates."""
    t = np.linspace(0, 1e3)
    sim = ScipyOdeSimulator(earm_1_0.model, tspan=t, compiler="python")
    sim.run()
    # Also run with cython compiler if available.
    if CythonRhsBuilder.check_safe():
        ScipyOdeSimulator(earm_1_0.model, tspan=t, compiler="cython").run()
Пример #9
0
def test_earm_integration():
    """Ensure earm_1_0 model simulates."""
    t = np.linspace(0, 1e3)
    # Run with or without inline
    sim = ScipyOdeSimulator(earm_1_0.model, tspan=t)
    sim.run()
    if sim._compiler != 'python':
        # Also run without inline
        ScipyOdeSimulator(earm_1_0.model, tspan=t, compiler='python').run()
Пример #10
0
def test_earm_integration():
    """Ensure earm_1_0 model simulates."""
    t = np.linspace(0, 1e3)
    # Run with or without inline
    sim = ScipyOdeSimulator(earm_1_0.model, tspan=t)
    sim.run()
    if sim._compiler != 'python':
        # Also run without inline
        ScipyOdeSimulator(earm_1_0.model, tspan=t, compiler='python').run()
Пример #11
0
 def _check_parallel(self, integrator, use_analytic_jacobian):
     initials = [[10, 20, 30], [50, 60, 70]]
     sim = ScipyOdeSimulator(self.model,
                             self.sim.tspan,
                             initials=initials,
                             integrator=integrator,
                             use_analytic_jacobian=use_analytic_jacobian)
     base_res = sim.run(initials=initials)
     res = sim.run(initials=initials, num_processors=2)
     assert np.allclose(res.species, base_res.species)
Пример #12
0
def test_earm_integration():
    """Ensure earm_1_0 model simulates."""
    t = np.linspace(0, 1e3)
    # Run with or without inline
    sim = ScipyOdeSimulator(earm_1_0.model, tspan=t)
    sim.run()
    if ScipyOdeSimulator._use_inline:
        # Also run without inline
        ScipyOdeSimulator._use_inline = False
        ScipyOdeSimulator(earm_1_0.model, tspan=t).run()
        ScipyOdeSimulator._use_inline = True
Пример #13
0
def test_robertson_integration():
    """Ensure robertson model simulates."""
    t = np.linspace(0, 100)
    sim = ScipyOdeSimulator(robertson.model, tspan=t, compiler="python")
    simres = sim.run()
    assert simres.species.shape[0] == t.shape[0]
    # Also run with cython compiler if available.
    if CythonRhsBuilder.check_safe():
        sim = ScipyOdeSimulator(robertson.model, tspan=t, compiler="cython")
        simres = sim.run()
        assert simres.species.shape[0] == t.shape[0]
Пример #14
0
def test_earm_integration():
    """Ensure earm_1_0 model simulates."""
    t = np.linspace(0, 1e3)
    # Run with or without inline
    sim = ScipyOdeSimulator(earm_1_0.model, tspan=t)
    sim.run()
    if ScipyOdeSimulator._use_inline:
        # Also run without inline
        ScipyOdeSimulator._use_inline = False
        ScipyOdeSimulator(earm_1_0.model, tspan=t).run()
        ScipyOdeSimulator._use_inline = True
Пример #15
0
def test_robertson_integration():
    """Ensure robertson model simulates."""
    t = np.linspace(0, 100)
    # Run with or without inline
    sim = ScipyOdeSimulator(robertson.model)
    simres = sim.run(tspan=t)
    assert simres.species.shape[0] == t.shape[0]
    if sim._compiler != 'python':
        # Also run without inline
        sim = ScipyOdeSimulator(robertson.model, tspan=t, compiler='python')
        simres = sim.run()
        assert simres.species.shape[0] == t.shape[0]
Пример #16
0
def test_robertson_integration():
    """Ensure robertson model simulates."""
    t = np.linspace(0, 100)
    # Run with or without inline
    sim = ScipyOdeSimulator(robertson.model)
    simres = sim.run(tspan=t)
    assert simres.species.shape[0] == t.shape[0]
    if sim._compiler != 'python':
        # Also run without inline
        sim = ScipyOdeSimulator(robertson.model, tspan=t, compiler='python')
        simres = sim.run()
        assert simres.species.shape[0] == t.shape[0]
Пример #17
0
def test_robertson_integration():
    """Ensure robertson model simulates."""
    t = np.linspace(0, 100)
    # Run with or without inline
    sim = ScipyOdeSimulator(robertson.model)
    simres = sim.run(tspan=t)
    assert simres.species.shape[0] == t.shape[0]
    if ScipyOdeSimulator._use_inline:
        # Also run without inline
        ScipyOdeSimulator._use_inline = False
        sim = ScipyOdeSimulator(robertson.model, tspan=t)
        simres = sim.run()
        assert simres.species.shape[0] == t.shape[0]
        ScipyOdeSimulator._use_inline = True
Пример #18
0
def test_robertson_integration():
    """Ensure robertson model simulates."""
    t = np.linspace(0, 100)
    # Run with or without inline
    sim = ScipyOdeSimulator(robertson.model)
    simres = sim.run(tspan=t)
    assert simres.species.shape[0] == t.shape[0]
    if ScipyOdeSimulator._use_inline:
        # Also run without inline
        ScipyOdeSimulator._use_inline = False
        sim = ScipyOdeSimulator(robertson.model, tspan=t)
        simres = sim.run()
        assert simres.species.shape[0] == t.shape[0]
        ScipyOdeSimulator._use_inline = True
Пример #19
0
class TestScipyOdeCompilerTests(TestScipySimulatorBase):
    """Test vode and analytic jacobian with different compiler backends"""
    def setUp(self):
        super(TestScipyOdeCompilerTests, self).setUp()
        self.args = {'model': self.model,
                     'tspan': self.time,
                     'integrator': 'vode',
                     'use_analytic_jacobian': True}

        self.python_sim = ScipyOdeSimulator(compiler='python', **self.args)
        self.python_res = self.python_sim.run()

    def test_cython(self):
        sim = ScipyOdeSimulator(compiler='cython', **self.args)
        simres = sim.run()
        assert simres.species.shape[0] == self.args['tspan'].shape[0]
        assert np.allclose(self.python_res.dataframe, simres.dataframe)

    def test_theano(self):
        sim = ScipyOdeSimulator(compiler='theano', **self.args)
        simres = sim.run()
        assert simres.species.shape[0] == self.args['tspan'].shape[0]
        assert np.allclose(self.python_res.dataframe, simres.dataframe)

    @unittest.skipIf(sys.version_info.major >= 3, 'weave not available for '
                                                  'Python 3')
    def test_weave(self):
        sim = ScipyOdeSimulator(compiler='weave', **self.args)
        simres = sim.run()
        assert simres.species.shape[0] == self.args['tspan'].shape[0]
        assert np.allclose(self.python_res.dataframe, simres.dataframe)
Пример #20
0
class TestScipyOdeCompilerTests(TestScipySimulatorBase):
    """Test vode and analytic jacobian with different compiler backends"""
    def setUp(self):
        super(TestScipyOdeCompilerTests, self).setUp()
        self.args = {'model': self.model,
                     'tspan': self.time,
                     'integrator': 'vode',
                     'use_analytic_jacobian': True}

        self.python_sim = ScipyOdeSimulator(compiler='python', **self.args)
        self.python_res = self.python_sim.run()

    def test_cython(self):
        sim = ScipyOdeSimulator(compiler='cython', **self.args)
        simres = sim.run()
        assert simres.species.shape[0] == self.args['tspan'].shape[0]
        assert np.allclose(self.python_res.dataframe, simres.dataframe)

    def test_theano(self):
        sim = ScipyOdeSimulator(compiler='theano', **self.args)
        simres = sim.run()
        assert simres.species.shape[0] == self.args['tspan'].shape[0]
        assert np.allclose(self.python_res.dataframe, simres.dataframe)

    @unittest.skipIf(sys.version_info.major >= 3, 'weave not available for '
                                                  'Python 3')
    def test_weave(self):
        sim = ScipyOdeSimulator(compiler='weave', **self.args)
        simres = sim.run()
        assert simres.species.shape[0] == self.args['tspan'].shape[0]
        assert np.allclose(self.python_res.dataframe, simres.dataframe)
Пример #21
0
 def test_unicode_obsname_nonascii():
     """Ensure non-ascii unicode observable names error in python 2."""
     t = np.linspace(0, 100)
     rob_copy = copy.deepcopy(robertson.model)
     rob_copy.observables[0].name = u'A_total\u1234'
     sim = ScipyOdeSimulator(rob_copy)
     simres = sim.run(tspan=t)
Пример #22
0
 def test_unicode_obsname_nonascii():
     """Ensure non-ascii unicode observable names error in python 2."""
     t = np.linspace(0, 100)
     rob_copy = copy.deepcopy(robertson.model)
     rob_copy.observables[0].name = u'A_total\u1234'
     sim = ScipyOdeSimulator(rob_copy)
     simres = sim.run(tspan=t)
Пример #23
0
def test_integrate_with_expression():
    """Ensure a model with Expressions simulates."""

    Monomer('s1')
    Monomer('s9')
    Monomer('s16')
    Monomer('s20')

    # Parameters should be able to contain s(\d+) without error
    Parameter('ks0', 2e-5)
    Parameter('ka20', 1e5)

    Initial(s9(), Parameter('s9_0', 10000))

    Observable('s1_obs', s1())
    Observable('s9_obs', s9())
    Observable('s16_obs', s16())
    Observable('s20_obs', s20())

    Expression('keff', (ks0 * ka20) / (ka20 + s9_obs))

    Rule('R1', None >> s16(), ks0)
    Rule('R2', None >> s20(), ks0)
    Rule('R3', s16() + s20() >> s16() + s1(), keff)

    time = np.linspace(0, 40)
    sim = ScipyOdeSimulator(model, tspan=time)
    simres = sim.run()
    keff_vals = simres.expressions['keff']
    assert len(keff_vals) == len(time)
    assert np.allclose(keff_vals, 1.8181818181818182e-05)
Пример #24
0
def test_integrate_with_expression():
    """Ensure a model with Expressions simulates."""

    Monomer('s1')
    Monomer('s9')
    Monomer('s16')
    Monomer('s20')

    # Parameters should be able to contain s(\d+) without error
    Parameter('ks0',2e-5)
    Parameter('ka20', 1e5)

    Initial(s9(), Parameter('s9_0', 10000))

    Observable('s1_obs', s1())
    Observable('s9_obs', s9())
    Observable('s16_obs', s16())
    Observable('s20_obs', s20())

    Expression('keff', (ks0*ka20)/(ka20+s9_obs))

    Rule('R1', None >> s16(), ks0)
    Rule('R2', None >> s20(), ks0)
    Rule('R3', s16() + s20() >> s16() + s1(), keff)

    time = np.linspace(0, 40)
    sim = ScipyOdeSimulator(model, tspan=time)
    simres = sim.run()
    keff_vals = simres.expressions['keff']
    assert len(keff_vals) == len(time)
    assert np.allclose(keff_vals, 1.8181818181818182e-05)
Пример #25
0
def param_sweep(param, low, high, outputs):
    sim = ScipyOdeSimulator(m.model, te)
    results = []
    params = {'k1': 0.03, 'k2': 10000}
    for k in np.linspace(low, high, 10):
        params['k3'] = k3
        result = sim.run(param_values=params)
        results.append(result)
Пример #26
0
def test_unicode_obsname_ascii():
    """Ensure ascii-convetible unicode observable names are handled."""
    t = np.linspace(0, 100)
    rob_copy = copy.deepcopy(robertson.model)
    rob_copy.observables[0].name = u'A_total'
    sim = ScipyOdeSimulator(rob_copy)
    simres = sim.run(tspan=t)
    simres.all
    simres.dataframe
Пример #27
0
 def test_unicode_exprname_nonascii():
     """Ensure non-ascii unicode expression names error in python 2."""
     t = np.linspace(0, 100)
     rob_copy = copy.deepcopy(robertson.model)
     ab = rob_copy.observables['A_total'] + rob_copy.observables['B_total']
     expr = Expression(u'A_plus_B\u1234', ab, _export=False)
     rob_copy.add_component(expr)
     sim = ScipyOdeSimulator(rob_copy)
     simres = sim.run(tspan=t)
Пример #28
0
def test_unicode_obsname_ascii():
    """Ensure ascii-convetible unicode observable names are handled."""
    t = np.linspace(0, 100)
    rob_copy = copy.deepcopy(robertson.model)
    rob_copy.observables[0].name = u'A_total'
    sim = ScipyOdeSimulator(rob_copy)
    simres = sim.run(tspan=t)
    simres.all
    simres.dataframe
Пример #29
0
 def test_unicode_exprname_nonascii():
     """Ensure non-ascii unicode expression names error in python 2."""
     t = np.linspace(0, 100)
     rob_copy = copy.deepcopy(robertson.model)
     ab = rob_copy.observables['A_total'] + rob_copy.observables['B_total']
     expr = Expression(u'A_plus_B\u1234', ab, _export=False)
     rob_copy.add_component(expr)
     sim = ScipyOdeSimulator(rob_copy)
     simres = sim.run(tspan=t)
Пример #30
0
def test_unicode_exprname_ascii():
    """Ensure ascii-convetible unicode expression names are handled."""
    t = np.linspace(0, 100)
    rob_copy = copy.deepcopy(robertson.model)
    ab = rob_copy.observables['A_total'] + rob_copy.observables['B_total']
    expr = Expression(u'A_plus_B', ab, _export=False)
    rob_copy.add_component(expr)
    sim = ScipyOdeSimulator(rob_copy)
    simres = sim.run(tspan=t)
    simres.all
    simres.dataframe
Пример #31
0
def test_unicode_exprname_ascii():
    """Ensure ascii-convetible unicode expression names are handled."""
    t = np.linspace(0, 100)
    rob_copy = copy.deepcopy(robertson.model)
    ab = rob_copy.observables['A_total'] + rob_copy.observables['B_total']
    expr = Expression(u'A_plus_B', ab, _export=False)
    rob_copy.add_component(expr)
    sim = ScipyOdeSimulator(rob_copy)
    simres = sim.run(tspan=t)
    simres.all
    simres.dataframe
Пример #32
0
class Earm10ODESuite(object):
    def setup(self):
        self.nsims = 100
        self.timer = timeit.default_timer
        self.model = earm_1_0.model
        self.model.reset_equations()
        self.parameter_set = np.repeat(
            [[p.value for p in self.model.parameters]], self.nsims, axis=0)
        integrator_options_common = {
            'model': self.model,
            'tspan': np.linspace(0, 20000, 101),
            'param_values': self.parameter_set
        }

        self.sim_lsoda = ScipyOdeSimulator(
            integrator='lsoda',
            compiler='cython',
            integrator_options={'atol': 1e-6, 'rtol': 1e-6, 'mxstep': 20000},
            **integrator_options_common
        )
        self.sim_lsoda_no_compiler_directives = ScipyOdeSimulator(
            integrator='lsoda',
            compiler='cython',
            cython_directives={},
            integrator_options={'atol': 1e-6, 'rtol': 1e-6, 'mxstep': 20000},
            **integrator_options_common
        )

        self.sim_cupsoda = CupSodaSimulator(
            integrator_options={'atol': 1e-6, 'rtol': 1e-6, 'max_steps': 20000},
            **integrator_options_common
        )

    def time_scipy_lsoda(self):
        self.sim_lsoda.run()

    def time_scipy_lsoda_no_compiler_directives(self):
        self.sim_lsoda_no_compiler_directives.run()

    def time_cupsoda(self):
        self.sim_cupsoda.run()
Пример #33
0
    def test_vode_jac_solver_run(self):
        """Test vode and analytic jacobian."""
        args = {
            'model': self.model,
            'tspan': self.time,
            'integrator': 'vode',
            'use_analytic_jacobian': True
        }
        solver_vode_jac = ScipyOdeSimulator(**args)
        res1 = solver_vode_jac.run()
        # Test again with analytic jacobian
        if ScipyOdeSimulator._use_inline:
            ScipyOdeSimulator._use_inline = False
            sim = ScipyOdeSimulator(**args)
            simres = sim.run()
            assert simres.species.shape[0] == args['tspan'].shape[0]
            assert np.allclose(res1.dataframe, simres.dataframe)
            ScipyOdeSimulator._use_inline = True

        # Test again using theano
        solver = ScipyOdeSimulator(use_theano=True, **args)
        simres = solver.run()
        assert np.allclose(res1.dataframe, simres.dataframe)
Пример #34
0
def plot_arrestin_noarrestin_ppjnk3():
    """
    Plot ppJNK3 activation with and withou arrestin
    Returns
    -------

    """
    # Pre-equilibration
    exp_data = pd.read_csv('../data/exp_data_3min.csv')
    tspan = np.linspace(0, exp_data['Time (secs)'].values[-1], 181)
    solver = ScipyOdeSimulator(model, tspan=tspan)

    pars_arr = np.copy(par_set_calibrated)
    pars_noarr = np.copy(par_set_calibrated)

    # Pre-equilibration
    time_eq = np.linspace(0, 100, 100)
    pars_arr_eq = np.copy(par_set_calibrated)
    pars_noarr_eq = np.copy(par_set_calibrated)

    pars_noarr_eq[arrestin_idx] = 0
    pars_noarr_eq[jnk3_initial_idxs] = [0.5958, 0, 0.0042]

    all_pars = np.stack((pars_arr_eq, pars_noarr_eq))
    all_pars[:,
             kcat_idx] = 0  # Setting catalytic reactions to zero for pre-equilibration
    eq_conc = pre_equilibration(model, time_eq, all_pars)[1]

    # Simulating models with initials from pre-equilibration and parameters for condition with/without arrestin
    sim = solver.run(param_values=[pars_arr, pars_noarr], initials=eq_conc).all

    print((sim[0]['all_jnk3'][-1]) / (sim[1]['all_jnk3'][-1]))
    print(sim[0]['all_jnk3'][-1], sim[1]['all_jnk3'][-1])

    plt.plot(tspan,
             sim[0]['all_jnk3'],
             color='r',
             label='ppJNK3 with Arrestin-3')
    plt.plot(tspan,
             sim[1]['all_jnk3'],
             color='k',
             label='ppJNK3 no Arrestin-3')
    plt.xlabel('Time (s)')
    plt.ylabel(r' Normalized Concentration')
    plt.legend()
    plt.savefig('arrestin_noarrestin_ppjnk3.pdf',
                format='pdf',
                bbox_inches='tight')
Пример #35
0
class TestScipyOdeCompilerTests(TestScipySimulatorBase):
    """Test vode and analytic jacobian with different compiler backends"""
    def setUp(self):
        super(TestScipyOdeCompilerTests, self).setUp()
        self.args = {'model': self.model,
                     'tspan': self.time,
                     'integrator': 'vode',
                     'use_analytic_jacobian': True}

        self.python_sim = ScipyOdeSimulator(compiler='python', **self.args)
        self.python_res = self.python_sim.run()

    def test_cython(self):
        sim = ScipyOdeSimulator(compiler='cython', **self.args)
        simres = sim.run()
        assert simres.species.shape[0] == self.args['tspan'].shape[0]
        assert np.allclose(self.python_res.dataframe, simres.dataframe)
Пример #36
0
class TestSimulationResultEarm13(object):
    def setUp(self):
        self.model = earm_1_3.model
        self.tspan = np.linspace(0, 100, 101)
        self.sim = ScipyOdeSimulator(self.model, tspan=self.tspan)
        self.simres = self.sim.run()

    @raises(ValueError)
    def test_dynamic_observable_nonpattern(self):
        self.simres.observable('cSmac')

    @raises(ValueError)
    def test_match_nonexistent_pattern(self):
        m = self.model.monomers
        self.simres.observable(m.cSmac() % m.Bid())

    def test_on_demand_observable(self):
        m = self.model.monomers
        assert isinstance(self.simres.observable(m.cSmac()), pd.Series)
Пример #37
0
class TestSimulationResultEarm13(object):
    def setUp(self):
        self.model = earm_1_3.model
        self.tspan = np.linspace(0, 100, 101)
        self.sim = ScipyOdeSimulator(self.model, tspan=self.tspan)
        self.simres = self.sim.run()

    @raises(ValueError)
    def test_dynamic_observable_nonpattern(self):
        self.simres.observable('cSmac')

    @raises(ValueError)
    def test_match_nonexistent_pattern(self):
        m = self.model.monomers
        self.simres.observable(m.cSmac() % m.Bid())

    def test_on_demand_observable(self):
        m = self.model.monomers
        assert isinstance(self.simres.observable(m.cSmac()), pd.Series)
Пример #38
0
def test_model(simbio_model, pysb_model):
    """Run models with SimBio and PySB, and compare results at each timepoint."""

    t = np.linspace(0, 20_000, 1_000)
    solver_options = {"atol": 1e-6, "rtol": 1e-6}

    # SimBio
    sim = Simulator(
        simbio_model, builder="numpy", solver=ODEint, solver_kwargs=solver_options
    )
    _, df_simbio = sim.run(t)

    # PySB
    sim_pysb = ScipyOdeSimulator(
        pysb_model, integrator="lsoda", integrator_options=solver_options
    )
    df_pysb = pysb_dataframe(sim_pysb.run(t), pysb_model)

    assert np.allclose(df_pysb, df_simbio[df_pysb.columns], rtol=1e-2, atol=1e-2)
Пример #39
0
    def compare_to_pysb_simulation(self):
        examples = [
            tyson_oscillator.model, robertson.model,
            expression_observables.model, bax_pore_sequential.model,
            bax_pore.model, bngwiki_egfr_simple.model
        ]
        for example in examples:
            example.name = example.name.replace('pysb.examples.', '')
            with self.subTest(example=example.name):
                ## pysb part

                tspan = np.linspace(0, 100, 101)
                sim = ScipyOdeSimulator(example,
                                        tspan=tspan,
                                        integrator_options={
                                            'rtol': 1e-8,
                                            'atol': 1e-8
                                        },
                                        compiler='python')
                pysb_simres = sim.run()

                ## amici part

                amici.pysb2amici(example, example.name, verbose=False)
                sys.path.insert(0, example.name)
                amici_model_module = importlib.import_module(example.name)
                model_pysb = amici_model_module.getModel()

                model_pysb.setTimepoints(tspan)

                solver = model_pysb.getSolver()
                rdata = amici.runAmiciSimulation(model_pysb, solver)

                # check agreement of species simulation

                self.assertTrue(
                    np.isclose(rdata['x'], pysb_simres.species, 1e-4,
                               1e-4).all())
Пример #40
0
class Solver(object):
    """An interface for numeric integration of models.

    Parameters
    ----------
    model : pysb.Model
        Model to integrate.
    tspan : vector-like
        Time values over which to integrate. The first and last values define
        the time range, and the returned trajectories will be sampled at every
        value.
    use_analytic_jacobian : boolean, optional
        Whether to provide the solver a Jacobian matrix derived analytically
        from the model ODEs. Defaults to False. If False, the integrator may
        approximate the Jacobian by finite-differences calculations when
        necessary (depending on the integrator and settings).
    integrator : string, optional (default: 'vode')
        Name of the integrator to use, taken from the list of integrators known
        to :py:class:`scipy.integrate.ode`.
    cleanup : bool, optional
        If True (default), delete the temporary files after the simulation is
        finished. If False, leave them in place. Useful for debugging.
    verbose : bool, optional (default: False)
        Verbose output 
    integrator_options
        Additional parameters for the integrator.

    Attributes
    ----------
    model : pysb.Model
        Model passed to the constructor
    tspan : vector-like
        Time values passed to the constructor.
    y : numpy.ndarray
        Species trajectories. Dimensionality is ``(len(tspan),
        len(model.species))``.
    yobs : numpy.ndarray with record-style data-type
        Observable trajectories. Length is ``len(tspan)`` and record names
        follow ``model.observables`` names.
    yobs_view : numpy.ndarray
        An array view (sharing the same data buffer) on ``yobs``.
        Dimensionality is ``(len(tspan), len(model.observables))``.
    yexpr : numpy.ndarray with record-style data-type
        Expression trajectories. Length is ``len(tspan)`` and record names
        follow ``model.expressions_dynamic()`` names.
    yexpr_view : numpy.ndarray
        An array view (sharing the same data buffer) on ``yexpr``.
        Dimensionality is ``(len(tspan), len(model.expressions_dynamic()))``.
    integrator : scipy.integrate.ode
        Integrator object.

    Notes
    -----
    The expensive step of generating the code for the right-hand side of the
    model's ODEs is performed during initialization. If you need to integrate
    the same model repeatedly with different parameters then you should build a
    single Solver object and then call its ``run`` method as needed.

    """
    def __init__(self, model, tspan, use_analytic_jacobian=False,
                 integrator='vode', cleanup=True,
                 verbose=False, **integrator_options):
        self._sim = ScipyOdeSimulator(model, verbose=verbose, tspan=tspan,
                                     use_analytic_jacobian=
                                     use_analytic_jacobian,
                                     integrator=integrator, cleanup=cleanup,
                                     **integrator_options)
        self.result = None

    @property
    def _use_inline(self):
        return ScipyOdeSimulator._use_inline

    @_use_inline.setter
    def _use_inline(self, use_inline):
        ScipyOdeSimulator._use_inline = use_inline

    @property
    def yobs(self):
        return self.result.observables if self.result is not None else None

    @property
    def y(self):
        return self.result.species if self.result is not None else None

    def run(self, param_values=None, y0=None):
        """Perform an integration.

        Returns nothing; access the Solver object's ``y``, ``yobs``, or
        ``yobs_view`` attributes to retrieve the results.

        Parameters
        ----------
        param_values : vector-like or dictionary, optional
            Values to use for every parameter in the model. Ordering is
            determined by the order of model.parameters. 
            If passed as a dictionary, keys must be parameter names.
            If not specified, parameter values will be taken directly from
            model.parameters.
        y0 : vector-like, optional
            Values to use for the initial condition of all species. Ordering is
            determined by the order of model.species. If not specified, initial
            conditions will be taken from model.initial_conditions (with
            initial condition parameter values taken from `param_values` if
            specified).
        """
        self.result = self._sim.run(param_values=param_values, initials=y0)
Пример #41
0
def test_set_initial_to_zero():
    sim = ScipyOdeSimulator(robertson.model, tspan=np.linspace(0, 100))
    simres = sim.run(initials={robertson.model.monomers['A'](): 0})
    assert np.allclose(simres.observables['A_total'], 0)
Пример #42
0
class Tropical:
    mach_eps = numpy.finfo(float).eps

    def __init__(self, model):
        """
        Constructor of tropical function
        :param model: PySB model
        """
        self.model = model
        self.tspan = None
        # self.y = None
        self.passengers = []
        self.eqs_for_tropicalization = {}
        # self.all_sp_signatures = {}
        self.all_comb = {}
        self.sim = None
        self.is_setup = False

    def tropicalize(self, tspan=None, param_values=None, type_sign='production', diff_par=1, ignore=1, epsilon=1,
                    find_passengers_by='imp_nodes', sp_to_visualize=None, plot_imposed_trace=False, verbose=False):
        """
        tropicalization of driver species
        :param type_sign: Type of max-plus signature. This is to see the way a species is being produced or consumed
        :param diff_par: Parameter that defines when a monomial or combination of monomials is larger than the others
        :param find_passengers_by: Option to find passenger species. 'imp_nodes' finds the nodes that only have one edge.
        'qssa' finds passenger species using the quasi steady state approach
        :param plot_imposed_trace: Option to plot imposed trace
        :param tspan: Time span
        :param param_values: PySB model parameter values
        :param ignore: Initial time points to ignore
        :param epsilon: Order of magnitude difference between solution of ODE and imposed trace to consider species as
        passenger
        :param verbose: Verbose
        :return:
        """
        all_signatures = dynamic_signatures(param_values, self, tspan=tspan, type_sign=type_sign,
                                            diff_par=diff_par,
                                            ignore=ignore, epsilon=epsilon, find_passengers_by=find_passengers_by,
                                            sp_to_visualize=sp_to_visualize, plot_imposed_trace=plot_imposed_trace,
                                            verbose=False)

        return all_signatures

    def setup_tropical(self, tspan, type_sign, find_passengers_by):
        """

        :param tspan: time of simulation
        :param type_sign: type of dynamical signature. It can either 'production' or 'consumption
        :param find_passengers_by: Method to find non important species
        :return:
        """
        if tspan is not None:
            self.tspan = tspan
        else:
            raise SimulatorException("'tspan' must be defined.")

        if type_sign not in ['production', 'consumption']:
            raise Exception('Wrong type_sign')

        self.sim = ScipyOdeSimulator(self.model, self.tspan)

        if find_passengers_by is 'imp_nodes':
            self.find_nonimportant_nodes()
            self.equations_to_tropicalize()

        if not self.all_comb:
            self.set_combinations_sm(type_sign=type_sign)

        self.is_setup = True
        return

    @staticmethod
    def merge_dicts(*dict_args):
        """
        Given any number of dicts, shallow copy and merge into a new dict,
        precedence goes to key value pairs in latter dicts.
        """
        result = {}
        for dictionary in dict_args:
            result.update(dictionary)
        return result

    @staticmethod
    def choose_max2(pd_series, diff_par, mon_comb, type_sign='production'):
        """

        :param type_sign: Type of signature. It can be 'consumption' or 'consumption'
        :param mon_comb: combinations of monomials that produce certain species
        :param pd_series: Pandas series whose axis labels are the monomials and the data is their values at a specific
        time point
        :param diff_par: Parameter to define when a monomial is larger
        :return: monomial or combination of monomials that dominate at certain time point
        """

        if type_sign == 'production':
            monomials = pd_series[pd_series > 0]
            value_to_add = 1e-100
            sign = 1
            ascending = False
        elif type_sign == 'consumption':
            monomials = pd_series[pd_series < 0]
            value_to_add = -1e-100
            sign = -1
            ascending = True
        else:
            raise Exception('Wrong type_sign')

        # chooses the larger monomial or combination of monomials that satisfy diff_par
        largest_prod = 'ND'
        for comb in mon_comb.keys():
            # comb is an integer that represents the number of monomials in a combination
            if comb == mon_comb.keys()[-1]:
                break

            if len(mon_comb[comb].keys()) == 1:
                largest_prod = mon_comb[comb].keys()[0]
                break

            monomials_values = {}
            for idx in mon_comb[comb].keys():
                value = 0
                for j in mon_comb[comb][idx]:
                    # j(reversible) might not be in the prod df because it has a negative value
                    if j not in list(monomials.index):
                        value += value_to_add
                    else:
                        value += monomials.loc[j]
                monomials_values[idx] = value

            foo2 = pd.Series(monomials_values).sort_values(ascending=ascending)
            comb_largest = mon_comb[comb][list(foo2.index)[0]]
            for cm in list(foo2.index):
                # Compares the largest combination of monomials to other combinations whose monomials that are not
                # present in comb_largest
                if len(set(comb_largest) - set(mon_comb[comb][cm])) == len(comb_largest):
                    value_prod_largest = math.log10(sign * foo2.loc[list(foo2.index)[0]])
                    if abs(value_prod_largest - math.log10(sign * foo2.loc[cm])) > diff_par and value_prod_largest > -5:
                        largest_prod = list(foo2.index)[0]
                        break
            if largest_prod != 'ND':
                break
        return largest_prod

    def find_nonimportant_nodes(self):
        """

        :return: a list of non-important nodes
        """
        rcts_sp = list(sum([i['reactants'] for i in self.model.reactions_bidirectional], ()))
        pdts_sp = list(sum([i['products'] for i in self.model.reactions_bidirectional], ()))
        imp_rcts = set([x for x in rcts_sp if rcts_sp.count(x) > 1])
        imp_pdts = set([x for x in pdts_sp if pdts_sp.count(x) > 1])
        imp_nodes = set.union(imp_pdts, imp_rcts)
        idx = list(set(range(len(self.model.odes))) - set(imp_nodes))
        self.passengers = idx
        return self.passengers

    def find_passengers(self, y, epsilon=None, plot=False, verbose=False):
        """
        Finds passenger species based in the Quasi Steady State Approach (QSSA) in the model
        :param verbose: Verbose
        :param y: Solution of the differential equations
        :param epsilon: Minimum difference between the imposed trace and the dynamic solution to be considered passenger
        :param plot: Boolean, True to plot the dynamic solution and the imposed trace.
        :return: The passenger species
        """
        # TODO fix this function
        sp_imposed_trace = []
        assert not self.passengers

        # Loop through all equations
        for i, eq in enumerate(self.model.odes):
            # Solve equation of imposed trace. It can have more than one solution (Quadratic solutions)
            sol = sympy.solve(eq, sympy.Symbol('__s%d' % i))
            sp_imposed_trace.append(sol)
        for sp_idx, trace_soln in enumerate(sp_imposed_trace):
            distance_imposed = 999
            for idx, solu in enumerate(trace_soln):
                # Check is solution is time independent
                if solu.is_real:
                    imp_trace_values = [float(solu) + self.mach_eps] * (len(self.tspan) - 1)
                else:
                    # If the imposed trace depends on the value of other species, then we replace species and parameter
                    # values to get the imposed trace
                    for p in self.param_values:
                        solu = solu.subs(p, self.param_values[p])

                    # After replacing parameter for its values, then we get the species in the equation and pass
                    # their dynamic solution
                    variables = [atom for atom in solu.atoms(sympy.Symbol)]
                    f = sympy.lambdify(variables, solu, modules=dict(sqrt=numpy.lib.scimath.sqrt))
                    args = [y[str(l)] for l in variables]  # arguments to put in the lambdify function
                    imp_trace_values = f(*args)

                if any(isinstance(n, complex) for n in imp_trace_values):
                    if verbose:
                        print("solution {0} from equation {1} is complex".format(idx, sp_idx))
                    continue
                elif any(n < 0 for n in imp_trace_values):
                    if verbose:
                        print("solution {0} from equation {1} is negative".format(idx, sp_idx))
                    continue
                diff_trace_ode = abs(numpy.log10(imp_trace_values) - numpy.log10(y['__s%d' % sp_idx]))
                if max(diff_trace_ode) < distance_imposed:
                    distance_imposed = max(diff_trace_ode)

                if plot:
                    self.plot_imposed_trace(y=y, tspan=self.tspan[1:], imp_trace_values=imp_trace_values,
                                            sp_idx=sp_idx, diff_trace_ode=diff_trace_ode, epsilon=epsilon)

            if distance_imposed < epsilon:
                self.passengers.append(sp_idx)

        return self.passengers

    def plot_imposed_trace(self, y, tspan, imp_trace_values, sp_idx, diff_trace_ode, epsilon):
        """

        :param y: Solution of the differential equations
        :param tspan: time span of the solution of the differential equations
        :param imp_trace_values: Imposed trace values
        :param sp_idx: Index of the molecular species to be plotted
        :param diff_trace_ode: Maxmimum difference between the dynamic and the imposed trace
        :param epsilon: Order of magnitude difference between solution of ODE and imposed trace to consider species as
        passenger
        :return: Plot of the imposed trace and the dnamic solution
        """
        plt.figure()
        plt.semilogy(tspan, imp_trace_values, 'r--', linewidth=5, label='imposed')
        plt.semilogy(tspan, y['__s{0}'.format(sp_idx)], label='full')
        plt.legend(loc=0)
        plt.xlabel('time', fontsize=20)
        plt.ylabel('population', fontsize=20)
        if max(diff_trace_ode) < epsilon:
            plt.title(str(self.model.species[sp_idx]) + 'passenger', fontsize=20)
        else:
            plt.title(self.model.species[sp_idx], fontsize=20)
        plt.savefig('s%d' % sp_idx + '_imposed_trace' + '.png', bbox_inches='tight', dpi=400)

    def equations_to_tropicalize(self):
        """

        :return: Dict, keys are the index of the driver species, values are the differential equations
        """

        idx = list(set(range(len(self.model.odes))) - set(self.passengers))
        eqs = {i: self.model.odes[i] for i in idx}
        self.eqs_for_tropicalization = eqs
        return

    def signal_signature(self, param_values, diff_par=1, type_sign='production', sp_to_visualize=None):
        if param_values is not None:
            if type(param_values) is str:
                param_values = hf.read_pars(param_values)
            # accept vector of parameter values as an argument
            if len(param_values) != len(self.model.parameters):
                print(param_values)
                raise Exception("param_values must be the same length as model.parameters")
            if not isinstance(param_values, numpy.ndarray):
                param_values = numpy.array(param_values)
        else:
            # create parameter vector from the values in the model
            param_values = numpy.array([p.value for p in self.model.parameters])

        # convert model parameters into dictionary
        param_values = dict((p.name, param_values[i]) for i, p in enumerate(self.model.parameters))

        y = self.sim.run(param_values=param_values).dataframe
        # Dictionary whose keys are species and values are the monomial signatures
        all_signatures = {}

        if type_sign == 'production':
            mon_type = 'products'
        elif type_sign == 'consumption':
            mon_type = 'reactants'
        else:
            raise Exception("type sign must be 'production' or 'consumption'")

        for sp in self.eqs_for_tropicalization:

            # reaction terms
            monomials = []

            for term in self.model.reactions_bidirectional:
                if sp in term['reactants'] and term['reversible'] is True:
                    monomials.append((-1) * term['rate'])
                elif sp in term[mon_type]:
                    monomials.append(term['rate'])

            # Dictionary whose keys are the symbolic monomials and the values are the simulation results
            mons_dict = {}
            for mon_p in monomials:
                mon_p_values = mon_p.subs(param_values)
                var_prod = [atom for atom in mon_p_values.atoms(sympy.Symbol)]  # Variables of monomial
                arg_prod = [numpy.maximum(self.mach_eps, y[str(va)]) for va in var_prod]
                f_prod = sympy.lambdify(var_prod, mon_p_values)
                prod_values = f_prod(*arg_prod)
                mons_dict[mon_p] = prod_values

            # Dataframe whose rownames are the monomials and the columns contain their values at each time point
            mons_df = pd.DataFrame(mons_dict).T

            signature_species = mons_df.apply(self.choose_max2, args=(diff_par, self.all_comb[sp], type_sign))
            all_signatures[sp] = list(signature_species)

        # self.all_sp_signatures = all_signatures

        if sp_to_visualize:
            self.visualization2(y, all_signatures, param_values, sp_to_visualize)

        return all_signatures

    def set_combinations_sm(self, type_sign='production', create_sm=False):
        if type_sign == 'production':
            mon_type = 'products'
        elif type_sign == 'consumption':
            mon_type = 'reactants'
        else:
            raise Exception("type sign must be 'production' or 'consumption'")

        for sp in self.eqs_for_tropicalization:

            # reaction terms
            monomials = []

            for term in self.model.reactions_bidirectional:
                if sp in term['reactants'] and term['reversible'] is True:
                    monomials.append((-1) * term['rate'])
                elif sp in term[mon_type]:
                    monomials.append(term['rate'])

            mon_comb = OrderedDict()
            prod_idx = 0

            for L in range(1, len(monomials) + 1):
                prod_comb_names = {}
                for subset in itertools.combinations(monomials, L):
                    prod_comb_names['M{0}{1}'.format(L, prod_idx)] = subset
                    prod_idx += 1
                mon_comb[L] = prod_comb_names
            self.all_comb[sp] = mon_comb

            merged_mon_comb = self.merge_dicts(*mon_comb.values())
            merged_mon_comb.update({'ND': 'N'})
            # Substitution matrix
            len_ND = len(max(merged_mon_comb.values(), key=len)) + 1
            sm = numpy.zeros((len(merged_mon_comb.keys()), len(merged_mon_comb.keys())))
            for i, a in enumerate(merged_mon_comb):
                for j, b in enumerate(merged_mon_comb):
                    if a == 'ND' and b == 'ND':
                        sm[i, j] = 0
                    elif a == 'ND':
                        sm[i, j] = 2 * len_ND - len(merged_mon_comb[b])
                    elif b == 'ND':
                        sm[i, j] = 2 * len_ND - len(merged_mon_comb[a])
                    else:
                        sm[i, j] = self.sub_value(merged_mon_comb[a], merged_mon_comb[b])
                        # max(len(self.all_comb[sp][a]), len(self.all_comb[sp][b])) - len(
                        #             set(self.all_comb[sp][a]).intersection(self.all_comb[sp][b]))

            if create_sm:
                sm_df = pd.DataFrame(data=sm, index=merged_mon_comb.keys(), columns=merged_mon_comb.keys())
                sm_df.to_csv('/home/oscar/Documents/tropical_earm/subs_matrix_consumption/sm_{0}.{1}'.format(sp, 'csv'))

    @staticmethod
    def sub_value(a, b):
        value = 2 * len(max(a, b, key=len)) - len(min(a, b, key=len)) - len(set(a).intersection(b))
        return value

    def visualization2(self, y, all_signatures, param_values, sp_to_vis=None):
        if sp_to_vis:
            species_ready = list(set(sp_to_vis).intersection(all_signatures.keys()))
        else:
            raise Exception('list of driver species must be defined')

        if not species_ready:
            raise Exception('None of the input species is a driver')

        for sp in species_ready:

            # Setting up figure
            plt.figure(1)
            plt.subplot(313)

            mon_val = OrderedDict()
            signature = all_signatures[sp]

            if not signature:
                continue

            merged_mon_comb = self.merge_dicts(*self.all_comb[sp].values())
            merged_mon_comb.update({'ND': 'N'})

            for idx, mon in enumerate(list(set(signature))):
                mon_val[merged_mon_comb[mon]] = idx

            mon_rep = [0] * len(signature)
            for i, m in enumerate(signature):
                mon_rep[i] = mon_val[merged_mon_comb[m]]
            # mon_rep = [mon_val[self.all_comb[sp][m]] for m in signature]

            y_pos = numpy.arange(len(mon_val.keys()))
            plt.scatter(self.tspan, mon_rep)
            plt.yticks(y_pos, mon_val.keys())
            plt.ylabel('Monomials', fontsize=16)
            plt.xlabel('Time(s)', fontsize=16)
            plt.xlim(0, self.tspan[-1])
            plt.ylim(0, max(y_pos))

            plt.subplot(312)
            for name in self.model.odes[sp].as_coefficients_dict():
                mon = name
                mon = mon.subs(param_values)
                var_to_study = [atom for atom in mon.atoms(sympy.Symbol)]
                arg_f1 = [numpy.maximum(self.mach_eps, y[str(va)]) for va in var_to_study]
                f1 = sympy.lambdify(var_to_study, mon)
                mon_values = f1(*arg_f1)
                mon_name = str(name).partition('__')[2]
                plt.plot(self.tspan, mon_values, label=mon_name)
            plt.ylabel('Rate(m/sec)', fontsize=16)
            plt.legend(bbox_to_anchor=(-0.1, 0.85), loc='upper right', ncol=3)

            plt.subplot(311)
            plt.plot(self.tspan, y['__s%d' % sp], label=hf.parse_name(self.model.species[sp]))
            plt.ylabel('Molecules', fontsize=16)
            plt.legend(bbox_to_anchor=(-0.15, 0.85), loc='upper right', ncol=1)
            plt.suptitle('Tropicalization' + ' ' + str(self.model.species[sp]))

            # plt.show()
            plt.savefig('s%d' % sp + '.png', bbox_inches='tight', dpi=400)
            plt.clf()

    def get_passenger(self):
        """

        :return: Passenger species of the systems
        """
        return self.passengers
Пример #43
0
class TestScipySimulator(object):
    @with_model
    def setUp(self):
        Monomer('A', ['a'])
        Monomer('B', ['b'])

        Parameter('ksynthA', 100)
        Parameter('ksynthB', 100)
        Parameter('kbindAB', 100)

        Parameter('A_init', 0)
        Parameter('B_init', 0)

        Initial(A(a=None), A_init)
        Initial(B(b=None), B_init)

        Observable("A_free", A(a=None))
        Observable("B_free", B(b=None))
        Observable("AB_complex", A(a=1) % B(b=1))

        Rule('A_synth', None >> A(a=None), ksynthA)
        Rule('B_synth', None >> B(b=None), ksynthB)
        Rule('AB_bind', A(a=None) + B(b=None) >> A(a=1) % B(b=1), kbindAB)

        self.model = model

        # Convenience shortcut for accessing model monomer objects
        self.mon = lambda m: self.model.monomers[m]

        # This timespan is chosen to be enough to trigger a Jacobian evaluation
        # on the various solvers.
        self.time = np.linspace(0, 1)
        self.sim = ScipyOdeSimulator(self.model, tspan=self.time,
                                     integrator='vode')

    def tearDown(self):
        self.model = None
        self.time = None
        self.sim = None

    def test_vode_solver_run(self):
        """Test vode."""
        simres = self.sim.run()
        assert simres.nsims == 1

    def test_vode_jac_solver_run(self):
        """Test vode and analytic jacobian."""
        solver_vode_jac = ScipyOdeSimulator(self.model, tspan=self.time,
                                            integrator='vode',
                                            use_analytic_jacobian=True)
        solver_vode_jac.run()

    def test_lsoda_solver_run(self):
        """Test lsoda."""
        solver_lsoda = ScipyOdeSimulator(self.model, tspan=self.time,
                                         integrator='lsoda')
        solver_lsoda.run()

    def test_lsoda_jac_solver_run(self):
        """Test lsoda and analytic jacobian."""
        solver_lsoda_jac = ScipyOdeSimulator(self.model, tspan=self.time,
                                             integrator='lsoda',
                                             use_analytic_jacobian=True)
        solver_lsoda_jac.run()

    def test_y0_as_list(self):
        """Test y0 with list of initial conditions"""
        # Test the initials getter method before anything is changed
        assert np.allclose(self.sim.initials[0:3],
                           [ic[1].value for ic in
                            self.model.initial_conditions])

        initials = [10, 20, 0, 0]
        simres = self.sim.run(initials=initials)
        assert np.allclose(self.sim.initials, initials)
        assert np.allclose(simres.observables['A_free'][0], 10)

    def test_y0_as_ndarray(self):
        """Test y0 with numpy ndarray of initial conditions"""
        simres = self.sim.run(initials=np.asarray([10, 20, 0, 0]))
        assert np.allclose(simres.observables['A_free'][0], 10)

    def test_y0_as_dictionary_monomer_species(self):
        """Test y0 with model-defined species."""
        simres = self.sim.run(initials={self.mon('A')(a=None): 10,
                               self.mon('B')(b=1) % self.mon('A')(a=1): 0,
                               self.mon('B')(b=None): 0})
        assert np.allclose(self.sim.initials_list, [10, 0, 1, 0])
        assert np.allclose(simres.observables['A_free'][0], 10)

    def test_y0_as_dictionary_with_bound_species(self):
        """Test y0 with dynamically generated species."""
        simres = self.sim.run(initials={self.mon('A')(a=None): 0,
                               self.mon('B')(b=1) % self.mon('A')(a=1): 100,
                               self.mon('B')(b=None): 0})
        assert np.allclose(simres.observables['AB_complex'][0], 100)

    @raises(TypeError)
    def test_y0_non_numeric_value(self):
        """Test y0 with non-numeric value."""
        self.sim.run(initials={self.mon('A')(a=None): 'eggs'})

    def test_param_values_as_dictionary(self):
        """Test param_values as a dictionary."""
        simres = self.sim.run(param_values={'kbindAB': 0})
        # kbindAB=0 should ensure no AB_complex is produced.
        assert np.allclose(simres.observables["AB_complex"], 0)

    def test_param_values_as_list_ndarray(self):
        """Test param_values as a list and ndarray."""
        param_values = [50, 60, 70, 0, 0, 1]
        self.sim.run(param_values=param_values)
        assert np.allclose(self.sim.param_values, param_values)
        # Same thing, but with a numpy array
        param_values = np.asarray([55, 65, 75, 0, 0, 1])
        self.sim.run(param_values=param_values)
        assert np.allclose(self.sim.param_values, param_values)

    @raises(IndexError)
    def test_param_values_invalid_dictionary_key(self):
        """Test param_values with invalid parameter name."""
        self.sim.run(param_values={'spam': 150})

    @raises(ValueError, TypeError)
    def test_param_values_non_numeric_value(self):
        """Test param_values with non-numeric value."""
        self.sim.run(param_values={'ksynthA': 'eggs'})

    def test_result_dataframe(self):
        df = self.sim.run().dataframe
Пример #44
0
from erbb_exec import model
import numpy as np
#from pysb.integrate import odesolve
from pysb.simulator import ScipyOdeSimulator

t = np.linspace(0,2000, num=2000)

#yout = odesolve(model, t, integrator='lsoda')
solver = ScipyOdeSimulator(model, t, integrator='lsoda')
solver.run()
def LSD(prob, n_exp, n_cell_types, n_cells):

    dip_dist = []

    low_dips = -0.04 * np.log(2)
    high_dips =  0.04 * np.log(2)
    dips = np.linspace(low_dips, high_dips, n_cell_types)
    # dip_mean = -0.01 * np.log(2)
    # dip_var = 0.01 * np.log(2)

    # Discretize normal distribution of dip rates - used in post drug simulation
    # normal = sp.norm.pdf(dips, dip_mean, dip_var)
    # print(normal)
    # sum = 0
    # for i in range(1, n_cell_types):
    #     sum += normal[i] * (dips[i] - dips[i - 1])
    # print(sum)

    # normal_hist = normal * (dips[1] - dips[0])
    # print(normal_hist)
    print(dips)

    Model()
    [Monomer("Cell", ['dip'], {'dip': ["%d" % i for i in range(n_cell_types)]})]
    print(model.monomers)

    Parameter('cellInit_0', 1)
    [Parameter('cellInit_%d' % i) for i in range(1, n_cell_types)]
    # Parameter('Cell_1init')
    print(model.parameters)

    Initial(Cell(dip="0"), cellInit_0)  # could not be a string - parameter only - didn't know how to set up
    [Initial(Cell(dip="%d" % i), model.parameters["cellInit_%d" % i]) for i in range(1, n_cell_types)]
    print(model.initial_conditions)

    [Observable("Obs_Cell%d" % i, Cell(dip="%d" % i)) for i in range(n_cell_types)]
    Observable("Obs_All", Cell())
    print(model.observables)

    k_div = 0.040 * np.log(2)
    [Parameter("k_div_%d" % i, k_div) for i in range(len(dips))]
    k_death = k_div-dips
    [Parameter("k_death_%d" % i, k) for i, k in enumerate(k_death)]
    print(model.parameters)

    [Rule("Cell%d_Div" % i, Cell(dip="%d" % i) >> Cell(dip="%d" % i) + Cell(dip="%d" % i),
          model.parameters["k_div_%d" % i]) for i in range(len(dips))]
    [Rule("Cell%d_Death" % i, Cell(dip="%d" % i) >> None,
          model.parameters["k_death_%d" % i]) for i in range(len(k_death))]
    # print(model.rules)
    # for i in range(n_cell_types):
    #     print(model.parameters['cellInit_%d' %i])
    # quit()

    np.random.seed(5)

    for exp in range(n_exp):
        # num_cells = np.random.poisson(n_cells)
        num_cells = 1
        picks = np.random.multinomial(num_cells, prob)
        picks_total = np.sum(picks)
        if picks_total != 0:
            div_death = {}
            for i in range(n_cell_types):
                model.parameters['cellInit_%d' %i].value = picks[i]
                div_death["k_div_%d" %i] = 0.04 * np.log(2)
                div_death["k_death_%d" %i] = 0.005 * np.log(2)
        else:
            continue
        # print(model.parameters)
        t1 = np.linspace(0, 169, 168)  # 7 days
        sim = ScipyOdeSimulator(model, verbose=False)
        # sim1 = BngSimulator(model, tspan=t1, verbose=False)
        x1 = sim.run(tspan=t1,
                     param_values=div_death)  # returns np.array with species and obs
        # plt.plot(x1.tout[0], np.log2(x1.all["Obs_All"]), color = 'k', lw=2)
        # plt.plot(x1.tout[0], np.log2(x1.all["Obs_Cell0"]), color = 'b', lw=2)
        # plt.plot(x1.tout[0], np.log2(x1.all["Obs_Cell1"]), color = 'g', lw=2)
        # plt.plot(x1.tout[0], np.log2(x1.all["Obs_Cell2"]), color = 'r', lw=2)
        # print(model.parameters)
        # quit()
        t2 = np.linspace(0, 336, 337)
        # sim2 = BngSimulator(model, tspan=t2, verbose=False)
        # x2 = sim2.run(param_values={"cellInit_{}".format(i): x1.all["Obs_Cell%{}".format(i)][-1] for i in range(n_cell_types),
        #                             "k_death_{}".format(i): k_death[i] for i in range(n_cell_types)})
        # print(model.species)
        # print(x1.species[-1])
        # for r in model.reactions:
        #     print(r)
        x2 = sim.run(tspan=t2,
                     initials=x1.species[-1],
                     param_values=[p.value for p in model.parameters])

        # plt.plot(x2.tout[0]+x1.tout[0][-1], np.log2(x2.all["Obs_All"]), color = 'k', lw=2, label = "All")
        # plt.plot(x2.tout[0]+x1.tout[0][-1], np.log2(x2.all["Obs_Cell0"]), color = 'b', lw=2, label = "Cell0")
        # plt.plot(x2.tout[0]+x1.tout[0][-1], np.log2(x2.all["Obs_Cell1"]), color = 'g', lw=2, label = "Cell1")
        # plt.plot(x2.tout[0]+x1.tout[0][-1], np.log2(x2.all["Obs_Cell2"]), color = 'r', lw=2, label = "Cell2")
        # plt.legend()
        # plt.show()
        # print x1.all["Obs_Cell0"][-1]
        # print x1.all["Obs_Cell1"][-1]
        # print x1.all["Obs_Cell2"][-1]

        print(expt_dip(t_hours=x2.tout[0], assay_vals=np.log2(x2.all["Obs_All"])))
        print(dips)

        dip,std_err,first_tp,intercept = expt_dip(t_hours=x2.tout[0], assay_vals=np.log2(x2.all["Obs_All"]))

        if dip is not None:
            dip_dist.append(dip)

        plt.plot(x1.tout[0], np.log2(x1.all["Obs_All"]), '0.5', lw=2)
        plt.plot(x1.tout[0][-1] + x2.tout[0], np.log2(x2.all["Obs_All"]), '0.5', lw=2)
        plt.xlabel("Time (hours)")
        plt.ylabel("Population Doublings")
        plt.title("Deterministic LSD trajectories", weight = "bold")

    plt.figure("DIP Rate Distribution")
    sns.distplot(dip_dist, kde=False, color='k', hist_kws={"alpha":0.5}, bins = 5)
    plt.xlabel("DIP Rate")
    plt.ylabel("Frequency")
    plt.title("LSD Biased DIP Rate Distribution", weight = "bold")

    return dip_dist
Пример #46
0
from __future__ import print_function
from pysb.simulator import ScipyOdeSimulator
from tutorial_a import model

t = [0, 10, 20, 30, 40, 50, 60]
simulator = ScipyOdeSimulator(model, tspan=t)
simresult = simulator.run()
print(simresult.species)
Пример #47
0
 def test_lsoda_jac_solver_run(self):
     """Test lsoda and analytic jacobian."""
     solver_lsoda_jac = ScipyOdeSimulator(self.model, tspan=self.time,
                                          integrator='lsoda',
                                          use_analytic_jacobian=True)
     solver_lsoda_jac.run()
Пример #48
0
import copy
import numpy as np
import matplotlib.pyplot as plt
from pysb.simulator import ScipyOdeSimulator

from pysb.examples.fixed_initial import model

n_obs = len(model.observables)
tspan = np.linspace(0, 0.5)

plt.figure(figsize=(8,4))

# Simulate the model as written, with free F fixed.
sim = ScipyOdeSimulator(model, tspan)
res = sim.run()
obs = res.observables.view(float).reshape(-1, n_obs)
plt.subplot(121)
plt.plot(res.tout[0], obs)
plt.ylabel('Amount')
plt.xlabel('Time')
plt.legend([x.name for x in model.observables], frameon=False)
plt.title('Free F fixed')

# Make a copy of the model and unfix the initial condition for free F.
model2 = copy.deepcopy(model)
model2.reset_equations()
model2.initials[1].fixed = False
sim2 = ScipyOdeSimulator(model2, tspan)
res2 = sim2.run()
obs2 = res2.observables.view(float).reshape(-1, n_obs)
Пример #49
0
def odesolve(model, tspan, param_values=None, y0=None, integrator='vode',
             cleanup=True, verbose=False, **integrator_options):
    """Integrate a model's ODEs over a given timespan.

    This is a simple function-based interface to integrating (a.k.a. solving or
    simulating) a model. If you need to integrate a model repeatedly with
    different parameter values or initial conditions (as in parameter
    estimation), using the Solver class directly will provide much better
    performance.

    Parameters
    ----------
    model : pysb.Model
        Model to integrate.
    tspan : vector-like
        Time values over which to integrate. The first and last values define
        the time range, and the returned trajectories will be sampled at every
        value.
    param_values : vector-like, optional
        Values to use for every parameter in the model. Ordering is determined
        by the order of model.parameters. If not specified, parameter values
        will be taken directly from model.parameters.
    y0 : vector-like, optional
        Values to use for the initial condition of all species. Ordering is
        determined by the order of model.species. If not specified, initial
        conditions will be taken from model.initial_conditions (with initial
        condition parameter values taken from `param_values` if specified).
    integrator : string, optional
        Name of the integrator to use, taken from the list of integrators known
        to :py:class:`scipy.integrate.ode`.
    cleanup : bool, optional
        Remove temporary files after completion if True. Set to False for
        debugging purposes.
    verbose : bool, optionsal
        Increase verbosity of simulator output.
    integrator_options :
        Additional parameters for the integrator.

    Returns
    -------
    yfull : record array
        The trajectories calculated by the integration. The first dimension is
        time and its length is identical to that of `tspan`. The second
        dimension is species/observables and its length is the sum of the
        lengths of model.species and model.observables. The dtype of the array
        specifies field names: '__s0', '__s1', etc. for the species and
        observable names for the observables. See Notes below for further
        explanation and caveats.

    Notes
    -----
    This function was the first implementation of integration support and
    accordingly it has a few warts:

    * It performs expensive code generation every time it is called.

    * The returned array, with its record-style data-type, allows convenient
      selection of individual columns by their field names, but does not permit
      slice ranges or indexing by integers for columns. If you only need access
      to your model's observables this is usually not a problem, but sometimes
      it's more convenient to have a "regular" array. See Examples below for
      code to do this.

    The actual integration code has since been moved to the Solver class and
    split up such that the code generation is only performed on
    initialization. The model may then be integrated repeatedly with different
    parameter values or initial conditions with much better
    performance. Additionally, Solver makes the species trajectories available
    as a simple array and only uses the record array for the observables where
    it makes sense.

    This function now simply serves as a wrapper for creating a Solver object,
    calling its ``run`` method, and building the record array to return.

    Examples
    --------
    Simulate a model and display the results for an observable:

    >>> from pysb.examples.robertson import model
    >>> from numpy import linspace
    >>> numpy.set_printoptions(precision=4)
    >>> yfull = odesolve(model, linspace(0, 40, 10))
    >>> print(yfull['A_total'])            #doctest: +NORMALIZE_WHITESPACE
    [ 1.      0.899   0.8506  0.8179  0.793   0.7728  0.7557  0.7408  0.7277
    0.7158]

    Obtain a view on a returned record array which uses an atomic data-type and
    integer indexing (note that the view's data buffer is shared with the
    original array so there is no extra memory cost):

    >>> print(yfull.shape)
    (10,)
    >>> print(yfull.dtype)                 #doctest: +NORMALIZE_WHITESPACE
    [('__s0', '<f8'), ('__s1', '<f8'), ('__s2', '<f8'), ('A_total', '<f8'),
    ('B_total', '<f8'), ('C_total', '<f8')]
    >>> print(yfull[0:4, 1:3])             #doctest: +ELLIPSIS
    Traceback (most recent call last):
      ...
    IndexError: too many indices...
    >>> yarray = yfull.view(float).reshape(len(yfull), -1)
    >>> print(yarray.shape)
    (10, 6)
    >>> print(yarray.dtype)
    float64
    >>> print(yarray[0:4, 1:3])
    [[  0.0000e+00   0.0000e+00]
     [  2.1672e-05   1.0093e-01]
     [  1.6980e-05   1.4943e-01]
     [  1.4502e-05   1.8209e-01]]

    """
    integrator_options['integrator'] = integrator
    sim = ScipyOdeSimulator(model, tspan=tspan, cleanup=cleanup,
                            verbose=verbose, **integrator_options)
    simres = sim.run(param_values=param_values, initials=y0)
    return simres.all
Пример #50
0
 def test_weave(self):
     sim = ScipyOdeSimulator(compiler='weave', **self.args)
     simres = sim.run()
     assert simres.species.shape[0] == self.args['tspan'].shape[0]
     assert np.allclose(self.python_res.dataframe, simres.dataframe)
Пример #51
0
class BMIModel(object):
    """This class represents a BMI model wrapping a model assembled by INDRA.

    Parameters
    ----------
    model : pysb.Model
        A PySB model assembled by INDRA to be wrapped in BMI.
    inputs : Optional[list[str]]
        A list of variable names that are considered to be inputs to the model
        meaning that they are read from other models. Note that designating
        a variable as input means that it must be provided by another component
        during the simulation.
    stop_time : int
        The stopping time for this model, controlling the time units up to
        which the model is simulated.
    outside_name_map : dict
        A dictionary mapping outside variables names to inside variable names
        (i.e. ones that are in the wrapped model)
    """
    def __init__(self, model, inputs=None, stop_time=1000,
                 outside_name_map=None):
        self.model = model
        generate_equations(model)

        self.inputs = inputs if inputs else []
        self.stop_time = stop_time
        self.outside_name_map = outside_name_map if outside_name_map else {}

        self.dt = numpy.array(10.0)
        self.units = 'seconds'
        self.sim = None
        self.attributes = copy.copy(default_attributes)
        self.species_name_map = {}
        for idx, species in enumerate(self.model.species):
            monomer = species.monomer_patterns[0].monomer
            self.species_name_map[monomer.name] = idx
        self.input_vars = self._get_input_vars()
        # These attributes are related to the simulation state
        self.state = numpy.array([100.0 for s in self.species_name_map.keys()])
        self.time = numpy.array(0.0)
        self.status = 'start'
        self.time_course = [(self.time, self.state)]
        # EMELI needs a DONE attribute
        self.DONE = False

    def _get_input_vars(self):
        return self.inputs
        # The code below attempts to discover input variables, it is currently
        # inactive but could be made optional later
        # species_is_obj = {s: False for s in self.species_name_map.keys()}
        # for ann in self.model.annotations:
        #     if ann.predicate == 'rule_has_object':
        #         species_is_obj[ann.object] = True
        # # Return all the variables that aren't objects in a rule
        # input_vars = [s for s, tf in species_is_obj.items() if not tf]
        # return input_vars

    # Simulation functions
    def initialize(self, cfg_file=None, mode=None):
        """Initialize the model for simulation, possibly given a config file.

        Parameters
        ----------
        cfg_file : Optional[str]
            The name of the configuration file to load, optional.
        """
        self.sim = ScipyOdeSimulator(self.model)
        self.state = numpy.array(copy.copy(self.sim.initials)[0])
        self.time = numpy.array(0.0)
        self.status = 'initialized'

    def update(self, dt=None):
        """Simulate the model for a given time interval.

        Parameters
        ----------
        dt : Optional[float]
            The time step to simulate, if None, the default built-in time step
            is used.
        """
        # EMELI passes dt = -1 so we need to handle that here
        dt = dt if (dt is not None and dt > 0) else self.dt
        tspan = [0, dt]
        # Run simulaton with initials set to current state
        res = self.sim.run(tspan=tspan, initials=self.state)
        # Set the state based on the result here
        self.state  = res.species[-1]
        self.time += dt
        if self.time > self.stop_time:
            self.DONE = True
        print((self.time, self.state))
        self.time_course.append((self.time.copy(), self.state.copy()))

    def finalize(self):
        """Finish the simulation and clean up resources as needed."""
        self.status = 'finalized'

    # Setter functions for state variables
    def set_value(self, var_name, value):
        """Set the value of a given variable to a given value.

        Parameters
        ----------
        var_name : str
            The name of the variable in the model whose value should be set.

        value : float
            The value the variable should be set to
        """
        if var_name in self.outside_name_map:
            var_name = self.outside_name_map[var_name]
            print('%s=%.5f' % (var_name, 1e9*value))
            if var_name == 'Precipitation':
                value = 1e9*value
        species_idx = self.species_name_map[var_name]
        self.state[species_idx] = value

    def set_values(self, var_name, value):
        """Set the value of a given variable to a given value.

        Parameters
        ----------
        var_name : str
            The name of the variable in the model whose value should be set.

        value : float
            The value the variable should be set to
        """
        self.set_value(var_name, value)

    # Getter functions for state
    def get_value(self, var_name):
        """Return the value of a given variable.

        Parameters
        ----------
        var_name : str
            The name of the variable whose value should be returned

        Returns
        -------
        value : float
            The value of the given variable in the current state
        """
        if var_name in self.outside_name_map:
            var_name = self.outside_name_map[var_name]
        species_idx = self.species_name_map[var_name]
        return self.state[species_idx]

    def get_values(self, var_name):
        """Return the value of a given variable.

        Parameters
        ----------
        var_name : str
            The name of the variable whose value should be returned

        Returns
        -------
        value : float
            The value of the given variable in the current state
        """
        return self.get_value(var_name)

    def get_status(self):
        """Return the current status of the model."""
        return self.status

    # Getter functions for basic properties
    def get_attribute(self, att_name):
        """Return the value of a given attribute.

        Atrributes include: model_name, version, author_name, grid_type,
        time_step_type, step_method, time_units

        Parameters
        ----------
        att_name : str
            The name of the attribute whose value should be returned.

        Returns
        -------
        value : str
            The value of the attribute
        """
        return self.attributes.get(att_name)

    def get_input_var_names(self):
        """Return a list of variables names that can be set as input.

        Returns
        -------
        var_names : list[str]
            A list of variable names that can be set from the outside
        """
        in_vars = copy.copy(self.input_vars)
        for idx, var in enumerate(in_vars):
            if self._map_in_out(var) is not None:
                in_vars[idx] = self._map_in_out(var)
        return in_vars

    def get_output_var_names(self):
        """Return a list of variables names that can be read as output.

        Returns
        -------
        var_names : list[str]
            A list of variable names that can be read from the outside
        """
        # Return all the variables that aren't input variables
        all_vars = list(self.species_name_map.keys())
        output_vars = list(set(all_vars) - set(self.input_vars))
        # Re-map to outside var names if needed
        for idx, var in enumerate(output_vars):
            if self._map_in_out(var) is not None:
                output_vars[idx] = self._map_in_out(var)
        return output_vars

    def get_var_name(self, var_name):
        """Return the internal variable name given an outside variable name.

        Parameters
        ----------
        var_name : str
            The name of the outside variable to map

        Returns
        -------
        internal_var_name : str
            The internal name of the corresponding variable
        """
        return self._map_out_in(var_name)

    def get_var_units(self, var_name):
        """Return the units of a given variable.

        Parameters
        ----------
        var_name : str
            The name of the variable whose units should be returned

        Returns
        -------
        unit : str
            The units of the variable
        """
        return '1'

    def get_var_type(self, var_name):
        """Return the type of a given variable.


        Parameters
        ----------
        var_name : str
            The name of the variable whose type should be returned

        Returns
        -------
        unit : str
            The type of the variable as a string
        """
        return 'float64'

    def get_var_rank(self, var_name):
        """Return the matrix rank of the given variable.

        Parameters
        ----------
        var_name : str
            The name of the variable whose rank should be returned

        Returns
        -------
        rank : int
            The dimensionality of the variable, 0 for scalar, 1 for vector,
            etc.
        """
        return numpy.int16(0)

    def get_start_time(self):
        """Return the initial time point of the model.

        Returns
        -------
        start_time : float
            The initial time point of the model.
        """
        return 0.0

    def get_current_time(self):
        """Return the current time point that the model is at during simulation

        Returns
        -------
        time : float
            The current time point
        """
        return self.time

    def get_time_step(self):
        """Return the time step associated with model simulation.

        Returns
        -------
        dt : float
            The time step for model simulation
        """
        return self.dt

    def get_time_units(self):
        """Return the time units of the model simulation.

        Returns
        -------
        units : str
            The time unit of simulation as a string
        """
        return self.units

    def make_repository_component(self):
        """Return an XML string representing this BMI in a workflow.

        This description is required by EMELI to discover and load models.

        Returns
        -------
        xml : str
            String serialized XML representation of the component in the
            model repository.
        """
        component = etree.Element('component')

        comp_name = etree.Element('comp_name')
        comp_name.text = self.model.name
        component.append(comp_name)

        mod_path = etree.Element('module_path')
        mod_path.text = os.getcwd()
        component.append(mod_path)

        mod_name = etree.Element('module_name')
        mod_name.text = self.model.name
        component.append(mod_name)

        class_name = etree.Element('class_name')
        class_name.text = 'model_class'
        component.append(class_name)

        model_name = etree.Element('model_name')
        model_name.text = self.model.name
        component.append(model_name)

        lang = etree.Element('language')
        lang.text = 'python'
        component.append(lang)

        ver = etree.Element('version')
        ver.text = self.get_attribute('version')
        component.append(ver)

        au = etree.Element('author')
        au.text = self.get_attribute('author_name')
        component.append(au)

        hu = etree.Element('help_url')
        hu.text = 'http://github.com/sorgerlab/indra'
        component.append(hu)

        for tag in ('cfg_template', 'time_step_type', 'time_units',
                    'grid_type', 'description', 'comp_type', 'uses_types'):
            elem = etree.Element(tag)
            elem.text = tag
            component.append(elem)

        return etree.tounicode(component, pretty_print=True)

    def export_into_python(self):
        """Write the model into a pickle and create a module that loads it.

        The model basically exports itself as a pickle file and a Python
        file is then written which loads the pickle file. This allows importing
        the model in the simulation workflow.
        """
        pkl_path = self.model.name + '.pkl'
        with open(pkl_path, 'wb') as fh:
            pickle.dump(self, fh, protocol=2)
        py_str = """
        import pickle
        with open('%s', 'rb') as fh:
            model_class = pickle.load(fh)
        """ % os.path.abspath(pkl_path)
        py_str = textwrap.dedent(py_str)
        py_path = self.model.name + '.py'
        with open(py_path, 'w') as fh:
            fh.write(py_str)

    def _map_out_in(self, outside_var_name):
        """Return the internal name of a variable mapped from outside."""
        return self.outside_name_map.get(outside_var_name)

    def _map_in_out(self, inside_var_name):
        """Return the external name of a variable mapped from inside."""
        for out_name, in_name in self.outside_name_map.items():
            if inside_var_name == in_name:
                return out_name
        return None
Пример #52
0
def test_save_load():
    tspan = np.linspace(0, 100, 101)
    model = tyson_oscillator.model
    test_unicode_name = u'Hello \u2603 and \U0001f4a9!'
    model.name = test_unicode_name
    sim = ScipyOdeSimulator(model, integrator='lsoda')
    simres = sim.run(tspan=tspan, param_values={'k6': 1.0})

    sim_rob = ScipyOdeSimulator(robertson.model, integrator='lsoda')
    simres_rob = sim_rob.run(tspan=tspan)

    # Reset equations from any previous network generation
    robertson.model.reset_equations()
    A = robertson.model.monomers['A']

    # NFsim without expressions
    nfsim1 = BngSimulator(robertson.model)
    nfres1 = nfsim1.run(n_runs=2, method='nf', tspan=np.linspace(0, 1))
    # Test attribute saving (text, float, list)
    nfres1.custom_attrs['note'] = 'NFsim without expressions'
    nfres1.custom_attrs['pi'] = 3.14
    nfres1.custom_attrs['some_list'] = [1, 2, 3]

    # NFsim with expressions
    nfsim2 = BngSimulator(expression_observables.model)
    nfres2 = nfsim2.run(n_runs=1, method='nf', tspan=np.linspace(0, 100, 11))

    with tempfile.NamedTemporaryFile() as tf:
        # Cannot have two file handles on Windows
        tf.close()

        simres.save(tf.name, dataset_name='test', append=True)

        # Try to reload when file contains only one dataset and group
        SimulationResult.load(tf.name)

        simres.save(tf.name, append=True)

        # Trying to overwrite an existing dataset gives a ValueError
        assert_raises(ValueError, simres.save, tf.name, append=True)

        # Trying to write to an existing file without append gives an IOError
        assert_raises(IOError, simres.save, tf.name)

        # Trying to write a SimulationResult to the same group with a
        # different model name results in a ValueError
        assert_raises(ValueError, simres_rob.save, tf.name,
                      dataset_name='robertson', group_name=model.name,
                      append=True)

        simres_rob.save(tf.name, append=True)

        # Trying to load from a file with more than one group without
        # specifying group_name should raise a ValueError
        assert_raises(ValueError, SimulationResult.load, tf.name)

        # Trying to load from a group with more than one dataset without
        # specifying a dataset_name should raise a ValueError
        assert_raises(ValueError, SimulationResult.load, tf.name,
                      group_name=model.name)

        # Load should succeed when specifying group_name and dataset_name
        simres_load = SimulationResult.load(tf.name, group_name=model.name,
                                            dataset_name='test')
        assert simres_load._model.name == test_unicode_name

        # Saving network free results requires include_obs_exprs=True,
        # otherwise a warning should be raised
        with warnings.catch_warnings(record=True) as w:
            warnings.simplefilter("always")
            nfres1.save(tf.name, dataset_name='nfsim_no_obs', append=True)
            assert len(w) == 1
            assert issubclass(w[-1].category, UserWarning)

        nfres1.save(tf.name, include_obs_exprs=True,
                    dataset_name='nfsim test', append=True)

        # NFsim load
        nfres1_load = SimulationResult.load(tf.name,
                                            group_name=nfres1._model.name,
                                            dataset_name='nfsim test')

        # NFsim with expression
        nfres2.save(tf.name, include_obs_exprs=True, append=True)
        nfres2_load = SimulationResult.load(tf.name,
                                            group_name=nfres2._model.name)

    _check_resultsets_equal(simres, simres_load)
    _check_resultsets_equal(nfres1, nfres1_load)
    _check_resultsets_equal(nfres2, nfres2_load)
Пример #53
0
def test_save_load():
    tspan = np.linspace(0, 100, 101)
    # Make a copy of model so other tests etc. don't see the changed name.
    model = copy.deepcopy(tyson_oscillator.model)
    test_unicode_name = u'Hello \u2603 and \U0001f4a9!'
    model.name = test_unicode_name
    sim = ScipyOdeSimulator(model, integrator='lsoda')
    simres = sim.run(tspan=tspan, param_values={'k6': 1.0})

    sim_rob = ScipyOdeSimulator(robertson.model, integrator='lsoda')
    simres_rob = sim_rob.run(tspan=tspan)

    # Reset equations from any previous network generation
    robertson.model.reset_equations()
    A = robertson.model.monomers['A']

    # NFsim without expressions
    nfsim1 = BngSimulator(robertson.model)
    nfres1 = nfsim1.run(n_runs=2, method='nf', tspan=np.linspace(0, 1))
    # Test attribute saving (text, float, list)
    nfres1.custom_attrs['note'] = 'NFsim without expressions'
    nfres1.custom_attrs['pi'] = 3.14
    nfres1.custom_attrs['some_list'] = [1, 2, 3]

    # NFsim with expressions
    nfsim2 = BngSimulator(expression_observables.model)
    nfres2 = nfsim2.run(n_runs=1, method='nf', tspan=np.linspace(0, 100, 11))

    with tempfile.NamedTemporaryFile() as tf:
        # Cannot have two file handles on Windows
        tf.close()

        simres.save(tf.name, dataset_name='test', append=True)

        # Try to reload when file contains only one dataset and group
        SimulationResult.load(tf.name)

        simres.save(tf.name, append=True)

        # Trying to overwrite an existing dataset gives a ValueError
        assert_raises(ValueError, simres.save, tf.name, append=True)

        # Trying to write to an existing file without append gives an IOError
        assert_raises(IOError, simres.save, tf.name)

        # Trying to write a SimulationResult to the same group with a
        # different model name results in a ValueError
        assert_raises(ValueError, simres_rob.save, tf.name,
                      dataset_name='robertson', group_name=model.name,
                      append=True)

        simres_rob.save(tf.name, append=True)

        # Trying to load from a file with more than one group without
        # specifying group_name should raise a ValueError
        assert_raises(ValueError, SimulationResult.load, tf.name)

        # Trying to load from a group with more than one dataset without
        # specifying a dataset_name should raise a ValueError
        assert_raises(ValueError, SimulationResult.load, tf.name,
                      group_name=model.name)

        # Load should succeed when specifying group_name and dataset_name
        simres_load = SimulationResult.load(tf.name, group_name=model.name,
                                            dataset_name='test')
        assert simres_load._model.name == test_unicode_name

        # Saving network free results requires include_obs_exprs=True,
        # otherwise a warning should be raised
        with warnings.catch_warnings(record=True) as w:
            warnings.simplefilter("always")
            nfres1.save(tf.name, dataset_name='nfsim_no_obs', append=True)
            assert len(w) == 1
            assert issubclass(w[-1].category, UserWarning)

        nfres1.save(tf.name, include_obs_exprs=True,
                    dataset_name='nfsim test', append=True)

        # NFsim load
        nfres1_load = SimulationResult.load(tf.name,
                                            group_name=nfres1._model.name,
                                            dataset_name='nfsim test')

        # NFsim with expression
        nfres2.save(tf.name, include_obs_exprs=True, append=True)
        nfres2_load = SimulationResult.load(tf.name,
                                            group_name=nfres2._model.name)

    _check_resultsets_equal(simres, simres_load)
    _check_resultsets_equal(nfres1, nfres1_load)
    _check_resultsets_equal(nfres2, nfres2_load)
Пример #54
0
def odesolve(model, tspan, param_values=None, y0=None, integrator='vode',
             cleanup=True, verbose=False, **integrator_options):
    """Integrate a model's ODEs over a given timespan.

    This is a simple function-based interface to integrating (a.k.a. solving or
    simulating) a model. If you need to integrate a model repeatedly with
    different parameter values or initial conditions (as in parameter
    estimation), using the Solver class directly will provide much better
    performance.

    Parameters
    ----------
    model : pysb.Model
        Model to integrate.
    tspan : vector-like
        Time values over which to integrate. The first and last values define
        the time range, and the returned trajectories will be sampled at every
        value.
    param_values : vector-like, optional
        Values to use for every parameter in the model. Ordering is determined
        by the order of model.parameters. If not specified, parameter values
        will be taken directly from model.parameters.
    y0 : vector-like, optional
        Values to use for the initial condition of all species. Ordering is
        determined by the order of model.species. If not specified, initial
        conditions will be taken from model.initial_conditions (with initial
        condition parameter values taken from `param_values` if specified).
    integrator : string, optional
        Name of the integrator to use, taken from the list of integrators known
        to :py:class:`scipy.integrate.ode`.
    cleanup : bool, optional
        Remove temporary files after completion if True. Set to False for
        debugging purposes.
    verbose : bool, optionsal
        Increase verbosity of simulator output.
    integrator_options :
        Additional parameters for the integrator.

    Returns
    -------
    yfull : record array
        The trajectories calculated by the integration. The first dimension is
        time and its length is identical to that of `tspan`. The second
        dimension is species/observables and its length is the sum of the
        lengths of model.species and model.observables. The dtype of the array
        specifies field names: '__s0', '__s1', etc. for the species and
        observable names for the observables. See Notes below for further
        explanation and caveats.

    Notes
    -----
    This function was the first implementation of integration support and
    accordingly it has a few warts:

    * It performs expensive code generation every time it is called.

    * The returned array, with its record-style data-type, allows convenient
      selection of individual columns by their field names, but does not permit
      slice ranges or indexing by integers for columns. If you only need access
      to your model's observables this is usually not a problem, but sometimes
      it's more convenient to have a "regular" array. See Examples below for
      code to do this.

    The actual integration code has since been moved to the Solver class and
    split up such that the code generation is only performed on
    initialization. The model may then be integrated repeatedly with different
    parameter values or initial conditions with much better
    performance. Additionally, Solver makes the species trajectories available
    as a simple array and only uses the record array for the observables where
    it makes sense.

    This function now simply serves as a wrapper for creating a Solver object,
    calling its ``run`` method, and building the record array to return.

    Examples
    --------
    Simulate a model and display the results for an observable:

    >>> from pysb.examples.robertson import model
    >>> from numpy import linspace
    >>> numpy.set_printoptions(precision=4)
    >>> yfull = odesolve(model, linspace(0, 40, 10))
    >>> print(yfull['A_total'])            #doctest: +NORMALIZE_WHITESPACE
    [ 1.      0.899   0.8506  0.8179  0.793   0.7728  0.7557  0.7408  0.7277
    0.7158]

    Obtain a view on a returned record array which uses an atomic data-type and
    integer indexing (note that the view's data buffer is shared with the
    original array so there is no extra memory cost):

    >>> print(yfull.shape)
    (10,)
    >>> print(yfull.dtype)                 #doctest: +NORMALIZE_WHITESPACE
    [('__s0', '<f8'), ('__s1', '<f8'), ('__s2', '<f8'), ('A_total', '<f8'),
    ('B_total', '<f8'), ('C_total', '<f8')]
    >>> print(yfull[0:4, 1:3])             #doctest: +ELLIPSIS
    Traceback (most recent call last):
      ...
    IndexError: too many indices...
    >>> yarray = yfull.view(float).reshape(len(yfull), -1)
    >>> print(yarray.shape)
    (10, 6)
    >>> print(yarray.dtype)
    float64
    >>> print(yarray[0:4, 1:3])
    [[  0.0000e+00   0.0000e+00]
     [  2.1672e-05   1.0093e-01]
     [  1.6980e-05   1.4943e-01]
     [  1.4502e-05   1.8209e-01]]

    """
    integrator_options['integrator'] = integrator
    sim = ScipyOdeSimulator(model, tspan=tspan, cleanup=cleanup,
                            verbose=verbose, **integrator_options)
    simres = sim.run(param_values=param_values, initials=y0)
    return simres.all
Пример #55
0
 def test_lsoda_solver_run(self):
     """Test lsoda."""
     solver_lsoda = ScipyOdeSimulator(self.model,
                                      tspan=self.time,
                                      integrator='lsoda')
     solver_lsoda.run()
Пример #56
0
class Solver(object):
    """An interface for numeric integration of models.

    Parameters
    ----------
    model : pysb.Model
        Model to integrate.
    tspan : vector-like
        Time values over which to integrate. The first and last values define
        the time range, and the returned trajectories will be sampled at every
        value.
    use_analytic_jacobian : boolean, optional
        Whether to provide the solver a Jacobian matrix derived analytically
        from the model ODEs. Defaults to False. If False, the integrator may
        approximate the Jacobian by finite-differences calculations when
        necessary (depending on the integrator and settings).
    integrator : string, optional (default: 'vode')
        Name of the integrator to use, taken from the list of integrators known
        to :py:class:`scipy.integrate.ode`.
    cleanup : bool, optional
        If True (default), delete the temporary files after the simulation is
        finished. If False, leave them in place. Useful for debugging.
    verbose : bool, optional (default: False)
        Verbose output 
    integrator_options
        Additional parameters for the integrator.

    Attributes
    ----------
    model : pysb.Model
        Model passed to the constructor
    tspan : vector-like
        Time values passed to the constructor.
    y : numpy.ndarray
        Species trajectories. Dimensionality is ``(len(tspan),
        len(model.species))``.
    yobs : numpy.ndarray with record-style data-type
        Observable trajectories. Length is ``len(tspan)`` and record names
        follow ``model.observables`` names.
    yobs_view : numpy.ndarray
        An array view (sharing the same data buffer) on ``yobs``.
        Dimensionality is ``(len(tspan), len(model.observables))``.
    yexpr : numpy.ndarray with record-style data-type
        Expression trajectories. Length is ``len(tspan)`` and record names
        follow ``model.expressions_dynamic()`` names.
    yexpr_view : numpy.ndarray
        An array view (sharing the same data buffer) on ``yexpr``.
        Dimensionality is ``(len(tspan), len(model.expressions_dynamic()))``.
    integrator : scipy.integrate.ode
        Integrator object.

    Notes
    -----
    The expensive step of generating the code for the right-hand side of the
    model's ODEs is performed during initialization. If you need to integrate
    the same model repeatedly with different parameters then you should build a
    single Solver object and then call its ``run`` method as needed.

    """
    def __init__(self, model, tspan, use_analytic_jacobian=False,
                 integrator='vode', cleanup=True,
                 verbose=False, **integrator_options):
        self._sim = ScipyOdeSimulator(model, verbose=verbose, tspan=tspan,
                                     use_analytic_jacobian=
                                     use_analytic_jacobian,
                                     integrator=integrator, cleanup=cleanup,
                                     **integrator_options)
        self.result = None
        self._yexpr_view = None
        self._yobs_view = None

    @property
    def _use_inline(self):
        return ScipyOdeSimulator._use_inline

    @_use_inline.setter
    def _use_inline(self, use_inline):
        ScipyOdeSimulator._use_inline = use_inline

    @property
    def y(self):
        return self.result.species if self.result is not None else None

    @property
    def yobs(self):
        return self.result.observables if self.result is not None else None

    @property
    def yobs_view(self):
        if self._yobs_view is None:
            self._yobs_view = self.yobs.view(float).reshape(len(self.yobs), -1)
        return self._yobs_view

    @property
    def yexpr(self):
        return self.result.expressions if self.result is not None else None

    @property
    def yexpr_view(self):
        if self._yexpr_view is None:
            self._yexpr_view = self.yexpr.view(float).reshape(len(self.yexpr),
                                                              -1)
        return self._yexpr_view

    def run(self, param_values=None, y0=None):
        """Perform an integration.

        Returns nothing; access the Solver object's ``y``, ``yobs``, or
        ``yobs_view`` attributes to retrieve the results.

        Parameters
        ----------
        param_values : vector-like or dictionary, optional
            Values to use for every parameter in the model. Ordering is
            determined by the order of model.parameters. 
            If passed as a dictionary, keys must be parameter names.
            If not specified, parameter values will be taken directly from
            model.parameters.
        y0 : vector-like, optional
            Values to use for the initial condition of all species. Ordering is
            determined by the order of model.species. If not specified, initial
            conditions will be taken from model.initial_conditions (with
            initial condition parameter values taken from `param_values` if
            specified).
        """
        self._yobs_view = None
        self._yexpr_view = None
        self.result = self._sim.run(param_values=param_values, initials=y0)
Пример #57
0
 def test_lsoda_solver_run(self):
     """Test lsoda."""
     solver_lsoda = ScipyOdeSimulator(self.model, tspan=self.time,
                                      integrator='lsoda')
     solver_lsoda.run()
Пример #58
0
def test_set_initial_to_zero():
    sim = ScipyOdeSimulator(robertson.model, tspan=np.linspace(0, 100))
    simres = sim.run(initials={robertson.model.monomers['A'](): 0})
    assert np.allclose(simres.observables['A_total'], 0)