Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

model of lac operon in E. coli

using ComponentArrays: ComponentArray
using SimpleUnPack
using DiffEqCallbacks
using OrdinaryDiffEq
using SteadyStateDiffEq
using CairoMakie
function model707!(D, u, p, t)
    hil(x, k) = x / (x + k)
    hil(x, k, n) = hil(x^n, k^n)
    @unpack Le, a1, RToverK1, K2, δM, δY, δL, c1, kL, KML, kg, KMg = p
    @unpack M, Y, L = u
    D.M = a1 / (1 + RToverK1 * (K2 / (K2 + L))^4) - δM * M
    D.Y = c1 * M - δY * Y
    D.L = kL * Y * hil(Le, KML) - 2kg * (Y/4) * hil(L, KMg) - δL * L
    nothing
end
model707! (generic function with 1 method)
ps707 = ComponentArray(
    δM = 0.48,
    δY = 0.03,
    δL = 0.02,
    a1 = 0.29,
    K2 = 2.92e6,
    RToverK1 = 213.2,
    c1 = 18.8,
    kL = 6e4,
    KML = 680.0,
    kg = 3.6e3,
    KMg = 7e5,
    Le = 0.0,
)

ics707 = ComponentArray(
    M = 0.01,
    Y = 0.1,
    L = 0.0,
)
ComponentVector{Float64}(M = 0.01, Y = 0.1, L = 0.0)

Events

affect_le1!(integrator) = integrator.p.Le = 50
affect_le2!(integrator) = integrator.p.Le = 100
affect_le3!(integrator) = integrator.p.Le = 150
affect_le4!(integrator) = integrator.p.Le = 0
event_le1 = PresetTimeCallback([500.0], affect_le1!)
event_le2 = PresetTimeCallback([1000.0], affect_le2!)
event_le3 = PresetTimeCallback([1500.0], affect_le3!)
event_le4 = PresetTimeCallback([2000.0], affect_le4!)
cbs = CallbackSet(event_le1, event_le2, event_le3, event_le4)
SciMLBase.CallbackSet{Tuple{}, Tuple{SciMLBase.DiscreteCallback{DiffEqCallbacks.PresetTimeFunction{Vector{Float64}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(Main.var"##249".affect_le1!)}, typeof(Main.var"##249".affect_le1!), DiffEqCallbacks.PresetTimeFunction{Vector{Float64}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(Main.var"##249".affect_le1!)}, typeof(SciMLBase.FINALIZE_DEFAULT), Nothing, Tuple{}}, SciMLBase.DiscreteCallback{DiffEqCallbacks.PresetTimeFunction{Vector{Float64}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(Main.var"##249".affect_le2!)}, typeof(Main.var"##249".affect_le2!), DiffEqCallbacks.PresetTimeFunction{Vector{Float64}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(Main.var"##249".affect_le2!)}, typeof(SciMLBase.FINALIZE_DEFAULT), Nothing, Tuple{}}, SciMLBase.DiscreteCallback{DiffEqCallbacks.PresetTimeFunction{Vector{Float64}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(Main.var"##249".affect_le3!)}, typeof(Main.var"##249".affect_le3!), DiffEqCallbacks.PresetTimeFunction{Vector{Float64}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(Main.var"##249".affect_le3!)}, typeof(SciMLBase.FINALIZE_DEFAULT), Nothing, Tuple{}}, SciMLBase.DiscreteCallback{DiffEqCallbacks.PresetTimeFunction{Vector{Float64}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(Main.var"##249".affect_le4!)}, typeof(Main.var"##249".affect_le4!), DiffEqCallbacks.PresetTimeFunction{Vector{Float64}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(Main.var"##249".affect_le4!)}, typeof(SciMLBase.FINALIZE_DEFAULT), Nothing, Tuple{}}}}((), (SciMLBase.DiscreteCallback{DiffEqCallbacks.PresetTimeFunction{Vector{Float64}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(Main.var"##249".affect_le1!)}, typeof(Main.var"##249".affect_le1!), DiffEqCallbacks.PresetTimeFunction{Vector{Float64}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(Main.var"##249".affect_le1!)}, typeof(SciMLBase.FINALIZE_DEFAULT), Nothing, Tuple{}}(DiffEqCallbacks.PresetTimeFunction{Vector{Float64}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(Main.var"##249".affect_le1!)}([500.0], true, SciMLBase.INITIALIZE_DEFAULT, Main.var"##249".affect_le1!), Main.var"##249".affect_le1!, DiffEqCallbacks.PresetTimeFunction{Vector{Float64}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(Main.var"##249".affect_le1!)}([500.0], true, SciMLBase.INITIALIZE_DEFAULT, Main.var"##249".affect_le1!), SciMLBase.FINALIZE_DEFAULT, Bool[1, 1], nothing, ()), SciMLBase.DiscreteCallback{DiffEqCallbacks.PresetTimeFunction{Vector{Float64}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(Main.var"##249".affect_le2!)}, typeof(Main.var"##249".affect_le2!), DiffEqCallbacks.PresetTimeFunction{Vector{Float64}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(Main.var"##249".affect_le2!)}, typeof(SciMLBase.FINALIZE_DEFAULT), Nothing, Tuple{}}(DiffEqCallbacks.PresetTimeFunction{Vector{Float64}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(Main.var"##249".affect_le2!)}([1000.0], true, SciMLBase.INITIALIZE_DEFAULT, Main.var"##249".affect_le2!), Main.var"##249".affect_le2!, DiffEqCallbacks.PresetTimeFunction{Vector{Float64}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(Main.var"##249".affect_le2!)}([1000.0], true, SciMLBase.INITIALIZE_DEFAULT, Main.var"##249".affect_le2!), SciMLBase.FINALIZE_DEFAULT, Bool[1, 1], nothing, ()), SciMLBase.DiscreteCallback{DiffEqCallbacks.PresetTimeFunction{Vector{Float64}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(Main.var"##249".affect_le3!)}, typeof(Main.var"##249".affect_le3!), DiffEqCallbacks.PresetTimeFunction{Vector{Float64}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(Main.var"##249".affect_le3!)}, typeof(SciMLBase.FINALIZE_DEFAULT), Nothing, Tuple{}}(DiffEqCallbacks.PresetTimeFunction{Vector{Float64}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(Main.var"##249".affect_le3!)}([1500.0], true, SciMLBase.INITIALIZE_DEFAULT, Main.var"##249".affect_le3!), Main.var"##249".affect_le3!, DiffEqCallbacks.PresetTimeFunction{Vector{Float64}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(Main.var"##249".affect_le3!)}([1500.0], true, SciMLBase.INITIALIZE_DEFAULT, Main.var"##249".affect_le3!), SciMLBase.FINALIZE_DEFAULT, Bool[1, 1], nothing, ()), SciMLBase.DiscreteCallback{DiffEqCallbacks.PresetTimeFunction{Vector{Float64}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(Main.var"##249".affect_le4!)}, typeof(Main.var"##249".affect_le4!), DiffEqCallbacks.PresetTimeFunction{Vector{Float64}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(Main.var"##249".affect_le4!)}, typeof(SciMLBase.FINALIZE_DEFAULT), Nothing, Tuple{}}(DiffEqCallbacks.PresetTimeFunction{Vector{Float64}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(Main.var"##249".affect_le4!)}([2000.0], true, SciMLBase.INITIALIZE_DEFAULT, Main.var"##249".affect_le4!), Main.var"##249".affect_le4!, DiffEqCallbacks.PresetTimeFunction{Vector{Float64}, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(Main.var"##249".affect_le4!)}([2000.0], true, SciMLBase.INITIALIZE_DEFAULT, Main.var"##249".affect_le4!), SciMLBase.FINALIZE_DEFAULT, Bool[1, 1], nothing, ())))

