Commit bdf6d98a authored by Miroslav Kratochvil's avatar Miroslav Kratochvil 🚴
Browse files

consistency: enforce serpent_case

Closes #32
parent 57373df3
......@@ -22,7 +22,7 @@ import Pkg
import SBML # conflict with Reaction struct name
include("banner.jl")
_printBanner()
_print_banner()
# autoloading
const _inc(path...) = include(joinpath(path...))
......
"""
fluxBalanceAnalysis(model::M, optimizer) where {M<:MetabolicModel}
flux_balance_analysis(model::M, optimizer) where {M<:MetabolicModel}
Flux balance analysis solves the following problem for the input `model`:
```
......@@ -8,10 +8,10 @@ s.t. S x = b
xₗ ≤ x ≤ xᵤ
```
Returns a solved model from [`optimizeModel`](@ref).
Returns a solved model from [`optimize_model`](@ref).
"""
fluxBalanceAnalysis(model::M, optimizer) where {M<:MetabolicModel} =
optimizeModel(model, optimizer; sense = MOI.MAX_SENSE)
flux_balance_analysis(model::M, optimizer) where {M<:MetabolicModel} =
optimize_model(model, optimizer; sense = MOI.MAX_SENSE)
"""
fba(model::CobraModel, optimizer; objective_func::Union{Reaction, Array{Reaction, 1}}=Reaction[], weights=Float64[], solver_attributes=Dict{Any, Any}(), constraints=Dict{String, Tuple{Float64,Float64}}())
......@@ -42,7 +42,7 @@ function fba(
sense = MOI.MAX_SENSE,
)
# get core optimization problem
cbm, v, mb, lbcons, ubcons = makeOptimizationModel(model, optimizer, sense = sense)
cbm, v, mb, lbcons, ubcons = make_optimization_model(model, optimizer, sense = sense)
# modify core optimization problem according to user specifications
if !isempty(solver_attributes) # set other attributes
......@@ -86,7 +86,7 @@ function fba(
@objective(cbm, sense, sum(opt_weights[i] * v[i] for i in objective_indices))
else # use default objective
# automatically assigned by makeOptimizationModel
# automatically assigned by make_optimization_model
end
optimize!(cbm)
......
......@@ -43,17 +43,17 @@ function atom_exchange(flux_dict::Dict{String,Float64}, model::CobraModel)
end
"""
get_exchanges(rxndict::Dict{String, Float64}; topN=8, ignorebound=1000.0, verbose=true)
get_exchanges(rxndict::Dict{String, Float64}; top_n=8, ignorebound=1000.0, verbose=true)
Display the topN producing and consuming exchange fluxes.
Set topN to a large number to get all the consuming/producing fluxes.
Display the top_n producing and consuming exchange fluxes.
Set top_n to a large number to get all the consuming/producing fluxes.
Ignores infinite (problem upper/lower bound) fluxes (set with ignorebound).
When `verbose` is false, the output is not printed out.
Return these reactions in two dictionaries: `consuming`, `producing`
"""
function exchange_reactions(
rxndict::Dict{String,Float64};
topN = 8,
top_n = 8,
ignorebound = 1000.0,
verbose = true,
)
......@@ -71,7 +71,7 @@ function exchange_reactions(
consuming = Dict{String,Float64}()
producing = Dict{String,Float64}()
verbose && println("Consuming fluxes:")
for i = 1:min(topN, length(rxndict))
for i = 1:min(top_n, length(rxndict))
if rxndict[rxns[inds_cons[i]]] < -eps()
verbose && println(
rxns[inds_cons[i]],
......@@ -85,7 +85,7 @@ function exchange_reactions(
end
verbose && println("Producing fluxes:")
for i = 1:min(topN, length(rxndict))
for i = 1:min(top_n, length(rxndict))
if rxndict[rxns[inds_prod[i]]] > eps()
verbose && println(
rxns[inds_prod[i]],
......
"""
fluxVariabilityAnalysis(
flux_variability_analysis(
model::LM,
reactions::Vector{Int},
optimizer,
......@@ -25,7 +25,7 @@ scheduled in parallel on `workers`.
Returns a matrix of minima and maxima of size (length(reactions),2).
"""
function fluxVariabilityAnalysis(
function flux_variability_analysis(
model::LM,
reactions::Vector{Int},
optimizer,
......@@ -33,18 +33,18 @@ function fluxVariabilityAnalysis(
gamma::AbstractFloat = 1.0,
)::Matrix{Float64} where {LM<:MetabolicModel}
if any(reactions .< 1) || any(reactions .> nReactions(model))
if any(reactions .< 1) || any(reactions .> n_reactions(model))
throw(DomainError(reactions, "Index exceeds number of reactions."))
end
(optimization_model, x0) = fluxBalanceAnalysis(model, optimizer)
(optimization_model, x0) = flux_balance_analysis(model, optimizer)
Z0 = JuMP.objective_value(optimization_model)
optimization_model = nothing # we won't need this one anymore, so free the memory
# store a JuMP optimization model at all workers
save_model = :(
begin
optmodel, x = COBREXA.makeOptimizationModel($model, $optimizer)
optmodel, x = COBREXA.make_optimization_model($model, $optimizer)
COBREXA._FVA_add_constraint(optmodel, $(objective(model)), x, $Z0, $gamma)
optmodel
end
......@@ -66,7 +66,7 @@ function fluxVariabilityAnalysis(
end
"""
fluxVariabilityAnalysis(
flux_variability_analysis(
model::LM,
optimizer;
gamma::AbstractFloat = 1.0,
......@@ -74,13 +74,13 @@ end
A simpler version of FVA that maximizes and minimizes all reactions in the model.
"""
function fluxVariabilityAnalysis(
function flux_variability_analysis(
model::LM,
optimizer;
gamma::AbstractFloat = 1.0,
) where {LM<:MetabolicModel}
n = nReactions(model)
return fluxVariabilityAnalysis(model, collect(1:n), optimizer; gamma = gamma)
n = n_reactions(model)
return flux_variability_analysis(model, collect(1:n), optimizer; gamma = gamma)
end
......@@ -140,7 +140,7 @@ function fva(
constraints = Dict{String,Tuple{Float64,Float64}}(),
sense = MOI.MAX_SENSE,
)
cbm, v, mb, lbcons, ubcons = makeOptimizationModel(model, optimizer, sense = sense)
cbm, v, mb, lbcons, ubcons = make_optimization_model(model, optimizer, sense = sense)
if !isempty(solver_attributes) # set other attributes
for (k, v) in solver_attributes
......
......@@ -34,14 +34,15 @@ function pfba(
if typeof(optimizer) <: AbstractArray # choose optimizer
cbm, v, mb, lbcons, ubcons =
makeOptimizationModel(model, optimizer[1], sense = sense)
make_optimization_model(model, optimizer[1], sense = sense)
if !isempty(solver_attributes["opt1"]) # set other attributes
for (k, v) in solver_attributes["opt1"]
set_optimizer_attribute(cbm, k, v)
end
end
else # singe optimizer
cbm, v, mb, lbcons, ubcons = makeOptimizationModel(model, optimizer, sense = sense)
cbm, v, mb, lbcons, ubcons =
make_optimization_model(model, optimizer, sense = sense)
if !isempty(solver_attributes) # set other attributes
for (k, v) in solver_attributes
set_optimizer_attribute(cbm, k, v)
......
......@@ -5,7 +5,7 @@ include_dependency(joinpath(_PKG_ROOT_DIR, "Project.toml"))
const COBREXA_VERSION =
VersionNumber(Pkg.TOML.parsefile(joinpath(_PKG_ROOT_DIR, "Project.toml"))["version"])
function _printBanner()
function _print_banner()
c = Base.text_colors
n = c[:normal] # text
b = c[:bold] * c[:blue]
......
......@@ -2,7 +2,7 @@
Convert LinearModel to the JuMP model, place objectives and the equality
constraint.
"""
function makeOptimizationModel(
function make_optimization_model(
model::LM,
optimizer;
sense = MOI.MAX_SENSE,
......@@ -23,12 +23,13 @@ end
"""
Use JuMP to solve an instance of LinearModel
"""
function optimizeModel(
function optimize_model(
model::LM,
optimizer;
sense = MOI.MIN_SENSE,
) where {LM<:MetabolicModel}
optimization_model, x, _, _, _ = makeOptimizationModel(model, optimizer; sense = sense)
optimization_model, x, _, _, _ =
make_optimization_model(model, optimizer; sense = sense)
JuMP.optimize!(optimization_model)
return (optimization_model, x)
end
......@@ -120,7 +120,7 @@ end
reconstruct_model_sbml(file_location::String)
"""
function reconstruct_model_sbml(file_location::String)
# m = readSBML(file_location)
# m = read_sbml(file_location)
# m is now a Model structure with:
# m.reactions
# m.species
......
......@@ -3,25 +3,25 @@ Load a model in MAT (Matlab) format and returns a `LinearModel`
See also: `MAT.jl`
"""
function loadModel(filePath::String, varName::String)
function load_model(file_path::String, var_name::String)
# read file
vars = matread(filePath)
vars = matread(file_path)
if haskey(vars, varName)
return convertToLinearModel(vars[varName])
if haskey(vars, var_name)
return convert_to_linear_model(vars[var_name])
else
error("Variable `$varName` does not exist in the specified MAT file.")
error("Variable `$var_name` does not exist in the specified MAT file.")
end
end
"""
Convert a dictionary read from a MAT file to LinearModel
"""
function convertToLinearModel(model::Dict)
modelKeys = ["S", "b", "c", "ub", "lb"]
function convert_to_linear_model(model::Dict)
model_keys = ["S", "b", "c", "ub", "lb"]
for key in modelKeys
for key in model_keys
if !(key in keys(model))
error("No variable $key found in the MAT file.")
end
......
......@@ -2,4 +2,4 @@
"""
Import a LinearModel from a SBML file
"""
loadSBMLModel(filename::String)::SBMLModel = SBMLModel(SBML.readSBML(filename))
load_sbml_model(filename::String)::SBMLModel = SBMLModel(SBML.readSBML(filename))
......@@ -5,15 +5,15 @@ NB: Does NOT export general inequality constraints (eg coupling)
See also: `MAT.jl`
"""
function writeModel(filePath::String, model::LinearModel, varName::String = "model")
matwrite(filePath, Dict(varName => convertToExportable(model)))
function write_model(file_path::String, model::LinearModel, var_name::String = "model")
matwrite(file_path, Dict(var_name => convert_to_exportable(model)))
end
"""
Convert a LinearModel to exportable format
SparseVectors are not written and read properly, SparseMatrix is okay
"""
function convertToExportable(model::LinearModel)
function convert_to_exportable(model::LinearModel)
return Dict(
"S" => model.S,
"b" => Array(model.b),
......
"""
Add constraints of the following form to a CoupledLinearModel and return a modified one.
The arguments are same as for in-place `addCouplingConstraints!`.
The arguments are same as for in-place `add_coupling_constraints!`.
"""
function addCouplingConstraints(m::CoupledLinearModel, args...)
newLp = deepcopy(m)
addCouplingConstraints!(newLp, args...)
return newLp
function add_coupling_constraints(m::CoupledLinearModel, args...)
new_lp = deepcopy(m)
add_coupling_constraints!(new_lp, args...)
return new_lp
end
"""
Add constraints to a plain `LinearModel` (converts it to the coupled type)
"""
addCouplingConstraints(m::LinearModel, args...) =
addCouplingConstraints(convert(CoupledLinearModel, m), args...)
add_coupling_constraints(m::LinearModel, args...) =
add_coupling_constraints(convert(CoupledLinearModel, m), args...)
"""
In-place add coupling constraints in form
......@@ -21,13 +21,13 @@ In-place add coupling constraints in form
cₗ ≤ C x ≤ cᵤ
```
"""
function addCouplingConstraints!(
function add_coupling_constraints!(
m::CoupledLinearModel,
c::V,
cl::AbstractFloat,
cu::AbstractFloat,
) where {V<:VecType}
return addCouplingConstraints!(
return add_coupling_constraints!(
m,
sparse(reshape(c, (1, length(c)))),
sparse([cl]),
......@@ -36,7 +36,7 @@ function addCouplingConstraints!(
end
function addCouplingConstraints!(
function add_coupling_constraints!(
m::CoupledLinearModel,
C::M,
cl::V,
......@@ -45,7 +45,7 @@ function addCouplingConstraints!(
all([length(cu), length(cl)] .== size(C, 1)) ||
throw(DimensionMismatch("mismatched numbers of constraints"))
size(C, 2) == nReactions(m) ||
size(C, 2) == n_reactions(m) ||
throw(DimensionMismatch("mismatched number of reactions"))
m.C = vcat(m.C, sparse(C))
......@@ -57,54 +57,54 @@ end
"""
Remove coupling constraints from the linear model and return the modified model.
Arguments are the same as for in-place version `removeCouplingConstraints!`.
Arguments are the same as for in-place version `remove_coupling_constraints!`.
"""
function removeCouplingConstraints(m::CoupledLinearModel, args...)
newModel = deepcopy(m)
removeCouplingConstraints!(newModel, args...)
return newModel
function remove_coupling_constraints(m::CoupledLinearModel, args...)
new_model = deepcopy(m)
remove_coupling_constraints!(new_model, args...)
return new_model
end
"""
Removes a set of coupling constraints from a CoupledLinearModel in-place.
"""
function removeCouplingConstraints!(m::CoupledLinearModel, constraint::Int)
removeCouplingConstraints!(m, [constraint])
function remove_coupling_constraints!(m::CoupledLinearModel, constraint::Int)
remove_coupling_constraints!(m, [constraint])
end
function removeCouplingConstraints!(m::CoupledLinearModel, constraints::Vector{Int})
toBeKept = filter(e -> e constraints, 1:nCouplingConstraints(m))
m.C = m.C[toBeKept, :]
m.cl = m.cl[toBeKept]
m.cu = m.cu[toBeKept]
function remove_coupling_constraints!(m::CoupledLinearModel, constraints::Vector{Int})
to_be_kept = filter(e -> e constraints, 1:n_coupling_constraints(m))
m.C = m.C[to_be_kept, :]
m.cl = m.cl[to_be_kept]
m.cu = m.cu[to_be_kept]
end
"""
Change the lower and/or upper bounds ('cl' and 'cu') for given coupling constraints
"""
function changeCouplingBounds!(
function change_coupling_bounds!(
model::CoupledLinearModel,
constraints::Vector{Int};
cl::V = Array{Float64}(undef, 0),
cu::V = Array{Float64}(undef, 0),
) where {V<:VecType}
found = [index 1:nCouplingConstraints(model) for index in constraints]
redConstraints = constraints[found]
found = [index 1:n_coupling_constraints(model) for index in constraints]
red_constraints = constraints[found]
length(redConstraints) == length(unique(redConstraints)) ||
length(red_constraints) == length(unique(red_constraints)) ||
error("`constraints` appears to contain duplicates")
if !isempty(cl)
length(constraints) == length(cl) ||
throw(DimensionMismatch("`constraints` size doesn't match with `cl`"))
model.cl[redConstraints] = cl[found]
model.cl[red_constraints] = cl[found]
end
if !isempty(cu)
length(constraints) == length(cu) ||
throw(DimensionMismatch("`constraints` size doesn't match with `cu`"))
model.cu[redConstraints] = cu[found]
model.cu[red_constraints] = cu[found]
end
end
"""
Adds reactions to the model `m`
"""
function addReactions(
function add_reactions(
m::LinearModel,
s::V1,
b::V2,
c::AbstractFloat,
xl::AbstractFloat,
xu::AbstractFloat;
checkConsistency = false,
check_consistency = false,
) where {V1<:VecType,V2<:VecType}
return addReactions(
return add_reactions(
m,
sparse(reshape(s, (length(s), 1))),
sparse(b),
sparse([c]),
sparse([xl]),
sparse([xu]),
checkConsistency = checkConsistency,
check_consistency = check_consistency,
)
end
function addReactions(
function add_reactions(
m::LinearModel,
s::V1,
b::V2,
......@@ -31,9 +31,9 @@ function addReactions(
xu::AbstractFloat,
rxn::String,
mets::K;
checkConsistency = false,
check_consistency = false,
) where {V1<:VecType,V2<:VecType,K<:StringVecType}
return addReactions(
return add_reactions(
m,
sparse(reshape(s, (length(s), 1))),
sparse(b),
......@@ -42,22 +42,22 @@ function addReactions(
sparse([xu]),
[rxn],
mets,
checkConsistency = checkConsistency,
check_consistency = check_consistency,
)
end
function addReactions(
function add_reactions(
m::LinearModel,
Sp::M,
b::V,
c::V,
xl::V,
xu::V;
checkConsistency = false,
check_consistency = false,
) where {M<:MatType,V<:VecType}
rxns = ["r$x" for x = length(m.rxns)+1:length(m.rxns)+length(xu)]
mets = ["m$x" for x = length(m.mets)+1:length(m.mets)+size(Sp)[1]]
return addReactions(
return add_reactions(
m,
Sp,
b,
......@@ -66,13 +66,13 @@ function addReactions(
xu,
rxns,
mets,
checkConsistency = checkConsistency,
check_consistency = check_consistency,
)
end
function addReactions(m1::LinearModel, m2::LinearModel; checkConsistency = false)
return addReactions(
function add_reactions(m1::LinearModel, m2::LinearModel; check_consistency = false)
return add_reactions(
m1,
m2.S,
m2.b,
......@@ -81,12 +81,12 @@ function addReactions(m1::LinearModel, m2::LinearModel; checkConsistency = false
m2.xu,
m2.rxns,
m2.mets,
checkConsistency = checkConsistency,
check_consistency = check_consistency,
)
end
function addReactions(
function add_reactions(
m::LinearModel,
Sp::M,
b::V,
......@@ -95,7 +95,7 @@ function addReactions(
xu::V,
rxns::K,
mets::K;
checkConsistency = false,
check_consistency = false,
) where {M<:MatType,V<:VecType,K<:StringVecType}
Sp = sparse(Sp)
......@@ -109,48 +109,58 @@ function addReactions(
all(length.([c, xl, xu, rxns]) .== size(Sp, 2)) ||
throw(DimensionMismatch("inconsistent number of reactions"))
newReactions = findall(Bool[!(rxn in m.rxns) for rxn in rxns])
newMetabolites = findall(Bool[!(met in m.mets) for met in mets])
if checkConsistency
(newReactions1, newMetabolites1) =
verifyConsistency(m, Sp, b, c, xl, xu, rxns, mets, newReactions, newMetabolites)
new_reactions = findall(Bool[!(rxn in m.rxns) for rxn in rxns])
new_metabolites = findall(Bool[!(met in m.mets) for met in mets])
if check_consistency
(newReactions1, newMetabolites1) = verify_consistency(
m,
Sp,
b,
c,
xl,
xu,
rxns,
mets,
new_reactions,
new_metabolites,
)
end
newMets = vcat(m.mets, mets[newMetabolites])
new_mets = vcat(m.mets, mets[new_metabolites])
zeroBlock = spzeros(length(newMetabolites), nReactions(m))
extS = vcat(sparse(m.S), zeroBlock)
zero_block = spzeros(length(new_metabolites), n_reactions(m))
ext_s = vcat(sparse(m.S), zero_block)
mapping = [findfirst(isequal(met), newMets) for met in mets]
(I, J, elements) = findnz(sparse(Sp[:, newReactions]))
extSp = spzeros(length(newMets), length(newReactions))
mapping = [findfirst(isequal(met), new_mets) for met in mets]
(I, J, elements) = findnz(sparse(Sp[:, new_reactions]))
ext_sp = spzeros(length(new_mets), length(new_reactions))
for (k, i) in enumerate(I)
newI = mapping[i]
extSp[newI, J[k]] = elements[k]
new_i = mapping[i]
ext_sp[new_i, J[k]] = elements[k]
end
newS = hcat(extS, extSp)
newb = vcat(m.b, b[newMetabolites])
#newC = hcat(m.C, spzeros(size(m.C, 1), length(newReactions)))
newc = vcat(m.c, c[newReactions])
newxl = vcat(m.xl, xl[newReactions])
newxu = vcat(m.xu, xu[newReactions])
newRxns = vcat(m.rxns, rxns[newReactions])
#newLp = LinearModel(newS, newb, newC, m.cl, m.cu, newc, newxl, newxu, newRxns, newMets)
newLp = LinearModel(newS, newb, newc, newxl, newxu, newRxns, newMets)
if checkConsistency
return (newLp, newReactions, newMetabolites)
new_s = hcat(ext_s, ext_sp)
newb = vcat(m.b, b[new_metabolites])
#new_c = hcat(m.C, spzeros(size(m.C, 1), length(new_reactions)))
newc = vcat(m.c, c[new_reactions])
newxl = vcat(m.xl, xl[new_reactions])
newxu = vcat(m.xu, xu[new_reactions])
new_rxns = vcat(m.rxns, rxns[new_reactions])
#new_lp = LinearModel(new_s, newb, new_c, m.cl, m.cu, newc, newxl, newxu, new_rxns, new_mets)
new_lp = LinearModel(new_s, newb, newc, newxl, newxu, new_rxns, new_mets)
if check_consistency
return (new_lp, new_reactions, new_metabolites)
else
return newLp
return new_lp
end
end
"""
Verifies the consistency of a given model
"""
function verifyConsistency(