Skip to content

Commit 4d0b9af

Browse files
committed
add tests
1 parent a5105a7 commit 4d0b9af

File tree

3 files changed

+112
-15
lines changed

3 files changed

+112
-15
lines changed

ext/CatalystGraphMakieExtension.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ module CatalystGraphMakieExtension
44
using Catalyst, GraphMakie, Graphs, Symbolics, SparseArrays
55
using Symbolics: get_variables!
66
import Catalyst: species_reaction_graph, incidencematgraph, lattice_plot, lattice_animation
7-
import SparseArrays: rowvals, nonzeros, nzrange
87

98
# Creates and exports graph plotting functions.
109
include("CatalystGraphMakieExtension/graph_makie_extension_spatial_modelling.jl")

ext/CatalystGraphMakieExtension/rn_graph_plot.jl

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,20 +62,38 @@ function Graphs.edges(g::MultiGraphWrap)
6262
edgelist = vcat(collect(Graphs.edges(g.g)), g.multiedges)[g.edgeorder]
6363
end
6464

65-
function gen_distances(g::MultiGraphWrap; inc = 0.25)
65+
function gen_distances(g::MultiGraphWrap; inc = 0.4)
6666
edgelist = edges(g)
6767
distances = zeros(length(edgelist))
68-
for (i,e) in enumerate(edgelist)
69-
fwd = findall(==(e), edgelist); rev = findall(==(reverse(e)), edgelist)
70-
distances[i] != 0 && continue
71-
distances[fwd] = collect(0:inc:inc*(length(fwd)-1))
72-
distances[rev] = collect(inc:inc:inc*(length(rev)))
68+
edgedict = Dict(edgelist[1] => [1])
69+
for (i, e) in enumerate(edgelist[2:end])
70+
if edgelist[i] != edgelist[i+1]
71+
edgedict[e] = [i+1]
72+
else
73+
push!(edgedict[e], i+1)
74+
end
75+
end
76+
77+
for (edge, inds) in edgedict
78+
if haskey(edgedict, Edge(dst(edge), src(edge)))
79+
distances[inds[1]] != 0. && continue
80+
inds_ = edgedict[Edge(dst(edge), src(edge))]
81+
82+
len = length(inds) + length(inds_)
83+
sp = -inc/2*(len-1)
84+
ep = sp + inc*(len-1)
85+
dists = collect(sp:inc:ep)
86+
distances[inds] = dists[1:length(inds)]
87+
distances[inds_] = -dists[length(inds)+1:end]
88+
else
89+
sp = -inc/2*(length(inds)-1)
90+
ep = sp + inc*(length(inds)-1)
91+
distances[inds] = collect(sp:inc:ep)
92+
end
7393
end
7494
distances
7595
end
7696