Fig 7.07 (A)

tend = 2500.0
prob707a = ODEProblem(model707!, ics707, tend, ps707)
@time sol = solve(prob707a, TRBDF2(), callback=cbs)
  2.646401 seconds (9.90 M allocations: 665.815 MiB, 5.19% gc time, 99.94% compilation time)
retcode: Success Interpolation: 3rd order Hermite t: 240-element Vector{Float64}: 0.0 0.0030529842319340244 0.033582826551274265 0.33888124974467665 0.5477010840687467 1.232203566098551 1.5959869662444681 2.758101062245429 3.2693670361144287 4.798210419289836 ⋮ 2341.056374122994 2354.809120783752 2368.56186744451 2384.9266245640156 2402.6546813683526 2422.133329485706 2445.809794150764 2471.159897882199 2500.0 u: 240-element Vector{ComponentArrays.ComponentVector{Float64, Vector{Float64}, Tuple{ComponentArrays.Axis{(M = 1, Y = 2, L = 3)}}}}: ComponentVector{Float64}(M = 0.01, Y = 0.1, L = 0.0) ComponentVector{Float64}(M = 0.009989486738585279, Y = 0.10056447448231473, L = 0.0) ComponentVector{Float64}(M = 0.009885196281903036, Y = 0.10617340605644321, L = 0.0) ComponentVector{Float64}(M = 0.008921417727493039, Y = 0.1588941805281965, L = 0.0) ComponentVector{Float64}(M = 0.008339329567549437, Y = 0.19166694626706238, L = 0.0) ComponentVector{Float64}(M = 0.006787931490691709, Y = 0.2838261093861022, L = 0.0) ComponentVector{Float64}(M = 0.006151548282965767, Y = 0.324718480811908, L = 0.0) ComponentVector{Float64}(M = 0.004713019403940765, Y = 0.42948674529969344, L = 0.0) ComponentVector{Float64}(M = 0.004300286188421522, Y = 0.46589331472611184, L = 0.0) ComponentVector{Float64}(M = 0.003518319014641902, Y = 0.554148300189143, L = 0.0) ⋮ ComponentVector{Float64}(M = 0.0028205726801400588, Y = 1.9241038351623863, L = 5.829399253601597e-7) ComponentVector{Float64}(M = 0.0028205729625649244, Y = 1.8708769433755819, L = 4.1313191691717554e-7) ComponentVector{Float64}(M = 0.002820572226050805, Y = 1.8357448193981682, L = 2.932525231469262e-7) ComponentVector{Float64}(M = 0.002820575897916057, Y = 1.8090779353669042, L = 1.952287700754176e-7) ComponentVector{Float64}(M = 0.002820567439376446, Y = 1.791797395692932, L = 1.2558790920225764e-7) ComponentVector{Float64}(M = 0.0028205694744951578, Y = 1.7809525629578338, L = 7.742591125873105e-8) ComponentVector{Float64}(M = 0.0028205729539459673, Y = 1.7740397872058438, L = 4.286151587842106e-8) ComponentVector{Float64}(M = 0.002820572434854223, Y = 1.7705250237515948, L = 2.2738995730092172e-8) ComponentVector{Float64}(M = 0.0028205716159487135, Y = 1.768770786799461, L = 1.1019125514760435e-8)
fig = Figure()
ax = Axis(fig[1, 1], xlabel="Time (min)", ylabel="Concentration", title="Fig 7.7 (A)\nLac operon model in E. coli")
lines!(ax, 0..tend, t -> sol(t).Y, label="β-galactosidase monomer")
lines!(ax, 0..tend, t -> 50 * (500<=t<1000) + 100 * (1000<=t<1500) + 150 * (1500<=t<2000), label="External lactose")
axislegend(ax, position=:lt)
fig
Figure()

