diff --git a/examples/oncology/tumor_proliferation_invasion.jl b/examples/oncology/tumor_proliferation_invasion.jl new file mode 100644 index 00000000..d39ae5dc --- /dev/null +++ b/examples/oncology/tumor_proliferation_invasion.jl @@ -0,0 +1,88 @@ +# Load Dependencies +using Catlab +using Catlab.Graphics +using CombinatorialSpaces +using Decapodes +using DiagrammaticEquations, DiagrammaticEquations.Deca +using Distributions +using MLStyle +using OrdinaryDiffEq +using LinearAlgebra +using ComponentArrays +using CairoMakie +using GeometryBasics: Point2, Point3 +Point2D = Point2{Float64} +Point3D = Point3{Float64} + +# Load in our Decapodes models +using Decapodes.Canon.Oncology + +# Examine our models +# Note that the implementation is entirely specified by its documentation +@doc invasion + +@doc logistic + +@doc gompertz + +# Load in a mesh, initial conditions, and a plotting function +function show_heatmap(Cdata) + heatmap(reshape(Cdata, (floor(Int64, sqrt(length(Cdata))), floor(Int64, sqrt(length(Cdata)))))) +end + +s = triangulated_grid(50,50,0.2,0.2,Point2D); +sd = EmbeddedDeltaDualComplex2D{Bool, Float64, Point2D}(s); +subdivide_duals!(sd, Circumcenter()); + +constants_and_parameters = ( + invasion_Dif = 0.005, + invasion_Kd = 0.5, + Cmax = 10) + +# "The model ... considers an equivalent radially symmetric tumour" +# - Murray J.D., Glioblastoma brain tumours +c_dist = MvNormal([25, 25], 2) +C = 100 * [pdf(c_dist, [p[1], p[2]]) for p in sd[:point]] + +u₀ = ComponentArray(C=C) + +# Compose our Proliferation-Invasion models +proliferation_invasion_composition_diagram = @relation () begin + proliferation(C, fC, Cmax) + invasion(C, fC, Cmax) +end + +logistic_proliferation_invasion_cospan = oapply(proliferation_invasion_composition_diagram, + [Open(logistic, [:C, :fC, :Cmax]), + Open(invasion, [:C, :fC, :Cmax])]) + +logistic_proliferation_invasion = apex(logistic_proliferation_invasion_cospan) + +gompertz_proliferation_invasion_cospan = oapply(proliferation_invasion_composition_diagram, + [Open(gompertz, [:C, :fC, :Cmax]), + Open(invasion, [:C, :fC, :Cmax])]) + +gompertz_proliferation_invasion = apex(gompertz_proliferation_invasion_cospan) + +# Generate the logistic simulation +logistic_sim = evalsim(logistic_proliferation_invasion) + +lₘ = logistic_sim(sd, default_dec_generate, DiagonalHodge()) + +# Execute the logistic simulation +tₑ = 15.0 + +prob = ODEProblem(lₘ, u₀, (0, tₑ), constants_and_parameters) +logistic_soln = solve(prob, Tsit5()) + +show_heatmap(logistic_soln(tₑ).C) + +# Generate the Gompertz simulation +gompertz_sim = evalsim(gompertz_proliferation_invasion) +gₘ = gompertz_sim(sd, default_dec_generate, DiagonalHodge()) + +# Execute the Gompertz simulation +prob = ODEProblem(gₘ, u₀, (0, tₑ), constants_and_parameters) +gompertz_soln = solve(prob, Tsit5()) + +show_heatmap(gompertz_soln(tₑ).C) diff --git a/src/canon/Canon.jl b/src/canon/Canon.jl index 2008dd69..aaec6be6 100644 --- a/src/canon/Canon.jl +++ b/src/canon/Canon.jl @@ -45,5 +45,6 @@ include("Physics.jl") include("Chemistry.jl") include("Biology.jl") include("Environment.jl") +include("Oncology.jl") end diff --git a/src/canon/Oncology.jl b/src/canon/Oncology.jl new file mode 100644 index 00000000..3b5b7ddd --- /dev/null +++ b/src/canon/Oncology.jl @@ -0,0 +1,58 @@ +module Oncology + +using DiagrammaticEquations +using DiagrammaticEquations.Deca + +# for testing +using Decapodes +using ComponentArrays +using CombinatorialSpaces + +using ..Canon +using Markdown + +@docapode("TumorInvasion" + ,"https://en.wikipedia.org/wiki/Cancer_cell#Causes" + ,"Eq. 35 from Yi et al. + A Review of Mathematical Models for Tumor Dynamics and Treatment Resistance + Evolution of Solid Tumors" + ,invasion + ,begin + (C,fC)::Form0 + (Dif, Kd, Cmax)::Constant + + ∂ₜ(C) == Dif * Δ(C) + fC - Kd * C +end) + +@docapode("Logistic" + ,"https://en.wikipedia.org/wiki/Logistic_function" + ,"Eq. 5 from Yi et al. + A Review of Mathematical Models for Tumor Dynamics and Treatment Resistance + Evolution of Solid Tumors" + ,logistic + ,begin + (C,fC)::Form0 + Cmax::Constant + + fC == C * (1 - C / Cmax) + end) + +@docapode("Gompertz" + ,"https://en.wikipedia.org/wiki/Gompertz_function" + ,"Eq. 6 from Yi et al. + A Review of Mathematical Models for Tumor Dynamics and Treatment Resistance + Evolution of Solid Tumors" + ,gompertz + ,begin + (C,fC)::Form0 + Cmax::Constant + + fC == C * ln(Cmax / C) +end) + +## Another way to account for angiogenesis effect on tumor +## growth is by assuming the carrying capacity of the tumor is +## determined by the effective tumor vascular support that is +## in turn affected by the tumor volume (Eqs. 15 and 16). -Review of... + +end diff --git a/src/canon/Physics.jl b/src/canon/Physics.jl index 90839fe7..44afb8b3 100644 --- a/src/canon/Physics.jl +++ b/src/canon/Physics.jl @@ -101,7 +101,7 @@ end) end ) -@docapode("Schoedinger" +@docapode("Schroedinger" ,"https://en.wikipedia.org/wiki/Schrodinger_equation" ,"The evolution of the wave function over time." ,schroedinger diff --git a/src/operators.jl b/src/operators.jl index f8f60098..2e77cecb 100644 --- a/src/operators.jl +++ b/src/operators.jl @@ -136,6 +136,7 @@ function default_dec_generate(sd, my_symbol, hodge=GeometricHodge()) :plus => (+) :(-) || :neg => x -> -1 .* x + :ln => (x -> log.(x)) _ => error("Unmatched operator $my_symbol") end diff --git a/src/simulation.jl b/src/simulation.jl index c1a44539..897df55a 100644 --- a/src/simulation.jl +++ b/src/simulation.jl @@ -333,17 +333,20 @@ end =# end end + # TODO: Clean this in another PR (with a @match maybe). if(operator == :(*)) operator = promote_arithmetic_map[operator] end if(operator == :(-)) operator = promote_arithmetic_map[operator] end + if(operator == :(/)) + operator = promote_arithmetic_map[operator] + end if(operator == :(^)) operator = promote_arithmetic_map[operator] end - visited_2[op] = true visited_Var[r] = true c = BinaryCall(operator, equality, a1name, a2name, rname)