def create_model_gene_toggle(max_s1_copies=100, max_s2_copies=100): """ creates stochastic version of Gardner's gene toggle model """ s1_count = lambda s1, s2: s1 s2_count = lambda s1, s2: s2 s1_birth = lambda s1, s2: 16.0 / (1.0 + s2) s1_death = lambda s1, s2: 1.0 * s1 s2_birth = lambda s1, s2: 50.0 / (1.0 + (s1**2.5)) s2_death = lambda s1, s2: 1.0 * s2 propensities = (s1_birth, s1_death, s2_birth, s2_death) transitions = ((1, 0), (-1, 0), (0, 1), (0, -1)) shape = (max_s1_copies + 1, max_s2_copies + 1) initial_state = (0, ) * 2 return model.create( name='Gardner\'s gene toggle according to Munsky & Khammash', species=('S1', 'S2'), species_counts=(s1_count, s2_count), reactions=('*->S1', 'S1->*', '*->S2', 'S2->*'), propensities=propensities, transitions=transitions, shape=shape, initial_state=initial_state)
def create_model_gene_toggle(max_s1_copies=100, max_s2_copies=100): """ creates stochastic version of Gardner's gene toggle model """ s1_count = lambda s1, s2 : s1 s2_count = lambda s1, s2 : s2 s1_birth = lambda s1, s2 : 16.0/(1.0+s2) s1_death = lambda s1, s2 : 1.0*s1 s2_birth = lambda s1, s2 : 50.0/(1.0+(s1**2.5)) s2_death = lambda s1, s2 : 1.0*s2 propensities = (s1_birth, s1_death, s2_birth, s2_death) transitions = ((1, 0), (-1, 0), (0, 1), (0, -1)) shape = (max_s1_copies+1, max_s2_copies+1) initial_state = (0, )*2 return model.create( name = 'Gardner\'s gene toggle according to Munsky & Khammash', species = ('S1', 'S2'), species_counts = (s1_count, s2_count), reactions = ('*->S1', 'S1->*', '*->S2', 'S2->*'), propensities = propensities, transitions = transitions, shape = shape, initial_state = initial_state )
def main(): initial_copies = 20 m = model.create(propensities=[lambda x: initial_copies - x], transitions=[(1, )], shape=(initial_copies + 1, ), initial_state=(0, )) s = solver.create(model=m, sink=False) r = recorder.create((('A->B', ), )) time_steps = numpy.linspace(0.0, 3.0, 6) for t in time_steps: s.step(t) r.write(t, s.y) pylab.figure() for t, d in zip(r['A->B'].times, r['A->B'].distributions): marginal = d.to_dense(m.shape) pylab.plot(marginal, label='t = %.1f' % t) pylab.xlabel('Reaction count') pylab.ylabel('Probability') pylab.legend() pylab.savefig('simple_plot.png')
def main(): initial_copies = 20 m = model.create( propensities = [lambda x: initial_copies - x], transitions = [(1, )], shape = (initial_copies + 1, ), initial_state = (0, ) ) s = solver.create( model = m, sink = False ) r = recorder.create( (('A->B', ), ) ) time_steps = numpy.linspace(0.0, 3.0, 6) for t in time_steps: s.step(t) r.write(t, s.y) pylab.figure() for t, d in zip(r['A->B'].times, r['A->B'].distributions): marginal = d.to_dense(m.shape) pylab.plot(marginal, label = 't = %.1f' % t) pylab.xlabel('Reaction count') pylab.ylabel('Probability') pylab.legend() pylab.savefig('simple_plot.png')
def create_model(initial_copies=None): """ Returns mapping storing model. NB state space format: (c2_copies, c1_copies, s_copies) """ if initial_copies is None: initial_copies = default_initial_copies() s_copies = lambda *x: x[2] c1_copies = lambda *x: x[1] c2_copies = lambda *x: x[0] p_copies = lambda *x: initial_copies['S'] - x[0] - x[1] - x[2] e1_copies = lambda *x: initial_copies['E1'] - x[1] e2_copies = lambda *x: initial_copies['E2'] - x[0] return model.create(name='dual enzymatic reactions', reactions=( 'S+E1 -> C1', 'C1 -> S+E1', 'C1 -> P+E1', 'P+E2 -> C2', 'C2 -> P+E2', 'C2 -> S+E2', ), propensities=( lambda *x: 4.0 * s_copies(*x) * e1_copies(*x), lambda *x: 5.0 * c1_copies(*x), lambda *x: 1.0 * c1_copies(*x), lambda *x: 4.0 * p_copies(*x) * e2_copies(*x), lambda *x: 5.0 * c2_copies(*x), lambda *x: 1.0 * c2_copies(*x), ), transitions=( (0, 1, -1), (0, -1, 1), (0, -1, 0), (1, 0, 0), (-1, 0, 0), (-1, 0, 1), ), species=( 'S', 'C1', 'C2', 'P', 'E1', 'E2', ), species_counts=( s_copies, c1_copies, c2_copies, p_copies, e1_copies, e2_copies, ), initial_state=(0, 0, initial_copies['S']))
def compare_against_binomial(rate, shape): m = model.create(propensities=(lambda *x: rate * (shape[0] - x[0]), ), transitions=((1, ), ), shape=shape, initial_state=(0, )) compare_against_exact(m, t=1.0, f=lambda p: p.to_dense(shape), p_exact=exact_binomial(rate, shape[0]))
def compare_against_binomial(rate, shape): m = model.create( propensities = (lambda *x : rate*(shape[0]-x[0]), ), transitions = ((1, ), ), shape = shape, initial_state = (0, ) ) compare_against_exact(m, t = 1.0, f = lambda p : p.to_dense(shape), p_exact = exact_binomial(rate, shape[0]))
def create_model_uni_dim(initial_copies=10, rate=0.001): """ returns model for P+Q -> PQ with initial copies of P, Q and rate specified. """ m = model.create(name='Unidirectional Dimerisation', propensities=[lambda x: rate * (initial_copies - x)**2], transitions=[(1, )], reactions=['P+Q -> PQ'], species=['P', 'Q', 'PQ'], species_counts=(lambda x: initial_copies - x, ) * 2 + (lambda x: x, ), shape=(initial_copies + 1, ), initial_state=(0, )) return m
def main(): """ the complete example from the slides """ import numpy from cmepy import solver, recorder, model from cmepy.util import non_neg s_0 = 50 e_0 = 10 s = lambda *x : x[0] e = lambda *x : non_neg(e_0 - x[1]) c = lambda *x : x[1] p = lambda *x : non_neg(s_0 - x[0] - x[1]) m = model.create( species_counts = (s, e, c, p, ), propensities = ( lambda *x : 0.01*s(*x)*e(*x), lambda *x : 35.0*c(*x), lambda *x : 30.0*c(*x), ), transitions = ( (-1, 1), (1, -1), (0, -1) ), shape = (s_0 + 1, min(s_0, e_0) + 1), initial_state = (s_0, 0) ) enzyme_solver = solver.create( model = m, sink = False ) time_steps = numpy.linspace(0.0, 10.0, 101) r = recorder.create( (['S', 'E', 'C', 'P'], m.species_counts) ) for t in time_steps: enzyme_solver.step(t) r.write(t, enzyme_solver.y) recorder.display_plots(r)
def create_model_uni_dim(initial_copies = 10, rate = 0.001): """ returns model for P+Q -> PQ with initial copies of P, Q and rate specified. """ m = model.create( name = 'Unidirectional Dimerisation', propensities = [lambda x : rate*(initial_copies-x)**2], transitions = [(1, )], reactions = ['P+Q -> PQ'], species = ['P', 'Q', 'PQ'], species_counts = (lambda x : initial_copies - x, )*2 + (lambda x : x, ), shape = (initial_copies + 1, ), initial_state = (0, ) ) return m
def create_model_michaelis_menten(s_0=50, e_0=10): """ Creates a model for a simple michaelis-menten enzymatic reaction system: E+S <-> C -> E + D The reaction propensities are E+S -> C : 0.01 C -> E+S : 35.0 C -> E+D : 30.0 while the initial counts are s_0 copies of S, e_0 copies of E, and zero copies of both C and D. """ # first, define functions mapping states to species copy counts species_c = ( lambda *x: x[0], lambda *x: non_neg(e_0 - x[1]), lambda *x: x[1], lambda *x: non_neg(s_0 - x[0] - x[1]), ) # second, define reaction propensities via species counts props = ( lambda *x: 0.01 * species_c[0](*x) * species_c[1](*x), lambda *x: 35.0 * species_c[2](*x), lambda *x: 30.0 * species_c[2](*x), ) # construct the model return model.create(name='simple Michaelis-Menten system', species=( 'S', 'E', 'C', 'D', ), species_counts=species_c, reactions=( 'E+S->C', 'C->E+S', 'C->E+D', ), propensities=props, transitions=((-1, 1), (1, -1), (0, -1)), shape=(s_0 + 1, max(s_0, e_0) + 1), initial_state=(s_0, 0))
def compare_against_poisson(rates, shape): # generate model & create a solver for it size = len(shape) def constant_propensity(rate): return lambda *x : rate props = tuple(constant_propensity(r) for r in rates) transitions = tuple((0,)*i + (1,) + (0,)*(size-1-i) for i in xrange(size)) m = model.create( propensities = props, transitions = transitions, shape = shape, initial_state = (0, )*size ) compare_against_exact(m, t = 1.0, f = lambda p : p.to_dense(shape), p_exact = exact_poisson(rates, shape))
def compare_against_poisson(rates, shape): # generate model & create a solver for it size = len(shape) def constant_propensity(rate): return lambda *x: rate props = tuple(constant_propensity(r) for r in rates) transitions = tuple( (0, ) * i + (1, ) + (0, ) * (size - 1 - i) for i in xrange(size)) m = model.create(propensities=props, transitions=transitions, shape=shape, initial_state=(0, ) * size) compare_against_exact(m, t=1.0, f=lambda p: p.to_dense(shape), p_exact=exact_poisson(rates, shape))
def create_model_michaelis_menten(s_0 = 50, e_0 = 10): """ Creates a model for a simple michaelis-menten enzymatic reaction system: E+S <-> C -> E + D The reaction propensities are E+S -> C : 0.01 C -> E+S : 35.0 C -> E+D : 30.0 while the initial counts are s_0 copies of S, e_0 copies of E, and zero copies of both C and D. """ # first, define functions mapping states to species copy counts species_c = ( lambda *x : x[0], lambda *x : non_neg(e_0 - x[1]), lambda *x : x[1], lambda *x : non_neg(s_0 - x[0] - x[1]), ) # second, define reaction propensities via species counts props = ( lambda *x : 0.01*species_c[0](*x)*species_c[1](*x), lambda *x : 35.0*species_c[2](*x), lambda *x : 30.0*species_c[2](*x), ) # construct the model return model.create( name = 'simple Michaelis-Menten system', species = ('S', 'E', 'C', 'D', ), species_counts = species_c, reactions = ('E+S->C', 'C->E+S', 'C->E+D', ), propensities = props, transitions = ((-1, 1), (1, -1), (0, -1)), shape = (s_0 + 1, max(s_0, e_0) + 1), initial_state = (s_0, 0) )
from cmepy import model A2B2C = model.create( name = 'simplest nontrivial mono-molecular reaction', propensities = ( lambda *x: non_neg(31.0-x[0]), lambda *x: non_neg(x[0]-x[1]), ), transitions = ( (1, 0), (0, 1), ), reactions = ( 'A->B', 'B->C', ), species_counts = ( lambda *x: non_neg(31-x[0]), lambda *x: non_neg(x[0]-x[1]), lambda *x: x[1], ), species = ( 'A', 'B', 'C', ), shape = (32, 32), initial_state = (0, 0) ) A2B2A = model.create(
def create_model(): """ create species count state space version of the competing clonotypes model """ shape = (50, 50) # we first define the mappings from the state space to species counts # this is pretty easy since we choose species count state space species_count_a = lambda *x : x[0] species_count_b = lambda *x : x[1] # we now define the reaction propensities using the species counts def reaction_a_birth(*x): """ propensity of birth reaction for species a """ s_a = species_count_a(*x) s_b = species_count_b(*x) return numpy.where(s_a + s_b > 0, 60.0*s_a*(numpy.divide(0.5, s_a + s_b) + numpy.divide(0.5, (s_a + 10*100))), 0.0) def reaction_a_decay(*x): return 1.0*species_count_a(*x) def reaction_b_birth(*x): """ propensity of birth reaction for species b """ s_a = species_count_a(*x) s_b = species_count_b(*x) return numpy.where(s_a + s_b > 0, 60.0*s_b*(numpy.divide(0.5, s_a + s_b) + numpy.divide(0.5, (s_b + 10*100))), 0.0) def reaction_b_decay(*x): return 1.0*species_count_b(*x) return model.create( name = 'T Cell clonoTypes', reactions = ( '*->A', 'A->*', '*->B', 'B->*', ), propensities = ( reaction_a_birth, reaction_a_decay, reaction_b_birth, reaction_b_decay, ), transitions = ( (1, 0), (-1, 0), (0, 1), (0, -1), ), species = ( 'A', 'B', ), species_counts = ( species_count_a, species_count_b, ), shape = shape, initial_state = (10, 10) )
def create_model(): """ create species count state space version of the competing clonotypes model """ shape = (50, 50) # we first define the mappings from the state space to species counts # this is pretty easy since we choose species count state space species_count_a = lambda *x: x[0] species_count_b = lambda *x: x[1] # we now define the reaction propensities using the species counts def reaction_a_birth(*x): """ propensity of birth reaction for species a """ s_a = species_count_a(*x) s_b = species_count_b(*x) return numpy.where( s_a + s_b > 0, 60.0 * s_a * (numpy.divide(0.5, s_a + s_b) + numpy.divide(0.5, (s_a + 10 * 100))), 0.0) def reaction_a_decay(*x): return 1.0 * species_count_a(*x) def reaction_b_birth(*x): """ propensity of birth reaction for species b """ s_a = species_count_a(*x) s_b = species_count_b(*x) return numpy.where( s_a + s_b > 0, 60.0 * s_b * (numpy.divide(0.5, s_a + s_b) + numpy.divide(0.5, (s_b + 10 * 100))), 0.0) def reaction_b_decay(*x): return 1.0 * species_count_b(*x) return model.create(name='T Cell clonoTypes', reactions=( '*->A', 'A->*', '*->B', 'B->*', ), propensities=( reaction_a_birth, reaction_a_decay, reaction_b_birth, reaction_b_decay, ), transitions=( (1, 0), (-1, 0), (0, 1), (0, -1), ), species=( 'A', 'B', ), species_counts=( species_count_a, species_count_b, ), shape=shape, initial_state=(10, 10))
def create_model_quad_autocat(max_p=30, max_q=30, fixed_s=True, s_0=10, d_0=2, vol=1.0): """ Creates a species-count based model for the system of reactions: S->P D+P->D+P+P P+P->P+Q P+Q->Q+Q P->* Q->* The copy counts of the species S and D are assumed to be constant, with s_0 (default 10) copies of S and d_0 (default 2) copies of D. If fixed_s is set to False, copy count of species S will no longer be constant, and will be decreased by the reaction S->P. """ model_name = 'Quadratic Autocatalator (%s S)' p = lambda *x: x[0] q = lambda *x: x[1] d = lambda *x: d_0 if fixed_s: s = lambda *x: s_0 model_name %= 'fixed' transitions = ( (1, 0), (1, 0), (-1, 1), (-1, 1), (-1, 0), (0, -1), ) shape = (max_p + 1, max_q + 1) initial_state = (0, ) * 2 else: model_name %= 'variable' s = lambda *x: x[2] transitions = ( (1, 0, -1), (1, 0, 0), (-1, 1, 0), (-1, 1, 0), (-1, 0, 0), (0, -1, 0), ) shape = (max_p + 1, max_q + 1, s_0 + 1) initial_state = ( 0, 0, 3, ) m = model.create(name=model_name, reactions=( 'S->P', 'D+P->D+2P', 'P+P->P+Q', 'P+Q->2Q', 'P->*', 'Q->*', ), propensities=( lambda *x: 0.002 * (vol**-1) * s(*x), lambda *x: 0.001 * (vol**-2) * d(*x) * p(*x), lambda *x: 0.005 * (vol**-2) * p(*x) * non_neg(p(*x) - 1) / 2.0, lambda *x: 0.004 * (vol**-2) * p(*x) * q(*x), lambda *x: 0.002 * (vol**-1) * p(*x), lambda *x: 0.050 * (vol**-1) * q(*x), ), transitions=transitions, species=( 'P', 'Q', 'S', 'D', ), species_counts=( p, q, s, d, ), shape=shape, initial_state=initial_state) return m
def main(): import numpy from cmepy import solver, recorder, model from cmepy.util import non_neg s_0 = 50 e_0 = 10 s = lambda *x : x[0] e = lambda *x : non_neg(e_0 - x[1]) c = lambda *x : x[1] p = lambda *x : non_neg(s_0 - x[0] - x[1]) m = model.create( species_counts = (s, e, c, p, ), propensities = ( lambda *x : 0.01*s(*x)*e(*x), lambda *x : 35.0*c(*x), lambda *x : 30.0*c(*x), ), transitions = ( (-1, 1), (1, -1), (0, -1) ), shape = (s_0 + 1, min(s_0, e_0) + 1), initial_state = (s_0, 0) ) enzyme_solver = solver.create( model = m, sink = False ) time_steps = numpy.linspace(0.0, 30.0, 101) species = ['S', 'E', 'C', 'P'] r = recorder.create( (species, m.species_counts) ) for t in time_steps: enzyme_solver.step(t) r.write(t, enzyme_solver.y) import pylab species_colours = { 'S' : 'r', 'E' : 'k', 'C' : 'g', 'P' : 'b', } pylab.figure() for var in species: colour = species_colours[var] measurement = r[var] mu = numpy.reshape(numpy.array(measurement.expected_value), (-1, )) sigma = numpy.array(measurement.standard_deviation) mu_style = '-'+colour mu_pm_sigma_style = '--'+colour pylab.plot(measurement.times, mu, mu_style, label = var) pylab.plot(measurement.times, mu + sigma, mu_pm_sigma_style) pylab.plot(measurement.times, mu - sigma, mu_pm_sigma_style) title_lines = ( 'Enzymatic Reaction Species Counts:', 'expected values $\pm$ 1 standard deviation', ) pylab.title('\n'.join(title_lines)) pylab.xlabel('time') pylab.ylabel('species count') pylab.legend() pylab.show()
def create_model(initial_copies = None): """ Returns mapping storing model. NB state space format: (c2_copies, c1_copies, s_copies) """ if initial_copies is None: initial_copies = default_initial_copies() s_copies = lambda *x : x[2] c1_copies = lambda *x : x[1] c2_copies = lambda *x : x[0] p_copies = lambda *x : initial_copies['S'] - x[0] - x[1] - x[2] e1_copies = lambda *x : initial_copies['E1'] - x[1] e2_copies = lambda *x : initial_copies['E2'] - x[0] return model.create( name = 'dual enzymatic reactions', reactions = ( 'S+E1 -> C1', 'C1 -> S+E1', 'C1 -> P+E1', 'P+E2 -> C2', 'C2 -> P+E2', 'C2 -> S+E2', ), propensities = ( lambda *x : 4.0*s_copies(*x)*e1_copies(*x), lambda *x : 5.0*c1_copies(*x), lambda *x : 1.0*c1_copies(*x), lambda *x : 4.0*p_copies(*x)*e2_copies(*x), lambda *x : 5.0*c2_copies(*x), lambda *x : 1.0*c2_copies(*x), ), transitions = ( (0, 1, -1), (0, -1, 1), (0, -1, 0), (1, 0, 0), (-1, 0, 0), (-1, 0, 1), ), species = ( 'S', 'C1', 'C2', 'P', 'E1', 'E2', ), species_counts = ( s_copies, c1_copies, c2_copies, p_copies, e1_copies, e2_copies, ), initial_state = (0, 0, initial_copies['S']) )
Some models adapted from the Discrete Stochastic Models Test Suite. See http://code.google.com/p/dsmts/ """ from cmepy import model DSMTS_001_01 = model.create( name = 'Birth-death model (001), variant 01', propensities = ( lambda *x: 0.1*x[0], lambda *x: 0.11*x[0], ), reactions = ( 'X -> 2X', 'X -> *', ), transitions = ( (1, ), (-1, ), ), species_counts = ( lambda *x : x[0], ), species = ( 'X', ), shape = (200, ), initial_state = (100, ) )
""" Some models adapted from the Discrete Stochastic Models Test Suite. See http://code.google.com/p/dsmts/ """ from cmepy import model DSMTS_001_01 = model.create(name='Birth-death model (001), variant 01', propensities=( lambda *x: 0.1 * x[0], lambda *x: 0.11 * x[0], ), reactions=( 'X -> 2X', 'X -> *', ), transitions=( (1, ), (-1, ), ), species_counts=(lambda *x: x[0], ), species=('X', ), shape=(200, ), initial_state=(100, ))
c = lambda *x: x[1] p = lambda *x: non_neg(s_0 - x[0] - x[1]) # model definition, in terms of species count functions m = model.create(name='enzyme kinetics', species=( 'S', 'E', 'C', 'P', ), species_counts=( s, e, c, p, ), reactions=( 'E+S->C', 'C->E+S', 'C->E+P', ), propensities=( lambda *x: 0.01 * s(*x) * e(*x), lambda *x: 35.0 * c(*x), lambda *x: 30.0 * c(*x), ), transitions=((-1, 1), (1, -1), (0, -1)), shape=(s_0 + 1, min(s_0, e_0) + 1), initial_state=(s_0, 0))
def create_model_quad_autocat(max_p=30, max_q=30, fixed_s=True, s_0=10, d_0=2, vol=1.0): """ Creates a species-count based model for the system of reactions: S->P D+P->D+P+P P+P->P+Q P+Q->Q+Q P->* Q->* The copy counts of the species S and D are assumed to be constant, with s_0 (default 10) copies of S and d_0 (default 2) copies of D. If fixed_s is set to False, copy count of species S will no longer be constant, and will be decreased by the reaction S->P. """ model_name = 'Quadratic Autocatalator (%s S)' p = lambda *x : x[0] q = lambda *x : x[1] d = lambda *x : d_0 if fixed_s: s = lambda *x : s_0 model_name %= 'fixed' transitions = ( (1, 0), (1, 0), (-1, 1), (-1, 1), (-1, 0), (0, -1), ) shape = (max_p+1, max_q+1) initial_state = (0, )*2 else: model_name %= 'variable' s = lambda *x : x[2] transitions = ( (1, 0, -1), (1, 0, 0), (-1, 1, 0), (-1, 1, 0), (-1, 0, 0), (0, -1, 0), ) shape = (max_p+1, max_q+1, s_0+1) initial_state = (0, 0, 3, ) m = model.create( name = model_name, reactions = ( 'S->P', 'D+P->D+2P', 'P+P->P+Q', 'P+Q->2Q', 'P->*', 'Q->*', ), propensities = ( lambda *x : 0.002 * (vol ** -1) * s(*x), lambda *x : 0.001 * (vol ** -2) * d(*x) * p(*x), lambda *x : 0.005 * (vol ** -2) * p(*x) * non_neg(p(*x) - 1) / 2.0, lambda *x : 0.004 * (vol ** -2) * p(*x) * q(*x), lambda *x : 0.002 * (vol ** -1) * p(*x), lambda *x : 0.050 * (vol ** -1) * q(*x), ), transitions = transitions, species = ('P', 'Q', 'S', 'D', ), species_counts = ( p, q, s, d, ), shape = shape, initial_state = initial_state ) return m
from cmepy.util import non_neg s_0 = 50 e_0 = 10 # species count function definitions s = lambda *x : x[0] e = lambda *x : non_neg(e_0 - x[1]) c = lambda *x : x[1] p = lambda *x : non_neg(s_0 - x[0] - x[1]) # model definition, in terms of species count functions m = model.create( name = 'enzyme kinetics', species = ('S', 'E', 'C', 'P', ), species_counts = (s, e, c, p, ), reactions = ('E+S->C', 'C->E+S', 'C->E+P', ), propensities = ( lambda *x : 0.01*s(*x)*e(*x), lambda *x : 35.0*c(*x), lambda *x : 30.0*c(*x), ), transitions = ( (-1, 1), (1, -1), (0, -1) ), shape = (s_0 + 1, min(s_0, e_0) + 1), initial_state = (s_0, 0) )