Unverified Commit e861fcd1 authored by St. Elmo's avatar St. Elmo
Browse files

fix enzyme generic mods

parent c300e07c
Pipeline #56510 passed with stages
in 12 minutes and 31 seconds
......@@ -54,11 +54,12 @@ The model wraps another "internal" model, and adds following modifications:
The structure contains fields `columns` that describe the contents of the
coupling columns, `coupling_row_reaction`, `coupling_row_gene_product` and
`coupling_row_mass_group` that describe correspondence of the coupling rows to
original model and determine the coupling bounds, and `inner`, which is the
original wrapped model. Note, `objective` is the objective vector of the model.
Special care needs to be taken to ensure that its length is the sum of
`n_reactions(model)` and `n_genes(model)` when the user modifies it, where
`model` is the GeckoModel in question.
original model and determine the coupling bounds, `gene_row_lookup` that maps
the index of a gene in the inner model to a row in the gene product coupling
matrix, and `inner`, which is the original wrapped model. Note, `objective` is
the objective vector of the model. Special care needs to be taken to ensure that
its length is the sum of `n_reactions(model)` and `n_genes(model)` when the user
modifies it, where `model` is the GeckoModel in question.
Implementation exposes the split reactions (available as `reactions(model)`),
but retains the original "simple" reactions accessible by [`fluxes`](@ref). All
......@@ -112,16 +113,17 @@ Returns the internal reactions in a [`GeckoModel`](@ref) (these may be split
to forward- and reverse-only parts with different isozyme indexes; reactions
IDs are mangled accordingly with suffixes).
"""
reactions(model::GeckoModel) =
let inner_reactions = reactions(model.inner)
[
function reactions(model::GeckoModel)
inner_reactions = reactions(model.inner)
mangeled_reactions = [
_gecko_reaction_name(
inner_reactions[col.reaction_idx],
col.direction,
col.isozyme_idx,
) for col in model.columns
]
end
[mangeled_reactions; genes(model)]
end
"""
n_reactions(model::GeckoModel)
......@@ -129,7 +131,7 @@ reactions(model::GeckoModel) =
Returns the number of all irreversible reactions in `model` as well as the
number of gene products that take part in enzymatic reactions.
"""
n_reactions(model::GeckoModel) = length(model.columns)
n_reactions(model::GeckoModel) = length(model.columns) + n_genes(model)
"""
bounds(model::GeckoModel)
......
......@@ -8,7 +8,7 @@ function that returns a dictionary of solved fluxes.
"""
gene_product_dict(model::GeckoModel, opt_model) =
is_solved(opt_model) ?
Dict(genes(model) .=> value.(opt_model[:x])[(n_reactions(model)+1):end]) : nothing
Dict(genes(model) .=> value.(opt_model[:x])[(end-n_genes(model)+1):end]) : nothing
"""
gene_product_dict(model::GeckoModel)
......@@ -26,7 +26,7 @@ gene_product_mass_group_dict(model::GeckoModel, opt_model) =
is_solved(opt_model) ?
Dict(
grp.group_id => dot(
value.(opt_model[:x])[n_reactions(model).+grp.gene_product_idxs],
value.(opt_model[:x])[(n_reactions(model)-n_genes(model)).+grp.gene_product_idxs],
grp.gene_product_molar_masses,
) for grp in model.coupling_row_mass_group
) : nothing
......
......@@ -50,6 +50,24 @@
@test isapprox(prot_mass, total_gene_product_mass, atol = TEST_TOLERANCE)
@test isapprox(prot_mass, mass_groups["uncategorized"], atol = TEST_TOLERANCE)
# test enzyme objective
growth_lb = rxn_fluxes["BIOMASS_Ecoli_core_w_GAM"]*0.9
opt_model = flux_balance_analysis(
gm,
Tulip.Optimizer;
modifications = [
change_objective(
genes(gm);
weights = [],
sense = COBREXA.MIN_SENSE,
),
change_constraint("BIOMASS_Ecoli_core_w_GAM", lb = growth_lb),
change_optimizer_attribute("IPM_IterationsLimit", 1000)
]
)
mass_groups_min = gene_product_mass_group_dict(gm, opt_model)
@test mass_groups_min["uncategorized"] < mass_groups["uncategorized"]
end
@testset "GECKO small model" begin
......@@ -73,8 +91,10 @@ end
"r6", m4 nothing, 0, 100
end
gs = [Gene("g$i") for i = 1:4]
gs = [Gene("g$i") for i = 1:5]
m.reactions["r2"].grr = [["g5"],]
m.reactions["r3"].grr = [["g1"],]
m.reactions["r4"].grr = [["g1"], ["g2"]]
m.reactions["r5"].grr = [["g3", "g4"]]
m.reactions["r6"].objective_coefficient = 1.0
......@@ -120,4 +140,6 @@ end
@test isapprox(rxn_fluxes["r6"], 3.181818181753438, atol = TEST_TOLERANCE)
@test isapprox(gene_products["g4"], 0.09090909090607537, atol = TEST_TOLERANCE)
@test isapprox(mass_groups["uncategorized"], 0.5, atol = TEST_TOLERANCE)
@test length(genes(gm)) == 4
@test length(genes(gm.inner)) == 5
end
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment