Skip to content

Commit 5f3b7e8

Browse files
committed
fix docs and reference flux
This evening commit is written in honor of GERD, the everyone's fav baby reflux.
1 parent 6673d85 commit 5f3b7e8

File tree

1 file changed

+57
-58
lines changed

1 file changed

+57
-58
lines changed

src/frontend/mmdf.jl

Lines changed: 57 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -18,56 +18,41 @@
1818
$(TYPEDSIGNATURES)
1919
2020
Perform a max-min driving force analysis using `optimizer` on the `model` with
21-
supplied ΔG⁰s in `reaction_standard_gibbs_free_energies`, as defined by Noor, et
22-
al., "Pathway thermodynamics highlights kinetic obstacles in central
23-
metabolism.", PLoS computational biology, 2014.
24-
25-
Optionally, `reference_flux` can be used to set the directions of each reaction
26-
in `model` (all reactions are assumed to proceed forward by default). The
27-
supplied `reference_flux` should be free of internal cycles i.e.
28-
thermodynamically consistent. This optional input is important if a reaction in
29-
`model` normally runs in reverse (negative flux). Note, only the signs are
30-
extracted from this input, so be careful with floating point precision near 0.
31-
32-
The max-min driving force algorithm returns the Gibbs free energy of the
33-
reactions, the concentrations of metabolites and the actual maximum minimum
34-
driving force. The optimization problem solved is:
35-
```
36-
max min -ΔᵣG
37-
s.t. ΔᵣG = ΔrG⁰ + R T S' ln(C)
38-
ΔᵣG ≤ 0
39-
ln(Cₗ) ≤ ln(C) ≤ ln(Cᵤ)
40-
```
41-
where `ΔrG` are the Gibbs energies dissipated by the reactions, R is the gas
42-
constant, T is the temperature, S is the stoichiometry of the model, and C is
43-
the vector of metabolite concentrations (and their respective lower and upper
44-
bounds).
45-
46-
In case no feasible solution exists, `nothing` is returned.
47-
48-
Reactions specified in `ignore_reaction_ids` are internally ignored when
49-
calculating the max-min driving force. Importantly, this should include water
50-
and proton importers.
51-
52-
Since biochemical thermodynamics are assumed, the `proton_metabolites` and `water_metabolites`
53-
need to be specified so that they can be ignored in the calculations.
54-
Effectively this assumes an aqueous environment at constant pH is used.
55-
56-
`constant_concentrations` is used to fix the concentrations of certain
57-
metabolites (such as CO₂) by passing a dictionary mapping metabolite id to its
58-
constant value. `concentration_ratios` is used to specify additional constraints
59-
on metabolite pair concentrations (typically, this is done with various
60-
cofactors, such as the ATP/ADP ratio. For example, you can fix the concentration
61-
of ATP to be always 5× higher than of ADP by specifying `Dict("atp_ratio" =>
62-
("atp_c","adp_c", 5.0))` if these metabolites are called `atp_c` and `adp_c` in
63-
the model. `concentration_lb` and `concentration_ub` set the `Cₗ` and `Cᵤ` in
64-
the optimization problems (these are overwritten by `constant_concentrations` if
65-
supplied).
66-
67-
`T` and `R` can be specified in the corresponding units; defaults are K and
68-
kJ/K/mol. The unit of metabolite concentrations is typically molar, and the ΔG⁰s
69-
have units of kJ/mol. Other units can be used, as long as they are consistent.
70-
As usual, optimizer settings can be changed with `settings`.
21+
supplied reaction standard Gibbs energies in `reaction_standard_gibbs_free_energies`.
22+
23+
The method was described by by: Noor, et al., "Pathway thermodynamics highlights
24+
kinetic obstacles in central metabolism.", PLoS computational biology, 2014.
25+
26+
`reference_flux` sets the directions of each reaction in `model`. The scale of
27+
the values is not important, only the direction is examined (w.r.t.
28+
`reference_flux_atol` tolerance). Ideally, the supplied `reference_flux` should
29+
be completely free of internal cycles, which enables the thermodynamic
30+
consistency. To get the cycle-free flux, you can use
31+
[`loopless_flux_balance_analysis`](@ref) (computationally complex but gives
32+
very good fluxes), [`parsimonious_flux_balance_analysis`](@ref) or
33+
[`linear_parsimonious_flux_balance_analysis`](@ref) (computationally simplest
34+
but the consistency is not guaranteed).
35+
36+
Internally, [`fbc_log_concentration_constraints`](@ref) is used to lay out the
37+
base structure of the problem.
38+
39+
Following arguments are set optionally:
40+
- `water_metabolites`, `proton_metabolites` and `ignored_metabolites` allow to
41+
completely ignore constraints on a part of the metabolite set, which is
42+
explicitly recommended especially for water and protons (since the analyses
43+
generally assume aqueous environment of constant pH)
44+
- `constant_concentrations` can be used to fix the concentrations of the
45+
metabolites
46+
- `concentration_lower_bound` and `concentration_upper_bound` set the default
47+
concentration bounds for all other metabolites
48+
- `concentration ratios` is a dictionary that assigns a tuple of
49+
metabolite-metabolite-concentration ratio constraint names; e.g. ATP/ADP
50+
ratio can be fixed to five-times-more-ATP by setting `concentration_ratios =
51+
Dict("adenosin_ratio" => ("atp", "adp", 5.0))`
52+
- `T` and `R` default to the usual required thermodynamic constraints in the
53+
usual units (K and kJ/K/mol, respectively). These multiply the
54+
log-concentrations to obtain the actual Gibbs energies and thus driving
55+
forces.
7156
"""
7257
function max_min_driving_force_analysis(
7358
model::A.AbstractFBCModel,
@@ -82,13 +67,15 @@ function max_min_driving_force_analysis(
8267
concentration_upper_bound = 1e-1, # M
8368
T = 298.15, # Kelvin
8469
R = 8.31446261815324e-3, # kJ/K/mol
70+
reference_flux_atol = 1e-6,
8571
check_ignored_reactions = missing,
8672
settings = [],
8773
optimizer,
8874
)
8975

90-
# First let's check if all the identifiers are okay because we use quite a
91-
# lot of these.
76+
# First let's just check if all the identifiers are okay because we use
77+
# quite a lot of these; the rest of the function may be a bit cleaner with
78+
# this checked properly.
9279

9380
model_reactions = Set(A.reactions(model))
9481
model_metabolites = Set(A.metabolites(model))
@@ -97,9 +84,10 @@ function max_min_driving_force_analysis(
9784
DomainError(
9885
reaction_standard_gibbs_free_energies,
9986
"unknown reactions referenced by reaction_standard_gibbs_free_energies",
100-
o,
10187
),
10288
)
89+
all(x -> haskey(reaction_standard_gibbs_free_energies, x), keys(reference_flux)) ||
90+
throw(DomainError(reference_flux, "some reactions have no reference flux"))
10391
all(in(model_reactions), keys(reference_flux)) || throw(
10492
DomainError(
10593
reaction_standard_gibbs_free_energies,
@@ -154,9 +142,12 @@ function max_min_driving_force_analysis(
154142
throw(AssertionError("check_ignored_reactions validation failed"))
155143
end
156144

157-
default_bound =
145+
# that was a lot of checking.
146+
147+
default_concentration_bound =
158148
C.Between(log(concentration_lower_bound), log(concentration_upper_bound))
159-
zero_concentration_metabolites = union(
149+
150+
no_concentration_metabolites = union(
160151
Set(Symbol.(water_metabolites)),
161152
Set(Symbol.(proton_metabolites)),
162153
Set(Symbol.(ignored_metabolites)),
@@ -165,14 +156,14 @@ function max_min_driving_force_analysis(
165156
constraints =
166157
fbc_log_concentration_constraints(
167158
model,
168-
concentration_bound = met -> if met in zero_concentration_metabolites
159+
concentration_bound = met -> if met in no_concentration_metabolites
169160
C.EqualTo(0)
170161
else
171162
mid = String(met)
172163
if haskey(constant_concentrations, mid)
173164
C.EqualTo(log(constant_concentrations[mid]))
174165
else
175-
default_bound
166+
default_concentration_bound
176167
end
177168
end,
178169
) + :max_min_driving_force^C.variable()
@@ -181,7 +172,15 @@ function max_min_driving_force_analysis(
181172
let r = Symbol(rid)
182173
r => C.Constraint(
183174
value = dGr0 + (R * T) * constraints.reactant_log_concentrations[r],
184-
bound = C.Between(-Inf, 0),
175+
bound = let rf = reference_flux[rid]
176+
if isapprox(rf, 0.0, atol = reference_flux_atol)
177+
C.EqualTo(0)
178+
elseif rf > 0
179+
C.Between(-Inf, 0)
180+
else
181+
C.Between(0, Inf)
182+
end
183+
end,
185184
)
186185
end for (rid, dGr0) in reaction_standard_gibbs_free_energies
187186
)

0 commit comments

Comments
 (0)