Skip to content

Commit

Permalink
Merge pull request #6 from PALEOtoolkit/pycall_requires
Browse files Browse the repository at this point in the history
use Requires.jl to remove direct dependency on PyCall.jl
  • Loading branch information
sjdaines authored May 6, 2022
2 parents ef5cba5 + 3766cdd commit 31ee8a0
Show file tree
Hide file tree
Showing 3 changed files with 225 additions and 210 deletions.
6 changes: 3 additions & 3 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "PALEOmodel"
uuid = "bf7b4fbe-ccb1-42c5-83c2-e6e9378b660c"
authors = ["Stuart Daines <[email protected]>"]
version = "0.14.3"
version = "0.14.4"

[deps]
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Expand All @@ -15,8 +15,8 @@ Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
NLsolve = "2774e3e8-f4cf-5e23-947b-6d7e65073b56"
PALEOboxes = "804b410e-d900-4b2a-9ecd-f5a06d4c1fd4"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0"
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
Expand All @@ -36,8 +36,8 @@ Infiltrator = "1.0"
JLD2 = "0.4"
NLsolve = "4.5"
PALEOboxes = "0.15, 0.16, 0.17"
PyCall = "1.92"
RecipesBase = "1.2"
Requires = "1.0"
Revise = "3.1"
SciMLBase = "1.29"
SparseDiffTools = "1.13"
Expand Down
211 changes: 4 additions & 207 deletions src/ReactionNetwork.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ Functions to analyize a PALEOboxes.Model that contains a reaction network
"""
module ReactionNetwork

using PyCall
import Printf

import Requires
import PALEOboxes as PB
import PALEOmodel

Expand Down Expand Up @@ -266,212 +265,10 @@ function show_ratesummaries(ratesummaries; select_species=[])
return nothing
end

"""
show_network_rate_nodes(model::PB.Model, domainname, output [, outputrec] [, indices] [.rate_thresh=0.0]) -> graph
Display reaction network as a `pydot` `graph`, including nodes for reactions.
NB: requires the Python `pydot` package. See <https://github.com/JuliaPy/PyCall.jl>,
and the docstring for `pyimport_conda`. Assuming that a conda-based Python is being used,
julia> using PyCall
julia> pyimport_conda("pydot", "pydot")
will download and install the Python package.
"""
function show_network_rate_nodes(
model::PB.Model, domainname, output;
outputrec=length(output.domains[domainname]),
indices=nothing,
rate_thresh=0.0,
species_root_only=true
)

rate_totals = get_rates(model, output, domainname;
outputrec=outputrec,
indices=indices)

rate_max = 0.0
for (rname, r) in rate_totals
rate_max = max(rate_max, r)
end

# species_ratevars = get_all_species_ratevars(model, domainname)

ratesummaries = get_all_species_ratesummaries(
model, output, domainname,
outputrec=outputrec,
indices=indices,
species_root_only=species_root_only
)

pydot = pyimport_conda("pydot", "pydot")
graph = pydot.Dot("Reactions", graph_type="digraph", bgcolor="white", layout="dot", rank="same", splines="line")

for (species, ratesummary) in ratesummaries

node = pydot.Node(species, label=species)
graph.add_node(node)

net = ratesummary.net
if abs(net) >= rate_thresh
node = pydot.Node(species*"_net", label=string(abs(net)), shape="diamond")
graph.add_node(node)
if net > 0
from, to = species, species*"_net"
else
from, to = species*"_net", species
end
net_norm = abs(net)/rate_max
edge = pydot.Edge(
from, to,
color="black",
weight=Int(floor(100*net_norm))+1,
penwidth=max(1.0, 20.0*net_norm)
)
graph.add_edge(edge)
end
end


dom = PB.get_domain(model, domainname)

colourlist = ["green", "black", "blue"]
rate_idx = 1
for rj in dom.reactions
rvs = PB.get_rate_stoichiometry(rj)
if !isnothing(rvs)


for (ratevarname, processname, stoichvec) in rvs
if abs(rate_totals[ratevarname]) >= rate_thresh
if processname == "photolysis"
colour="red"
else
colour=colourlist[mod(rate_idx, length(colourlist))+1]
end

rate_norm = abs(rate_totals[ratevarname])/rate_max
node = pydot.Node(ratevarname, shape="box", color=colour)
graph.add_node(node)
for (speciesname, stoich) in stoichvec
if species_root_only
speciesname = get_species_root(speciesname)
end
if stoich*rate_totals[ratevarname] > 0
from, to = ratevarname, speciesname
else
from, to = speciesname, ratevarname
end
if stoich != 0
rate_stoich_norm = rate_norm * abs(stoich)
edge = pydot.Edge(
from, to,
color=colour,
weight=Int(floor(100*rate_stoich_norm))+1,
penwidth=max(1.0, 20.0*rate_stoich_norm),
)
graph.add_edge(edge)
end
end
rate_idx += 1
end
end
end
end

return graph
end


function display_svg(graph)
output_graphviz_svg = graph.create_svg()
display("image/svg+xml", output_graphviz_svg)
end

#=
function show_network(model::PB.Model, domainname, output;
outputrec=length(output.domains[domainname]),
indices=nothing,
rate_thresh=0.0)
rate_totals = get_rates(model, output, domainname;
outputrec=outputrec,
indices=indices)
rate_max = 0.0
for (rname, r) in rate_totals
rate_max = max(rate_max, r)
end
species_ratevars = get_all_species_ratevars(model, domainname)
pydot = pyimport_conda("pydot", "pydot")
graph = pydot.Dot("Reactions", graph_type="digraph", bgcolor="white", layout="dot", splines="line")
for (species, rates) in species_ratevars
node = pydot.Node(species, label=species)
graph.add_node(node)
end
dom = PB.get_domain(model, domainname)
rate_idx = 1
for rj in dom.reactions
rvs = PB.get_rate_stoichiometry(rj)
if !isnothing(rvs)
for (ratevarname, processname, stoichvec) in rvs
if rate_totals[ratevarname] >= rate_thresh
rate_norm= rate_totals[ratevarname]/rate_max
reactants = []
products = []
for (speciesname, stoich) in stoichvec
if stoich < 0
push!(reactants, speciesname)
end
if stoich > 0
push!(products, speciesname)
end
end
for r in reactants
for p in products
edge = pydot.Edge(r, p, color="blue", weight=Int(floor(100*rate_norm)), penwidth=max(1.0, 20.0*rate_norm))
graph.add_edge(edge)
end
end
rate_idx += 1
end
end
end
end
return graph
end
=#

"""
test_pydot()

Test python pydot package and graphviz command-line tools installed and working
"""
function test_pydot()
pydot = pyimport_conda("pydot", "pydot")
graph = pydot.Dot("my_graph", graph_type="graph", bgcolor="white")
my_node = pydot.Node("a", label="Foo")
graph.add_node(my_node)
graph.add_node(pydot.Node("b", shape="circle"))
my_edge = pydot.Edge("a", "b", color="blue")
graph.add_edge(my_edge)

output_graphviz_svg = graph.create_svg()
display("image/svg+xml", output_graphviz_svg)

return graph
function __init__()
# If PyCall is available, include additional functions using Python pydot.
Requires.@require PyCall="438e738f-606a-5dbb-bf0a-cddfbfd45ab0" include("ReactionNetworkVis.jl")
end

end # module
Loading

2 comments on commit 31ee8a0

@sjdaines
Copy link
Member Author

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/59801

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 v0.14.4 -m "<description of version>" 31ee8a0ec8a5c87024ea4341542f3d09e25696e2
git push origin v0.14.4

Please sign in to comment.