Unverified Commit cf0f49ef authored by Miroslav Kratochvil's avatar Miroslav Kratochvil Committed by GitHub
Browse files

Merge pull request #443 from LCSB-BioCore/mk-eff-sparse

more efficient building of sparse stoichiometries
parents 6857bbc6 73774a74
Pipeline #45547 passed with stages
in 36 minutes and 46 seconds
...@@ -107,22 +107,36 @@ function stoichiometry(model::JSONModel) ...@@ -107,22 +107,36 @@ function stoichiometry(model::JSONModel)
rxn_ids = reactions(model) rxn_ids = reactions(model)
met_ids = metabolites(model) met_ids = metabolites(model)
S = SparseArrays.spzeros(length(met_ids), length(rxn_ids)) n_entries = 0
for r in model.rxns
for _ in r["metabolites"]
n_entries += 1
end
end
MI = Vector{Int}()
RI = Vector{Int}()
SV = Vector{Float64}()
sizehint!(MI, n_entries)
sizehint!(RI, n_entries)
sizehint!(SV, n_entries)
for (i, rid) in enumerate(rxn_ids) for (i, rid) in enumerate(rxn_ids)
r = model.rxns[model.rxn_index[rid]] r = model.rxns[model.rxn_index[rid]]
for (mid, coeff) in r["metabolites"] for (mid, coeff) in r["metabolites"]
if !haskey(model.met_index, mid) haskey(model.met_index, mid) || throw(
throw( DomainError(
DomainError( met_id,
met_id, "Unknown metabolite found in stoichiometry of $(rxn_ids[i])",
"Unknown metabolite found in stoichiometry of $(rxn_ids[i])", ),
), )
)
end push!(MI, model.met_index[mid])
S[model.met_index[mid], i] = coeff push!(RI, i)
push!(SV, coeff)
end end
end end
return S return SparseArrays.sparse(MI, RI, SV, length(met_ids), length(rxn_ids))
end end
""" """
......
...@@ -108,24 +108,39 @@ n_genes(model::StandardModel)::Int = length(model.genes) ...@@ -108,24 +108,39 @@ n_genes(model::StandardModel)::Int = length(model.genes)
Return the stoichiometric matrix associated with `model` in sparse format. Return the stoichiometric matrix associated with `model` in sparse format.
""" """
function stoichiometry(model::StandardModel)::SparseMat function stoichiometry(model::StandardModel)::SparseMat
S = SparseArrays.spzeros(n_metabolites(model), n_reactions(model)) n_entries = 0
mets = metabolites(model) # vector of metabolite ids for (_, r) in model.reactions
for _ in r.metabolites
n_entries += 1
end
end
MI = Vector{Int}()
RI = Vector{Int}()
SV = Vector{Float64}()
sizehint!(MI, n_entries)
sizehint!(RI, n_entries)
sizehint!(SV, n_entries)
# establish the ordering
rxns = reactions(model) rxns = reactions(model)
for (i, rid) in enumerate(rxns) # column, in order met_idx = Dict(mid => i for (i, mid) in enumerate(metabolites(model)))
# fill the matrix entries
for (ridx, rid) in enumerate(rxns)
for (mid, coeff) in model.reactions[rid].metabolites for (mid, coeff) in model.reactions[rid].metabolites
j = findfirst(==(mid), mets) # row haskey(met_idx, mid) || throw(
if isnothing(j) DomainError(
throw( mid,
DomainError( "Metabolite $(mid) not found in model but occurs in stoichiometry of $(rid)",
mid, ),
"Metabolite $(mid) not found in model but occurs in stoichiometry of $(rid)", )
), push!(MI, met_idx[mid])
) push!(RI, ridx)
end push!(SV, coeff)
S[j, i] = coeff
end end
end end
return S return SparseArrays.sparse(MI, RI, SV, n_metabolites(model), n_reactions(model))
end end
""" """
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment