Skip to content

Commit

Permalink
Merge pull request #24 from SciML/aj/wip
Browse files Browse the repository at this point in the history
cleanup tests add script to clone the physiome
  • Loading branch information
shahriariravanian authored Mar 23, 2021
2 parents aa072b4 + a263a19 commit d281318
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 37 deletions.
9 changes: 5 additions & 4 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "CellMLToolkit"
uuid = "03cb29e0-1ef4-4721-aa24-cf58a006576f"
authors = ["Shahriar Iravanian <siravan@svtsim.com>"]
version = "2.1.1"
version = "2.1.0"

[deps]
EzXML = "8f5d6c58-4d21-5cfd-889c-e3ad7ee6a615"
Expand All @@ -12,16 +12,17 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[compat]
EzXML = "1.1"
JSON3 = "1.8"
MathML = "0.1"
ModelingToolkit = "5.13"
SymbolicUtils = "0.9"
julia = "1.5"

[extras]
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
DifferentialEquations = "0c46a032-eb83-5123-abaf-570d42b7fbaa"
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78"
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test", "ModelingToolkit", "DifferentialEquations", "Plots"]
test = ["Test", "ModelingToolkit", "OrdinaryDiffEq", "JSON3"]
5 changes: 4 additions & 1 deletion src/CellMLToolkit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ using SymbolicUtils: FnType, Sym, operation, arguments
using ModelingToolkit
using EzXML

include("utils.jl")
export curl_exposures

include("cellml.jl")

