diff --git a/.github/workflows/CompatHelper.yml b/.github/workflows/CompatHelper.yml index 369f4b915..2afd0558c 100644 --- a/.github/workflows/CompatHelper.yml +++ b/.github/workflows/CompatHelper.yml @@ -3,10 +3,29 @@ on: schedule: - cron: 0 0 * * * workflow_dispatch: +permissions: + contents: write + pull-requests: write jobs: CompatHelper: runs-on: ubuntu-latest steps: + - name: Check if Julia is already available in the PATH + id: julia_in_path + run: which julia + continue-on-error: true + - name: Install Julia, but only if it is not already available in the PATH + uses: julia-actions/setup-julia@v1 + with: + version: '1' + arch: ${{ runner.arch }} + if: steps.julia_in_path.outcome != 'success' + - name: "Add the General registry via Git" + run: | + import Pkg + ENV["JULIA_PKG_SERVER"] = "" + Pkg.Registry.add("General") + shell: julia --color=yes {0} - name: "Install CompatHelper" run: | import Pkg diff --git a/Project.toml b/Project.toml index 5c0dfc3cd..ac3b50af2 100644 --- a/Project.toml +++ b/Project.toml @@ -1,11 +1,12 @@ name = "COBREXA" uuid = "babc4406-5200-4a30-9033-bf5ae714c842" authors = ["The developers of COBREXA.jl"] -version = "1.4.0" +version = "1.4.1" [deps] Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b" DistributedData = "f6a0035f-c5ac-4ad0-b410-ad102ced35df" +DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" JuMP = "4076af6c-e467-56ae-b986-b466b2749572" @@ -22,27 +23,28 @@ StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" [compat] +Clarabel = "0.3" DistributedData = "0.1.4, 0.2" +DocStringExtensions = "0.8, 0.9" HDF5 = "0.16" JSON = "0.21" -JuMP = "0.21.0, 0.22.0, 0.23, 1" +JuMP = "1" MAT = "0.10" MacroTools = "0.5.6" -OSQP = "0.6" OrderedCollections = "1.4" -SBML = "~1.1" +SBML = "~1.3" StableRNGs = "1.0" Tulip = "0.7.0, 0.8.0, 0.9.2" julia = "1.5" [extras] Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" +Clarabel = "61c947e1-3e6d-4ee4-985a-eec8c727bd6e" Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6" GLPK = "60bf3e95-4087-53dc-ae20-288a0d20c6a6" -OSQP = "ab2f91bb-94b4-55e3-9ba0-7f65df51de79" SHA = "ea8e919c-243c-51af-8825-aaa63cd721ce" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" Tulip = "6dd1b50a-3aae-11e9-10b5-ef983d2400fa" [targets] -test = ["Aqua", "Downloads", "GLPK", "OSQP", "SHA", "Test", "Tulip"] +test = ["Aqua", "Clarabel", "Downloads", "GLPK", "SHA", "Test", "Tulip"] diff --git a/README.md b/README.md index 0ec26b778..47237b005 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ add COBREXA ``` You also need to install your favorite solver supported by `JuMP.jl` (such as -Gurobi, Mosek, CPLEX, GLPK, OSQP, etc., see a [list +Gurobi, Mosek, CPLEX, GLPK, Clarabel, etc., see a [list here](https://jump.dev/JuMP.jl/stable/installation/#Supported-solvers)). For example, you can install `Tulip.jl` solver by typing: ``` diff --git a/docs/Project.toml b/docs/Project.toml index 6d1d4c31c..1f523ccd8 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,6 +1,7 @@ [deps] COBREXA = "babc4406-5200-4a30-9033-bf5ae714c842" CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" +Clarabel = "61c947e1-3e6d-4ee4-985a-eec8c727bd6e" Clustering = "aaaa29a8-35af-508c-8bc3-b662a17a0fe5" ColorSchemes = "35d6a980-a343-548e-a6ea-1d62b119f2f4" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" @@ -10,7 +11,6 @@ InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240" JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" JuMP = "4076af6c-e467-56ae-b986-b466b2749572" Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306" -OSQP = "ab2f91bb-94b4-55e3-9ba0-7f65df51de79" Tulip = "6dd1b50a-3aae-11e9-10b5-ef983d2400fa" [compat] diff --git a/docs/src/examples/05b_fba_mods.jl b/docs/src/examples/05b_fba_mods.jl index a8027a6c1..8beff7a04 100644 --- a/docs/src/examples/05b_fba_mods.jl +++ b/docs/src/examples/05b_fba_mods.jl @@ -10,7 +10,7 @@ !isfile("e_coli_core.xml") && download("http://bigg.ucsd.edu/static/models/e_coli_core.xml", "e_coli_core.xml") -using COBREXA, GLPK, Tulip +using COBREXA, GLPK, Tulip, JuMP model = load_model("e_coli_core.xml") @@ -33,6 +33,6 @@ fluxes = flux_balance_analysis_dict( knockout(["b0978", "b0734"]), # knock out two genes change_optimizer(Tulip.Optimizer), # ignore the above optimizer and switch to Tulip change_optimizer_attribute("IPM_IterationsLimit", 1000), # customize Tulip - change_sense(MAX_SENSE), # explicitly tell Tulip to maximize the objective + change_sense(JuMP.MAX_SENSE), # explicitly tell Tulip to maximize the objective ], ) diff --git a/docs/src/examples/08_pfba.jl b/docs/src/examples/08_pfba.jl index 6ca3a2579..c10fbfd02 100644 --- a/docs/src/examples/08_pfba.jl +++ b/docs/src/examples/08_pfba.jl @@ -13,7 +13,7 @@ !isfile("e_coli_core.xml") && download("http://bigg.ucsd.edu/static/models/e_coli_core.xml", "e_coli_core.xml") -using COBREXA, Tulip, OSQP +using COBREXA, Tulip, Clarabel model = load_model("e_coli_core.xml") @@ -21,13 +21,13 @@ model = load_model("e_coli_core.xml") # capable of solving quadratic programs. # # As the simplest choice, we can use -# [`OSQP.jl`](https://osqp.org/docs/get_started/julia.html), but any any +# [`Clarabel.jl`](https://osqp.org/docs/get_started/julia.html), but any any # [`JuMP.jl`-supported # optimizer](https://jump.dev/JuMP.jl/stable/installation/#Supported-solvers) # that supports quadratic programming will work. -#md # !!! note "Note: OSQP can be sensitive" -#md # We recommend reading the documentation of `OSQP` before using it, since +#md # !!! note "Note: Clarabel can be sensitive" +#md # We recommend reading the documentation of `Clarabel` before using it, since #md # it may give inconsistent results depending on what settings #md # you use. Commercial solvers like `Gurobi`, `Mosek`, `CPLEX`, etc. #md # require less user engagement. @@ -40,10 +40,9 @@ model = load_model("e_coli_core.xml") fluxes = parsimonious_flux_balance_analysis_dict( model, - OSQP.Optimizer; + Clarabel.Optimizer; modifications = [ - silence, # optionally silence the optimizer (OSQP is very verbose by default) - change_optimizer_attribute("polish", true), # tell OSQP to invest time into improving the precision of the solution + silence, # optionally silence the optimizer (Clarabel is very verbose by default) change_constraint("R_EX_glc__D_e"; lb = -12, ub = -12), # fix glucose consumption rate ], ) @@ -69,8 +68,7 @@ flux_vector = parsimonious_flux_balance_analysis_vec( change_optimizer_attribute("IPM_IterationsLimit", 500), # we may change Tulip-specific attributes here ], qp_modifications = [ - change_optimizer(OSQP.Optimizer), # now switch to OSQP (Tulip wouldn't be able to finish the computation) - change_optimizer_attribute("polish", true), # get an accurate solution, see OSQP's documentation + change_optimizer(Clarabel.Optimizer), # now switch to Clarabel (Tulip wouldn't be able to finish the computation) silence, # and make it quiet. ], ) diff --git a/docs/src/examples/13_moma.jl b/docs/src/examples/13_moma.jl index c84463c16..200ccd07d 100644 --- a/docs/src/examples/13_moma.jl +++ b/docs/src/examples/13_moma.jl @@ -19,17 +19,14 @@ using COBREXA model = load_model(StandardModel, "e_coli_core.xml") -# MOMA analysis requires solution of a quadratic model, we will thus use OSQP as the main optimizer. +# MOMA analysis requires solution of a quadratic model, we will thus use Clarabel as the main optimizer. -using OSQP +using Clarabel # We will need a reference solution, which represents the original state of the # organism before the change. -reference_flux = flux_balance_analysis_dict( - model, - OSQP.Optimizer; - modifications = [silence, change_optimizer_attribute("polish", true)], -) +reference_flux = + flux_balance_analysis_dict(model, Clarabel.Optimizer; modifications = [silence]) # As the change here, we manually knock out CYTBD reaction: changed_model = change_bound(model, "R_CYTBD", lower = 0.0, upper = 0.0); @@ -40,8 +37,8 @@ flux_summary( minimize_metabolic_adjustment_analysis_dict( changed_model, reference_flux, - OSQP.Optimizer; - modifications = [silence, change_optimizer_attribute("polish", true)], + Clarabel.Optimizer; + modifications = [silence], ), ) @@ -51,7 +48,7 @@ flux_summary( flux_summary( flux_balance_analysis_dict( changed_model, - OSQP.Optimizer; - modifications = [silence, change_optimizer_attribute("polish", true)], + Clarabel.Optimizer; + modifications = [silence], ), ) diff --git a/docs/src/quickstart.md b/docs/src/quickstart.md index 50c6f1ca4..11c9709fa 100644 --- a/docs/src/quickstart.md +++ b/docs/src/quickstart.md @@ -8,7 +8,7 @@ add COBREXA ``` You also need to install your favorite solver supported by `JuMP.jl` (such as -Gurobi, Mosek, CPLEX, GLPK, OSQP, etc., see a [list +Gurobi, Mosek, CPLEX, GLPK, Clarabel, etc., see a [list here](https://jump.dev/JuMP.jl/stable/installation/#Supported-solvers)). For example, you can install `Tulip.jl` solver by typing: ``` diff --git a/src/COBREXA.jl b/src/COBREXA.jl index c84c4acad..9e75888f9 100644 --- a/src/COBREXA.jl +++ b/src/COBREXA.jl @@ -1,3 +1,28 @@ +""" +``` +\\\\\\\\\\ // // | COBREXA.jl v$(COBREXA.COBREXA_VERSION) + \\\\ \\\\// // | + \\\\ \\/ // | COnstraint-Based Reconstruction + \\\\ // | and EXascale Analysis in Julia + // \\\\ | + // /\\ \\\\ | See documentation and examples at: + // //\\\\ \\\\ | https://lcsb-biocore.github.io/COBREXA.jl +// // \\\\\\\\\\ | +``` + +To start up quickly, install your favorite optimizer, load a metabolic model in +a format such as SBML or JSON, and run a metabolic analysis such as the flux +balance analysis: +``` +import Pkg; Pkg.add("GLPK") +using COBREXA, GLPK +model = load_model("e_coli_core.xml") +x = flux_balance_analysis_dict(model, GLPK.Optimizer) +flux_summary(x) +``` + +A complete overview of the functionality can be found in the documentation. +""" module COBREXA using Distributed @@ -14,12 +39,17 @@ using Serialization using SparseArrays using StableRNGs using Statistics +using DocStringExtensions import Base: findfirst, getindex, show import Pkg import SBML # conflict with Reaction struct name -include("banner.jl") +const _PKG_ROOT_DIR = normpath(joinpath(@__DIR__, "..")) +include_dependency(joinpath(_PKG_ROOT_DIR, "Project.toml")) + +const COBREXA_VERSION = + VersionNumber(Pkg.TOML.parsefile(joinpath(_PKG_ROOT_DIR, "Project.toml"))["version"]) # autoloading const _inc(path...) = include(joinpath(path...)) @@ -34,6 +64,7 @@ _inc_all.( joinpath("base", "macros"), joinpath("base", "types"), joinpath("base", "types", "wrappers"), + joinpath("base", "ontologies"), "base", "io", joinpath("io", "show"), diff --git a/src/analysis/envelopes.jl b/src/analysis/envelopes.jl index 147d38f11..ddf22bc09 100644 --- a/src/analysis/envelopes.jl +++ b/src/analysis/envelopes.jl @@ -1,6 +1,6 @@ """ - envelope_lattice(model::MetabolicModel, rids::Vector{String}; kwargs...) +$(TYPEDSIGNATURES) Version of [`envelope_lattice`](@ref) that works on string reaction IDs instead of integer indexes. @@ -9,13 +9,7 @@ envelope_lattice(model::MetabolicModel, rids::Vector{String}; kwargs...) = envelope_lattice(model, Vector{Int}(indexin(rids, reactions(model))); kwargs...) """ - envelope_lattice( - model::MetabolicModel, - ridxs::Vector{Int}; - samples = 10, - ranges = collect(zip(bounds(model)...))[ridxs], - reaction_samples = fill(samples, length(ridxs)), - ) +$(TYPEDSIGNATURES) Create a lattice (list of "tick" vectors) for reactions at indexes `ridxs` in a model. Arguments `samples`, `ranges`, and `reaction_samples` may be optionally @@ -33,7 +27,7 @@ envelope_lattice( ) """ - objective_envelope(model::MetabolicModel, rids::Vector{String}, args...; kwargs...) +$(TYPEDSIGNATURES) Version of [`objective_envelope`](@ref) that works on string reaction IDs instead of integer indexes. @@ -47,16 +41,7 @@ objective_envelope(model::MetabolicModel, rids::Vector{String}, args...; kwargs. ) """ - objective_envelope( - model::MetabolicModel, - ridxs::Vector{Int}, - optimizer; - modifications = [], - lattice_args = (), - lattice = envelope_lattice(model, ridxs; lattice_args...), - analysis = screen_optimize_objective, - kwargs..., - ) +$(TYPEDSIGNATURES) Compute an array of objective values for the `model` for rates of reactions specified `ridxs` fixed to a regular range of values between their respective diff --git a/src/analysis/flux_balance_analysis.jl b/src/analysis/flux_balance_analysis.jl index 25a534b08..495f4545f 100644 --- a/src/analysis/flux_balance_analysis.jl +++ b/src/analysis/flux_balance_analysis.jl @@ -1,5 +1,5 @@ """ - flux_balance_analysis_vec(model::MetabolicModel, args...)::Maybe{Vector{Float64}} +$(TYPEDSIGNATURES) A variant of FBA that returns a vector of fluxes in the same order as reactions of the model, if the solution is found. @@ -17,7 +17,7 @@ flux_balance_analysis_vec( flux_vector(model, flux_balance_analysis(model, args...; kwargs...)) """ - flux_balance_analysis_dict(model::MetabolicModel, args...)::Maybe{Dict{String, Float64}} +$(TYPEDSIGNATURES) A variant of FBA that returns a dictionary assigning fluxes to reactions, if the solution is found. Arguments are passed to [`flux_balance_analysis`](@ref). @@ -33,11 +33,7 @@ flux_balance_analysis_dict( flux_dict(model, flux_balance_analysis(model, args...; kwargs...)) """ - flux_balance_analysis( - model::M, - optimizer; - modifications = [], - ) where {M<:MetabolicModel} +$(TYPEDSIGNATURES) Run flux balance analysis (FBA) on the `model` optionally specifying `modifications` to the problem. Basically, FBA solves this optimization problem: diff --git a/src/analysis/flux_variability_analysis.jl b/src/analysis/flux_variability_analysis.jl index 7935da1bd..b540ec598 100644 --- a/src/analysis/flux_variability_analysis.jl +++ b/src/analysis/flux_variability_analysis.jl @@ -1,14 +1,5 @@ """ - flux_variability_analysis( - model::MetabolicModel, - fluxes::Vector{Int}, - optimizer; - modifications = [], - workers = [myid()], - optimal_objective_value = nothing, - bounds = z -> (z, Inf), - ret = objective_value, - )::Matrix{Float64} +$(TYPEDSIGNATURES) Flux variability analysis solves a pair of optimization problems in `model` for each flux `f` described in `fluxes`: @@ -108,7 +99,7 @@ function flux_variability_analysis( end """ - flux_variability_analysis(model::MetabolicModel, flux_indexes::Vector{Int}, optimizer; kwargs...) +$(TYPEDSIGNATURES) An overload of [`flux_variability_analysis`](@ref) that explores the fluxes specified by integer indexes """ @@ -131,11 +122,7 @@ function flux_variability_analysis( end """ - flux_variability_analysis( - model::MetabolicModel, - optimizer; - kwargs... - ) +$(TYPEDSIGNATURES) A simpler version of [`flux_variability_analysis`](@ref) that maximizes and minimizes all declared fluxes in the model. Arguments are forwarded. @@ -144,12 +131,7 @@ flux_variability_analysis(model::MetabolicModel, optimizer; kwargs...) = flux_variability_analysis(model, reaction_flux(model), optimizer; kwargs...) """ - flux_variability_analysis_dict( - model::MetabolicModel, - optimizer; - kwargs... - ) - +$(TYPEDSIGNATURES) A variant of [`flux_variability_analysis`](@ref) that returns the individual maximized and minimized fluxes as two dictionaries (of dictionaries). All keyword arguments except `ret` are passed through. @@ -182,7 +164,7 @@ function flux_variability_analysis_dict(model::MetabolicModel, optimizer; kwargs end """ - _max_variability_flux(opt_model, flux, sense, ret) +$(TYPEDSIGNATURES) Internal helper for maximizing reactions in optimization model. """ @@ -194,7 +176,7 @@ function _max_variability_flux(opt_model, flux, sense, ret) end """ - reaction_variability_analysis(model::MetabolicModel, reaction_indexes::Vector{Int}, optimizer; kwargs...) +$(TYPEDSIGNATURES) A variant for [`flux_variability_analysis`](@ref) that examines actual reactions (selected by their indexes in `reactions` argument) instead of whole @@ -226,7 +208,7 @@ function reaction_variability_analysis( end """ - reaction_variability_analysis( model::MetabolicModel, optimizer; kwargs...) +$(TYPEDSIGNATURES) Shortcut for [`reaction_variability_analysis`](@ref) that examines all reactions. """ diff --git a/src/analysis/gecko.jl b/src/analysis/gecko.jl index eedef6208..b4b5dcab7 100644 --- a/src/analysis/gecko.jl +++ b/src/analysis/gecko.jl @@ -1,12 +1,5 @@ """ - make_gecko_model( - model::MetabolicModel; - reaction_isozymes::Union{Function,Dict{String,Vector{Isozyme}}} - gene_product_bounds::Union{Function,Dict{String,Tuple{Float64,Float64}}}, - gene_product_molar_mass::Union{Function,Dict{String,Float64}}, - gene_product_mass_group::Union{Function,Dict{String,String}} = _ -> "uncategorized", - gene_product_mass_group_bound::Union{Function,Dict{String,Float64}}, - ) +$(TYPEDSIGNATURES) Wrap a model into a [`GeckoModel`](@ref), following the structure given by GECKO algorithm (see [`GeckoModel`](@ref) documentation for details). diff --git a/src/analysis/max_min_driving_force.jl b/src/analysis/max_min_driving_force.jl index fb3e751c7..8bb20f4eb 100644 --- a/src/analysis/max_min_driving_force.jl +++ b/src/analysis/max_min_driving_force.jl @@ -1,24 +1,5 @@ """ - max_min_driving_force( - model::MetabolicModel, - reaction_standard_gibbs_free_energies::Dict{String,Float64}, - optimizer; - flux_solution::Dict{String,Float64} = Dict{String,Float64}(), - proton_ids::Vector{String} = ["h_c", "h_e"], - water_ids::Vector{String} = ["h2o_c", "h2o_e"], - constant_concentrations::Dict{String,Float64} = Dict{String,Float64}(), - concentration_ratios::Dict{Tuple{String,String},Float64} = Dict{ - Tuple{String,String}, - Float64, - }(), - concentration_lb = 1e-9, - concentration_ub = 100e-3, - T = _constants.T, - R = _constants.R, - small_flux_tol = 1e-6, - modifications = [], - ignore_reaction_ids = [], - ) +$(TYPEDSIGNATURES) Perform a max-min driving force analysis on the `model`, as defined by Noor, et al., "Pathway thermodynamics highlights kinetic obstacles in central metabolism.", PLoS @@ -183,29 +164,7 @@ function max_min_driving_force( end """ - max_min_driving_force_variability( - model::MetabolicModel, - reaction_standard_gibbs_free_energies::Dict{String,Float64}, - optimizer; - workers =[myid()], - optimal_objective_value = nothing, - bounds = z -> (z, Inf), - flux_solution::Dict{String,Float64} = Dict{String,Float64}(), - proton_ids::Vector{String} = ["h_c", "h_e"], - water_ids::Vector{String} = ["h2o_c", "h2o_e"], - constant_concentrations::Dict{String,Float64} = Dict{String,Float64}(), - concentration_ratios::Dict{Tuple{String,String},Float64} = Dict{ - Tuple{String,String}, - Float64, - }(), - concentration_lb = 1e-9, - concentration_ub = 100e-3, - T = _constants.T, - R = _constants.R, - small_flux_tol = 1e-6, - modifications = [], - ignore_reaction_ids = [], - ) +$(TYPEDSIGNATURES) Perform a variant of flux variability analysis on a max min driving force type problem. Arguments are forwarded to [`max_min_driving_force`](@ref). Calls [`screen`](@ref) @@ -256,11 +215,11 @@ function max_min_driving_force_variability( dgr_variants = [ [[_mmdf_add_df_bound(lb, ub), _mmdf_dgr_objective(ridx, sense)]] for - ridx = 1:n_reactions(model), sense in [MOI.MAX_SENSE, MOI.MIN_SENSE] + ridx = 1:n_reactions(model), sense in [MAX_SENSE, MIN_SENSE] ] concen_variants = [ [[_mmdf_add_df_bound(lb, ub), _mmdf_concen_objective(midx, sense)]] for - midx = 1:n_metabolites(model), sense in [MOI.MAX_SENSE, MOI.MIN_SENSE] + midx = 1:n_metabolites(model), sense in [MAX_SENSE, MIN_SENSE] ] return screen( @@ -278,6 +237,8 @@ function max_min_driving_force_variability( end """ +$(TYPEDSIGNATURES) + Helper function to change the objective to optimizing some dG. """ function _mmdf_dgr_objective(ridx, sense) @@ -287,6 +248,8 @@ function _mmdf_dgr_objective(ridx, sense) end """ +$(TYPEDSIGNATURES) + Helper function to change the objective to optimizing some concentration. """ function _mmdf_concen_objective(midx, sense) @@ -296,6 +259,8 @@ function _mmdf_concen_objective(midx, sense) end """ +$(TYPEDSIGNATURES) + Helper function to add a new constraint on the driving force. """ function _mmdf_add_df_bound(lb, ub) diff --git a/src/analysis/minimize_metabolic_adjustment.jl b/src/analysis/minimize_metabolic_adjustment.jl index d15501f37..e51e0ea0d 100644 --- a/src/analysis/minimize_metabolic_adjustment.jl +++ b/src/analysis/minimize_metabolic_adjustment.jl @@ -1,11 +1,5 @@ """ - minimize_metabolic_adjustment_analysis( - model::MetabolicModel, - flux_ref::Union{Dict{String,Float64}, Vector{Float64}}, - optimizer; - modifications = [], - kwargs... - ) +$(TYPEDSIGNATURES) Run minimization of metabolic adjustment (MOMA) on `model` with respect to `flux_ref`, which is a vector of fluxes in the order of `reactions(model)`. @@ -52,7 +46,7 @@ minimize_metabolic_adjustment_analysis( ) """ - minimize_metabolic_adjustment(flux_ref::Vector{Float64}) +$(TYPEDSIGNATURES) An optimization model modification that implements the MOMA in [`minimize_metabolic_adjustment_analysis`](@ref). @@ -69,7 +63,7 @@ minimize_metabolic_adjustment(flux_ref::Vector{Float64}) = end """ - minimize_metabolic_adjustment(flux_ref_dict::Dict{String, Float64}) +$(TYPEDSIGNATURES) Overload of [`minimize_metabolic_adjustment`](@ref) that works with a dictionary of fluxes. @@ -82,7 +76,7 @@ minimize_metabolic_adjustment(flux_ref_dict::Dict{String,Float64}) = ) """ - minimize_metabolic_adjustment_analysis_vec(model::MetabolicModel, args...; kwargs...) +$(TYPEDSIGNATURES) Perform minimization of metabolic adjustment (MOMA) and return a vector of fluxes in the same order as the reactions in `model`. Arguments are forwarded to @@ -95,7 +89,7 @@ minimize_metabolic_adjustment_analysis_vec(model::MetabolicModel, args...; kwarg flux_vector(model, minimize_metabolic_adjustment_analysis(model, args...; kwargs...)) """ - minimize_metabolic_adjustment_analysis_dict(model::MetabolicModel, args...; kwargs...) +$(TYPEDSIGNATURES) Perform minimization of metabolic adjustment (MOMA) and return a dictionary mapping the reaction IDs to fluxes. Arguments are forwarded to [`minimize_metabolic_adjustment`](@ref) diff --git a/src/analysis/modifications/crowding.jl b/src/analysis/modifications/crowding.jl index 510f96799..8bad4c23c 100644 --- a/src/analysis/modifications/crowding.jl +++ b/src/analysis/modifications/crowding.jl @@ -1,6 +1,6 @@ """ - add_crowding_constraints(weights::Dict{Int64, Float64}) +$(TYPEDSIGNATURES) Adds a molecular crowding constraint to the optimization problem: `∑ wᵢ × vᵢ ≤ 1` where `wᵢ` is a weight and `vᵢ` is a flux index in the model's reactions specified in `weights` as `vᵢ @@ -23,7 +23,7 @@ add_crowding_constraints(weights::Dict{Int64,Float64}) = end """ - add_crowding_constraints(weights::Dict{String, Float64}) +$(TYPEDSIGNATURES) Variant of [`add_crowding_constraints`](@ref) that takes a dictinary of reactions `ids` instead of reaction indices mapped to weights. diff --git a/src/analysis/modifications/generic.jl b/src/analysis/modifications/generic.jl index eb8e9dddb..bcf1c0b89 100644 --- a/src/analysis/modifications/generic.jl +++ b/src/analysis/modifications/generic.jl @@ -1,6 +1,6 @@ """ - constrain_objective_value(tolerance) +$(TYPEDSIGNATURES) Limit the objective value to `tolerance`-times the current objective value, as with [`objective_bounds`](@ref). @@ -13,7 +13,7 @@ constrain_objective_value(tolerance) = end """ - change_constraint(id::String; lb=nothing, ub=nothing) +$(TYPEDSIGNATURES) Change the lower and upper bounds (`lb` and `ub` respectively) of reaction `id` if supplied. """ @@ -25,7 +25,7 @@ change_constraint(id::String; lb = nothing, ub = nothing) = end """ - change_objective(new_objective::Union{String,Vector{String}}; weights=[], sense=MAX_SENSE) +$(TYPEDSIGNATURES) Modification that changes the objective function used in a constraint based analysis function. `new_objective` can be a single reaction identifier, or an diff --git a/src/analysis/modifications/knockout.jl b/src/analysis/modifications/knockout.jl index a547b281c..b55715e61 100644 --- a/src/analysis/modifications/knockout.jl +++ b/src/analysis/modifications/knockout.jl @@ -1,5 +1,5 @@ """ - knockout(gene_ids::Vector{String}) +$(TYPEDSIGNATURES) A modification that zeroes the bounds of all reactions that would be knocked out by the combination of specified genes (effectively disabling the @@ -20,14 +20,14 @@ knockout(gene_ids::Vector{String}) = (model, optmodel) -> _do_knockout(model, optmodel, gene_ids) """ - knockout(gene_id::String) +$(TYPEDSIGNATURES) A helper variant of [`knockout`](@ref) for a single gene. """ knockout(gene_id::String) = knockout([gene_id]) """ - _do_knockout(model::MetabolicModel, opt_model) +$(TYPEDSIGNATURES) Internal helper for knockouts on generic MetabolicModels. This can be overloaded so that the knockouts may work differently (more efficiently) with diff --git a/src/analysis/modifications/loopless.jl b/src/analysis/modifications/loopless.jl index 32cb70987..b7578ac74 100644 --- a/src/analysis/modifications/loopless.jl +++ b/src/analysis/modifications/loopless.jl @@ -1,8 +1,5 @@ """ - add_loopless_constraints(; - max_flux_bound = _constants.default_reaction_bound, - strict_inequality_tolerance = _constants.loopless_strict_inequality_tolerance, - ) +$(TYPEDSIGNATURES) Add quasi-thermodynamic constraints to the model to ensure that no thermodynamically infeasible internal cycles can occur. Adds the following constraints to the problem: diff --git a/src/analysis/modifications/moment.jl b/src/analysis/modifications/moment.jl index 94616fa3a..31b2e56f6 100644 --- a/src/analysis/modifications/moment.jl +++ b/src/analysis/modifications/moment.jl @@ -1,8 +1,5 @@ """ - add_moment_constraints( - ksas::Dict{String,Float64}, - protein_mass_fraction::Float64 - ) +$(TYPEDSIGNATURES) A modification that adds enzyme capacity constraints to the problem using a _modified_ version of the MOMENT algorithm. Requires specific activities, `ksas` [mmol product/g diff --git a/src/analysis/modifications/optimizer.jl b/src/analysis/modifications/optimizer.jl index 2287ef4be..41c51bdf8 100644 --- a/src/analysis/modifications/optimizer.jl +++ b/src/analysis/modifications/optimizer.jl @@ -1,9 +1,9 @@ """ - change_sense(objective_sense) +$(TYPEDSIGNATURES) Change the objective sense of optimization. -Possible arguments are `MOI.MAX_SENSE` and `MOI.MIN_SENSE`. +Possible arguments are `MAX_SENSE` and `MIN_SENSE`. If you want to change the objective and sense at the same time, use [`change_objective`](@ref) instead to do both at once. @@ -12,7 +12,7 @@ change_sense(objective_sense) = (_, opt_model) -> set_objective_sense(opt_model, objective_sense) """ - change_optimizer(optimizer) +$(TYPEDSIGNATURES) Change the JuMP optimizer used to run the optimization. @@ -23,7 +23,7 @@ problems that may require different optimizers for different parts, such as the change_optimizer(optimizer) = (_, opt_model) -> set_optimizer(opt_model, optimizer) """ - change_optimizer_attribute(attribute_key, value) +$(TYPEDSIGNATURES) Change a JuMP optimizer attribute. The attributes are optimizer-specific, refer to the JuMP documentation and the documentation of the specific optimizer for diff --git a/src/analysis/parsimonious_flux_balance_analysis.jl b/src/analysis/parsimonious_flux_balance_analysis.jl index 12475f15c..8d06f4d45 100644 --- a/src/analysis/parsimonious_flux_balance_analysis.jl +++ b/src/analysis/parsimonious_flux_balance_analysis.jl @@ -1,11 +1,5 @@ """ - parsimonious_flux_balance_analysis( - model::MetabolicModel, - optimizer; - modifications = [], - qp_modifications = [], - relax_bounds=[1.0, 0.999999, 0.99999, 0.9999, 0.999, 0.99], - ) +$(TYPEDSIGNATURES) Run parsimonious flux balance analysis (pFBA) on the `model`. In short, pFBA runs two consecutive optimization problems. The first is traditional FBA: @@ -36,14 +30,15 @@ finds a minimal total flux through the model that still satisfies the (slightly relaxed) optimum. This is done using a quadratic problem optimizer. If the original optimizer does not support quadratic optimization, it can be changed using the callback in `qp_modifications`, which are applied after the FBA. See -the documentation of [`flux_balance_analysis`](@ref) for usage examples of modifications. +the documentation of [`flux_balance_analysis`](@ref) for usage examples of +modifications. Thhe optimum relaxation sequence can be specified in `relax` parameter, it -defaults to multiplicative range of `[1.0, 0.999999, ..., 0.99]` of the -original bound. +defaults to multiplicative range of `[1.0, 0.999999, ..., 0.99]` of the original +bound. -Returns an optimized model that contains the pFBA solution; or `nothing` if the -optimization failed. +Returns an optimized model that contains the pFBA solution (or an unsolved model +if something went wrong). # Example ``` @@ -61,7 +56,7 @@ function parsimonious_flux_balance_analysis( ) # Run FBA opt_model = flux_balance_analysis(model, optimizer; modifications = modifications) - is_solved(opt_model) || return nothing # FBA failed + is_solved(opt_model) || return opt_model # FBA failed # get the objective Z = objective_value(opt_model) @@ -88,13 +83,11 @@ function parsimonious_flux_balance_analysis( unregister(opt_model, :pfba_constraint) end - is_solved(opt_model) || return nothing # pFBA failed - return opt_model end """ - parsimonious_flux_balance_analysis_vec(model::MetabolicModel, args...; kwargs...) +$(TYPEDSIGNATURES) Perform parsimonious flux balance analysis on `model` using `optimizer`. Returns a vector of fluxes in the same order as the reactions in `model`. @@ -108,7 +101,7 @@ parsimonious_flux_balance_analysis_vec(model::MetabolicModel, args...; kwargs... flux_vector(model, parsimonious_flux_balance_analysis(model, args...; kwargs...)) """ - parsimonious_flux_balance_analysis_dict(model::MetabolicModel, args...; kwargs...) +$(TYPEDSIGNATURES) Perform parsimonious flux balance analysis on `model` using `optimizer`. Returns a dictionary mapping the reaction IDs to fluxes. Arguments are diff --git a/src/analysis/sampling/affine_hit_and_run.jl b/src/analysis/sampling/affine_hit_and_run.jl index 92669cf5b..b369b0be6 100644 --- a/src/analysis/sampling/affine_hit_and_run.jl +++ b/src/analysis/sampling/affine_hit_and_run.jl @@ -1,12 +1,5 @@ """ - function affine_hit_and_run( - m::MetabolicModel, - warmup_points::Matrix{Float64}; - sample_iters = 100 .* (1:5), - workers = [myid()], - chains = length(workers), - seed = rand(Int), - ) +$(TYPEDSIGNATURES) Run a hit-and-run style sampling that starts from `warmup_points` and uses their affine combinations for generating the run directions to sample the space @@ -77,7 +70,7 @@ function affine_hit_and_run( end """ - _affine_hit_and_run_chain(warmup, lbs, ubs, iters, seed) +$(TYPEDSIGNATURES) Internal helper function for computing a single affine hit-and-run chain. """ diff --git a/src/analysis/sampling/warmup_variability.jl b/src/analysis/sampling/warmup_variability.jl index a16078ba7..8764bbeb2 100644 --- a/src/analysis/sampling/warmup_variability.jl +++ b/src/analysis/sampling/warmup_variability.jl @@ -1,10 +1,5 @@ """ - warmup_from_variability( - model::MetabolicModel, - optimizer, - n_points::Int; - kwargs... - ) +$(TYPEDSIGNATURES) Generates FVA-like warmup points for samplers, by selecting random points by minimizing and maximizing reactions. Can not return more than 2 times the @@ -37,14 +32,7 @@ function warmup_from_variability( end """ - function warmup_from_variability( - model::MetabolicModel, - optimizer, - min_reactions::Vector{Int}=1:n_reactions(model), - max_reactions::Vector{Int}=1:n_reactions(model); - modifications = [], - workers::Vector{Int} = [myid()], - )::Matrix{Float64} +$(TYPEDSIGNATURES) Generate FVA-like warmup points for samplers, by minimizing and maximizing the specified reactions. The result is returned as a matrix, each point occupies as @@ -99,7 +87,7 @@ function warmup_from_variability( end """ - _maximize_warmup_reaction(opt_model, rid, ret) +$(TYPEDSIGNATURES) A helper function for finding warmup points from reaction variability. """ diff --git a/src/analysis/screening.jl b/src/analysis/screening.jl index 1876fcef6..a4dd13af4 100644 --- a/src/analysis/screening.jl +++ b/src/analysis/screening.jl @@ -1,6 +1,6 @@ """ - _screen_args(argtuple, kwargtuple, modsname) +$(TYPEDSIGNATURES) Internal helper to check the presence and shape of modification and argument arrays in [`screen`](@ref) and pals. @@ -33,13 +33,7 @@ function _screen_args(argtuple, kwargtuple, modsname) end """ - screen( - model::MetabolicModel; - variants::Array{V,N}, # defaults to an array of identities - analysis, - args::Array{A,N}, # defaults to an array of empty argument lists - workers = [myid()], - )::Array where {V<:AbstractVector,A,N} +$(TYPEDSIGNATURES) Take an array of model-modifying function vectors in `variants`, and execute the function `analysis` on all variants of the `model` specified by `variants`. @@ -111,13 +105,7 @@ screen(args...; kwargs...) = _screen_impl(args...; kwargs..., _screen_args(args, kwargs, :variants)...) """ - _screen_impl( - model::MetabolicModel; - variants::Array{V,N}, - analysis, - args::Array{A,N}, - workers = [myid()], - )::Array where {V<:AbstractVector,A,N} +$(TYPEDSIGNATURES) The actual implementation of [`screen`](@ref). """ @@ -151,7 +139,7 @@ function _screen_impl( end """ - screen_variant(model::MetabolicModel, variant::Vector, analysis, args = ()) +$(TYPEDSIGNATURES) Helper function for [`screen`](@ref) that applies all single-argument functions in `variant` to the `model` (in order from "first" to @@ -167,7 +155,7 @@ function screen_variant(model::MetabolicModel, variant::Vector, analysis, args = end """ - screen_variants(model, variants, analysis; workers=[myid()]) +$(TYPEDSIGNATURES) A shortcut for [`screen`](@ref) that only works with model variants. """ @@ -175,7 +163,7 @@ screen_variants(model, variants, analysis; workers = [myid()]) = screen(model; variants = variants, analysis = analysis, workers = workers) """ - screen_optimize_objective(_, optmodel)::Maybe{Float64} +$(TYPEDSIGNATURES) A variant of [`optimize_objective`](@ref) directly usable in [`screen_optmodel_modifications`](@ref). @@ -183,7 +171,7 @@ A variant of [`optimize_objective`](@ref) directly usable in screen_optimize_objective(_, optmodel)::Maybe{Float64} = optimize_objective(optmodel) """ - _screen_optmodel_prepare(model, optimizer, common_modifications) +$(TYPEDSIGNATURES) Internal helper for [`screen_optmodel_modifications`](@ref) that creates the model and applies the modifications. @@ -198,7 +186,7 @@ function _screen_optmodel_prepare(model, optimizer, common_modifications) end """ - _screen_optmodel_item((mods, args)) +$(TYPEDSIGNATURES) Internal helper for [`screen_optmodel_modifications`](@ref) that computes one item of the screening task. @@ -212,15 +200,7 @@ function _screen_optmodel_item((mods, args)) end """ - screen_optmodel_modifications( - model::MetabolicModel, - optimizer; - common_modifications::VF = [], - modifications::Array{V,N}, # defaults to an array with no modifications - args::Array{A,N}, # defaults to an array of empty argument lists - analysis::Function, - workers = [myid()], - )::Array where {V<:AbstractVector,VF<:AbstractVector,A,N} +$(TYPEDSIGNATURES) Screen multiple modifications of the same optimization model. @@ -254,15 +234,7 @@ screen_optmodel_modifications(args...; kwargs...) = _screen_optmodel_modificatio ) """ - _screen_optmodel_modifications_impl( - model::MetabolicModel, - optimizer; - common_modifications::VF = [], - modifications::Array{V,N}, - args::Array{A,N}, - analysis::Function, - workers = [myid()], - )::Array where {V<:AbstractVector,VF<:AbstractVector,A,N} +$(TYPEDSIGNATURES) The actual implementation of [`screen_optmodel_modifications`](@ref). """ diff --git a/src/analysis/smoment.jl b/src/analysis/smoment.jl index 391345fb9..179d41597 100644 --- a/src/analysis/smoment.jl +++ b/src/analysis/smoment.jl @@ -1,11 +1,6 @@ """ - make_smoment_model( - model::MetabolicModel; - reaction_isozyme::Union{Function,Dict{String,Isozyme}}, - gene_product_molar_mass::Union{Function,Dict{String,Float64}}, - total_enzyme_capacity::Float64, - ) +$(TYPEDSIGNATURES) Construct a model with a structure given by sMOMENT algorithm; returns a [`SMomentModel`](@ref) (see the documentation for details). diff --git a/src/banner.jl b/src/banner.jl deleted file mode 100644 index 00f62a550..000000000 --- a/src/banner.jl +++ /dev/null @@ -1,32 +0,0 @@ -const _PKG_ROOT_DIR = normpath(joinpath(@__DIR__, "..")) -include_dependency(joinpath(_PKG_ROOT_DIR, "Project.toml")) - -const COBREXA_VERSION = - VersionNumber(Pkg.TOML.parsefile(joinpath(_PKG_ROOT_DIR, "Project.toml"))["version"]) - -function __init__() - if myid() == 1 && Base.JLOptions().banner != 0 - _print_banner() - end -end - -function _print_banner() - c = Base.text_colors - n = c[:normal] - y = c[:bold] * c[:cyan] - - println( - " - $(y)//$(n) | - \\\\\\\\\\ // $(y)//$(n) | $(c[:bold])COBREXA.jl $(c[:normal]) v$(COBREXA_VERSION) - \\\\ \\\\// $(y)//$(n) | - \\\\ \\/ $(y)//$(n) | $(c[:bold])CO$(c[:normal])nstraint-$(c[:bold])B$(c[:normal])ased $(c[:bold])R$(c[:normal])econstruction - \\\\ $(y)//$(n) | and $(c[:bold])EX$(c[:normal])ascale $(c[:bold])A$(c[:normal])nalysis in Julia - // $(y)\\\\$(n) | - // $(y)/\\ \\\\$(n) | See documentation and examples at: - // $(y)//\\\\ \\\\$(n) | https://lcsb-biocore.github.io/COBREXA.jl - // $(y)// \\\\\\\\\\$(n) | - // | - ", - ) -end diff --git a/src/base/constants.jl b/src/base/constants.jl index 3a752c11c..001c82087 100644 --- a/src/base/constants.jl +++ b/src/base/constants.jl @@ -63,6 +63,3 @@ const _constants = ( T = 298.15, # Kelvin R = 8.31446261815324e-3, # kJ/K/mol ) - -const MAX_SENSE = MOI.MAX_SENSE -const MIN_SENSE = MOI.MIN_SENSE diff --git a/src/base/identifiers.jl b/src/base/identifiers.jl new file mode 100644 index 000000000..92b147a93 --- /dev/null +++ b/src/base/identifiers.jl @@ -0,0 +1,33 @@ +""" +This module uses annotation identifiers to classify reactions, metabolites, +genes, etc. If an subject has a matching annotation, then it is assumed that it +is part of the associated class of objects. +""" +module Identifiers +using ..COBREXA.SBOTerms + +const EXCHANGE_REACTIONS = [SBOTerms.EXCHANGE_REACTION] + +const TRANSPORT_REACTIONS = [ + SBOTerms.TRANSPORT_REACTION, + SBOTerms.TRANSCELLULAR_MEMBRANE_INFLUX_REACTION, + SBOTerms.TRANSCELLULAR_MEMBRANE_EFFLUX_REACTION, +] + +const METABOLIC_REACTIONS = [SBOTerms.BIOCHEMICAL_REACTION] + +const BIOMASS_REACTIONS = [SBOTerms.BIOMASS_PRODUCTION] + +const ATP_MAINTENANCE_REACTIONS = [SBOTerms.ATP_MAINTENANCE] + +const PSEUDOREACTIONS = [ + SBOTerms.EXCHANGE_REACTION, + SBOTerms.DEMAND_REACTION, + SBOTerms.BIOMASS_PRODUCTION, + SBOTerms.ATP_MAINTENANCE, + SBOTerms.PSEUDOREACTION, + SBOTerms.SINK_REACTION, +] + +const SPONTANEOUS_REACTIONS = [SBOTerms.SPONTANEOUS_REACTION] +end diff --git a/src/base/logging/log.jl b/src/base/logging/log.jl index 7b24ba874..866846988 100644 --- a/src/base/logging/log.jl +++ b/src/base/logging/log.jl @@ -1,6 +1,6 @@ """ - macro _make_logging_group(sym::Symbol, doc::String) +$(TYPEDSIGNATURES) This creates a group of functions that allow masking out topic-related logging actions. A call that goes as follows: diff --git a/src/base/macros/is_xxx_reaction.jl b/src/base/macros/is_xxx_reaction.jl new file mode 100644 index 000000000..b8601df86 --- /dev/null +++ b/src/base/macros/is_xxx_reaction.jl @@ -0,0 +1,49 @@ + +""" +@_is_reaction_fn(anno_id, identifier) + +A helper for creating functions like `is_exchange_reaction`. +""" +macro _is_reaction_fn(anno_id, identifiers) + + fname = Symbol(:is_, anno_id, :_reaction) + grammar = any(startswith.(anno_id, ["a", "e", "i", "o", "u"])) ? "an" : "a" + + body = quote + begin + anno = reaction_annotations(model, reaction_id) + for key in annotation_keys + if haskey(anno, key) + any(in.($identifiers, Ref(anno[key]))) && return true + end + end + return false + end + end + + docstring = """ + $fname( + model::MetabolicModel, + reaction_id::String; + annotation_keys = ["sbo", "SBO"], + ) + + Check if a reaction is annotated as $(grammar) $(anno_id) reaction. Uses + `$identifiers` internally, which includes SBO identifiers. In + the reaction annotations, use the keys in `annotation_keys` to look for entries. + Returns false if no hits or if no keys are found. + """ + Expr( + :macrocall, + Symbol("@doc"), + __source__, + docstring, + :( + $fname( + model::MetabolicModel, + reaction_id::String; + annotation_keys = ["sbo", "SBO"], + ) = $body + ), + ) +end diff --git a/src/base/macros/model_wrapper.jl b/src/base/macros/model_wrapper.jl index ccbdb0e29..66de84db6 100644 --- a/src/base/macros/model_wrapper.jl +++ b/src/base/macros/model_wrapper.jl @@ -1,6 +1,6 @@ """ - _inherit_model_methods_impl(mtype::Symbol, arglist, access, fwdlist, fns...) +$(TYPEDSIGNATURES) A helper backend for [`@_inherit_model_methods`](@ref) and [`@_inherit_model_methods_fn`](@ref). @@ -38,7 +38,7 @@ function _inherit_model_methods_impl( end """ - @_inherit_model_methods +$(TYPEDSIGNATURES) Generates trivial accessor functions listed in `fns` for a model that is wrapped in type `mtype` as field `member`. @@ -55,7 +55,7 @@ macro _inherit_model_methods(mtype::Symbol, arglist, member::Symbol, fwdlist, fn end """ - @_inherit_model_methods_fn +$(TYPEDSIGNATURES) A more generic version of [`@_inherit_model_methods`](@ref) that accesses the "inner" model using an accessor function name. diff --git a/src/base/ontologies/SBOTerms.jl b/src/base/ontologies/SBOTerms.jl new file mode 100644 index 000000000..6a3e2a4f3 --- /dev/null +++ b/src/base/ontologies/SBOTerms.jl @@ -0,0 +1,84 @@ +""" +This module contains SBO terms recognized by COBREXA. For the full ontology, see +https://github.com/EBI-BioModels/SBO/blob/master/SBO_OBO.obo. + +If an SBO term appears here it *may* be used in a function; if an SBO term does +not appear here, then it is *not* used in a COBREXA function. + +These terms are used in `Identifiers.jl` which groups them as appropriate for +use in functions that classify reactions, metabolites, etc. +""" +module SBOTerms +const FLUX_BALANCE_FRAMEWORK = "SBO:0000624" +const RESOURCE_BALANCE_FRAMEWORK = "SBO:0000692" +const CONSTRAINT_BASED_FRAMEWORK = "SBO:0000693" + +const PRODUCT = "SBO:0000011" +const CONCENTRATION_OF_PRODUCT = "SBO:0000512" +const SIDE_PRODUCT = "SBO:0000603" + +const SUBSTRATE = "SBO:0000015" +const CONCENTRATION_OF_SUBSTRATE = "SBO:0000515" +const SIDE_SUBSTRATE = "SBO:0000604" + +const ENZYME = "SBO:0000014" +const TOTAL_CONCENTRATION_OF_ENZYME = "SBO:0000300" + +const TRANSCRIPTION = "SBO:0000183" +const TRANSLATION = "SBO:0000184" + +const GENE = "SBO:0000243" +const METABOLITE = "SBO:0000299" +const MACROMOLECULE = "SBO:0000245" +const SIMPLE_CHEMICAL = "SBO:0000247" +const RIBONUCLEIC_ACID = "SBO:0000250" +const DEOXYRIBONUCLEIC_ACID = "SBO:0000251" +const TRANSFER_RNA = "SBO:0000313" +const RIBOSOMAL_RNA = "SBO:0000314" +const MESSENGER_RNA = "SBO:0000278" +const TRANSPORTER = "SBO:0000284" +const PROTEIN_COMPLEX = "SBO:0000297" + +const MOLECULAR_MASS = "SBO:0000647" +const CATALYTIC_RATE_CONSTANT = "SBO:0000025" # turnover number synonym +const CAPACITY = "SBO:0000661" +const MICHAELIS_CONSTANT = "SBO:0000027" +const MICHAELIS_CONSTANT_FOR_PRODUCT = "SBO:0000323" +const MICHAELIS_CONSTANT_FOR_SUBSTRATE = "SBO:0000322" +const INHIBITORY_CONSTANT = "SBO:0000261" + +const STOICHIOMETRIC_COEFFICIENT = "SBO:0000481" +const AND = "SBO:0000173" +const OR = "SBO:0000174" + +const PH = "SBO:0000304" +const IONIC_STRENGTH = "SBO:0000623" + +const THERMODYNAMIC_TEMPERATURE = "SBO:0000147" +const STANDARD_GIBBS_FREE_ENERGY_OF_REACTION = "SBO:0000583" +const GIBBS_FREE_ENERGY_OF_REACTION = "SBO:0000617" +const STANDARD_GIBBS_FREE_ENERGY_OF_FORMATION = "SBO:0000582" +const TRANSFORMED_STANDARD_GIBBS_FREE_ENERGY_CHANGE_OF_REACTION = "SBO:0000620" +const TRANSFORMED_GIBBS_FREE_ENERGY_CHANGE_OF_REACTION = "SBO:0000622" +const TRANSFORMED_STANDARD_GIBBS_FREE_ENERGY_OF_FORMATION = "SBO:0000621" + +const BIOCHEMICAL_OR_TRANSPORT_REACTION = "SBO:0000167" +const BIOCHEMICAL_REACTION = "SBO:0000176" +const TRANSPORT_REACTION = "SBO:0000655" +const TRANSCELLULAR_MEMBRANE_INFLUX_REACTION = "SBO:0000587" +const TRANSCELLULAR_MEMBRANE_EFFLUX_REACTION = "SBO:0000588" +const FLUX_BOUND = "SBO:0000625" +const DEFAULT_FLUX_BOUND = "SBO:0000626" +const EXCHANGE_REACTION = "SBO:0000627" +const DEMAND_REACTION = "SBO:0000628" +const BIOMASS_PRODUCTION = "SBO:0000629" +const ATP_MAINTENANCE = "SBO:0000630" +const PSEUDOREACTION = "SBO:0000631" +const SINK_REACTION = "SBO:0000632" +const SPONTANEOUS_REACTION = "SBO:0000672" + +const ACTIVE_TRANSPORT = "SBO:0000657" +const PASSIVE_TRANSPORT = "SBO:0000658" + +const SUBSYSTEM = "SBO:0000633" +end diff --git a/src/base/solver.jl b/src/base/solver.jl index 02735a2bc..7d112e7d8 100644 --- a/src/base/solver.jl +++ b/src/base/solver.jl @@ -1,10 +1,6 @@ """ - make_optimization_model( - model::MetabolicModel, - optimizer; - sense = MAX_SENSE, - ) +$(TYPEDSIGNATURES) Convert `MetabolicModel`s to a JuMP model, place objectives and the equality constraint. @@ -36,7 +32,7 @@ function make_optimization_model(model::MetabolicModel, optimizer; sense = MAX_S end """ - is_solved(opt_model) +$(TYPEDSIGNATURES) Return `true` if `opt_model` solved successfully (solution is optimal or locally optimal). Return `false` if any other termination status is reached. @@ -45,7 +41,7 @@ Termination status is defined in the documentation of `JuMP`. is_solved(opt_model) = termination_status(opt_model) in [MOI.OPTIMAL, MOI.LOCALLY_SOLVED] """ - optimize_objective(opt_model)::Maybe{Float64} +$(TYPEDSIGNATURES) Shortcut for running JuMP `optimize!` on a model and returning the objective value, if solved. @@ -56,7 +52,7 @@ function optimize_objective(opt_model)::Maybe{Float64} end """ - get_optmodel_bounds(opt_model) +$(TYPEDSIGNATURES) Returns vectors of the lower and upper bounds of `opt_model` constraints, where `opt_model` is a JuMP model constructed by e.g. @@ -68,10 +64,7 @@ get_optmodel_bounds(opt_model) = ( ) """ - set_optmodel_bound!(vidx, opt_model; - ub::Maybe{Real} = nothing, - lb::Maybe{Real} = nothing, - ) +$(TYPEDSIGNATURES) Helper function to set the bounds of a variable in the model. Internally calls `set_normalized_rhs` from JuMP. If the bounds are set to `nothing`, they will @@ -88,7 +81,7 @@ function set_optmodel_bound!( end """ - solved_objective_value(opt_model)::Maybe{Float64} +$(TYPEDSIGNATURES) Returns the current objective value of a model, if solved. @@ -101,7 +94,7 @@ solved_objective_value(opt_model)::Maybe{Float64} = is_solved(opt_model) ? objective_value(opt_model) : nothing """ - flux_vector(opt_model)::Maybe{Vector{Float64}} +$(TYPEDSIGNATURES) Returns a vector of fluxes of the model, if solved. @@ -114,7 +107,7 @@ flux_vector(model::MetabolicModel, opt_model)::Maybe{Vector{Float64}} = is_solved(opt_model) ? reaction_flux(model)' * value.(opt_model[:x]) : nothing """ - flux_dict(model::MetabolicModel, opt_model)::Maybe{Dict{String, Float64}, Nothing} +$(TYPEDSIGNATURES) Returns the fluxes of the model as a reaction-keyed dictionary, if solved. @@ -128,7 +121,7 @@ flux_dict(model::MetabolicModel, opt_model)::Maybe{Dict{String,Float64}} = Dict(fluxes(model) .=> reaction_flux(model)' * value.(opt_model[:x])) : nothing """ - flux_dict(model::MetabolicModel) +$(TYPEDSIGNATURES) A pipeable variant of `flux_dict`. diff --git a/src/base/types/CoreModel.jl b/src/base/types/CoreModel.jl index db696c42a..9133fda6a 100644 --- a/src/base/types/CoreModel.jl +++ b/src/base/types/CoreModel.jl @@ -1,6 +1,6 @@ """ - struct CoreModel <: MetabolicModel +$(TYPEDEF) A "bare bones" core linear optimization problem of the form, with reaction and metabolite names. @@ -9,6 +9,9 @@ min c^T x s.t. S x = b xₗ ≤ x ≤ xᵤ ``` + +# Fields +$(TYPEDFIELDS) """ mutable struct CoreModel <: MetabolicModel S::SparseMat @@ -45,49 +48,49 @@ mutable struct CoreModel <: MetabolicModel end """ - reactions(a::CoreModel)::Vector{String} +$(TYPEDSIGNATURES) Get the reactions in a `CoreModel`. """ reactions(a::CoreModel)::Vector{String} = a.rxns """ - metabolites(a::CoreModel)::Vector{String} +$(TYPEDSIGNATURES) Metabolites in a `CoreModel`. """ metabolites(a::CoreModel)::Vector{String} = a.mets """ - stoichiometry(a::CoreModel)::SparseMat +$(TYPEDSIGNATURES) `CoreModel` stoichiometry matrix. """ stoichiometry(a::CoreModel)::SparseMat = a.S """ - bounds(a::CoreModel)::Tuple{Vector{Float64},Vector{Float64}} +$(TYPEDSIGNATURES) `CoreModel` flux bounds. """ bounds(a::CoreModel)::Tuple{Vector{Float64},Vector{Float64}} = (a.xl, a.xu) """ - balance(a::CoreModel)::SparseVec +$(TYPEDSIGNATURES) `CoreModel` target flux balance. """ balance(a::CoreModel)::SparseVec = a.b """ - objective(a::CoreModel)::SparseVec +$(TYPEDSIGNATURES) `CoreModel` objective vector. """ objective(a::CoreModel)::SparseVec = a.c """ - genes(a::CoreModel)::Vector{String} +$(TYPEDSIGNATURES) Collect all genes contained in the [`CoreModel`](@ref). The call is expensive for large models, because the vector is not stored and instead gets rebuilt @@ -107,7 +110,7 @@ function genes(a::CoreModel)::Vector{String} end """ - reaction_stoichiometry(model::CoreModel, rid::String)::Dict{String, Float64} +$(TYPEDSIGNATURES) Return the stoichiometry of reaction with ID `rid`. """ @@ -115,7 +118,7 @@ reaction_stoichiometry(m::CoreModel, rid::String)::Dict{String,Float64} = Dict(m.mets[k] => v for (k, v) in zip(findnz(m.S[:, first(indexin([rid], m.rxns))])...)) """ - reaction_stoichiometry(model::CoreModel, ridx)::Dict{String, Float64} +$(TYPEDSIGNATURES) Return the stoichiometry of reaction at index `ridx`. """ @@ -123,7 +126,7 @@ reaction_stoichiometry(m::CoreModel, ridx)::Dict{String,Float64} = Dict(m.mets[k] => v for (k, v) in zip(findnz(m.S[:, ridx])...)) """ - reaction_gene_association_vec(model::CoreModel)::Vector{Maybe{GeneAssociation}} +$(TYPEDSIGNATURES) Retrieve a vector of all gene associations in a [`CoreModel`](@ref), in the same order as `reactions(model)`. @@ -131,7 +134,7 @@ same order as `reactions(model)`. reaction_gene_association_vec(model::CoreModel)::Vector{Maybe{GeneAssociation}} = model.grrs """ - reaction_gene_association(model::CoreModel, ridx::Int)::Maybe{GeneAssociation} +$(TYPEDSIGNATURES) Retrieve the [`GeneAssociation`](@ref) from [`CoreModel`](@ref) by reaction index. @@ -140,7 +143,7 @@ reaction_gene_association(model::CoreModel, ridx::Int)::Maybe{GeneAssociation} = model.grrs[ridx] """ - reaction_gene_association(model::CoreModel, rid::String)::Maybe{GeneAssociation} +$(TYPEDSIGNATURES) Retrieve the [`GeneAssociation`](@ref) from [`CoreModel`](@ref) by reaction ID. """ @@ -148,7 +151,7 @@ reaction_gene_association(model::CoreModel, rid::String)::Maybe{GeneAssociation} model.grrs[first(indexin([rid], model.rxns))] """ - Base.convert(::Type{CoreModel}, m::M) where {M <: MetabolicModel} +$(TYPEDSIGNATURES) Make a `CoreModel` out of any compatible model type. """ diff --git a/src/base/types/CoreModelCoupled.jl b/src/base/types/CoreModelCoupled.jl index fd1fb4735..048ffa730 100644 --- a/src/base/types/CoreModelCoupled.jl +++ b/src/base/types/CoreModelCoupled.jl @@ -1,12 +1,15 @@ """ - mutable struct CoreCoupling{M} <: ModelWrapper where {M<:MetabolicModel} +$(TYPEDEF) A matrix-based wrap that adds reaction coupling matrix to the inner model. A flux `x` feasible in this model must satisfy: ``` cₗ ≤ C x ≤ cᵤ ``` + +# Fields +$(TYPEDFIELDS) """ mutable struct CoreCoupling{M} <: ModelWrapper where {M<:MetabolicModel} lm::M @@ -30,28 +33,28 @@ mutable struct CoreCoupling{M} <: ModelWrapper where {M<:MetabolicModel} end """ - unwrap_model(a::CoreCoupling) +$(TYPEDSIGNATURES) Get the internal [`CoreModel`](@ref) out of [`CoreCoupling`](@ref). """ unwrap_model(a::CoreCoupling) = a.lm """ - coupling(a::CoreCoupling)::SparseMat +$(TYPEDSIGNATURES) Coupling constraint matrix for a `CoreCoupling`. """ coupling(a::CoreCoupling)::SparseMat = vcat(coupling(a.lm), a.C) """ - n_coupling_constraints(a::CoreCoupling)::Int +$(TYPEDSIGNATURES) The number of coupling constraints in a `CoreCoupling`. """ n_coupling_constraints(a::CoreCoupling)::Int = n_coupling_constraints(a.lm) + size(a.C, 1) """ - coupling_bounds(a::CoreCoupling)::Tuple{Vector{Float64},Vector{Float64}} +$(TYPEDSIGNATURES) Coupling bounds for a `CoreCoupling`. """ @@ -59,7 +62,7 @@ coupling_bounds(a::CoreCoupling)::Tuple{Vector{Float64},Vector{Float64}} = vcat.(coupling_bounds(a.lm), (a.cl, a.cu)) """ - Base.convert(::Type{CoreCoupling{M}}, mm::MetabolicModel; clone_coupling = true) where {M} +$(TYPEDSIGNATURES) Make a `CoreCoupling` out of any compatible model type. """ diff --git a/src/base/types/FluxSummary.jl b/src/base/types/FluxSummary.jl index c1b65fc7e..13f136225 100644 --- a/src/base/types/FluxSummary.jl +++ b/src/base/types/FluxSummary.jl @@ -1,8 +1,11 @@ """ - FluxSummary +$(TYPEDEF) A struct used to store summary information about the solution of a constraint based analysis result. + +# Fields +$(TYPEDFIELDS) """ struct FluxSummary biomass_fluxes::OrderedDict{String,Float64} @@ -12,7 +15,7 @@ struct FluxSummary end """ - FluxSummary() +$(TYPEDSIGNATURES) A default empty constructor for `FluxSummary`. """ @@ -26,15 +29,7 @@ function FluxSummary() end """ - flux_summary(flux_result::Dict{String, Float64}; - exclude_exchanges = false, - exchange_prefixes = _constants.exchange_prefixes, - biomass_strings = _constants.biomass_strings, - exclude_biomass = false, - small_flux_bound = 1.0/_constants.default_reaction_bound^2, - large_flux_bound = _constants.default_reaction_bound, - keep_unbounded = false, - )::FluxSummary +$(TYPEDSIGNATURES) Summarize a dictionary of fluxes into small, useful representation of the most important information contained. Useful for pretty-printing and quickly diff --git a/src/base/types/FluxVariabilitySummary.jl b/src/base/types/FluxVariabilitySummary.jl index 97a5edc94..c1b451096 100644 --- a/src/base/types/FluxVariabilitySummary.jl +++ b/src/base/types/FluxVariabilitySummary.jl @@ -1,7 +1,10 @@ """ - FluxVariabilitySummary +$(TYPEDEF) Stores summary information about the result of a flux variability analysis. + +# Fields +$(TYPEDFIELDS) """ struct FluxVariabilitySummary biomass_fluxes::Dict{String,Vector{Maybe{Float64}}} @@ -9,7 +12,7 @@ struct FluxVariabilitySummary end """ - FluxVariabilitySummary() +$(TYPEDSIGNATURES) A default empty constructor for [`FluxVariabilitySummary`](@ref). """ @@ -21,12 +24,7 @@ function FluxVariabilitySummary() end """ - flux_variability_summary(flux_result::Tuple{Dict{String, Dict{String, Float64}}, Dict{String, Dict{String, Float64}}}; - exclude_exchanges = false, - exchange_prefixes = _constants.exchange_prefixes, - biomass_strings = _constants.biomass_strings, - exclude_biomass = false, - )::FluxVariabilitySummary +$(TYPEDSIGNATURES) Summarize a dictionary of flux dictionaries obtained eg. from [`flux_variability_analysis_dict`](@ref). The simplified summary representation diff --git a/src/base/types/Gene.jl b/src/base/types/Gene.jl index b27dec9fa..909c60411 100644 --- a/src/base/types/Gene.jl +++ b/src/base/types/Gene.jl @@ -1,20 +1,20 @@ """ -Gene struct. +$(TYPEDEF) # Fields -```` -id :: String -name :: Maybe{String} -notes :: Dict{String, Vector{String}} -annotation :: Dict{String, Union{Vector{String}, String}} -```` +$(TYPEDFIELDS) """ mutable struct Gene id::String name::Maybe{String} notes::Notes annotations::Annotations - - Gene(id::String = ""; name = nothing, notes = Notes(), annotations = Annotations()) = - new(id, name, notes, annotations) end + +""" +$(TYPEDSIGNATURES) + +A convenient constructor for a `Gene`. +""" +Gene(id = ""; name = nothing, notes = Notes(), annotations = Annotations()) = + Gene(String(id), name, notes, annotations) diff --git a/src/base/types/HDF5Model.jl b/src/base/types/HDF5Model.jl index 38907b0ff..c6b710733 100644 --- a/src/base/types/HDF5Model.jl +++ b/src/base/types/HDF5Model.jl @@ -1,6 +1,6 @@ """ - struct HDF5Model +$(TYPEDEF) A model that is stored in HDF5 format. The model data is never really pulled into memory, but instead mmap'ed as directly as possible into the Julia @@ -15,6 +15,9 @@ create a temporary model that behaves like a model "in memory", save it to a temporary file. For related reasons, you can not use `convert` models to `HDF5Model` format, because the conversion would impliy having the model saved somewhere. + +# Fields +$(TYPEDFIELDS) """ mutable struct HDF5Model <: MetabolicModel h5::Maybe{HDF5.File} diff --git a/src/base/types/Isozyme.jl b/src/base/types/Isozyme.jl index 685f86c35..b7dc6cb9b 100644 --- a/src/base/types/Isozyme.jl +++ b/src/base/types/Isozyme.jl @@ -1,15 +1,10 @@ """ - mutable struct Isozyme +$(TYPEDEF) Information about isozyme composition and activity. # Fields -- `gene_product_count :: Dict{String, Int}` assigns each gene product ID its - count in the isozyme complex (which is used to determine the total mass of - the isozyme) -- `kcat_forward`, `kcat_reverse` -- forward and reverse turnover numbers of the - isozyme -```` +$(TYPEDFIELDS) """ mutable struct Isozyme gene_product_count::Dict{String,Int} diff --git a/src/base/types/JSONModel.jl b/src/base/types/JSONModel.jl index 535afc1cd..03ab30a5d 100644 --- a/src/base/types/JSONModel.jl +++ b/src/base/types/JSONModel.jl @@ -1,13 +1,5 @@ """ - struct JSONModel <: MetabolicModel - json::Dict{String,Any} - rxn_index::Dict{String,Int} - rxns::Vector{Any} - met_index::Dict{String,Int} - mets::Vector{Any} - gene_index::Dict{String,Int} - genes::Vector{Any} - end +$(TYPEDEF) A struct used to store the contents of a JSON model, i.e. a model read from a file ending with `.json`. These model files typically store all the model data @@ -28,6 +20,9 @@ model = load_json_model("some_model.json") model.json # see the actual underlying JSON reactions(model) # see the list of reactions ```` + +# Fields +$(TYPEDFIELDS) """ struct JSONModel <: MetabolicModel json::Dict{String,Any} @@ -77,28 +72,28 @@ end _parse_notes(x)::Notes = _parse_annotations(x) """ - reactions(model::JSONModel) +$(TYPEDSIGNATURES) Extract reaction names (stored as `.id`) from JSON model. """ reactions(model::JSONModel) = [_json_rxn_name(r, i) for (i, r) in enumerate(model.rxns)] """ - metabolites(model::JSONModel) +$(TYPEDSIGNATURES) Extract metabolite names (stored as `.id`) from JSON model. """ metabolites(model::JSONModel) = [_json_met_name(m, i) for (i, m) in enumerate(model.mets)] """ - genes(model::JSONModel) +$(TYPEDSIGNATURES) Extract gene names from a JSON model. """ genes(model::JSONModel) = [_json_gene_name(g, i) for (i, g) in enumerate(model.genes)] """ - stoichiometry(model::JSONModel) +$(TYPEDSIGNATURES) Get the stoichiometry. Assuming the information is stored in reaction object under key `.metabolites`. @@ -140,7 +135,7 @@ function stoichiometry(model::JSONModel) end """ - bounds(model::JSONModel) +$(TYPEDSIGNATURES) Get the bounds for reactions, assuming the information is stored in `.lower_bound` and `.upper_bound`. @@ -151,7 +146,7 @@ bounds(model::JSONModel) = ( ) """ - objective(model::JSONModel) +$(TYPEDSIGNATURES) Collect `.objective_coefficient` keys from model reactions. """ @@ -159,7 +154,7 @@ objective(model::JSONModel) = sparse([float(get(rxn, "objective_coefficient", 0.0)) for rxn in model.rxns]) """ - reaction_gene_associaton(model::JSONModel, rid::String) +$(TYPEDSIGNATURES) Parses the `.gene_reaction_rule` from reactions. """ @@ -169,7 +164,7 @@ reaction_gene_association(model::JSONModel, rid::String) = _maybemap( ) """ - reaction_subsystem(model::JSONModel, rid::String) +$(TYPEDSIGNATURES) Parses the `.subsystem` out from reactions. """ @@ -177,7 +172,7 @@ reaction_subsystem(model::JSONModel, rid::String) = get(model.rxns[model.rxn_index[rid]], "subsystem", nothing) """ - metabolite_formula(model::JSONModel, mid::String) +$(TYPEDSIGNATURES) Parse and return the metabolite `.formula` """ @@ -185,7 +180,7 @@ metabolite_formula(model::JSONModel, mid::String) = _maybemap(_parse_formula, get(model.mets[model.met_index[mid]], "formula", nothing)) """ - metabolite_charge(model::JSONModel, mid::String) +$(TYPEDSIGNATURES) Return the metabolite `.charge` """ @@ -193,7 +188,7 @@ metabolite_charge(model::JSONModel, mid::String) = get(model.mets[model.met_index[mid]], "charge", 0) """ - metabolite_compartment(model::JSONModel, mid::String) +$(TYPEDSIGNATURES) Return the metabolite `.compartment` """ @@ -201,7 +196,7 @@ metabolite_compartment(model::JSONModel, mid::String) = get(model.mets[model.met_index[mid]], "compartment", nothing) """ - gene_annotations(model::JSONModel, gid::String)::Annotations +$(TYPEDSIGNATURES) Gene annotations from the [`JSONModel`](@ref). """ @@ -211,7 +206,7 @@ gene_annotations(model::JSONModel, gid::String)::Annotations = _maybemap( ) """ - gene_notes(model::JSONModel, gid::String)::Notes +$(TYPEDSIGNATURES) Gene notes from the [`JSONModel`](@ref). """ @@ -219,7 +214,7 @@ gene_notes(model::JSONModel, gid::String)::Notes = _maybemap(_parse_notes, get(model.genes[model.gene_index[gid]], "notes", nothing)) """ - reaction_annotations(model::JSONModel, rid::String)::Annotations +$(TYPEDSIGNATURES) Reaction annotations from the [`JSONModel`](@ref). """ @@ -229,7 +224,7 @@ reaction_annotations(model::JSONModel, rid::String)::Annotations = _maybemap( ) """ - reaction_notes(model::JSONModel, rid::String)::Notes +$(TYPEDSIGNATURES) Reaction notes from the [`JSONModel`](@ref). """ @@ -237,7 +232,7 @@ reaction_notes(model::JSONModel, rid::String)::Notes = _maybemap(_parse_notes, get(model.rxns[model.rxn_index[rid]], "notes", nothing)) """ - metabolite_annotations(model::JSONModel, mid::String)::Annotations +$(TYPEDSIGNATURES) Metabolite annotations from the [`JSONModel`](@ref). """ @@ -247,7 +242,7 @@ metabolite_annotations(model::JSONModel, mid::String)::Annotations = _maybemap( ) """ - metabolite_notes(model::JSONModel, mid::String)::Notes +$(TYPEDSIGNATURES) Metabolite notes from the [`JSONModel`](@ref). """ @@ -255,7 +250,7 @@ metabolite_notes(model::JSONModel, mid::String)::Notes = _maybemap(_parse_notes, get(model.mets[model.met_index[mid]], "notes", nothing)) """ - reaction_stoichiometry(model::JSONModel, rid::String)::Dict{String, Float64} +$(TYPEDSIGNATURES) Return the stoichiometry of reaction with ID `rid`. """ @@ -263,7 +258,7 @@ reaction_stoichiometry(model::JSONModel, rid::String)::Dict{String,Float64} = model.rxns[model.rxn_index[rid]]["metabolites"] """ - reaction_name(model::JSONModel, rid::String) +$(TYPEDSIGNATURES) Return the name of reaction with ID `rid`. """ @@ -271,7 +266,7 @@ reaction_name(model::JSONModel, rid::String) = get(model.rxns[model.rxn_index[rid]], "name", nothing) """ - metabolite_name(model::JSONModel, mid::String) +$(TYPEDSIGNATURES) Return the name of metabolite with ID `mid`. """ @@ -279,7 +274,7 @@ metabolite_name(model::JSONModel, mid::String) = get(model.mets[model.met_index[mid]], "name", nothing) """ - gene_name(model::JSONModel, gid::String) +$(TYPEDSIGNATURES) Return the name of gene with ID `gid`. """ @@ -287,7 +282,7 @@ gene_name(model::JSONModel, gid::String) = get(model.genes[model.gene_index[gid]], "name", nothing) """ - Base.convert(::Type{JSONModel}, mm::MetabolicModel) +$(TYPEDSIGNATURES) Convert any [`MetabolicModel`](@ref) to [`JSONModel`](@ref). """ diff --git a/src/base/types/MATModel.jl b/src/base/types/MATModel.jl index aa0fb7ff3..bd8d6f512 100644 --- a/src/base/types/MATModel.jl +++ b/src/base/types/MATModel.jl @@ -1,7 +1,10 @@ """ - struct MATModel +$(TYPEDEF) Wrapper around the models loaded in dictionaries from the MATLAB representation. + +# Fields +$(TYPEDFIELDS) """ struct MATModel <: MetabolicModel mat::Dict{String,Any} @@ -11,7 +14,7 @@ n_metabolites(m::MATModel)::Int = size(m.mat["S"], 1) n_reactions(m::MATModel)::Int = size(m.mat["S"], 2) """ - reactions(m::MATModel)::Vector{String} +$(TYPEDSIGNATURES) Extracts reaction names from `rxns` key in the MAT file. """ @@ -24,7 +27,7 @@ function reactions(m::MATModel)::Vector{String} end """ - _mat_has_squashed_coupling(mat) +$(TYPEDSIGNATURES) Guesses whether C in the MAT file is stored in A=[S;C]. """ @@ -33,7 +36,7 @@ _mat_has_squashed_coupling(mat) = """ - metabolites(m::MATModel)::Vector{String} +$(TYPEDSIGNATURES) Extracts metabolite names from `mets` key in the MAT file. """ @@ -47,14 +50,14 @@ function metabolites(m::MATModel)::Vector{String} end """ - stoichiometry(m::MATModel) +$(TYPEDSIGNATURES) Extract the stoichiometry matrix, stored under key `S`. """ stoichiometry(m::MATModel) = sparse(m.mat["S"]) """ - bounds(m::MATModel) +$(TYPEDSIGNATURES) Extracts bounds from the MAT file, saved under `lb` and `ub`. """ @@ -64,7 +67,7 @@ bounds(m::MATModel) = ( ) """ - balance(m::MATModel) +$(TYPEDSIGNATURES) Extracts balance from the MAT model, defaulting to zeroes if not present. """ @@ -77,7 +80,7 @@ function balance(m::MATModel) end """ - objective(m::MATModel) +$(TYPEDSIGNATURES) Extracts the objective from the MAT model (defaults to zeroes). """ @@ -85,7 +88,7 @@ objective(m::MATModel) = sparse(reshape(get(m.mat, "c", zeros(n_reactions(m), 1)), n_reactions(m))) """ - coupling(m::MATModel) +$(TYPEDSIGNATURES) Extract coupling matrix stored, in `C` key. """ @@ -94,7 +97,7 @@ coupling(m::MATModel) = sparse(get(m.mat, "C", zeros(0, n_reactions(m)))) """ - coupling_bounds(m::MATModel) +$(TYPEDSIGNATURES) Extracts the coupling constraints. Currently, there are several accepted ways to store these in MATLAB models; this takes the constraints from vectors `cl` and `cu`. """ @@ -114,7 +117,7 @@ function coupling_bounds(m::MATModel) end """ - genes(m::MATModel) +$(TYPEDSIGNATURES) Extracts the possible gene list from `genes` key. """ @@ -124,7 +127,7 @@ function genes(m::MATModel) end """ - reaction_gene_association(m::MATModel, rid::String) +$(TYPEDSIGNATURES) Extracts the associations from `grRules` key, if present. """ @@ -138,7 +141,7 @@ function reaction_gene_association(m::MATModel, rid::String) end """ - metabolite_formula(m::MATModel, mid::String) +$(TYPEDSIGNATURES) Extract metabolite formula from key `metFormula` or `metFormulas`. """ @@ -148,7 +151,7 @@ metabolite_formula(m::MATModel, mid::String) = _maybemap( ) """ - metabolite_charge(m::MATModel, mid::String)::Maybe{Int} +$(TYPEDSIGNATURES) Extract metabolite charge from `metCharge` or `metCharges`. """ @@ -161,7 +164,7 @@ function metabolite_charge(m::MATModel, mid::String)::Maybe{Int} end """ - metabolite_compartment(m::MATModel, mid::String) +$(TYPEDSIGNATURES) Extract metabolite compartment from `metCompartment` or `metCompartments`. """ @@ -171,7 +174,7 @@ metabolite_compartment(m::MATModel, mid::String) = _maybemap( ) """ - reaction_stoichiometry(model::MATModel, rid::String)::Dict{String, Float64} +$(TYPEDSIGNATURES) Return the stoichiometry of reaction with ID `rid`. """ @@ -181,7 +184,7 @@ function reaction_stoichiometry(m::MATModel, rid::String)::Dict{String,Float64} end """ - reaction_stoichiometry(model::MATModel, ridx)::Dict{String, Float64} +$(TYPEDSIGNATURES) Return the stoichiometry of reaction at index `ridx`. """ @@ -198,7 +201,7 @@ end # out there. """ - Base.convert(::Type{MATModel}, m::MetabolicModel) +$(TYPEDSIGNATURES) Convert any metabolic model to `MATModel`. """ @@ -248,7 +251,7 @@ function Base.convert(::Type{MATModel}, m::MetabolicModel) end """ - reaction_name(m::MATModel, mid::String) +$(TYPEDSIGNATURES) Extract reaction name from `rxnNames`. """ @@ -258,7 +261,7 @@ reaction_name(m::MATModel, rid::String) = _maybemap( ) """ - metabolite_name(m::MATModel, mid::String) +$(TYPEDSIGNATURES) Extract metabolite name from `metNames`. """ diff --git a/src/base/types/MetabolicModel.jl b/src/base/types/MetabolicModel.jl index ee764cffe..7474b1e61 100644 --- a/src/base/types/MetabolicModel.jl +++ b/src/base/types/MetabolicModel.jl @@ -10,7 +10,7 @@ _missing_impl_error(m, a) = throw(MethodError(m, a)) """ - reactions(a::MetabolicModel)::Vector{String} +$(TYPEDSIGNATURES) Return a vector of reaction identifiers in a model. The vector precisely corresponds to the columns in [`stoichiometry`](@ref) matrix. @@ -26,7 +26,7 @@ function reactions(a::MetabolicModel)::Vector{String} end """ - metabolites(a::MetabolicModel)::Vector{String} +$(TYPEDSIGNATURES) Return a vector of metabolite identifiers in a model. The vector precisely corresponds to the rows in [`stoichiometry`](@ref) matrix. @@ -39,7 +39,7 @@ function metabolites(a::MetabolicModel)::Vector{String} end """ - n_reactions(a::MetabolicModel)::Int +$(TYPEDSIGNATURES) Get the number of reactions in a model. """ @@ -48,7 +48,7 @@ function n_reactions(a::MetabolicModel)::Int end """ - n_metabolites(a::MetabolicModel)::Int +$(TYPEDSIGNATURES) Get the number of metabolites in a model. """ @@ -57,7 +57,7 @@ function n_metabolites(a::MetabolicModel)::Int end """ - stoichiometry(a::MetabolicModel)::SparseMat +$(TYPEDSIGNATURES) Get the sparse stoichiometry matrix of a model. A feasible solution `x` of a model `m` is defined as satisfying the equations: @@ -72,7 +72,7 @@ function stoichiometry(a::MetabolicModel)::SparseMat end """ - bounds(a::MetabolicModel)::Tuple{Vector{Float64},Vector{Float64}} +$(TYPEDSIGNATURES) Get the lower and upper solution bounds of a model. """ @@ -81,7 +81,7 @@ function bounds(a::MetabolicModel)::Tuple{Vector{Float64},Vector{Float64}} end """ - balance(a::MetabolicModel)::SparseVec +$(TYPEDSIGNATURES) Get the sparse balance vector of a model. """ @@ -90,7 +90,7 @@ function balance(a::MetabolicModel)::SparseVec end """ - objective(a::MetabolicModel)::SparseVec +$(TYPEDSIGNATURES) Get the objective vector of the model. Analysis functions, such as [`flux_balance_analysis`](@ref), are supposed to maximize `dot(objective, x)` @@ -101,7 +101,7 @@ function objective(a::MetabolicModel)::SparseVec end """ - fluxes(a::MetabolicModel)::Vector{String} +$(TYPEDSIGNATURES) In some models, the [`reactions`](@ref) that correspond to the columns of [`stoichiometry`](@ref) matrix do not fully represent the semantic contents of @@ -121,7 +121,7 @@ function n_fluxes(a::MetabolicModel)::Int end """ - reaction_flux(a::MetabolicModel)::SparseMat +$(TYPEDSIGNATURES) Retrieve a sparse matrix that describes the correspondence of a solution of the linear system to the fluxes (see [`fluxes`](@ref) for rationale). Returns a @@ -136,7 +136,7 @@ function reaction_flux(a::MetabolicModel)::SparseMat end """ - coupling(a::MetabolicModel)::SparseMat +$(TYPEDSIGNATURES) Get a matrix of coupling constraint definitions of a model. By default, there is no coupling in the models. @@ -146,7 +146,7 @@ function coupling(a::MetabolicModel)::SparseMat end """ - n_coupling_constraints(a::MetabolicModel)::Int +$(TYPEDSIGNATURES) Get the number of coupling constraints in a model. """ @@ -155,7 +155,7 @@ function n_coupling_constraints(a::MetabolicModel)::Int end """ - coupling_bounds(a::MetabolicModel)::Tuple{Vector{Float64},Vector{Float64}} +$(TYPEDSIGNATURES) Get the lower and upper bounds for each coupling bound in a model, as specified by `coupling`. By default, the model does not have any coupling bounds. @@ -165,7 +165,7 @@ function coupling_bounds(a::MetabolicModel)::Tuple{Vector{Float64},Vector{Float6 end """ - genes(a::MetabolicModel)::Vector{String} +$(TYPEDSIGNATURES) Return identifiers of all genes contained in the model. By default, there are no genes. @@ -178,7 +178,7 @@ function genes(a::MetabolicModel)::Vector{String} end """ - n_genes(a::MetabolicModel)::Int +$(TYPEDSIGNATURES) Return the number of genes in the model (as returned by [`genes`](@ref)). If you just need the number of the genes, this may be much more efficient than @@ -189,7 +189,7 @@ function n_genes(a::MetabolicModel)::Int end """ - reaction_gene_association(a::MetabolicModel, gene_id::String)::Maybe{GeneAssociation} +$(TYPEDSIGNATURES) Returns the sets of genes that need to be present so that the reaction can work (technically, a DNF on gene availability, with positive atoms only). @@ -205,7 +205,7 @@ function reaction_gene_association( end """ - reaction_subsystem(model::MetabolicModel, reaction_id::String)::Maybe{String} +$(TYPEDSIGNATURES) Return the subsystem of reaction `reaction_id` in `model` if it is assigned. If not, return `nothing`. @@ -215,7 +215,7 @@ function reaction_subsystem(model::MetabolicModel, reaction_id::String)::Maybe{S end """ - reaction_stoichiometry(model::MetaboliteModel, rid::String)::Dict{String, Float64} +$(TYPEDSIGNATURES) Return the stoichiometry of reaction with ID `rid` in the model. The dictionary maps the metabolite IDs to their stoichiometric coefficients. @@ -229,10 +229,7 @@ function reaction_stoichiometry(m::MetabolicModel, rid::String)::Dict{String,Flo end """ - metabolite_formula( - a::MetabolicModel, - metabolite_id::String, - )::Maybe{MetaboliteFormula} +$(TYPEDSIGNATURES) Return the formula of metabolite `metabolite_id` in `model`. Return `nothing` in case the formula is not known or irrelevant. @@ -245,7 +242,7 @@ function metabolite_formula( end """ - metabolite_charge(model::MetabolicModel, metabolite_id::String)::Maybe{Int} +$(TYPEDSIGNATURES) Return the charge associated with metabolite `metabolite_id` in `model`. Returns `nothing` if charge not present. @@ -255,7 +252,7 @@ function metabolite_charge(model::MetabolicModel, metabolite_id::String)::Maybe{ end """ - metabolite_compartment(model::MetabolicModel, metabolite_id::String)::Maybe{String} +$(TYPEDSIGNATURES) Return the compartment of metabolite `metabolite_id` in `model` if it is assigned. If not, return `nothing`. @@ -265,7 +262,7 @@ function metabolite_compartment(model::MetabolicModel, metabolite_id::String)::M end """ - reaction_annotations(a::MetabolicModel, reaction_id::String)::Annotations +$(TYPEDSIGNATURES) Return standardized names that may help identifying the reaction. The dictionary assigns vectors of possible identifiers to identifier system names, @@ -276,7 +273,7 @@ function reaction_annotations(a::MetabolicModel, reaction_id::String)::Annotatio end """ - metabolite_annotations(a::MetabolicModel, metabolite_id::String)::Annotations +$(TYPEDSIGNATURES) Return standardized names that may help to reliably identify the metabolite. The dictionary assigns vectors of possible identifiers to identifier system names, @@ -287,7 +284,7 @@ function metabolite_annotations(a::MetabolicModel, metabolite_id::String)::Annot end """ - gene_annotations(a::MetabolicModel, gene_id::String)::Annotations +$(TYPEDSIGNATURES) Return standardized names that identify the corresponding gene or product. The dictionary assigns vectors of possible identifiers to identifier system names, @@ -298,7 +295,7 @@ function gene_annotations(a::MetabolicModel, gene_id::String)::Annotations end """ - reaction_notes(model::MetabolicModel, reaction_id::String)::Notes +$(TYPEDSIGNATURES) Return the notes associated with reaction `reaction_id` in `model`. """ @@ -307,7 +304,7 @@ function reaction_notes(model::MetabolicModel, reaction_id::String)::Notes end """ - metabolite_notes(model::MetabolicModel, metabolite_id::String)::Notes +$(TYPEDSIGNATURES) Return the notes associated with metabolite `reaction_id` in `model`. """ @@ -316,7 +313,7 @@ function metabolite_notes(model::MetabolicModel, metabolite_id::String)::Notes end """ - gene_notes(model::MetabolicModel, gene_id::String)::Notes +$(TYPEDSIGNATURES) Return the notes associated with the gene `gene_id` in `model`. """ @@ -325,28 +322,28 @@ function gene_notes(model::MetabolicModel, gene_id::String)::Notes end """ - reaction_name(model::MetabolicModel, rid::String) +$(TYPEDSIGNATURES) Return the name of reaction with ID `rid`. """ reaction_name(model::MetabolicModel, rid::String) = nothing """ - metabolite_name(model::MetabolicModel, mid::String) +$(TYPEDSIGNATURES) Return the name of metabolite with ID `mid`. """ metabolite_name(model::MetabolicModel, mid::String) = nothing """ - gene_name(model::MetabolicModel, gid::String) +$(TYPEDSIGNATURES) Return the name of gene with ID `gid`. """ gene_name(model::MetabolicModel, gid::String) = nothing """ - precache!(a::MetabolicModel)::Nothing +$(TYPEDSIGNATURES) Do whatever is feasible to get the model into a state that can be read from as-quickly-as-possible. This may include e.g. generating helper index diff --git a/src/base/types/Metabolite.jl b/src/base/types/Metabolite.jl index d6b195d7b..79bb0330a 100644 --- a/src/base/types/Metabolite.jl +++ b/src/base/types/Metabolite.jl @@ -1,16 +1,8 @@ """ -Metabolite structure. +$(TYPEDEF) # Fields -```` -id :: String -name :: Maybe{String} -formula :: String -charge :: Int -compartment :: String -notes :: Dict{String, Vector{String}} -annotation :: Dict{String, Union{Vector{String}, String}} -```` +$(TYPEDFIELDS) """ mutable struct Metabolite id::String @@ -20,14 +12,19 @@ mutable struct Metabolite compartment::Maybe{String} notes::Notes annotations::Annotations - - Metabolite( - id = ""; - name = nothing, - formula = nothing, - charge = nothing, - compartment = nothing, - notes = Notes(), - annotations = Annotations(), - ) = new(id, name, formula, charge, compartment, notes, annotations) end + +""" +$(TYPEDSIGNATURES) + +A constructor for `Metabolite`s. +""" +Metabolite( + id = ""; + name = nothing, + formula = nothing, + charge = nothing, + compartment = nothing, + notes = Notes(), + annotations = Annotations(), +) = Metabolite(String(id), name, formula, charge, compartment, notes, annotations) diff --git a/src/base/types/ModelWrapper.jl b/src/base/types/ModelWrapper.jl index ccf289d3e..e1988f1ae 100644 --- a/src/base/types/ModelWrapper.jl +++ b/src/base/types/ModelWrapper.jl @@ -1,6 +1,6 @@ """ - unwrap_model(a::ModelWrapper) +$(TYPEDSIGNATURES) A simple helper to pick the single w """ diff --git a/src/base/types/Reaction.jl b/src/base/types/Reaction.jl index e23bc4086..b87e1c45c 100644 --- a/src/base/types/Reaction.jl +++ b/src/base/types/Reaction.jl @@ -1,18 +1,10 @@ """ - mutable struct Reaction - id::String - name::Maybe{String} - metabolites::Dict{String,Float64} - lb::Float64 - ub::Float64 - grr::Maybe{GeneAssociation} - subsystem::Maybe{String} - notes::Notes - annotations::Annotations - objective_coefficient::Float64 - end +$(TYPEDEF) A structure for representing a single reaction in a [`StandardModel`](@ref). + +# Fields +$(TYPEDFIELDS) """ mutable struct Reaction id::String @@ -28,18 +20,7 @@ mutable struct Reaction end """ - Reaction( - id = ""; - name = nothing, - metabolites = Dict{String,Float64}(), - lb = -_constants.default_reaction_bound, - ub = _constants.default_reaction_bound, - grr = nothing, - subsystem = nothing, - notes = Notes(), - annotations = Annotations(), - objective_coefficient = 0.0, - ) +$(TYPEDSIGNATURES) A constructor for Reaction that only takes a reaction `id` and assigns default/uninformative values to all the fields that are not @@ -73,12 +54,7 @@ function Reaction( end """ - Reaction( - id::String, - metabolites::Dict{String,Union{Int, Float64}}, - dir = :bidirectional; - default_bound = _constants.default_reaction_bound, - ) +$(TYPEDSIGNATURES) Convenience constructor for `Reaction`. The reaction equation is specified using `metabolites`, which is a dictionary mapping metabolite ids to stoichiometric diff --git a/src/base/types/ReactionStatus.jl b/src/base/types/ReactionStatus.jl index 0ca1da7b0..90940711b 100644 --- a/src/base/types/ReactionStatus.jl +++ b/src/base/types/ReactionStatus.jl @@ -1,5 +1,10 @@ """ +$(TYPEDEF) + Used for concise reporting of modeling results. + +# Fields +$(TYPEDFIELDS) """ mutable struct ReactionStatus already_present::Bool diff --git a/src/base/types/SBMLModel.jl b/src/base/types/SBMLModel.jl index d15536f67..fe14efda8 100644 --- a/src/base/types/SBMLModel.jl +++ b/src/base/types/SBMLModel.jl @@ -1,43 +1,46 @@ """ - struct SBMLModel +$(TYPEDEF) Thin wrapper around the model from SBML.jl library. Allows easy conversion from SBML to any other model format. + +# Fields +$(TYPEDFIELDS) """ struct SBMLModel <: MetabolicModel sbml::SBML.Model end """ - reactions(model::SBMLModel)::Vector{String} +$(TYPEDSIGNATURES) Get reactions from a [`SBMLModel`](@ref). """ reactions(model::SBMLModel)::Vector{String} = [k for k in keys(model.sbml.reactions)] """ - metabolites(model::SBMLModel)::Vector{String} +$(TYPEDSIGNATURES) Get metabolites from a [`SBMLModel`](@ref). """ metabolites(model::SBMLModel)::Vector{String} = [k for k in keys(model.sbml.species)] """ - n_reactions(model::SBMLModel)::Int +$(TYPEDSIGNATURES) Efficient counting of reactions in [`SBMLModel`](@ref). """ n_reactions(model::SBMLModel)::Int = length(model.sbml.reactions) """ - n_metabolites(model::SBMLModel)::Int +$(TYPEDSIGNATURES) Efficient counting of metabolites in [`SBMLModel`](@ref). """ n_metabolites(model::SBMLModel)::Int = length(model.sbml.species) """ - stoichiometry(model::SBMLModel)::SparseMat +$(TYPEDSIGNATURES) Recreate the stoichiometry matrix from the [`SBMLModel`](@ref). """ @@ -47,7 +50,7 @@ function stoichiometry(model::SBMLModel)::SparseMat end """ - bounds(model::SBMLModel)::Tuple{Vector{Float64},Vector{Float64}} +$(TYPEDSIGNATURES) Get the lower and upper flux bounds of model [`SBMLModel`](@ref). Throws `DomainError` in case if the SBML contains mismatching units. @@ -71,35 +74,35 @@ function bounds(model::SBMLModel)::Tuple{Vector{Float64},Vector{Float64}} end """ - balance(model::SBMLModel)::SparseVec +$(TYPEDSIGNATURES) Balance vector of a [`SBMLModel`](@ref). This is always zero. """ balance(model::SBMLModel)::SparseVec = spzeros(n_metabolites(model)) """ - objective(model::SBMLModel)::SparseVec +$(TYPEDSIGNATURES) Objective of the [`SBMLModel`](@ref). """ objective(model::SBMLModel)::SparseVec = SBML.flux_objective(model.sbml) """ - genes(model::SBMLModel)::Vector{String} +$(TYPEDSIGNATURES) Get genes of a [`SBMLModel`](@ref). """ genes(model::SBMLModel)::Vector{String} = [k for k in keys(model.sbml.gene_products)] """ - n_genes(model::SBMLModel)::Int +$(TYPEDSIGNATURES) Get number of genes in [`SBMLModel`](@ref). """ n_genes(model::SBMLModel)::Int = length(model.sbml.gene_products) """ - reaction_gene_association(model::SBMLModel, rid::String)::Maybe{GeneAssociation} +$(TYPEDSIGNATURES) Retrieve the [`GeneAssociation`](@ref) from [`SBMLModel`](@ref). """ @@ -107,7 +110,7 @@ reaction_gene_association(model::SBMLModel, rid::String)::Maybe{GeneAssociation} _maybemap(_parse_grr, model.sbml.reactions[rid].gene_product_association) """ - metabolite_formula(model::SBMLModel, mid::String)::Maybe{MetaboliteFormula} +$(TYPEDSIGNATURES) Get [`MetaboliteFormula`](@ref) from a chosen metabolite from [`SBMLModel`](@ref). """ @@ -115,36 +118,71 @@ metabolite_formula(model::SBMLModel, mid::String)::Maybe{MetaboliteFormula} = _maybemap(_parse_formula, model.sbml.species[mid].formula) """ - metabolite_compartment(model::SBMLModel, mid::String)::Maybe{String} +$(TYPEDSIGNATURES) Get the compartment of a chosen metabolite from [`SBMLModel`](@ref). """ metabolite_compartment(model::SBMLModel, mid::String) = model.sbml.species[mid].compartment """ - metabolite_charge(model::SBMLModel, mid::String)::Maybe{Int} +$(TYPEDSIGNATURES) Get charge of a chosen metabolite from [`SBMLModel`](@ref). """ metabolite_charge(model::SBMLModel, mid::String)::Maybe{Int} = model.sbml.species[mid].charge -function _sbml_export_annotation(annotation)::Maybe{String} - if isnothing(annotation) || isempty(annotation) - nothing - elseif length(annotation) != 1 || first(annotation).first != "" - @_io_log @warn "Possible data loss: multiple annotations converted to text for SBML" annotation - join(["$k: $v" for (k, v) in annotation], "\n") - else - @_io_log @warn "Possible data loss: trying to represent annotation in SBML is unlikely to work " annotation - first(annotation).second +function _parse_sbml_identifiers_org_uri(uri::String)::Tuple{String,String} + m = match(r"^http://identifiers.org/([^/]+)/(.*)$", uri) + isnothing(m) ? ("RESOURCE_URI", uri) : (m[1], m[2]) +end + +function _sbml_import_cvterms(sbo::Maybe{String}, cvs::Vector{SBML.CVTerm})::Annotations + res = Annotations() + isnothing(sbo) || (res["sbo"] = [sbo]) + for cv in cvs + cv.biological_qualifier == :is || continue + for (id, val) in _parse_sbml_identifiers_org_uri.(cv.resource_uris) + push!(get!(res, id, []), val) + end + end + return res +end + +function _sbml_export_cvterms(annotations::Annotations)::Vector{SBML.CVTerm} + isempty(annotations) && return [] + length(annotations) == 1 && haskey(annotations, "sbo") && return [] + [ + SBML.CVTerm( + biological_qualifier = :is, + resource_uris = [ + id == "RESOURCE_URI" ? val : "http://identifiers.org/$id/$val" for + (id, vals) = annotations if id != "sbo" for val in vals + ], + ), + ] +end + +function _sbml_export_sbo(annotations::Annotations)::Maybe{String} + haskey(annotations, "sbo") || return nothing + if length(annotations["sbo"]) != 1 + @_io_log @error "Data loss: SBO term is not unique for SBML export" annotations["sbo"] + return end + return annotations["sbo"][1] end -const _sbml_export_notes = _sbml_export_annotation +function _sbml_import_notes(notes::Maybe{String})::Notes + isnothing(notes) ? Notes() : Notes("" => [notes]) +end + +function _sbml_export_notes(notes::Notes)::Maybe{String} + isempty(notes) || @_io_log @error "Data loss: notes not exported to SBML" notes + nothing +end """ - reaction_stoichiometry(model::SBMLModel, rid::String)::Dict{String, Float64} +$(TYPEDSIGNATURES) Return the stoichiometry of reaction with ID `rid`. """ @@ -161,28 +199,78 @@ function reaction_stoichiometry(m::SBMLModel, rid::String)::Dict{String,Float64} end """ - reaction_name(model::SBMLModel, rid::String) +$(TYPEDSIGNATURES) Return the name of reaction with ID `rid`. """ reaction_name(model::SBMLModel, rid::String) = model.sbml.reactions[rid].name """ - metabolite_name(model::SBMLModel, mid::String) +$(TYPEDSIGNATURES) Return the name of metabolite with ID `mid`. """ metabolite_name(model::SBMLModel, mid::String) = model.sbml.species[mid].name """ - gene_name(model::SBMLModel, gid::String) +$(TYPEDSIGNATURES) Return the name of gene with ID `gid`. """ gene_name(model::SBMLModel, gid::String) = model.sbml.gene_products[gid].name """ - Base.convert(::Type{SBMLModel}, mm::MetabolicModel) +$(TYPEDSIGNATURES) + +Return the annotations of reaction with ID `rid`. +""" +reaction_annotations(model::SBMLModel, rid::String) = + _sbml_import_cvterms(model.sbml.reactions[rid].sbo, model.sbml.reactions[rid].cv_terms) + +""" +$(TYPEDSIGNATURES) + +Return the annotations of metabolite with ID `mid`. +""" +metabolite_annotations(model::SBMLModel, mid::String) = + _sbml_import_cvterms(model.sbml.species[mid].sbo, model.sbml.species[mid].cv_terms) + +""" +$(TYPEDSIGNATURES) + +Return the annotations of gene with ID `gid`. +""" +gene_annotations(model::SBMLModel, gid::String) = _sbml_import_cvterms( + model.sbml.gene_products[gid].sbo, + model.sbml.gene_products[gid].cv_terms, +) + +""" +$(TYPEDSIGNATURES) + +Return the notes about reaction with ID `rid`. +""" +reaction_notes(model::SBMLModel, rid::String) = + _sbml_import_notes(model.sbml.reactions[rid].notes) + +""" +$(TYPEDSIGNATURES) + +Return the notes about metabolite with ID `mid`. +""" +metabolite_notes(model::SBMLModel, mid::String) = + _sbml_import_notes(model.sbml.species[mid].notes) + +""" +$(TYPEDSIGNATURES) + +Return the notes about gene with ID `gid`. +""" +gene_notes(model::SBMLModel, gid::String) = + _sbml_import_notes(model.sbml.gene_products[gid].notes) + +""" +$(TYPEDSIGNATURES) Convert any metabolic model to [`SBMLModel`](@ref). """ @@ -198,30 +286,36 @@ function Base.convert(::Type{SBMLModel}, mm::MetabolicModel) comps = _default.("compartment", metabolite_compartment.(Ref(mm), mets)) compss = Set(comps) + metid(x) = startswith(x, "M_") ? x : "M_$x" + rxnid(x) = startswith(x, "R_") ? x : "R_$x" + gprid(x) = startswith(x, "G_") ? x : "G_$x" + return SBMLModel( SBML.Model( compartments = Dict( comp => SBML.Compartment(constant = true) for comp in compss ), species = Dict( - mid => SBML.Species( + metid(mid) => SBML.Species( name = metabolite_name(mm, mid), compartment = _default("compartment", comps[mi]), - formula = metabolite_formula(mm, mid), + formula = _maybemap(_unparse_formula, metabolite_formula(mm, mid)), charge = metabolite_charge(mm, mid), constant = false, boundary_condition = false, only_substance_units = false, + sbo = _sbml_export_sbo(metabolite_annotations(mm, mid)), notes = _sbml_export_notes(metabolite_notes(mm, mid)), - annotation = _sbml_export_annotation(metabolite_annotations(mm, mid)), + metaid = metid(mid), + cv_terms = _sbml_export_cvterms(metabolite_annotations(mm, mid)), ) for (mi, mid) in enumerate(mets) ), reactions = Dict( - rid => SBML.Reaction( + rxnid(rid) => SBML.Reaction( name = reaction_name(mm, rid), reactants = [ SBML.SpeciesReference( - species = mets[i], + species = metid(mets[i]), stoichiometry = -stoi[i, ri], constant = true, ) for @@ -229,7 +323,7 @@ function Base.convert(::Type{SBMLModel}, mm::MetabolicModel) ], products = [ SBML.SpeciesReference( - species = mets[i], + species = metid(mets[i]), stoichiometry = stoi[i, ri], constant = true, ) for @@ -246,16 +340,20 @@ function Base.convert(::Type{SBMLModel}, mm::MetabolicModel) reaction_gene_association(mm, rid), ), reversible = true, + sbo = _sbml_export_sbo(reaction_annotations(mm, rid)), notes = _sbml_export_notes(reaction_notes(mm, rid)), - annotation = _sbml_export_annotation(reaction_annotations(mm, rid)), + metaid = rxnid(rid), + cv_terms = _sbml_export_cvterms(reaction_annotations(mm, rid)), ) for (ri, rid) in enumerate(rxns) ), gene_products = Dict( - gid => SBML.GeneProduct( + gprid(gid) => SBML.GeneProduct( label = gid, name = gene_name(mm, gid), + sbo = _sbml_export_sbo(gene_annotations(mm, gid)), notes = _sbml_export_notes(gene_notes(mm, gid)), - annotation = _sbml_export_annotation(gene_annotations(mm, gid)), + metaid = gprid(gid), + cv_terms = _sbml_export_cvterms(gene_annotations(mm, gid)), ) for gid in genes(mm) ), active_objective = "objective", diff --git a/src/base/types/Serialized.jl b/src/base/types/Serialized.jl index 1d1741816..aef1c887c 100644 --- a/src/base/types/Serialized.jl +++ b/src/base/types/Serialized.jl @@ -1,13 +1,13 @@ """ - mutable struct Serialized{M <: MetabolicModel} - m::Maybe{M} - filename::String - end +$(TYPEDEF) A meta-model that represents a model that is serialized on the disk. The internal model will be loaded on-demand by using any accessor, or by calling [`precache!`](@ref) directly. + +# Fields +$(TYPEDFIELDS) """ mutable struct Serialized{M} <: ModelWrapper where {M<:MetabolicModel} m::Maybe{M} @@ -19,7 +19,7 @@ mutable struct Serialized{M} <: ModelWrapper where {M<:MetabolicModel} end """ - unwrap_model(m::Serialized) +$(TYPEDSIGNATURES) Unwrap the serialized model (precaching it transparently). """ @@ -29,7 +29,7 @@ function unwrap_model(m::Serialized) end """ - precache!(model::Serialized{MetabolicModel})::Nothing +$(TYPEDSIGNATURES) Load the `Serialized` model from disk in case it's not alreadly loaded. """ diff --git a/src/base/types/StandardModel.jl b/src/base/types/StandardModel.jl index e842525e9..211a1e088 100644 --- a/src/base/types/StandardModel.jl +++ b/src/base/types/StandardModel.jl @@ -1,5 +1,5 @@ """ - mutable struct StandardModel +$(TYPEDEF) `StandardModel` is used to store a constraint based metabolic model with meta-information. Meta-information is defined as annotation details, which @@ -26,19 +26,14 @@ types if performance is critical. See also: [`Reaction`](@ref), [`Metabolite`](@ref), [`Gene`](@ref) -# Fields -``` -id :: String -reactions :: OrderedDict{String, Reaction} -metabolites :: OrderedDict{String, Metabolite} -genes :: OrderedDict{String, Gene} -``` - # Example ``` model = load_model(StandardModel, "my_model.json") keys(model.reactions) ``` + +# Fields +$(TYPEDFIELDS) """ mutable struct StandardModel <: MetabolicModel id::String @@ -56,7 +51,7 @@ end # MetabolicModel interface follows """ - reactions(model::StandardModel) +$(TYPEDSIGNATURES) Return a vector of reaction id strings contained in `model`. The order of reaction ids returned here matches the order used to construct the @@ -65,7 +60,7 @@ stoichiometric matrix. reactions(model::StandardModel)::StringVecType = collect(keys(model.reactions)) """ - n_reactions(model::StandardModel) +$(TYPEDSIGNATURES) Return the number of reactions contained in `model`. """ @@ -73,7 +68,7 @@ n_reactions(model::StandardModel)::Int = length(model.reactions) """ - metabolites(model::StandardModel) +$(TYPEDSIGNATURES) Return a vector of metabolite id strings contained in `model`. The order of metabolite strings returned here matches the order used to construct @@ -82,28 +77,28 @@ the stoichiometric matrix. metabolites(model::StandardModel)::StringVecType = collect(keys(model.metabolites)) """ -n_metabolites(model::StandardModel) +$(TYPEDSIGNATURES) Return the number of metabolites in `model`. """ n_metabolites(model::StandardModel)::Int = length(model.metabolites) """ - genes(model::StandardModel) +$(TYPEDSIGNATURES) Return a vector of gene id strings in `model`. """ genes(model::StandardModel)::StringVecType = collect(keys(model.genes)) """ - n_genes(model::StandardModel) +$(TYPEDSIGNATURES) Return the number of genes in `model`. """ n_genes(model::StandardModel)::Int = length(model.genes) """ - stoichiometry(model::StandardModel) +$(TYPEDSIGNATURES) Return the stoichiometric matrix associated with `model` in sparse format. """ @@ -144,7 +139,7 @@ function stoichiometry(model::StandardModel)::SparseMat end """ - lower_bounds(model::StandardModel)::Vector{Float64} +$(TYPEDSIGNATURES) Return the lower bounds for all reactions in `model` in sparse format. """ @@ -152,7 +147,7 @@ lower_bounds(model::StandardModel)::Vector{Float64} = sparse([model.reactions[rxn].lb for rxn in reactions(model)]) """ - upper_bounds(model::StandardModel)::Vector{Float64} +$(TYPEDSIGNATURES) Return the upper bounds for all reactions in `model` in sparse format. Order matches that of the reaction ids returned in `reactions()`. @@ -161,7 +156,7 @@ upper_bounds(model::StandardModel)::Vector{Float64} = sparse([model.reactions[rxn].ub for rxn in reactions(model)]) """ - bounds(model::StandardModel)::Tuple{Vector{Float64},Vector{Float64}} +$(TYPEDSIGNATURES) Return the lower and upper bounds, respectively, for reactions in `model`. Order matches that of the reaction ids returned in `reactions()`. @@ -170,7 +165,7 @@ bounds(model::StandardModel)::Tuple{Vector{Float64},Vector{Float64}} = (lower_bounds(model), upper_bounds(model)) """ - balance(model::StandardModel) +$(TYPEDSIGNATURES) Return the balance of the linear problem, i.e. b in Sv = 0 where S is the stoichiometric matrix and v is the flux vector. @@ -178,7 +173,7 @@ and v is the flux vector. balance(model::StandardModel)::SparseVec = spzeros(length(model.metabolites)) """ - objective(model::StandardModel) +$(TYPEDSIGNATURES) Return sparse objective vector for `model`. """ @@ -186,7 +181,7 @@ objective(model::StandardModel)::SparseVec = sparse([model.reactions[rid].objective_coefficient for rid in keys(model.reactions)]) """ - reaction_gene_association(model::StandardModel, id::String) +$(TYPEDSIGNATURES) Return the gene reaction rule in string format for reaction with `id` in `model`. Return `nothing` if not available. @@ -195,7 +190,7 @@ reaction_gene_association(model::StandardModel, id::String)::Maybe{GeneAssociati _maybemap(identity, model.reactions[id].grr) """ - metabolite_formula(model::StandardModel, id::String) +$(TYPEDSIGNATURES) Return the formula of reaction `id` in `model`. Return `nothing` if not present. @@ -204,7 +199,7 @@ metabolite_formula(model::StandardModel, id::String)::Maybe{MetaboliteFormula} = _maybemap(_parse_formula, model.metabolites[id].formula) """ - metabolite_charge(model::StandardModel, id::String) +$(TYPEDSIGNATURES) Return the charge associated with metabolite `id` in `model`. Return nothing if not present. @@ -213,7 +208,7 @@ metabolite_charge(model::StandardModel, id::String)::Maybe{Int} = model.metabolites[id].charge """ - metabolite_compartment(model::StandardModel, id::String) +$(TYPEDSIGNATURES) Return compartment associated with metabolite `id` in `model`. Return `nothing` if not present. @@ -222,7 +217,7 @@ metabolite_compartment(model::StandardModel, id::String)::Maybe{String} = model.metabolites[id].compartment """ - reaction_subsystem(id::String, model::StandardModel) +$(TYPEDSIGNATURES) Return the subsystem associated with reaction `id` in `model`. Return `nothing` if not present. @@ -231,7 +226,7 @@ reaction_subsystem(model::StandardModel, id::String)::Maybe{String} = model.reactions[id].subsystem """ - metabolite_notes(model::StandardModel, id::String)::Notes +$(TYPEDSIGNATURES) Return the notes associated with metabolite `id` in `model`. Return an empty Dict if not present. @@ -240,7 +235,7 @@ metabolite_notes(model::StandardModel, id::String)::Maybe{Notes} = model.metabolites[id].notes """ - metabolite_annotations(model::StandardModel, id::String)::Annotations +$(TYPEDSIGNATURES) Return the annotation associated with metabolite `id` in `model`. Return an empty Dict if not present. @@ -249,7 +244,7 @@ metabolite_annotations(model::StandardModel, id::String)::Maybe{Annotations} = model.metabolites[id].annotations """ - gene_notes(model::StandardModel, id::String)::Notes +$(TYPEDSIGNATURES) Return the notes associated with gene `id` in `model`. Return an empty Dict if not present. @@ -257,7 +252,7 @@ Return an empty Dict if not present. gene_notes(model::StandardModel, id::String)::Maybe{Notes} = model.genes[id].notes """ - gene_annotations(model::StandardModel, id::String)::Annotations +$(TYPEDSIGNATURES) Return the annotation associated with gene `id` in `model`. Return an empty Dict if not present. @@ -266,7 +261,7 @@ gene_annotations(model::StandardModel, id::String)::Maybe{Annotations} = model.genes[id].annotations """ - reaction_notes(model::StandardModel, id::String)::Notes +$(TYPEDSIGNATURES) Return the notes associated with reaction `id` in `model`. Return an empty Dict if not present. @@ -274,7 +269,7 @@ Return an empty Dict if not present. reaction_notes(model::StandardModel, id::String)::Maybe{Notes} = model.reactions[id].notes """ - reaction_annotations(model::StandardModel, id::String)::Annotations +$(TYPEDSIGNATURES) Return the annotation associated with reaction `id` in `model`. Return an empty Dict if not present. @@ -283,7 +278,7 @@ reaction_annotations(model::StandardModel, id::String)::Maybe{Annotations} = model.reactions[id].annotations """ - reaction_stoichiometry(model::StandardModel, rid::String)::Dict{String, Float64} +$(TYPEDSIGNATURES) Return the stoichiometry of reaction with ID `rid`. """ @@ -291,28 +286,28 @@ reaction_stoichiometry(m::StandardModel, rid::String)::Dict{String,Float64} = m.reactions[rid].metabolites """ - reaction_name(m::StandardModel, rid::String) +$(TYPEDSIGNATURES) Return the name of reaction with ID `id`. """ reaction_name(m::StandardModel, rid::String) = m.reactions[rid].name """ - metabolite_name(m::StandardModel, mid::String) +$(TYPEDSIGNATURES) Return the name of metabolite with ID `id`. """ metabolite_name(m::StandardModel, mid::String) = m.metabolites[mid].name """ - gene_name(m::StandardModel, gid::String) +$(TYPEDSIGNATURES) Return the name of gene with ID `id`. """ gene_name(m::StandardModel, gid::String) = m.genes[gid].name """ -Base.convert(::Type{StandardModel}, model::MetabolicModel) +$(TYPEDSIGNATURES) Convert any `MetabolicModel` into a `StandardModel`. Note, some data loss may occur since only the generic interface is used during diff --git a/src/base/types/abstract/Maybe.jl b/src/base/types/abstract/Maybe.jl index ca5f092b6..7b5df0a39 100644 --- a/src/base/types/abstract/Maybe.jl +++ b/src/base/types/abstract/Maybe.jl @@ -7,7 +7,7 @@ A nice name for "nullable" type. const Maybe{T} = Union{Nothing,T} """ - _default(d::T, x::Maybe{T})::T where {T} +$(TYPEDSIGNATURES) Fold the `Maybe{T}` down to `T` by defaulting. """ @@ -16,7 +16,7 @@ function _default(d::T, x::Maybe{T})::T where {T} end """ - _maybemap(f, x::Maybe)::Maybe +$(TYPEDSIGNATURES) Apply a function to `x` only if it is not `nothing`. """ diff --git a/src/base/types/wrappers/GeckoModel.jl b/src/base/types/wrappers/GeckoModel.jl index 4b12951d2..dace278d7 100644 --- a/src/base/types/wrappers/GeckoModel.jl +++ b/src/base/types/wrappers/GeckoModel.jl @@ -1,7 +1,10 @@ """ - struct _gecko_reaction_column +$(TYPEDEF) A helper type for describing the contents of [`GeckoModel`](@ref)s. + +# Fields +$(TYPEDFIELDS) """ struct _gecko_reaction_column reaction_idx::Int @@ -14,10 +17,13 @@ struct _gecko_reaction_column end """ - struct _gecko_capacity +$(TYPEDEF) A helper struct that contains the gene product capacity terms organized by the grouping type, e.g. metabolic or membrane groups etc. + +# Fields +$(TYPEDFIELDS) """ struct _gecko_capacity group_id::String @@ -27,7 +33,7 @@ struct _gecko_capacity end """ - struct GeckoModel <: ModelWrapper +$(TYPEDEF) A model with complex enzyme concentration and capacity bounds, as described in *Sánchez, Benjamín J., et al. "Improving the phenotype predictions of a yeast @@ -64,6 +70,9 @@ Implementation exposes the split reactions (available as `reactions(model)`), but retains the original "simple" reactions accessible by [`fluxes`](@ref). The related constraints are implemented using [`coupling`](@ref) and [`coupling_bounds`](@ref). + +# Fields +$(TYPEDFIELDS) """ struct GeckoModel <: ModelWrapper objective::SparseVec @@ -78,7 +87,7 @@ end unwrap_model(model::GeckoModel) = model.inner """ - stoichiometry(model::GeckoModel) +$(TYPEDSIGNATURES) Return a stoichiometry of the [`GeckoModel`](@ref). The enzymatic reactions are split into unidirectional forward and reverse ones, each of which may have @@ -94,7 +103,7 @@ function stoichiometry(model::GeckoModel) end """ - objective(model::GeckoModel) +$(TYPEDSIGNATURES) Return the objective of the [`GeckoModel`](@ref). Note, the objective is with respect to the internal variables, i.e. [`reactions(model)`](@ref), which are @@ -104,7 +113,7 @@ have kinetic data. objective(model::GeckoModel) = model.objective """ - reactions(model::GeckoModel) +$(TYPEDSIGNATURES) Returns the internal reactions in a [`GeckoModel`](@ref) (these may be split to forward- and reverse-only parts with different isozyme indexes; reactions @@ -123,7 +132,7 @@ function reactions(model::GeckoModel) end """ - n_reactions(model::GeckoModel) +$(TYPEDSIGNATURES) Returns the number of all irreversible reactions in `model` as well as the number of gene products that take part in enzymatic reactions. @@ -131,7 +140,7 @@ number of gene products that take part in enzymatic reactions. n_reactions(model::GeckoModel) = length(model.columns) + n_genes(model) """ - bounds(model::GeckoModel) +$(TYPEDSIGNATURES) Return variable bounds for [`GeckoModel`](@ref). """ @@ -148,7 +157,7 @@ function bounds(model::GeckoModel) end """ - reaction_flux(model::GeckoModel) +$(TYPEDSIGNATURES) Get the mapping of the reaction rates in [`GeckoModel`](@ref) to the original fluxes in the wrapped model. @@ -162,7 +171,7 @@ function reaction_flux(model::GeckoModel) end """ - coupling(model::GeckoModel) +$(TYPEDSIGNATURES) Return the coupling of [`GeckoModel`](@ref). That combines the coupling of the wrapped model, coupling for split (arm) reactions, and the coupling for the total @@ -180,7 +189,7 @@ function coupling(model::GeckoModel) end """ - n_coupling_constraints(model::GeckoModel) +$(TYPEDSIGNATURES) Count the coupling constraints in [`GeckoModel`](@ref) (refer to [`coupling`](@ref) for details). @@ -191,7 +200,7 @@ n_coupling_constraints(model::GeckoModel) = length(model.coupling_row_mass_group) """ - coupling_bounds(model::GeckoModel) +$(TYPEDSIGNATURES) The coupling bounds for [`GeckoModel`](@ref) (refer to [`coupling`](@ref) for details). @@ -214,7 +223,7 @@ function coupling_bounds(model::GeckoModel) end """ - balance(model::GeckoModel) +$(TYPEDSIGNATURES) Return the balance of the reactions in the inner model, concatenated with a vector of zeros representing the enzyme balance of a [`GeckoModel`](@ref). @@ -223,14 +232,14 @@ balance(model::GeckoModel) = [balance(model.inner); spzeros(length(model.coupling_row_gene_product))] """ - n_genes(model::GeckoModel) +$(TYPEDSIGNATURES) Return the number of genes that have enzymatic constraints associated with them. """ n_genes(model::GeckoModel) = length(model.coupling_row_gene_product) """ - genes(model::GeckoModel) +$(TYPEDSIGNATURES) Return the gene ids of genes that have enzymatic constraints associated with them. """ @@ -238,14 +247,14 @@ genes(model::GeckoModel) = genes(model.inner)[[idx for (idx, _) in model.coupling_row_gene_product]] """ - metabolites(model::GeckoModel) +$(TYPEDSIGNATURES) Return the ids of all metabolites, both real and pseudo, for a [`GeckoModel`](@ref). """ metabolites(model::GeckoModel) = [metabolites(model.inner); genes(model) .* "#gecko"] """ - n_metabolites(model::GeckoModel) +$(TYPEDSIGNATURES) Return the number of metabolites, both real and pseudo, for a [`GeckoModel`](@ref). """ diff --git a/src/base/types/wrappers/SMomentModel.jl b/src/base/types/wrappers/SMomentModel.jl index bdf50a71d..98f8041f7 100644 --- a/src/base/types/wrappers/SMomentModel.jl +++ b/src/base/types/wrappers/SMomentModel.jl @@ -1,8 +1,11 @@ """ - struct _smoment_column +$(TYPEDEF) A helper type that describes the contents of [`SMomentModel`](@ref)s. + +# Fields +$(TYPEDFIELDS) """ struct _smoment_column reaction_idx::Int # number of the corresponding reaction in the inner model @@ -13,7 +16,7 @@ struct _smoment_column end """ - struct SMomentModel <: ModelWrapper +$(TYPEDEF) An enzyme-capacity-constrained model using sMOMENT algorithm, as described by *Bekiaris, Pavlos Stephanos, and Steffen Klamt, "Automatic construction of @@ -47,6 +50,9 @@ This implementation allows easy access to fluxes from the split reactions (available in `reactions(model)`), while the original "simple" reactions from the wrapped model are retained as [`fluxes`](@ref). All additional constraints are implemented using [`coupling`](@ref) and [`coupling_bounds`](@ref). + +# Fields +$(TYPEDFIELDS) """ struct SMomentModel <: ModelWrapper columns::Vector{_smoment_column} @@ -58,7 +64,7 @@ end unwrap_model(model::SMomentModel) = model.inner """ - stoichiometry(model::SMomentModel) +$(TYPEDSIGNATURES) Return a stoichiometry of the [`SMomentModel`](@ref). The enzymatic reactions are split into unidirectional forward and reverse ones. @@ -67,14 +73,14 @@ stoichiometry(model::SMomentModel) = stoichiometry(model.inner) * _smoment_column_reactions(model) """ - objective(model::SMomentModel) +$(TYPEDSIGNATURES) Reconstruct an objective of the [`SMomentModel`](@ref). """ objective(model::SMomentModel) = _smoment_column_reactions(model)' * objective(model.inner) """ - reactions(model::SMomentModel) +$(TYPEDSIGNATURES) Returns the internal reactions in a [`SMomentModel`](@ref) (these may be split to forward- and reverse-only parts; reactions IDs are mangled accordingly with @@ -89,14 +95,14 @@ reactions(model::SMomentModel) = end """ - n_reactions(model::SMomentModel) +$(TYPEDSIGNATURES) The number of reactions (including split ones) in [`SMomentModel`](@ref). """ n_reactions(model::SMomentModel) = length(model.columns) """ - bounds(model::SMomentModel) +$(TYPEDSIGNATURES) Return the variable bounds for [`SMomentModel`](@ref). """ @@ -104,7 +110,7 @@ bounds(model::SMomentModel) = ([col.lb for col in model.columns], [col.ub for col in model.columns]) """ - reaction_flux(model::SMomentModel) +$(TYPEDSIGNATURES) Get the mapping of the reaction rates in [`SMomentModel`](@ref) to the original fluxes in the wrapped model. @@ -113,7 +119,7 @@ reaction_flux(model::SMomentModel) = _smoment_column_reactions(model)' * reaction_flux(model.inner) """ - coupling(model::SMomentModel) +$(TYPEDSIGNATURES) Return the coupling of [`SMomentModel`](@ref). That combines the coupling of the wrapped model, coupling for split reactions, and the coupling for the total @@ -125,7 +131,7 @@ coupling(model::SMomentModel) = vcat( ) """ - n_coupling_constraints(model::SMomentModel) +$(TYPEDSIGNATURES) Count the coupling constraints in [`SMomentModel`](@ref) (refer to [`coupling`](@ref) for details). @@ -133,7 +139,7 @@ Count the coupling constraints in [`SMomentModel`](@ref) (refer to n_coupling_constraints(model::SMomentModel) = n_coupling_constraints(model.inner) + 1 """ - coupling_bounds(model::SMomentModel) +$(TYPEDSIGNATURES) The coupling bounds for [`SMomentModel`](@ref) (refer to [`coupling`](@ref) for details). diff --git a/src/base/utils/Annotation.jl b/src/base/utils/Annotation.jl index 6ec3636aa..9832d0d4c 100644 --- a/src/base/utils/Annotation.jl +++ b/src/base/utils/Annotation.jl @@ -4,10 +4,7 @@ _annotations(r::Reaction) = r.annotations _annotations(g::Gene) = g.annotations """ - annotation_index( - xs::AbstractDict{String}; - annotations = _annotations, - )::Dict{String,Dict{String,[String]}} +$(TYPEDSIGNATURES) Extract annotations from a dictionary of items `xs` and build an index that maps annotation "kinds" (e.g. `"PubChem"`) to the mapping from the annotations @@ -42,9 +39,7 @@ function annotation_index( end """ - ambiguously_identified_items( - index::Dict{String,Dict{String,[String]}}, - )::Vector{String} +$(TYPEDSIGNATURES) Find items (genes, metabolites, ...) from the annotation index that are identified non-uniquely by at least one of their annotations. diff --git a/src/base/utils/Reaction.jl b/src/base/utils/Reaction.jl index 8661d8658..011b732b9 100644 --- a/src/base/utils/Reaction.jl +++ b/src/base/utils/Reaction.jl @@ -1,5 +1,5 @@ """ - check_duplicate_reaction(rxn::Reaction, rxns::Dict{String, Reaction}; only_metabolites=true) +$(TYPEDSIGNATURES) Check if `rxn` already exists in `rxns` but has another `id`. If `only_metabolites` is `true` then only the metabolite `id`s are checked. @@ -39,7 +39,7 @@ function check_duplicate_reaction( end """ - is_boundary(rxn_dict::Dict{String, Float64}) +$(TYPEDSIGNATURES) Return true if the reaction denoted by `rxn_dict` is a boundary reaction, otherwise return false. Checks if on boundary by inspecting the number of metabolites in `rxn_dict`. @@ -57,7 +57,7 @@ is_boundary(rxn::Reaction) = is_boundary(rxn.metabolites) is_boundary(model::StandardModel, rxn::Reaction) = is_boundary(rxn) # for consistency with functions below """ - reaction_atom_balance(model::StandardModel, rxn) +$(TYPEDSIGNATURES) Returns a dictionary mapping the stoichiometry of atoms through a single reaction. Uses the metabolite information in `model` to determine the mass balance. Accepts a reaction @@ -87,7 +87,7 @@ reaction_atom_balance(model::StandardModel, rxn::Reaction) = reaction_atom_balance(model, rxn.id) """ - reaction_mass_balanced(model::StandardModel, rxn) +$(TYPEDSIGNATURES) Checks if `rxn` is atom balanced. Returns a boolean for whether the reaction is balanced, and the associated balance of atoms for convenience (useful if not balanced). Calls @@ -105,7 +105,7 @@ reaction_mass_balanced(model::StandardModel, reaction_dict::Dict{String,Float64} all(values(reaction_atom_balance(model, reaction_dict)) .== 0) """ - stoichiometry_string(rxn_dict::Dict{String, Float64}; format_id = x -> x) +$(TYPEDSIGNATURES) Return the reaction equation as a string. The metabolite strings can be manipulated by setting `format_id`. @@ -130,7 +130,7 @@ function stoichiometry_string(req; format_id = x -> x) end """ - stoichiometry_string(rxn::Reaction; kwargs) +$(TYPEDSIGNATURES) Alternative of [`stoichiometry_string`](@ref) take takes a `Reaction` as an argument. """ diff --git a/src/base/utils/Serialized.jl b/src/base/utils/Serialized.jl index 2ed27e51e..577d101c4 100644 --- a/src/base/utils/Serialized.jl +++ b/src/base/utils/Serialized.jl @@ -1,6 +1,6 @@ """ - serialize_model(model::MM, filename::String)::Serialized{MM} where {MM<:MetabolicModel} +$(TYPEDSIGNATURES) Serialize the `model` to file `filename`, returning a [`Serialized`](@ref) model that can be loaded back transparently by [`precache!`](@ref). The result @@ -22,7 +22,7 @@ function serialize_model( end """ - serialize_model(model::Serialized, filename::String)::Serialized +$(TYPEDSIGNATURES) Specialization of [`serialize_model`](@ref) that prevents nested serialization of already-serialized models. diff --git a/src/base/utils/StandardModel.jl b/src/base/utils/StandardModel.jl index 83d6be64d..3da400441 100644 --- a/src/base/utils/StandardModel.jl +++ b/src/base/utils/StandardModel.jl @@ -1,6 +1,6 @@ """ - Base.copy(m::StandardModel) +$(TYPEDSIGNATURES) Shallow copy of a [`StandardModel`](@ref) """ @@ -12,7 +12,7 @@ Base.copy(m::StandardModel) = StandardModel( ) """ - Base.copy(r::Reaction) +$(TYPEDSIGNATURES) Shallow copy of a [`Reaction`](@ref) """ @@ -29,7 +29,7 @@ Base.copy(r::Reaction) = Reaction( ) """ - Base.copy(m::Metabolite) +$(TYPEDSIGNATURES) Shallow copy of a [`Metabolite`](@ref) """ @@ -43,7 +43,7 @@ Base.copy(m::Metabolite) = Metabolite( ) """ - Base.copy(g::Gene) +$(TYPEDSIGNATURES) Shallow copy of a [`Gene`](@ref) """ diff --git a/src/base/utils/bounds.jl b/src/base/utils/bounds.jl index 763457646..5ca724795 100644 --- a/src/base/utils/bounds.jl +++ b/src/base/utils/bounds.jl @@ -1,5 +1,5 @@ """ - gamma_bounds(gamma) +$(TYPEDSIGNATURES) A bounds-generating function for [`flux_variability_analysis`](@ref) that limits the objective value to be at least `gamma*Z₀`, as usual in COBRA @@ -11,7 +11,7 @@ flux_variability_analysis(model, some_optimizer; bounds = gamma_bounds(0.9)) gamma_bounds(gamma) = z -> (gamma * z, Inf) """ - objective_bounds(tolerance) +$(TYPEDSIGNATURES) A bounds-generating function for [`flux_variability_analysis`](@ref) that limits the objective value to a small multiple of Z₀. Use as `bounds` argument, diff --git a/src/base/utils/chemical_formulas.jl b/src/base/utils/chemical_formulas.jl index da55f43fa..d4c081619 100644 --- a/src/base/utils/chemical_formulas.jl +++ b/src/base/utils/chemical_formulas.jl @@ -1,6 +1,6 @@ """ - _parse_formula(f::String)::MetaboliteFormula +$(TYPEDSIGNATURES) Parse a formula in format `C2H6O` into a [`MetaboliteFormula`](@ref), which is basically a dictionary of atom counts in the molecule. @@ -17,7 +17,7 @@ function _parse_formula(f::String)::MetaboliteFormula end """ - _unparse_formula(f::MetaboliteFormula)::String +$(TYPEDSIGNATURES) Format [`MetaboliteFormula`](@ref) to `String`. """ diff --git a/src/base/utils/enzymes.jl b/src/base/utils/enzymes.jl index 152437fb1..cf86b71b7 100644 --- a/src/base/utils/enzymes.jl +++ b/src/base/utils/enzymes.jl @@ -1,5 +1,5 @@ """ - gene_product_dict(model::GeckoModel, opt_model) +$(TYPEDSIGNATURES) Return a dictionary mapping protein molar concentrations to their ids. The argument `opt_model` is a solved optimization problem, typically returned by @@ -11,14 +11,14 @@ gene_product_dict(model::GeckoModel, opt_model) = Dict(genes(model) .=> value.(opt_model[:x])[(length(model.columns)+1):end]) : nothing """ - gene_product_dict(model::GeckoModel) +$(TYPEDSIGNATURES) A pipe-able variant of [`gene_product_dict`](@ref). """ gene_product_dict(model::GeckoModel) = x -> gene_product_dict(model, x) """ - gene_product_mass_group_dict(model::GeckoModel, opt_model) +$(TYPEDSIGNATURES) Extract the mass utilization in mass groups from a solved [`GeckoModel`](@ref). """ @@ -32,7 +32,7 @@ gene_product_mass_group_dict(model::GeckoModel, opt_model) = ) : nothing """ - gene_product_mass_group_dict(model::GeckoModel) +$(TYPEDSIGNATURES) A pipe-able variant of [`gene_product_mass_group_dict`](@ref). """ @@ -40,7 +40,7 @@ gene_product_mass_group_dict(model::GeckoModel) = x -> gene_product_mass_group_dict(model, x) """ - gene_product_mass(model::SMomentModel) +$(TYPEDSIGNATURES) Extract the total mass utilization in a solved [`SMomentModel`](@ref). """ @@ -49,8 +49,7 @@ gene_product_mass(model::SMomentModel, opt_model) = sum((col.capacity_required for col in model.columns) .* value.(opt_model[:x])) : nothing """ - gene_product_mass(model::SMomentModel) - +$(TYPEDSIGNATURES) A pipe-able variant of [`gene_product_mass`](@ref). """ diff --git a/src/base/utils/fluxes.jl b/src/base/utils/fluxes.jl index 6b9deecd8..cf23a3f9d 100644 --- a/src/base/utils/fluxes.jl +++ b/src/base/utils/fluxes.jl @@ -1,5 +1,5 @@ """ - metabolite_fluxes(model::MetabolicModel, flux_dict::Dict{String, Float64}) +$(TYPEDSIGNATURES) Return two dictionaries of metabolite `id`s mapped to reactions that consume or produce them, given the flux distribution supplied in `flux_dict`. @@ -33,7 +33,7 @@ function metabolite_fluxes(model::MetabolicModel, flux_dict::Dict{String,Float64 end """ - atom_fluxes(model::MetabolicModel, reaction_fluxes::Dict{String, Float64}) +$(TYPEDSIGNATURES) Return a dictionary mapping the flux of atoms across a flux solution given by `reaction_fluxes` using the reactions in `model` to determine the appropriate stoichiometry. diff --git a/src/base/utils/gecko.jl b/src/base/utils/gecko.jl index e25ec2863..219f45b6a 100644 --- a/src/base/utils/gecko.jl +++ b/src/base/utils/gecko.jl @@ -1,6 +1,6 @@ """ - _gecko_reaction_name(original_name::String, direction::Int) +$(TYPEDSIGNATURES) Internal helper for systematically naming reactions in [`GeckoModel`](@ref). """ @@ -10,7 +10,7 @@ _gecko_reaction_name(original_name::String, direction::Int, isozyme_idx::Int) = "$original_name#reverse#$isozyme_idx" """ - _gecko_reaction_column_reactions(model::GeckoModel) +$(TYPEDSIGNATURES) Retrieve a utility mapping between reactions and split reactions; rows correspond to "original" reactions, columns correspond to "split" reactions. @@ -19,7 +19,7 @@ _gecko_reaction_column_reactions(model::GeckoModel) = _gecko_reaction_column_reactions(model.columns, model.inner) """ - _gecko_reaction_column_reactions(columns, inner) +$(TYPEDSIGNATURES) Helper method that doesn't require the whole [`GeckoModel`](@ref). """ @@ -32,7 +32,7 @@ _gecko_reaction_column_reactions(columns, inner) = sparse( ) """ - _gecko_reaction_coupling(model::GeckoModel) +$(TYPEDSIGNATURES) Compute the part of the coupling for [`GeckoModel`](@ref) that limits the "arm" reactions (which group the individual split unidirectional reactions). @@ -52,7 +52,7 @@ _gecko_reaction_coupling(model::GeckoModel) = end """ - _gecko_gene_product_coupling(model::GeckoModel) +$(TYPEDSIGNATURES) Compute the part of the coupling for GeckoModel that limits the amount of each kind of protein available. @@ -73,7 +73,7 @@ _gecko_gene_product_coupling(model::GeckoModel) = end """ - _gecko_mass_group_coupling(model::GeckoModel) +$(TYPEDSIGNATURES) Compute the part of the coupling for [`GeckoModel`](@ref) that limits the total mass of each group of gene products. diff --git a/src/base/utils/gene_associations.jl b/src/base/utils/gene_associations.jl index 9e78a5999..109317900 100644 --- a/src/base/utils/gene_associations.jl +++ b/src/base/utils/gene_associations.jl @@ -1,6 +1,6 @@ """ - _parse_grr(gpa::SBML.GeneProductAssociation)::GeneAssociation +$(TYPEDSIGNATURES) Parse `SBML.GeneProductAssociation` structure to the simpler GeneAssociation. The input must be (implicitly) in a positive DNF. @@ -20,10 +20,7 @@ function _parse_grr(gpa::SBML.GeneProductAssociation)::GeneAssociation end """ - _unparse_grr( - ::Type{SBML.GeneProductAssociation}, - x::GeneAssociation, - )::SBML.GeneAssociation +$(TYPEDSIGNATURES) Convert a GeneAssociation to the corresponding `SBML.jl` structure. """ @@ -35,7 +32,7 @@ function _unparse_grr( end """ - _parse_grr(s::String)::GeneAssociation +$(TYPEDSIGNATURES) Parse a DNF gene association rule in format `(YIL010W and YLR043C) or (YIL010W and YGR209C)` to `GeneAssociation. Also accepts `OR`, `|`, `||`, `AND`, `&`, @@ -52,7 +49,7 @@ julia> _parse_grr("(YIL010W and YLR043C) or (YIL010W and YGR209C)") _parse_grr(s::String)::Maybe{GeneAssociation} = _maybemap(_parse_grr, _parse_grr_to_sbml(s)) """ - _parse_grr_to_sbml(str::String)::Maybe{SBML.GeneProductAssociation} +$(TYPEDSIGNATURES) Internal helper for parsing the string GRRs into SBML data structures. More general than [`_parse_grr`](@ref). @@ -119,7 +116,7 @@ function _parse_grr_to_sbml(str::String)::Maybe{SBML.GeneProductAssociation} end """ - unparse_grr(grr::Vector{Vector{Gene}} +$(TYPEDSIGNATURES) Converts a nested string gene reaction array back into a gene reaction rule string. diff --git a/src/base/utils/guesskey.jl b/src/base/utils/guesskey.jl index 4a9ad6302..183e82656 100644 --- a/src/base/utils/guesskey.jl +++ b/src/base/utils/guesskey.jl @@ -1,6 +1,6 @@ """ - _guesskey(ks, possibilities) +$(TYPEDSIGNATURES) Unfortunately, many model types that contain dictionares do not have standardized field names, so we need to try a few possibilities and guess the @@ -22,7 +22,7 @@ function _guesskey(avail, possibilities) end """ - gets(collection, fail, keys) +$(TYPEDSIGNATURES) Return `fail` if key in `keys` is not in `collection`, otherwise return `collection[key]`. Useful if may different keys need to be diff --git a/src/base/utils/looks_like.jl b/src/base/utils/looks_like.jl index 1b29f23f8..69f2d93d9 100644 --- a/src/base/utils/looks_like.jl +++ b/src/base/utils/looks_like.jl @@ -1,9 +1,5 @@ """ - looks_like_exchange_reaction(rxn_id::String; - exclude_biomass = false, - biomass_strings = _constants.biomass_strings, - exchange_prefixes = _constants.exchange_prefixes, - ) +$(TYPEDSIGNATURES) A predicate that matches reaction identifiers that look like exchange or biomass reactions, given the usual naming schemes in common model @@ -13,6 +9,12 @@ occurences of `biomass_strings` in the reaction id. Also see [`find_exchange_reactions`](@ref). +# Note +While `looks_like_exchange_reaction` is useful for heuristically finding a +reaction, it is preferable to use standardized terms for finding reactions (e.g. +SBO terms). See [`is_exchange_reaction`](@ref) for a more systematic +alternative. + # Example ``` findall(looks_like_exchange_reaction, reactions(model)) # returns indices @@ -35,7 +37,7 @@ function looks_like_exchange_reaction( end """ - find_exchange_reactions(m::MetabolicModel; kwargs...) +$(TYPEDSIGNATURES) Shortcut for finding exchange reaction indexes in a model; arguments are forwarded to [`looks_like_exchange_reaction`](@ref). @@ -44,7 +46,7 @@ find_exchange_reactions(m::MetabolicModel; kwargs...) = findall(id -> looks_like_exchange_reaction(id; kwargs...), reactions(m)) """ - find_exchange_reaction_ids(m::MetabolicModel; kwargs...) +$(TYPEDSIGNATURES) Shortcut for finding exchange reaction identifiers in a model; arguments are forwarded to [`looks_like_exchange_reaction`](@ref). @@ -53,17 +55,19 @@ find_exchange_reaction_ids(m::MetabolicModel; kwargs...) = filter(id -> looks_like_exchange_reaction(id, kwargs...), reactions(m)) """ - looks_like_biomass_reaction(rxn_id::String; - exclude_exchanges = false, - exchange_prefixes = _constants.exchange_prefixes, - biomass_strings = _constants.biomass_strings, - )::Bool +$(TYPEDSIGNATURES) A predicate that matches reaction identifiers that look like biomass reactions. Biomass reactions are identified by looking for occurences of `biomass_strings` in the reaction id. If `exclude_exchanges` is set, the strings that look like exchanges (from [`looks_like_exchange_reaction`](@ref)) will not match. +# Note +While `looks_like_biomass_reaction` is useful for heuristically finding a +reaction, it is preferable to use standardized terms for finding reactions (e.g. +SBO terms). See [`is_biomass_reaction`](@ref) for a more systematic +alternative. + # Example ``` filter(looks_like_biomass_reaction, reactions(model)) # returns strings @@ -81,7 +85,7 @@ function looks_like_biomass_reaction( end """ - find_biomass_reactions(m::MetabolicModel; kwargs...) +$(TYPEDSIGNATURES) Shortcut for finding biomass reaction indexes in a model; arguments are forwarded to [`looks_like_biomass_reaction`](@ref). @@ -90,7 +94,7 @@ find_biomass_reactions(m::MetabolicModel; kwargs...) = findall(id -> looks_like_biomass_reaction(id; kwargs...), reactions(m)) """ - find_biomass_reaction_ids(m::MetabolicModel; kwargs...) +$(TYPEDSIGNATURES) Shortcut for finding biomass reaction identifiers in a model; arguments are forwarded to [`looks_like_biomass_reaction`](@ref). @@ -99,9 +103,7 @@ find_biomass_reaction_ids(m::MetabolicModel; kwargs...) = filter(id -> looks_like_biomass_reaction(id; kwargs...), reactions(m)) """ - looks_like_extracellular_metabolite(rxn_id::String; - extracellular_suffixes = _constants.extracellular_suffixes, - )::Bool +$(TYPEDSIGNATURES) A predicate that matches metabolite identifiers that look like they are extracellular metabolites. Extracellular metabolites are identified by `extracellular_suffixes` at the end of the @@ -121,18 +123,27 @@ function looks_like_extracellular_metabolite( end """ - find_extracellular_metabolites(m::MetabolicModel; kwargs...) +$(TYPEDSIGNATURES) Shortcut for finding extracellular metabolite indexes in a model; arguments are forwarded to [`looks_like_extracellular_metabolite`](@ref). """ find_extracellular_metabolites(m::MetabolicModel; kwargs...) = findall(id -> looks_like_extracellular_metabolite(id; kwargs...), metabolites(m)) + """ - find_extracellular_metabolite_ids(m::MetabolicModel; kwargs...) +$(TYPEDSIGNATURES) Shortcut for finding extracellular metabolite identifiers in a model; arguments are forwarded to [`looks_like_extracellular_metabolite`](@ref). """ find_extracellular_metabolite_ids(m::MetabolicModel; kwargs...) = findall(id -> looks_like_extracellular_metabolite(id; kwargs...), metabolites(m)) + +@_is_reaction_fn "exchange" Identifiers.EXCHANGE_REACTIONS +@_is_reaction_fn "transport" Identifiers.TRANSPORT_REACTIONS +@_is_reaction_fn "biomass" Identifiers.BIOMASS_REACTIONS +@_is_reaction_fn "atp_maintenance" Identifiers.ATP_MAINTENANCE_REACTIONS +@_is_reaction_fn "pseudo" Identifiers.PSEUDOREACTIONS +@_is_reaction_fn "metabolic" Identifiers.METABOLIC_REACTIONS +@_is_reaction_fn "spontaneous" Identifiers.SPONTANEOUS_REACTIONS diff --git a/src/base/utils/smoment.jl b/src/base/utils/smoment.jl index 15751715c..4bbf4783c 100644 --- a/src/base/utils/smoment.jl +++ b/src/base/utils/smoment.jl @@ -1,6 +1,6 @@ """ - _smoment_reaction_name(original_name::String, direction::Int) +$(TYPEDSIGNATURES) Internal helper for systematically naming reactions in [`SMomentModel`](@ref). """ @@ -9,7 +9,7 @@ _smoment_reaction_name(original_name::String, direction::Int) = direction > 0 ? "$original_name#forward" : "$original_name#reverse" """ - _smoment_column_reactions(model::SMomentModel) +$(TYPEDSIGNATURES) Retrieve a utility mapping between reactions and split reactions; rows correspond to "original" reactions, columns correspond to "split" reactions. @@ -23,7 +23,7 @@ _smoment_column_reactions(model::SMomentModel) = sparse( ) """ - smoment_isozyme_speed(isozyme::Isozyme, gene_product_molar_mass) +$(TYPEDSIGNATURES) Compute a "score" for picking the most viable isozyme for [`make_smoment_model`](@ref), based on maximum kcat divided by relative mass of @@ -37,7 +37,7 @@ smoment_isozyme_speed(isozyme::Isozyme, gene_product_molar_mass) = ) """ - smoment_isozyme_speed(gene_product_molar_mass::Function) +$(TYPEDSIGNATURES) A piping- and argmax-friendly overload of [`smoment_isozyme_speed`](@ref). diff --git a/src/io/h5.jl b/src/io/h5.jl index 0bc7b66e5..5d7785305 100644 --- a/src/io/h5.jl +++ b/src/io/h5.jl @@ -1,6 +1,6 @@ """ - load_h5_model(file_name::String)::HDF5Model +$(TYPEDSIGNATURES) Return a HDF5Model associated with the given file. Does not actually load anything (for efficiency) -- use [`precache!`](@ref) to start pulling data into @@ -11,7 +11,7 @@ function load_h5_model(file_name::String)::HDF5Model end """ - save_h5_model(model::MetabolicModel, file_name::String)::HDF5Model +$(TYPEDSIGNATURES) Converts and writes a metabolic model to disk in the HDF5 format. @@ -41,7 +41,7 @@ function save_h5_model(model::MetabolicModel, file_name::String)::HDF5Model end """ - Base.close(model::HDF5Model) +$(TYPEDSIGNATURES) Close (and un-cache) the [`HDF5Model`](@ref) data. This allows the associated file to be opened for writing again. diff --git a/src/io/io.jl b/src/io/io.jl index 53f2e1347..4c8b268ba 100644 --- a/src/io/io.jl +++ b/src/io/io.jl @@ -1,6 +1,6 @@ """ - load_model(file_name::String)::MetabolicModel +$(TYPEDSIGNATURES) Generic function for loading models that chooses a specific loader function from the `file_name` extension, or throws an error. @@ -28,7 +28,7 @@ end """ - load_model(type::Type{T}, file_name::String)::T where T +$(TYPEDSIGNATURES) Helper function tht loads the model using [`load_model`](@ref) and return it converted to `type`. @@ -42,7 +42,7 @@ function load_model(type::Type{T}, file_name::String)::T where {T<:MetabolicMode end """ - save_model(model::MetabolicModel, file_name::String) +$(TYPEDSIGNATURES) Generic function for saving models that chooses a specific writer function from the `file_name` extension, or throws an error. diff --git a/src/io/json.jl b/src/io/json.jl index 6186ab5bb..918267a5c 100644 --- a/src/io/json.jl +++ b/src/io/json.jl @@ -1,5 +1,5 @@ """ - load_json_model(filename::String)::JSONModel +$(TYPEDSIGNATURES) Load and return a JSON-formatted model that is stored in `file_name`. """ @@ -8,7 +8,7 @@ function load_json_model(filename::String)::JSONModel end """ - save_json_model(model::MetabolicModel, file_name::String) +$(TYPEDSIGNATURES) Save a [`JSONModel`](@ref) in `model` to a JSON file `file_name`. diff --git a/src/io/mat.jl b/src/io/mat.jl index 314238b93..84b205868 100644 --- a/src/io/mat.jl +++ b/src/io/mat.jl @@ -1,6 +1,6 @@ """ - load_mat_model(file_name::String) +$(TYPEDSIGNATURES) Load and return a MATLAB file `file_name` that contains a COBRA-compatible model. @@ -12,7 +12,7 @@ function load_mat_model(file_name::String)::MATModel end """ - save_mat_model(model::MetabolicModel, file_name::String; model_name::String="model") +$(TYPEDSIGNATURES) Save a [`MATModel`](@ref) in `model` to a MATLAB file `file_name` in a format compatible with other MATLAB-based COBRA software. diff --git a/src/io/sbml.jl b/src/io/sbml.jl index 9debac4e3..574a60300 100644 --- a/src/io/sbml.jl +++ b/src/io/sbml.jl @@ -1,6 +1,6 @@ """ - load_sbml_model(file_name::String)::SBMLModel +$(TYPEDSIGNATURES) Load and return a SBML XML model in `file_name`. """ @@ -9,7 +9,7 @@ function load_sbml_model(file_name::String)::SBMLModel end """ - write_sbml_model(model::MetabolicModel, file_name::String) +$(TYPEDSIGNATURES) Write a given SBML model to `file_name`. """ diff --git a/src/io/show/MetabolicModel.jl b/src/io/show/MetabolicModel.jl index c9988b590..b600208be 100644 --- a/src/io/show/MetabolicModel.jl +++ b/src/io/show/MetabolicModel.jl @@ -1,4 +1,6 @@ """ +$(TYPEDSIGNATURES) + Pretty printing of everything metabolic-modelish. """ function Base.show(io::IO, ::MIME"text/plain", m::MetabolicModel) diff --git a/src/io/show/Reaction.jl b/src/io/show/Reaction.jl index b82c08329..b5e340615 100644 --- a/src/io/show/Reaction.jl +++ b/src/io/show/Reaction.jl @@ -1,6 +1,6 @@ """ - _pretty_substances(ss::Vector{String})::String +$(TYPEDSIGNATURES) Nicely format a substance list. """ diff --git a/src/io/show/Serialized.jl b/src/io/show/Serialized.jl index 83e427b93..598e2ceff 100644 --- a/src/io/show/Serialized.jl +++ b/src/io/show/Serialized.jl @@ -1,6 +1,6 @@ """ - Base.show(io::IO, ::MIME"text/plain", m::Serialized{M}) where {M} +$(TYPEDSIGNATURES) Show the [`Serialized`](@ref) model without unnecessarily loading it. """ diff --git a/src/io/show/pretty_printing.jl b/src/io/show/pretty_printing.jl index 8eb258345..8df6f6462 100644 --- a/src/io/show/pretty_printing.jl +++ b/src/io/show/pretty_printing.jl @@ -1,5 +1,5 @@ """ - _pretty_print_keyvals(io, def::String, payload; kwargs...) +$(TYPEDSIGNATURES) Nicely prints keys and values. """ @@ -7,11 +7,7 @@ _pretty_print_keyvals(io, def::String, payload; kwargs...) = _pretty_print_keyvals(io, def, isnothing(payload) ? "---" : string(payload); kwargs...) """ - _pretty_print_keyvals( - io, - def::String, - payload::String - ) +$(TYPEDSIGNATURES) Specialization of `_pretty_print_keyvals` for plain strings. """ @@ -25,11 +21,7 @@ function _pretty_print_keyvals(io, def::String, payload::String) end """ - _pretty_print_keyvals( - io, - def::String, - payload::Dict - ) +$(TYPEDSIGNATURES) Specialization of `_pretty_print_keyvals` for dictionaries. """ diff --git a/src/reconstruction/CoreModel.jl b/src/reconstruction/CoreModel.jl index 1336b8fc4..e791cce3e 100644 --- a/src/reconstruction/CoreModel.jl +++ b/src/reconstruction/CoreModel.jl @@ -1,5 +1,5 @@ """ - add_reactions!(model::CoreModel, rxns::Vector{Reaction}) +$(TYPEDSIGNATURES) Add `rxns` to `model` efficiently. The model must already contain the metabolites used by `rxns` in the model. @@ -32,7 +32,7 @@ function add_reactions!(model::CoreModel, rxns::Vector{Reaction}) end """ - add_reaction!(model::CoreModel, rxn::Reaction) +$(TYPEDSIGNATURES) Add `rxn` to `model`. The model must already contain the metabolites used by `rxn` in the model. @@ -40,15 +40,7 @@ Add `rxn` to `model`. The model must already contain the metabolites used by add_reaction!(model::CoreModel, rxn::Reaction) = add_reactions!(model, [rxn]) """ - add_reactions( - m::CoreModel, - s::VecType, - b::VecType, - c::AbstractFloat, - xl::AbstractFloat, - xu::AbstractFloat; - check_consistency = false, - ) +$(TYPEDSIGNATURES) Add reaction(s) to a `CoreModel` model `m`. """ @@ -73,17 +65,7 @@ function add_reactions( end """ - add_reactions( - m::CoreModel, - s::VecType, - b::VecType, - c::AbstractFloat, - xl::AbstractFloat, - xu::AbstractFloat, - rxn::String, - mets::K; - check_consistency = false, - ) +$(TYPEDSIGNATURES) """ function add_reactions( m::CoreModel, @@ -110,15 +92,7 @@ function add_reactions( end """ - add_reactions( - m::CoreModel, - Sp::MatType, - b::VecType, - c::VecType, - xl::VecType, - xu::VecType; - check_consistency = false, - ) +$(TYPEDSIGNATURES) """ function add_reactions( m::CoreModel, @@ -145,7 +119,7 @@ function add_reactions( end """ - add_reactions(m1::CoreModel, m2::CoreModel; check_consistency = false) +$(TYPEDSIGNATURES) Add all reactions from `m2` to `m1`. """ @@ -164,17 +138,7 @@ function add_reactions(m1::CoreModel, m2::CoreModel; check_consistency = false) end """ - add_reactions( - m::CoreModel, - Sp::MatType, - b::VecType, - c::VecType, - xl::VecType, - xu::VecType, - rxns::StringVecType, - mets::StringVecType; - check_consistency = false, - ) +$(TYPEDSIGNATURES) """ function add_reactions( m::CoreModel, @@ -245,18 +209,7 @@ function add_reactions( end """ - verify_consistency( - m::CoreModel, - Sp::M, - b::V, - c::V, - xl::B, - xu::B, - names::K, - mets::K, - new_reactions, - new_metabolites, - ) where {M<:MatType,V<:VecType,B<:VecTypeK<:StringVecType} +$(TYPEDSIGNATURES) Check the consistency of given reactions with existing reactions in `m`. @@ -438,11 +391,7 @@ end end """ - change_objective!( - model::CoreModel, - rxn_idxs::Vector{Int}; - weights = ones(length(rxn_idxs)), - ) +$(TYPEDSIGNATURES) Change the objective to reactions at given indexes, optionally specifying their `weights` in the same order. By default, all set weights are 1. @@ -458,7 +407,7 @@ function change_objective!( end """ - change_objective!(model::CoreModel, rxn_idx::Int) +$(TYPEDSIGNATURES) Change objective function of a CoreModel to a single `1` at reaction index `rxn_idx`. @@ -466,11 +415,7 @@ Change objective function of a CoreModel to a single `1` at reaction index change_objective!(model::CoreModel, rxn_idx::Int) = change_objective!(model, [rxn_idx]) """ - change_objective!( - model::CoreModel, - rxn_ids::Vector{String}; - weights = ones(length(rxn_ids)), - ) +$(TYPEDSIGNATURES) Change objective of given reaction IDs, optionally specifying objective `weights` in the same order as `rxn_ids`. By default, all set weights are 1. @@ -487,7 +432,7 @@ function change_objective!( end """ - change_objective!(model::CoreModel, rxn_id::String) +$(TYPEDSIGNATURES) Change objective function of a CoreModel to a single `1` at the given reaction ID. diff --git a/src/reconstruction/CoreModelCoupled.jl b/src/reconstruction/CoreModelCoupled.jl index ad2b4a81e..147cfab89 100644 --- a/src/reconstruction/CoreModelCoupled.jl +++ b/src/reconstruction/CoreModelCoupled.jl @@ -1,13 +1,5 @@ """ - add_reactions( - m::CoreModelCoupled, - s::V1, - b::V2, - c::AbstractFloat, - xl::AbstractFloat, - xu::AbstractFloat; - check_consistency = false, - ) where {V1<:VecType,V2<:VecType} +$(TYPEDSIGNATURES) Add reaction(s) to a `CoreModelCoupled` model `m`. @@ -31,17 +23,7 @@ function add_reactions( end """ - add_reactions( - m::CoreModelCoupled, - s::V1, - b::V2, - c::AbstractFloat, - xl::AbstractFloat, - xu::AbstractFloat, - rxn::String, - mets::K; - check_consistency = false, - ) where {V1<:VecType,V2<:VecType,K<:StringVecType} +$(TYPEDSIGNATURES) """ function add_reactions( @@ -75,16 +57,7 @@ function add_reactions( end """ - add_reactions( - m::CoreModelCoupled, - Sp::M, - b::V, - c::V, - xl::V, - xu::V; - check_consistency = false, - ) where {M<:MatType,V<:VecType} - +$(TYPEDSIGNATURES) """ function add_reactions( m::CoreModelCoupled, @@ -105,10 +78,9 @@ function add_reactions( end """ - add_reactions(m1::CoreModelCoupled, m2::CoreModel; check_consistency = false) +$(TYPEDSIGNATURES) Add all reactions from `m2` to `m1`. - """ function add_reactions(m1::CoreModelCoupled, m2::CoreModel; check_consistency = false) new_lm = add_reactions(m1.lm, m2, check_consistency = check_consistency) @@ -121,18 +93,7 @@ function add_reactions(m1::CoreModelCoupled, m2::CoreModel; check_consistency = end """ - add_reactions( - m::CoreModelCoupled, - Sp::M, - b::V, - c::V, - xl::V, - xu::V, - rxns::K, - mets::K; - check_consistency = false, - ) where {M<:MatType,V<:VecType,K<:StringVecType} - +$(TYPEDSIGNATURES) """ function add_reactions( m::CoreModelCoupled, @@ -165,7 +126,7 @@ function add_reactions( end """ - add_coupling_constraints(m::CoreCoupling, args...) +$(TYPEDSIGNATURES) Add constraints of the following form to CoreCoupling and return the modified model. @@ -179,7 +140,7 @@ function add_coupling_constraints(m::CoreCoupling, args...) end """ - add_coupling_constraints(m::CoreModel, args...) +$(TYPEDSIGNATURES) Add coupling constraints to a plain [`CoreModel`](@ref) (returns a [`CoreModelCoupled`](@ref)). @@ -187,12 +148,7 @@ Add coupling constraints to a plain [`CoreModel`](@ref) (returns a add_coupling_constraints(m::CoreModel, args...) = CoreModelCoupled(m, args...) """ - add_coupling_constraints!( - m::CoreCoupling, - c::VecType, - cl::AbstractFloat, - cu::AbstractFloat, - ) +$(TYPEDSIGNATURES) Overload for adding a single coupling constraint. """ @@ -206,12 +162,7 @@ function add_coupling_constraints!( end """ - add_coupling_constraints!( - m::CoreCoupling, - C::MatType, - cl::V, - cu::V, - ) where {V<:VecType} +$(TYPEDSIGNATURES) In-place add a single coupling constraint in form ``` @@ -237,7 +188,7 @@ function add_coupling_constraints!( end """ - remove_coupling_constraints(m::CoreCoupling, args...) +$(TYPEDSIGNATURES) Remove coupling constraints from the linear model, and return the modified model. Arguments are the same as for in-place version @@ -250,7 +201,7 @@ function remove_coupling_constraints(m::CoreCoupling, args...) end """ - remove_coupling_constraints!(m::CoreCoupling, constraint::Int) +$(TYPEDSIGNATURES) Removes a single coupling constraints from a [`CoreCoupling`](@ref) in-place. """ @@ -259,7 +210,7 @@ remove_coupling_constraints!(m::CoreCoupling, constraint::Int) = """ - remove_coupling_constraints!(m::CoreCoupling, constraints::Vector{Int}) +$(TYPEDSIGNATURES) Removes a set of coupling constraints from a [`CoreCoupling`](@ref) in-place. @@ -273,12 +224,7 @@ function remove_coupling_constraints!(m::CoreCoupling, constraints::Vector{Int}) end """ - change_coupling_bounds!( - model::CoreCoupling, - constraints::Vector{Int}; - cl::V = Float64[], - cu::V = Float64[], - ) where {V<:VecType} +$(TYPEDSIGNATURES) Change the lower and/or upper bounds (`cl` and `cu`) for the given list of coupling constraints. @@ -425,11 +371,7 @@ end end """ - change_objective!( - model::CoreCoupling, - args...; - kwargs..., - ) +$(TYPEDSIGNATURES) Forwards arguments to [`change_objective!`](@ref) of the internal model. """ diff --git a/src/reconstruction/Reaction.jl b/src/reconstruction/Reaction.jl index 11976d25a..3fe897e1b 100644 --- a/src/reconstruction/Reaction.jl +++ b/src/reconstruction/Reaction.jl @@ -1,6 +1,10 @@ - """ +$(TYPEDEF) + A small helper type for constructing reactions inline + +# Fields +$(TYPEDFIELDS) """ struct _Stoichiometry s::Dict{String,Float64} @@ -14,10 +18,11 @@ Base.convert(::Type{_Stoichiometry}, m::Metabolite) = _Stoichiometry(Dict(m.id = Base.:*(a::Real, m::Metabolite) = _Stoichiometry(Dict(m.id => a)) """ - metabolite1 + metabolite2 +$(TYPEDSIGNATURES) -Add 2 groups of [`Metabolite`](@ref)s together to form reactions inline. Use -with `+`, `*`, [`→`](@ref) and similar operators. +Shorthand for `metabolite1 + metabolite2`. Add 2 groups of [`Metabolite`](@ref)s +together to form reactions inline. Use with `+`, `*`, [`→`](@ref) and similar +operators. """ function Base.:+(a::_Stoichiometrizable, b::_Stoichiometrizable) ad = convert(_Stoichiometry, a).s @@ -30,6 +35,9 @@ function Base.:+(a::_Stoichiometrizable, b::_Stoichiometrizable) ) end +""" +$(TYPEDSIGNATURES) +""" function _make_reaction_dict(r, p) rd = convert(_Stoichiometry, r).s pd = convert(_Stoichiometry, p).s @@ -39,26 +47,28 @@ function _make_reaction_dict(r, p) end """ - substrates → products +$(TYPEDSIGNATURES) -Make a forward-only [`Reaction`](@ref) from `substrates` and `products`. +Shorthand for `substrates → products`. Make a forward-only [`Reaction`](@ref) +from `substrates` and `products`. """ →(substrates::Maybe{_Stoichiometrizable}, products::Maybe{_Stoichiometrizable}) = Reaction("", _make_reaction_dict(substrates, products), :forward) """ - substrates ← products +$(TYPEDSIGNATURES) -Make a reverse-only [`Reaction`](@ref) from `substrates` and `products`. +Shorthand for `substrates ← products`. Make a reverse-only [`Reaction`](@ref) +from `substrates` and `products`. """ ←(substrates::Maybe{_Stoichiometrizable}, products::Maybe{_Stoichiometrizable}) = Reaction("", _make_reaction_dict(substrates, products), :reverse) """ - substrates ↔ products +$(TYPEDSIGNATURES) -Make a bidirectional (reversible) [`Reaction`](@ref) from `substrates` and -`products`. +Shorthand for `substrates ↔ products`. Make a bidirectional (reversible) +[`Reaction`](@ref) from `substrates` and `products`. """ ↔(substrates::Maybe{_Stoichiometrizable}, products::Maybe{_Stoichiometrizable}) = Reaction("", _make_reaction_dict(substrates, products), :bidirectional) diff --git a/src/reconstruction/SerializedModel.jl b/src/reconstruction/SerializedModel.jl index c7564c43f..8f9d66f2c 100644 --- a/src/reconstruction/SerializedModel.jl +++ b/src/reconstruction/SerializedModel.jl @@ -10,7 +10,7 @@ @_serialized_change_unwrap remove_reactions """ - unwrap_serialized(model::Serialized) +$(TYPEDSIGNATURES) Returns the model stored in the serialized structure. """ diff --git a/src/reconstruction/StandardModel.jl b/src/reconstruction/StandardModel.jl index c3f6c792f..89c77f8eb 100644 --- a/src/reconstruction/StandardModel.jl +++ b/src/reconstruction/StandardModel.jl @@ -1,5 +1,5 @@ """ - add_reactions!(model::StandardModel, rxns::Vector{Reaction}) +$(TYPEDSIGNATURES) Add `rxns` to `model` based on reaction `id`. """ @@ -11,14 +11,14 @@ function add_reactions!(model::StandardModel, rxns::Vector{Reaction}) end """ - add_reaction!(model::StandardModel, rxn::Reaction) +$(TYPEDSIGNATURES) Add `rxn` to `model` based on reaction `id`. """ add_reaction!(model::StandardModel, rxn::Reaction) = add_reactions!(model, [rxn]) """ - add_metabolites!(model::StandardModel, mets::Vector{Metabolite}) +$(TYPEDSIGNATURES) Add `mets` to `model` based on metabolite `id`. """ @@ -30,14 +30,14 @@ function add_metabolites!(model::StandardModel, mets::Vector{Metabolite}) end """ - add_metabolite!(model::StandardModel, met::Metabolite) +$(TYPEDSIGNATURES) Add `met` to `model` based on metabolite `id`. """ add_metabolite!(model::StandardModel, met::Metabolite) = add_metabolites!(model, [met]) """ - add_genes!(model::StandardModel, genes::Vector{Gene}) +$(TYPEDSIGNATURES) Add `genes` to `model` based on gene `id`. """ @@ -49,14 +49,14 @@ function add_genes!(model::StandardModel, genes::Vector{Gene}) end """ - add_gene!(model::StandardModel, genes::Gene) +$(TYPEDSIGNATURES) Add `gene` to `model` based on gene `id`. """ add_gene!(model::StandardModel, gene::Gene) = add_genes!(model, [gene]) """ - @add_reactions!(model::Symbol, ex::Expr) +$(TYPEDSIGNATURES) Shortcut to add multiple reactions and their lower and upper bounds @@ -110,11 +110,7 @@ macro add_reactions!(model::Symbol, ex::Expr) end """ - remove_genes!( - model::StandardModel, - ids::Vector{String}; - knockout_reactions::Bool = false, - ) +$(TYPEDSIGNATURES) Remove all genes with `ids` from `model`. If `knockout_reactions` is true, then also constrain reactions that require the genes to function to carry zero flux. @@ -144,11 +140,7 @@ function remove_genes!( end """ - remove_gene!( - model::StandardModel, - id::Vector{String}; - knockout_reactions::Bool = false, - ) +$(TYPEDSIGNATURES) Remove gene with `id` from `model`. If `knockout_reactions` is true, then also constrain reactions that require the genes to function to carry zero flux. @@ -244,11 +236,7 @@ end end """ - change_objective!( - model::StandardModel, - rxn_ids::Vector{String}; - weights = ones(length(rxn_ids)), - ) +$(TYPEDSIGNATURES) Change the objective for `model` to reaction(s) with `rxn_ids`, optionally specifying their `weights`. By default, assume equal weights. If no objective exists in model, sets objective. diff --git a/src/reconstruction/community.jl b/src/reconstruction/community.jl index 3271f0eba..a2ca155a5 100644 --- a/src/reconstruction/community.jl +++ b/src/reconstruction/community.jl @@ -1,9 +1,5 @@ """ - add_community_objective!( - community::CoreModel, - objective_mets_weights::Dict{String, Float64}; - objective_id = "community_biomass", - ) +$(TYPEDSIGNATURES) Add an objective column to the `community` model with optional id `objective_id`. Supply a dictionary mapping the string names of the objective metabolites to their weights in @@ -41,11 +37,7 @@ function add_community_objective!( end """ - add_community_objective!( - community::StandardModel, - objective_mets_weights::Dict{String, Float64}; - objective_id = "community_biomass" - ) +$(TYPEDSIGNATURES) Variant of [`add_community_objective!`] that takes a `StandardModel` community model as input. """ @@ -69,11 +61,7 @@ function add_community_objective!( end """ - update_community_objective!( - community::CoreModel, - objective_id::String, - objective_mets_weights::Dict{String, Float64} - ) +$(TYPEDSIGNATURES) Update the weights for the objective column with id `objective_id` in `community` using `objective_mets_weights`, which maps metabolite ids to weights. The current weights are @@ -110,11 +98,7 @@ function update_community_objective!( end """ - update_community_objective!( - community::StandardModel, - objective_id::String, - objective_mets_weights::Dict{String, Float64} - ) +$(TYPEDSIGNATURES) Variant of [`update_community_objective!`] that takes a `StandardModel` community model as input. """ @@ -130,13 +114,7 @@ function update_community_objective!( end """ - join_with_exchanges( - ::Type{CoreModel}, - models::Vector{M}, - exchange_rxn_mets::Dict{String,String}; - biomass_ids = String[], - model_names = String[], - ) where {M<:MetabolicModel} +$(TYPEDSIGNATURES) Return a `CoreModel` representing the community model of `models` joined through their exchange reactions and metabolites in the dictionary `exchange_rxn_mets`, which maps @@ -324,13 +302,7 @@ function join_with_exchanges( end """ - join_with_exchanges( - ::Type{StandardModel}, - models::Vector{M}, - exchange_rxn_mets::Dict{String,String}; - biomass_ids = [], - model_names = [], - )::StandardModel where {M<:MetabolicModel} +$(TYPEDSIGNATURES) A variant of [`join_with_exchanges`](@ref) that returns a `StandardModel`. """ @@ -385,13 +357,7 @@ function join_with_exchanges( end """ - add_model_with_exchanges( - community::CoreModel, - model::MetabolicModel, - exchange_rxn_mets::Dict{String,String}; - model_name = "unknown_species", - biomass_id = nothing, - ) +$(TYPEDSIGNATURES) Add `model` to `community`, which is a pre-existing community model with exchange reactions and metabolites in the dictionary `exchange_rxn_mets`. The `model_name` is appended to each @@ -501,13 +467,7 @@ function add_model_with_exchanges( end """ - add_model_with_exchanges!( - community::StandardModel, - model::MetabolicModel, - exchange_rxn_mets::Dict{String,String}; - model_name = "unknown_species", - biomass_id = nothing, - ) +$(TYPEDSIGNATURES) The `StandardModel` variant of [`add_model_with_exchanges`](@ref), but is in-place. """ @@ -558,13 +518,7 @@ function add_model_with_exchanges!( end """ - add_model_with_exchanges( - community::StandardModel, - model::MetabolicModel, - exchange_rxn_mets::Dict{String,String}; - model_name = "unknown_species", - biomass_id = nothing, - ) +$(TYPEDSIGNATURES) The `StandardModel` variant of [`add_model_with_exchanges`](@ref). Makes a deepcopy of `community` and calls the inplace variant of this function on that copy. diff --git a/src/reconstruction/enzymes.jl b/src/reconstruction/enzymes.jl index 09dac3dc6..6f22cf800 100644 --- a/src/reconstruction/enzymes.jl +++ b/src/reconstruction/enzymes.jl @@ -1,5 +1,5 @@ """ - with_smoment(; kwargs...) +$(TYPEDSIGNATURES) Specifies a model variant which adds extra semantics of the sMOMENT algorithm, giving a [`SMomentModel`](@ref). The arguments are forwarded to @@ -8,7 +8,7 @@ giving a [`SMomentModel`](@ref). The arguments are forwarded to with_smoment(; kwargs...) = model -> make_smoment_model(model; kwargs...) """ - with_gecko(; kwargs...) +$(TYPEDSIGNATURES) Specifies a model variant which adds extra semantics of the Gecko algorithm, giving a [`GeckoModel`](@ref). The arguments are forwarded to diff --git a/src/reconstruction/gapfill_minimum_reactions.jl b/src/reconstruction/gapfill_minimum_reactions.jl index b3383f1f0..e3828e8fb 100644 --- a/src/reconstruction/gapfill_minimum_reactions.jl +++ b/src/reconstruction/gapfill_minimum_reactions.jl @@ -1,13 +1,5 @@ """ - function gapfill_minimum_reactions( - model::MetabolicModel, - universal_reactions::Vector{Reaction}, - optimizer; - objective_bounds = (_constants.tolerance, _constants.default_reaction_bound), - maximum_new_reactions = 5, - weights = fill(1.0, length(universal_reactions)), - modifications = [], - ) +$(TYPEDSIGNATURES) Find a minimal set of reactions from `universal_reactions` that should be added to `model` so that the model has a feasible solution with bounds on its @@ -27,6 +19,28 @@ information in Julia datatypes. To reduce the uncertainty in the MILP solver (and likely reduce the complexity), you may put a limit on the size of the added reaction set in `maximum_new_reactions`. + +# Common pitfalls + +If [`gapfill_minimum_reactions`](@ref) is supposed to generate any reasonable +output, the input model *MUST NOT* be feasible, otherwise there is "no work to +do" and no reactions are added. Notably, an inactive model (the flux is zero) +is considered to be feasible. If this is the case, [`gapfilled_rids`](@ref) +will return an empty vector (as opposed to `nothing`). + +To prevent this, you may need to modify the model to disallow the trivial +solutions (for example by putting a lower bound on reactions that you expect to +be working in the solved model, in a similar manner like how the ATP +maintenance reaction is bounded in E. Coli "core" model). The +`objective_bounds` parameter makes this easier by directly placing a bound on +the objective value of the model, which typically forces the model to be +active. + +The `maximum_new_reactions` parameter may have critical impact on performance +in some solvers, because (in a general worst case) there is +`2^maximum_new_reactions` model variants to be examined. Putting a hard limit +on the reaction count may serve as a heuristic that helps the solver not to +waste too much time solving impractically complex subproblems. """ function gapfill_minimum_reactions( model::MetabolicModel, @@ -104,13 +118,18 @@ function gapfill_minimum_reactions( end """ - gapfilled_mask(opt_model::BitVector) +$(TYPEDSIGNATURES) Get a `BitVector` of added reactions from the model solved by [`gapfill_minimum_reactions`](@ref). The bit indexes correspond to the indexes of `universal_reactions` given to the gapfilling function. In case the model is not solved, this returns `nothing`. +If this function returns a zero vector (instead of `nothing`), it is very +likely that the original model was already feasible and you may need to +constraint it more. Refer to "pitfalls" section in the documentation of +[`gapfill_minimum_reactions`](@ref) for more details. + # Example gapfill_minimum_reactions(myModel, myReactions, Tulip.Optimizer) |> gapfilled_mask @@ -119,11 +138,16 @@ gapfilled_mask(opt_model)::BitVector = is_solved(opt_model) ? value.(opt_model[:y]) .> 0 : nothing """ - gapfilled_rids(opt_model, universal_reactions::Vector{Reaction})::Vector{String} +$(TYPEDSIGNATURES) Utility to extract a short vector of IDs of the reactions added by the gapfilling algorithm. Use with `opt_model` returned from [`gapfill_minimum_reactions`](@ref). + +If this function returns an empty vector (instead of `nothing`), it is very +likely that the original model was already feasible and you may need to +constraint it more. Refer to "pitfalls" section in the documentation of +[`gapfill_minimum_reactions`](@ref) for more details. """ gapfilled_rids(opt_model, universal_reactions::Vector{Reaction}) = let v = gapfilled_mask(opt_model) @@ -131,7 +155,7 @@ gapfilled_rids(opt_model, universal_reactions::Vector{Reaction}) = end """ - gapfilled_rids(universal_reactions::Vector{Reaction}) +$(TYPEDSIGNATURES) Overload of [`gapfilled_rids`](@ref) that can be piped easily. @@ -143,10 +167,7 @@ gapfilled_rids(universal_reactions::Vector{Reaction}) = opt_model -> gapfilled_rids(opt_model, universal_reactions) """ - _universal_stoichiometry( - universal_reactions::Vector{Reaction}, - mids, - ) +$(TYPEDSIGNATURES) A helper function that constructs the stoichiometric matrix of a set of `universal_reactions`. The order of the metabolites is determined with diff --git a/src/reconstruction/modifications/generic.jl b/src/reconstruction/modifications/generic.jl index accac4048..383366500 100644 --- a/src/reconstruction/modifications/generic.jl +++ b/src/reconstruction/modifications/generic.jl @@ -1,5 +1,5 @@ """ - with_changed_bound(args...; kwargs...) +$(TYPEDSIGNATURES) Specifies a model variant that has a new bound set. Forwards arguments to [`change_bound`](@ref). Intended for usage with [`screen`](@ref). @@ -7,7 +7,7 @@ Specifies a model variant that has a new bound set. Forwards arguments to with_changed_bound(args...; kwargs...) = m -> change_bound(m, args...; kwargs...) """ - with_changed_bounds(args...; kwargs...) +$(TYPEDSIGNATURES) Specifies a model variant that has new bounds set. Forwards arguments to [`change_bounds`](@ref). Intended for usage with [`screen`](@ref). @@ -15,7 +15,7 @@ Specifies a model variant that has new bounds set. Forwards arguments to with_changed_bounds(args...; kwargs...) = m -> change_bounds(m, args...; kwargs...) """ - with_removed_metabolite(args...; kwargs...) +$(TYPEDSIGNATURES) Specifies a model variant without a certain metabolite. Forwards arguments to [`remove_metabolite`](@ref). Intended to be used with [`screen`](@ref). @@ -23,7 +23,7 @@ Specifies a model variant without a certain metabolite. Forwards arguments to with_removed_metabolite(args...; kwargs...) = m -> remove_metabolite(m, args...; kwargs...) """ - with_removed_metabolites(args...; kwargs...) +$(TYPEDSIGNATURES) Plural version of [`with_removed_metabolite`](@ref), calls [`remove_metabolites`](@ref) internally. @@ -32,7 +32,7 @@ with_removed_metabolites(args...; kwargs...) = m -> remove_metabolites(m, args...; kwargs...) """ - with_added_reactions(args...; kwargs...) +$(TYPEDSIGNATURES) Specifies a model variant with reactions added. Forwards the arguments to [`add_reactions`](@ref). Intended to be used with [`screen`](@ref). @@ -40,7 +40,7 @@ Specifies a model variant with reactions added. Forwards the arguments to with_added_reactions(args...; kwargs...) = m -> add_reactions(m, args...; kwargs...) """ - with_removed_reaction(args...; kwargs...) +$(TYPEDSIGNATURES) Specifies a model variant without a certain reaction. Forwards arguments to [`remove_reaction`](@ref). Intended to be used with [`screen`](@ref). @@ -48,7 +48,7 @@ Specifies a model variant without a certain reaction. Forwards arguments to with_removed_reaction(args...; kwargs...) = m -> remove_reaction(m, args...; kwargs...) """ - with_removed_reactions(args...; kwargs...) +$(TYPEDSIGNATURES) Plural version of [`with_removed_reaction`](@ref), calls [`remove_reactions`](@ref) internally. diff --git a/test/analysis/minimize_metabolic_adjustment.jl b/test/analysis/minimize_metabolic_adjustment.jl index 2759d1cfc..dbb115992 100644 --- a/test/analysis/minimize_metabolic_adjustment.jl +++ b/test/analysis/minimize_metabolic_adjustment.jl @@ -6,8 +6,8 @@ moma = minimize_metabolic_adjustment_analysis_dict( model, sol, - OSQP.Optimizer; - modifications = [silence, change_optimizer_attribute("polish", true)], + Clarabel.Optimizer; + modifications = [silence], ) @test isapprox(moma["biomass1"], 0.07692307692307691, atol = QP_TEST_TOLERANCE) diff --git a/test/analysis/parsimonious_flux_balance_analysis.jl b/test/analysis/parsimonious_flux_balance_analysis.jl index 341eb6c43..a0775e51f 100644 --- a/test/analysis/parsimonious_flux_balance_analysis.jl +++ b/test/analysis/parsimonious_flux_balance_analysis.jl @@ -8,11 +8,7 @@ change_constraint("EX_m1(e)", lb = -10.0), change_optimizer_attribute("IPM_IterationsLimit", 500), ], - qp_modifications = [ - change_optimizer(OSQP.Optimizer), - change_optimizer_attribute("polish", true), - silence, - ], + qp_modifications = [change_optimizer(Clarabel.Optimizer), silence], ) # The used optimizer doesn't really converge to the same answer everytime diff --git a/test/base/utils/looks_like.jl b/test/base/utils/looks_like.jl index c09966d33..6b88dccb5 100644 --- a/test/base/utils/looks_like.jl +++ b/test/base/utils/looks_like.jl @@ -76,3 +76,11 @@ end @test length(filter(looks_like_biomass_reaction, reactions(model))) == 1 @test length(filter(looks_like_extracellular_metabolite, metabolites(model))) == 20 end + +@testset "Ontology usage in is_xxx_reaction" begin + model = load_model(StandardModel, model_paths["e_coli_core.json"]) + + # macro generated, so only test positive and negative case + @test !is_biomass_reaction(model, "PFL") + @test is_biomass_reaction(model, "BIOMASS_Ecoli_core_w_GAM") +end diff --git a/test/runtests.jl b/test/runtests.jl index 847c7f35e..e19df54f1 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -8,7 +8,7 @@ using JuMP using LinearAlgebra using MAT using OrderedCollections -using OSQP +using Clarabel using SHA using SparseArrays using Statistics @@ -18,7 +18,7 @@ using GLPK # for MILPs # tolerance for comparing analysis results (should be a bit bigger than the # error tolerance in computations) TEST_TOLERANCE = 10 * COBREXA._constants.tolerance -QP_TEST_TOLERANCE = 1e-2 # for OSQP +QP_TEST_TOLERANCE = 1e-2 # for Clarabel print_timing(fn, t) = @info "$(fn) done in $(round(t; digits = 2))s"