Skip to content

Commit

Permalink
Merge pull request #17 from COBREXA/sew-pretty-print-canonical
Browse files Browse the repository at this point in the history
Add simple pretty printing and tests for CanonicalModel
  • Loading branch information
exaexa authored Nov 2, 2023
2 parents 995a052 + 1b03e2b commit 8253b47
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 9 deletions.
9 changes: 9 additions & 0 deletions docs/src/canonical.jl
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,15 @@ m.reactions["exchange2"] = Reaction(
)
nothing #hide

show_contains(x, y) = contains(sprint(show, MIME"text/plain"(), x), y) #src
@test show_contains(m, "reactions = ") #src
@test show_contains(m, "metabolites = ") #src
@test show_contains(m, "genes = ") #src
@test show_contains(m.reactions["and_back"], "\"export\"") #src
@test show_contains(m.reactions["forward"], "\"g1\"") #src
@test show_contains(m.metabolites["m1"], "\"inside\"") #src
@test show_contains(m.genes["g1"], "name = nothing") #src

# We should immediately find the basic accessors working:
A.stoichiometry(m)

Expand Down
30 changes: 21 additions & 9 deletions src/canonical.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ Base.@kwdef mutable struct Reaction
notes::A.Notes = A.Notes()
end

Base.show(io::Base.IO, ::MIME"text/plain", x::Reaction) = A.pretty_print_kwdef(io, x)

"""
$(TYPEDEF)
Expand All @@ -44,6 +46,8 @@ Base.@kwdef mutable struct Metabolite
notes::A.Notes = A.Notes()
end

Base.show(io::Base.IO, ::MIME"text/plain", x::Metabolite) = A.pretty_print_kwdef(io, x)

"""
$(TYPEDEF)
Expand All @@ -58,6 +62,8 @@ Base.@kwdef mutable struct Gene
notes::A.Notes = A.Notes()
end

Base.show(io::Base.IO, ::MIME"text/plain", x::Gene) = A.pretty_print_kwdef(io, x)

"""
$(TYPEDEF)
Expand All @@ -81,6 +87,8 @@ Base.@kwdef struct Model <: A.AbstractFBCModel
genes::Dict{String,Gene} = Dict()
end

Base.show(io::Base.IO, ::MIME"text/plain", x::Model) = A.pretty_print_kwdef(io, x)

A.reactions(m::Model) = sort(collect(keys(m.reactions)))
A.metabolites(m::Model) = sort(collect(keys(m.metabolites)))
A.genes(m::Model) = sort(collect(keys(m.genes)))
Expand All @@ -97,16 +105,20 @@ A.reaction_notes(m::Model, id::String) = m.reactions[id].notes
A.metabolite_notes(m::Model, id::String) = m.metabolites[id].notes
A.gene_notes(m::Model, id::String) = m.genes[id].notes

A.stoichiometry(m::Model) =
let rids = A.reactions(m)
#TODO this is dense
sparse(
Float64[
get(m.reactions[rid].stoichiometry, mid, 0.0) for mid in A.metabolites(m),
rid in rids
],
)
function A.stoichiometry(m::Model)
midxs = Dict(mid => idx for (idx, (mid, _)) in enumerate(m.metabolites))
I = Int[]
J = Int[]
V = Float64[]
for (ridx, (_, r)) in enumerate(m.reactions)
for (smid, v) in r.stoichiometry
push!(I, midxs[smid])
push!(J, ridx)
push!(V, v)
end
end
sparse(I, J, V, length(m.metabolites), length(m.reactions))
end

A.bounds(m::Model) = (
[m.reactions[rid].lower_bound for rid in A.reactions(m)],
Expand Down
22 changes: 22 additions & 0 deletions src/io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,28 @@ time.
"""
load(path::String) = load(guess_model_type_from_filename(path), path)

"""
$(TYPEDSIGNATURES)
Helper for nicely showing the contents of possibly complicated model
structures.
"""
function pretty_print_kwdef(io::Base.IO, x::T) where {T}
println(io, "$T(")
(_, cols) = displaysize(io)
for fn in fieldnames(T)
shw = repr(getfield(x, fn))
tgt_cols = max(16, cols - (2 + length(String(fn)) + 3 + 1))
if get(io, :limit, true)::Bool && length(shw) >= tgt_cols
shw = join(collect(shw)[begin:tgt_cols]) * ""
else
shw *= ","
end
println(io, " $fn = $shw")
end
println(io, ")")
end

Base.show(io::Base.IO, ::MIME"text/plain", m::AbstractFBCModel) = print(
io,
"$(typeof(m))(#= $(n_reactions(m)) reactions, $(n_metabolites(m)) metabolites =#)",
Expand Down

0 comments on commit 8253b47

Please sign in to comment.