"""
Expand Down Expand Up @@ -97,7 +100,7 @@ end
val is the new value
"""
function update_list!(l, sym::Symbol, val)
for (i,x) in enumerate(l)
for (i, x) in enumerate(l)
if first(x).name == sym
l[i] = (first(x) => val)
return
Expand Down
23 changes: 23 additions & 0 deletions src/utils.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""queries the cellml repo api for links to cellml model repo"""
function curl_exposures()
run(`curl -sL -H 'Accept: application/vnd.physiome.pmr2.json.1'
https://models.physiomeproject.org/search -d '{
"template": {"data": [
{"name": "Subject", "value": "CellML Model"},
{"name": "portal_type", "value": "ExposureFile"}
]}
}' -o cellml.json`)
end

"""
downloads the cellml model repository
todo use Base.Downloads to speed this up
"""
function grab(ls)
!ispath("data") && mkpath("data")
@sync Threads.@threads for l in ls
fn = splitdir(l)[end]
download(l, "data/$(fn)")
end
nothing
end
32 changes: 32 additions & 0 deletions test/beeler.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
path = @__DIR__
ml = CellModel(path * "/../models/beeler_reuter_1977.cellml.xml")

# @test length(ml.eqs) == 8
# @test ml.iv.op.name == :time

# eqs, vs = CellMLToolkit.flat_equations(ml)
# @test length(vs) == 8

# @test find_V(ml).op.name == :V

prob = ODEProblem(ml, (0,10000.0))
sol1 = solve(prob, Euler(), dt=0.01, saveat=1.0)
sol2 = solve(prob, TRBDF2(), dtmax=0.5, saveat=1.0)
V1 = map(x -> x[1], sol1.u)
V2 = map(x -> x[1], sol2.u)
err = sum(abs.(V1 .- V2)) / length(V1)
@test err < 0.1

# prob = ODEProblem(ml, (0,10000.0); jac=true)
# sol3 = solve(prob, TRBDF2(), dtmax=0.5, saveat=1.0)
# V3 = map(x -> x[1], sol2.u)
# err = sum(abs.(V1 .- V3)) / length(V1)
# @test err < 0.1

p = list_params(ml)
update_list!(p, "IstimPeriod", 280.0)
prob = ODEProblem(ml, (0,10000.0); jac=false, p=p)
sol4 = solve(prob, TRBDF2(), dtmax=0.5, saveat=1.0)
V4 = map(x -> x[1], sol2.u)
err = sum(abs.(V1[1:250] .- V4[1:250])) / 250
@test err < 0.1
40 changes: 8 additions & 32 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,36 +1,12 @@
using Test
using CellMLToolkit
using DifferentialEquations
using OrdinaryDiffEq
using JSON3, Base.Threads
using ModelingToolkit

path = @__DIR__
ml = CellModel(path * "/../models/beeler_reuter_1977.cellml.xml")
@testset "CellMLToolkit.jl" begin
@testset "beeler.jl" begin include("beeler.jl") end

# @test length(ml.eqs) == 8
# @test ml.iv.op.name == :time

# eqs, vs = CellMLToolkit.flat_equations(ml)
# @test length(vs) == 8

# @test find_V(ml).op.name == :V

prob = ODEProblem(ml, (0,10000.0))
sol1 = solve(prob, Euler(), dt=0.01, saveat=1.0)
sol2 = solve(prob, TRBDF2(), dtmax=0.5, saveat=1.0)
V1 = map(x -> x[1], sol1.u)
V2 = map(x -> x[1], sol2.u)
err = sum(abs.(V1 .- V2)) / length(V1)
@test err < 0.1

# prob = ODEProblem(ml, (0,10000.0); jac=true)
# sol3 = solve(prob, TRBDF2(), dtmax=0.5, saveat=1.0)
# V3 = map(x -> x[1], sol2.u)
# err = sum(abs.(V1 .- V3)) / length(V1)
# @test err < 0.1

p = list_params(ml)
update_list!(p, "IstimPeriod", 280.0)
prob = ODEProblem(ml, (0,10000.0); jac=false, p=p)
sol4 = solve(prob, TRBDF2(), dtmax=0.5, saveat=1.0)
V4 = map(x -> x[1], sol2.u)
err = sum(abs.(V1[1:250] .- V4[1:250])) / 250
@test err < 0.1
# mainly a used as a bin/ don't want to test every PR
# @testset "physiome.jl" begin include("test_physiome.jl") end
end
63 changes: 63 additions & 0 deletions test/test_physiome.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
"
in place modifies a matrix with data about how far to `solve`
we get for a given set of cellml files
uses @threads
"
function test_cellmls!(mat, fns)
@sync Threads.@threads for i in eachindex(fns)
@show i fns[i]
mat[i, :] = test_cellml!(mat[i, :], fns[i])
end
mat
end

"
in place modifies a row with data about how far to `solve`
we get for a given cellml file
"
function test_cellml!(row, fn)
row[1] = fn
try
ml = CellModel(fn)
sys = ml.sys
row[2] = true
row[5] = length(states(sys))
row[6] = length(parameters(sys))
prob = ODEProblem(ml, tspan)
row[3] = true
sol = solve(prob)
row[4] = true
catch e
row[end] = e
end
row
end

"""
a
"""
function main(dir="data/")
tspan = (0., 1.)
fns = readdir(dir; join=true)
names = [:filename, :to_system, :to_problem, :to_solve, :states, :parameters, :error]
n = length(names)
mat = Array{Any,2}(nothing, length(fns), n)
test_cellmls!(mat, fns)
replace!(mat, nothing => missing)
names .=> eachcol(mat) # used with DataFrame()
# CSV.write("aggregate_stats.csv", df)
# print(df)
end

function json_to_cellml_links()
s = read("cellml.json", String);
j = JSON3.read(s);
x = j.collection.links
map(x -> x.href[1:end - 5], x) # remove `/view` from urls
end

ls = json_to_cellml_links(curl_exposures())
@test length(ls) == 2379
CellMLToolkit.grab(ls[1:10])
df = main()
@test eltype(df) == Pair

2 comments on commit d281318

@anandijain
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator register()

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/32598

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v2.1.0 -m "<description of version>" d28131872ac50cc0494cee4a8c00d6d86e0b36aa
git push origin v2.1.0

Please sign in to comment.