77-
Base.copy(g::MultiGraphWrap) = MultiGraphWrap(g.g, g.multiedges, g.edgeorder)
78-
7997
"""
8098
plot_network(rn::ReactionSystem)
8199
@@ -154,12 +172,14 @@ function Catalyst.plot_complexes(rn::ReactionSystem)
154172

155173
deps = Set()
156174
edgelist = Vector{Graphs.SimpleEdge{Int}}()
157-
rows = SparseArrays.rowvals(D); vals = SparseArrays.nonzeros(D)
175+
rows = rowvals(D)
176+
vals = nonzeros(D)
158177

159178
# Construct the edge order for reactions.
160179
for (i, rx) in enumerate(rxs)
161-
inds = SparseArrays.nzrange(D, i)
162-
val = vals[inds]; row = rows[inds]
180+
inds = nzrange(D, i)
181+
val = vals[inds]
182+
row = rows[inds]
163183
(sub, prod) = val[1] == -1 ? (row[1], row[2]) : (row[2], row[1])
164184
push!(edgelist, Graphs.SimpleEdge(sub, prod))
165185

test/extensions/graphmakie.jl

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Catalyst, GraphMakie, CairoMakie, Graphs
1+
using Catalyst, GraphMakie, CairoMakie, Graphs, SparseArrays
22
include("../test_networks.jl")
33

44
# Test that speciesreactiongraph is generated correctly
@@ -77,8 +77,8 @@ let
7777
srg = CGME.MultiGraphWrap(rn)
7878
s = length(species(rn))
7979
@test ne(srg) == 8
80-
@test Graphs.Edge(3, s+2) srg.rateedges
81-
@test Graphs.Edge(2, s+3) srg.rateedges
80+
@test Graphs.Edge(3, s+2) srg.multiedges
81+
@test Graphs.Edge(2, s+3) srg.multiedges
8282
# Since B is both a dep and a reactant
8383
@test count(==(Graphs.Edge(2, s+3)), edges(srg)) == 2
8484

@@ -103,3 +103,81 @@ let
103103
@test count(==(Graphs.Edge(1, s+2)), edges(srg)) == 2
104104
@test count(==(Graphs.Edge(2, s+3)), edges(srg)) == 2
105105
end
106+
107+
function test_edgeorder(rn)
108+
# The initial edgelabels in `plot_complexes` is given by the order of reactions in reactions(rn).
109+
D = incidencemat(rn; sparse=true); img = incidencematgraph(rn)
110+
rxs = reactions(rn)
111+
edgelist = Vector{Graphs.SimpleEdge{Int}}()
112+
rows = rowvals(D)
113+
vals = nonzeros(D)
114+
115+
for (i, rx) in enumerate(rxs)
116+
inds = nzrange(D, i)
117+
val = vals[inds]
118+
row = rows[inds]
119+
(sub, prod) = val[1] == -1 ? (row[1], row[2]) : (row[2], row[1])
120+
push!(edgelist, Graphs.SimpleEdge(sub, prod))
121+
end
122+
123+
rxorder = sortperm(edgelist); sortededgelist = edgelist[rxorder]
124+
multiedges = Vector{Graphs.SimpleEdge{Int}}()
125+
for i in 2:length(sortededgelist)
126+
isequal(sortededgelist[i], sortededgelist[i-1]) && push!(multiedges, sortededgelist[i])
127+
end
128+
img_ = CGME.MultiGraphWrap(img, multiedges)
129+
130+
# Label iteration order is given by edgelist[rxorder. Actual edge drawing iteration order is given by edges(g)
131+
@test edgelist[rxorder] == Graphs.edges(img_)
132+
return rxorder
133+
end
134+
135+
# Test edge order for complexes.
136+
let
137+
# Multiple edges
138+
rn = @reaction_network begin
139+
k1, A --> B
140+
(k2, k3), C <--> D
141+
k4, A --> B
142+
end
143+
rxorder = test_edgeorder(rn)
144+
edgelabels = [repr(rx.rate) for rx in reactions(rn)]
145+
# Test internal order of labels is preserved
146+
@test edgelabels[rxorder][1] == "k1"
147+
@test edgelabels[rxorder][2] == "k4"
148+
149+
# Multiple edges with species dependencies
150+
rn = @reaction_network begin
151+
k1, A --> B
152+
(k2, k3), C <--> D
153+
k4, A --> B
154+
hillr(D, α, K, n), C --> D
155+
k5*B, A --> B
156+
end
157+
rxorder = test_edgeorder(rn)
158+
edgelabels = [repr(rx.rate) for rx in reactions(rn)]
159+
labels = ["k1", "k4", "k5*B(t)", "k2", "Catalyst.hillr(D(t), α, K, n)", "k3"]
160+
@test edgelabels[rxorder] == labels
161+
162+
rs = @reaction_network begin
163+
ka, Depot --> Central
164+
(k12, k21), Central <--> Peripheral
165+
ke, Central --> 0
166+
end
167+
test_edgeorder(rs)
168+
169+
rn = @reaction_network begin
170+
(k1, k2), A <--> B
171+
k3, C --> B
172+
(α, β), (A, B) --> C
173+
k4, B --> A
174+
(k5, k6), B <--> A
175+
k7, B --> C
176+
(k8, k9), C <--> A
177+
(k10, k11), (A, C) --> B
178+
(k12, k13), (C, B) --> A
179+
end
180+
rxorder = test_edgeorder(rn)
181+
edgelabels = [repr(rx.rate) for rx in reactions(rn)]
182+
@test edgelabels[rxorder][1:3] == ["k1", "k6", "k10"]
183+
end

0 commit comments

Comments
 (0)