Fig 7.07 (B)

Compare the original model and the modified model

function model707b!(D, u, p, t)
    hil(x, k) = x / (x + k)
    hil(x, k, n) = hil(x^n, k^n)
    @unpack Le, a1, RToverK1, K2, δM, δY, δL, c1, kL, KML, kg, KMg, Enz = p
    @unpack M, Y, L = u
    D.M = a1 / (1 + RToverK1 * (K2 / (K2 + L))^4) - δM * M
    D.Y = c1 * M - δY * Y
    D.L = 4kL * Enz * hil(Le, KML) - 2kg * Enz * hil(L, KMg) - δL * L
    nothing
end
model707b! (generic function with 1 method)
ps707b = ComponentArray(ps707; Enz=40.0)
prob707a = SteadyStateProblem(model707!, ics707, ps707)
prob707b = SteadyStateProblem(model707b!, ics707, ps707b)

lerange = range(0, 100, 101)

eprob = EnsembleProblem(prob707a;
    prob_func=(prob, i, repeat) -> remake(prob, p=ComponentArray(ps707; Le=lerange[i])),
    output_func=(sol, i) -> (sol.u.Y / 4, false)
)

eprob_mod = EnsembleProblem(prob707b;
    prob_func=(prob, i, repeat) -> remake(prob, p=ComponentArray(ps707b; Le=lerange[i])),
    output_func=(sol, i) -> (sol.u.Y / 4, false)
)

alg = DynamicSS(TRBDF2())
@time sim = solve(eprob, alg; trajectories=length(lerange))
@time sim_mod = solve(eprob_mod, alg; trajectories=length(lerange))

fig = Figure()
ax = Axis(fig[1, 1], xlabel="External lactose concentration (μM)", ylabel="β-galactosidase", title="Fig 7.7 (B)\nLac operon model in E. coli")
lines!(ax, lerange, sim.u, label="Original model")
lines!(ax, lerange, sim_mod.u, label="Modified model")
axislegend(ax, position=:lt)
fig
  1.664725 seconds (12.40 M allocations: 637.575 MiB, 4.40% gc time, 183.79% compilation time)
  1.365428 seconds (8.91 M allocations: 457.654 MiB, 5.59% gc time, 182.44% compilation time)
Figure()

This notebook was generated using Literate.jl.