Commit ab630f1e authored by Miroslav Kratochvil's avatar Miroslav Kratochvil
Browse files

remove the unnecessary reaction coupling from sMOMENT

parent 50735009
Pipeline #55065 failed with stages
in 10 minutes and 5 seconds
......@@ -7,13 +7,11 @@ A helper type that describes the contents of [`SMomentModel`](@ref)s.
struct _smoment_column
reaction_idx::Int # number of the corresponding reaction in the inner model
direction::Int # 0 if "as is" and unique, -1 if reverse-only part, 1 if forward-only part
coupling_row::Int # number of row in the coupling (0 if direction==0)
lb::Float64 # must be 0 if the reaction is unidirectional (if direction!=0)
ub::Float64
capacity_required::Float64 # must be 0 for bidirectional reactions (if direction==0)
end
# TODO fix the docstring
"""
struct SMomentModel <: ModelWrapper
......@@ -29,8 +27,6 @@ The model is constructed as follows:
- stoichiometry of the original model is retained as much as possible, but
enzymatic reations are split into forward and reverse parts (marked by a
suffix like `...#forward` and `...#reverse`),
- sums of forward and reverse reaction pair fluxes are constrained accordingly
to the original model,
- stoichiometry is expanded by a virtual metabolite "enzyme capacity" which is
consumed by all enzymatic reactions at a rate given by enzyme mass divided by
the corresponding kcat,
......@@ -40,25 +36,21 @@ The model is constructed as follows:
The `SMomentModel` structure contains a worked-out representation of the
optimization problem atop a wrapped [`MetabolicModel`](@ref), in particular the
separation of certain reactions into unidirectional forward and reverse parts,
the grouping of these reactions together into virtual "arm" reactions constrained
by bounds from the inner model, an "enzyme capacity" required for each
reaction, and the value of the maximum capacity constraint.
an "enzyme capacity" required for each reaction, and the value of the maximum
capacity constraint. Original coupling is retained.
In the structure, field `columns` describes the correspondence of stoichiometry
columns to the stoichiometry and data of the internal wrapped model; field
`coupling_row_reaction` maps the generated coupling constraints to reaction
indexes in the wrapped model, and `total_enzyme_capacity` is the total bound on
the enzyme capacity consumption as specified in sMOMENT algorithm.
columns to the stoichiometry and data of the internal wrapped model, and
`total_enzyme_capacity` is the total bound on the enzyme capacity consumption
as specified in sMOMENT algorithm.
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).
Original coupling is retained.
"""
struct SMomentModel <: ModelWrapper
columns::Vector{_smoment_column}
coupling_row_reaction::Vector{Int}
total_enzyme_capacity::Float64
inner::MetabolicModel
......@@ -130,7 +122,6 @@ enzyme capacity.
"""
coupling(model::SMomentModel) = vcat(
coupling(model.inner) * _smoment_column_reactions(model),
_smoment_reaction_coupling(model),
[col.capacity_required for col in model.columns]',
)
......@@ -141,7 +132,7 @@ Count the coupling constraints in [`SMomentModel`](@ref) (refer to
[`coupling`](@ref) for details).
"""
n_coupling_constraints(model::SMomentModel) =
n_coupling_constraints(model.inner) + length(model.coupling_row_reaction) + 1
n_coupling_constraints(model.inner) + 1
"""
coupling_bounds(model::SMomentModel)
......@@ -149,11 +140,9 @@ n_coupling_constraints(model::SMomentModel) =
The coupling bounds for [`SMomentModel`](@ref) (refer to [`coupling`](@ref) for
details).
"""
function coupling_bounds(model::SMomentModel)
(iclb, icub) = coupling_bounds(model.inner)
(ilb, iub) = bounds(model.inner)
return (
vcat(iclb, ilb[model.coupling_row_reaction], [0.0]),
vcat(icub, iub[model.coupling_row_reaction], [model.total_enzyme_capacity]),
coupling_bounds(model::SMomentModel) = let (iclb, icub) = coupling_bounds(model.inner)
(
vcat(iclb, [0.0]),
vcat(icub, [model.total_enzyme_capacity]),
)
end
......@@ -22,27 +22,6 @@ _smoment_column_reactions(model::SMomentModel) = sparse(
length(model.columns),
)
"""
_smoment_reaction_coupling(model::SMomentModel)
Compute the part of the coupling for [`SMomentModel`](@ref) that limits the
"arm" reactions (which group the individual split unidirectional reactions).
"""
_smoment_reaction_coupling(model::SMomentModel) =
let tmp = [
(col.coupling_row, i, col.direction) for
(i, col) = enumerate(model.columns) if col.direction != 0
]
sparse(
[row for (row, _, _) in tmp],
[col for (_, col, _) in tmp],
[val for (_, _, val) in tmp],
length(model.coupling_row_reaction),
length(model.columns),
)
end
"""
smoment_isozyme_speed(isozyme::Isozyme, gene_product_molar_mass)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment