diff --git a/Project.toml b/Project.toml index f76821e70b..4e2d51fd38 100644 --- a/Project.toml +++ b/Project.toml @@ -3,12 +3,14 @@ uuid = "479239e8-5488-4da2-87a7-35f2df7eef83" version = "5.0.1" [deps] +Catlab = "134e5e36-593f-5add-ad60-77f754baafbe" Latexify = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78" Reexport = "189a3867-3050-52da-a836-e630ba90ab69" [compat] +Catlab = "0.7.2" Latexify = "0.13.5" MacroTools = "0.5" ModelingToolkit = "3.14" diff --git a/src/Catalyst.jl b/src/Catalyst.jl index 6170f30a5e..0e5085a433 100644 --- a/src/Catalyst.jl +++ b/src/Catalyst.jl @@ -25,4 +25,11 @@ export dependants, dependents # for Latex printing of ReactionSystems include("latexify_recipes.jl") +# for making and saving graphs +import Base.Iterators: flatten +using Catlab.Graphics.Graphviz +import Catlab.Graphics.Graphviz: Graph, Edge +include("graphs.jl") +export savegraph + end # module diff --git a/src/graphs.jl b/src/graphs.jl new file mode 100644 index 0000000000..434abb2720 --- /dev/null +++ b/src/graphs.jl @@ -0,0 +1,45 @@ +# adapted from Petri.jl +# https://github.com/mehalter/Petri.jl + +graph_attrs = Attributes(:rankdir=>"LR") +node_attrs = Attributes(:shape=>"plain", :style=>"filled", :color=>"white") +edge_attrs = Attributes(:splines=>"splines") + +function edgify(δ, i, reverse::Bool) + attr = Attributes() + return map(δ) do p + val = String(p[1].op.name) + weight = "$(p[2])" + attr = Attributes(:label=>weight, :labelfontsize=>"6") + return Edge(reverse ? ["rx_$i", "$val"] : + ["$val", "rx_$i"], attr) + end +end + +""" + Graph(model::Model) + +convert a Model into a GraphViz Graph. Transition are green boxes and states are blue circles. Arrows go from the input states to the output states for each transition. +""" +function Graph(model::ReactionSystem) + rxs = reactions(model) + statenodes = [Node(string(s.name), Attributes(:shape=>"circle", :color=>"#6C9AC3")) for s in species(model)] + transnodes = [Node(string("rx_$i"), Attributes(:shape=>"point", :color=>"#E28F41", :width=>".1")) for (i,r) in enumerate(rxs)] + + stmts = vcat(statenodes, transnodes) + edges = map(enumerate(rxs)) do (i,r) + vcat(edgify(zip(r.substrates,r.substoich), i, false), + edgify(zip(r.products,r.prodstoich), i, true)) + end |> flatten |> collect + stmts = vcat(stmts, edges) + g = Graphviz.Graph("G", true, stmts, graph_attrs, node_attrs,edge_attrs) + return g +end + + +function savegraph(g::Graph, fname, fmt="png") + open(fname, "w") do io + run_graphviz(io, g, format=fmt) + end + nothing +end \ No newline at end of file