def create_model(**initial_counts): """ create_model(**initial_counts) -> model Creates a model for the catalytic reaction example. If specified, the optional keyword arguments A (defaults to 50) and D (defaults to 80) define the initial copy counts of species A and D respectively. """ initial_counts.setdefault('A', 50) initial_counts.setdefault('D', 80) s_1 = lambda *x: non_neg(initial_counts['A'] - x[0]) s_2 = lambda *x: non_neg(x[0] - x[1]) s_3 = lambda *x: x[1] s_4 = lambda *x: non_neg(initial_counts['D'] - x[2]) s_5 = lambda *x: x[2] return cmepy.model.create( name='simple catalytic reaction', reactions=('A->B', 'B->C', 'B+D->B+E'), propensities=(lambda *x: 1.0 * s_1(*x), lambda *x: 1000.0 * s_2(*x), lambda *x: 100.0 * s_4(*x) * s_2(*x)), transitions=((1, 0, 0), (0, 1, 0), (0, 0, 1)), species=('A', 'B', 'C', 'D', 'E'), species_counts=(s_1, s_2, s_3, s_4, s_5), shape=(initial_counts['A'] + 1, ) * 2 + (initial_counts['D'] + 1, ), initial_state=(0, ) * 3)
def create_model(**initial_counts): """ create_model(**initial_counts) -> model Creates a model for the catalytic reaction example. If specified, the optional keyword arguments A (defaults to 50) and D (defaults to 80) define the initial copy counts of species A and D respectively. """ initial_counts.setdefault('A', 50) initial_counts.setdefault('D', 80) s_1 = lambda *x : non_neg(initial_counts['A']-x[0]) s_2 = lambda *x : non_neg(x[0] - x[1]) s_3 = lambda *x : x[1] s_4 = lambda *x : non_neg(initial_counts['D']-x[2]) s_5 = lambda *x : x[2] return cmepy.model.create( name = 'simple catalytic reaction', reactions = ( 'A->B', 'B->C', 'B+D->B+E' ), propensities = ( lambda *x : 1.0 * s_1(*x), lambda *x : 1000.0 * s_2(*x), lambda *x : 100.0 * s_4(*x) * s_2(*x) ), transitions = ( (1, 0, 0), (0, 1, 0), (0, 0, 1) ), species = ( 'A', 'B', 'C', 'D', 'E' ), species_counts = ( s_1, s_2, s_3, s_4, s_5 ), shape = (initial_counts['A'] + 1, )*2 + (initial_counts['D'] + 1,), initial_state = (0, )*3 )
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_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 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 gen_states(**initial_counts): """ gen_states(**initial_counts) -> first state, ..., last state Creates a generator over states in a *truncated* reaction count state space, for the catalytic reaction example. If specified, the optional keyword arguments A (defaults to 50) and D (defaults to 80) define the initial copy counts of species A and D respectively. Each state yielded by this generator has the form state = (r_1, r_2, r_3), where non-negative integers r_1, r_2 and r_3 denote the count of the reactions 1, 2 and 3, respectively. Only states satisfying the following inequality are considered: (r_1, r_2, r_3) such that r_1 -3 <= r_2 <= r_1 The upper bound on r_2 follows from the model, as reaction 2 may occur at most once for each occurance of reaction 1. The lower bound on r_2 is an *artificial restriction that truncates the state space*. This introduces error, but because the rate constant of reaction 2 is 1000 times larger than the rate constant of reaction 1, the count of reaction 2 shall be close to the count of reaction 1 with high probability, and the resulting truncation error shall be small. This results in a truncated state space with roughly 4 * (A+1) * (D+1) states, compared to the 0.5 * (A+1)**2 * (D+1) states required for the full state space. """ initial_counts.setdefault('A', 50) initial_counts.setdefault('D', 80) for r_1 in xrange(initial_counts['A'] + 1): r_2_min = non_neg(r_1 - 3) r_2_max = r_1 for r_2 in xrange(r_2_min, r_2_max + 1): for r_3 in xrange(initial_counts['D'] + 1): yield (r_1, r_2, r_3) return
def create_model(dna_count=2, rna_max=15, m_max=15, d_max=15): # define mappings from state space to species copy counts dna = lambda *x: x[0] dna_d = lambda *x: x[1] dna_2d = lambda *x: dna_count - x[0] - x[1] rna = lambda *x: x[2] m = lambda *x: x[3] d = lambda *x: x[4] # define reaction propensity constants k = ( 4.3e-2, 7.0e-4, 7.8e-2, 3.9e-3, 1.2e7, 4.791e-1, 1.2e5, 8.765e-12, 1.0e8, 0.5, ) return cmepy.model.create( name='Goutsias transcription regulation', species=( 'DNA', 'DNA-D', 'DNA-2D', 'RNA', 'M', 'D', ), species_counts=( dna, dna_d, dna_2d, rna, m, d, ), reactions=( 'RNA -> RNA + M', 'M -> *', 'DNA-D -> RNA + DNA-D', 'RNA -> *', 'DNA + D -> DNA-D', 'DNA-D -> DNA + D', 'DNA-D + D -> DNA-2D', 'DNA-2D -> DNA-D + D', 'M + M -> D', 'D -> M + M', ), propensities=( lambda *x: k[0] * rna(*x), lambda *x: k[1] * m(*x), lambda *x: k[2] * dna_d(*x), lambda *x: k[3] * rna(*x), lambda *x: k[4] * dna(*x) * d(*x), lambda *x: k[5] * dna_d(*x), lambda *x: k[6] * dna_d(*x) * d(*x), lambda *x: k[7] * dna_2d(*x), lambda *x: k[8] * 0.5 * m(*x) * non_neg(m(*x) - 1), lambda *x: k[9] * d(*x), ), transitions=( (0, 0, 0, 1, 0), (0, 0, 0, -1, 0), (0, 0, 1, 0, 0), (0, 0, 1, 0, 0), (-1, 1, 0, 0, -1), (1, -1, 0, 0, 1), (0, -1, 0, 0, -1), (0, 1, 0, 0, 1), (0, 0, 0, -2, 1), (0, 0, 0, 2, -1), ), shape=(dna_count + 1, ) * 2 + (rna_max + 1, m_max + 1, d_max + 1), initial_state=(dna_count, 0, 0, 2, 6))
""" some mono-molecular models """ from cmepy.util import non_neg 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', ),
def create_model(max_papi = 100, papi_count = 5, dna_count = 1, lrp_count = 100): """ creates pap-pili epigenetic switch model. """ # define mappings from state space to species counts dna = lambda *x : x[0] dna_lrp = lambda *x : x[1] lrp_dna = lambda *x : x[2] lrp_dna_lrp = lambda *x : non_neg(dna_count - x[0] - x[1] - x[2]) lrp = lambda *x :non_neg( lrp_count - 2*lrp_dna_lrp(*x) - dna_lrp(*x) - lrp_dna(*x) ) papi = lambda *x : x[3] def f(r): return r / (1.0 + r) # define reaction propensities props = ( lambda *x : 1.0 * dna(*x) * lrp(*x), lambda *x : (2.5 - 2.25*f(papi(*x))) * lrp_dna(*x), lambda *x : 1.0 * dna(*x) * lrp(*x), lambda *x : (1.2 - 0.20 * f(papi(*x))) * dna_lrp(*x), lambda *x : 0.01 * lrp_dna(*x) * lrp(*x), lambda *x : (1.2 - 0.20 * f(papi(*x))) * lrp_dna_lrp(*x), lambda *x : 0.01 * dna_lrp(*x) * lrp(*x), lambda *x : (2.5 - 2.25 * f(papi(*x))) * lrp_dna_lrp(*x), lambda *x : 10.0 * lrp_dna(*x), lambda *x : 1.0 * papi(*x), ) # define corresponding reaction state space offsets transitions = ( (-1, 0, 1, 0), # LRP + DNA -> LRP-DNA (1, 0, -1, 0), # LRP-DNA -> LRP + DNA (-1, 1, 0, 0), # DNA + LRP -> DNA-LRP (1, -1, 0, 0), # DNA-LRP -> DNA + LRP (0, 0, -1, 0), # LRP-DNA + LRP -> LRP-DNA-LRP (0, 0, 1, 0), # LRP-DNA-LRP -> LRP-DNA + LRP (0, -1, 0, 0), # LRP + DNA-LRP -> LRP-DNA-LRP (0, 1, 0, 0), # LRP-DNA-LRP -> LRP + DNA-LRP (0, 0, 0, 1), # * -> PapI (0, 0, 0, -1), # PapI -> * ) species_names = ( 'DNA', 'DNA-LRP', 'LRP-DNA', 'LRP-DNA-LRP', 'LRP', 'PapI', ) species_counts = ( dna, dna_lrp, lrp_dna, lrp_dna_lrp, lrp, papi, ) return cmepy.model.create( name = 'pap-pili epigenetic switch', species = species_names, species_counts = species_counts, propensities = props, transitions = transitions, shape = (dna_count+1, )*3 + (max_papi+1, ), initial_state = (dna_count, 0, 0, papi_count) )
def create_model(dna_count=2, rna_max=15, m_max=15, d_max=15): # define mappings from state space to species copy counts dna = lambda *x : x[0] dna_d = lambda *x : x[1] dna_2d = lambda *x : dna_count - x[0] - x[1] rna = lambda *x : x[2] m = lambda *x : x[3] d = lambda *x : x[4] # define reaction propensity constants k = ( 4.3e-2, 7.0e-4, 7.8e-2, 3.9e-3, 1.2e7, 4.791e-1, 1.2e5, 8.765e-12, 1.0e8, 0.5, ) return cmepy.model.create( name = 'Goutsias transcription regulation', species = ( 'DNA', 'DNA-D', 'DNA-2D', 'RNA', 'M', 'D', ), species_counts = ( dna, dna_d, dna_2d, rna, m, d, ), reactions = ( 'RNA -> RNA + M', 'M -> *', 'DNA-D -> RNA + DNA-D', 'RNA -> *', 'DNA + D -> DNA-D', 'DNA-D -> DNA + D', 'DNA-D + D -> DNA-2D', 'DNA-2D -> DNA-D + D', 'M + M -> D', 'D -> M + M', ), propensities = ( lambda *x : k[0] * rna(*x), lambda *x : k[1] * m(*x), lambda *x : k[2] * dna_d(*x), lambda *x : k[3] * rna(*x), lambda *x : k[4] * dna(*x) * d(*x), lambda *x : k[5] * dna_d(*x), lambda *x : k[6] * dna_d(*x) * d(*x), lambda *x : k[7] * dna_2d(*x), lambda *x : k[8] * 0.5 * m(*x) * non_neg(m(*x) - 1), lambda *x : k[9] * d(*x), ), transitions = ( (0, 0, 0, 1, 0), (0, 0, 0, -1, 0), (0, 0, 1, 0, 0), (0, 0, 1, 0, 0), (-1, 1, 0, 0, -1), (1, -1, 0, 0, 1), (0, -1, 0, 0, -1), (0, 1, 0, 0, 1), (0, 0, 0, -2, 1), (0, 0, 0, 2, -1), ), shape = (dna_count+1, )*2 + (rna_max+1, m_max+1, d_max+1), initial_state = (dna_count, 0, 0, 2, 6) )
from cmepy import model 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) )
from cmepy import model 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', ),
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 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()