18
18
$(TYPEDSIGNATURES)
19
19
20
20
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.
71
56
"""
72
57
function max_min_driving_force_analysis (
73
58
model:: A.AbstractFBCModel ,
@@ -82,13 +67,15 @@ function max_min_driving_force_analysis(
82
67
concentration_upper_bound = 1e-1 , # M
83
68
T = 298.15 , # Kelvin
84
69
R = 8.31446261815324e-3 , # kJ/K/mol
70
+ reference_flux_atol = 1e-6 ,
85
71
check_ignored_reactions = missing ,
86
72
settings = [],
87
73
optimizer,
88
74
)
89
75
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.
92
79
93
80
model_reactions = Set (A. reactions (model))
94
81
model_metabolites = Set (A. metabolites (model))
@@ -97,9 +84,10 @@ function max_min_driving_force_analysis(
97
84
DomainError (
98
85
reaction_standard_gibbs_free_energies,
99
86
" unknown reactions referenced by reaction_standard_gibbs_free_energies" ,
100
- o,
101
87
),
102
88
)
89
+ all (x -> haskey (reaction_standard_gibbs_free_energies, x), keys (reference_flux)) ||
90
+ throw (DomainError (reference_flux, " some reactions have no reference flux" ))
103
91
all (in (model_reactions), keys (reference_flux)) || throw (
104
92
DomainError (
105
93
reaction_standard_gibbs_free_energies,
@@ -154,9 +142,12 @@ function max_min_driving_force_analysis(
154
142
throw (AssertionError (" check_ignored_reactions validation failed" ))
155
143
end
156
144
157
- default_bound =
145
+ # that was a lot of checking.
146
+
147
+ default_concentration_bound =
158
148
C. Between (log (concentration_lower_bound), log (concentration_upper_bound))
159
- zero_concentration_metabolites = union (
149
+
150
+ no_concentration_metabolites = union (
160
151
Set (Symbol .(water_metabolites)),
161
152
Set (Symbol .(proton_metabolites)),
162
153
Set (Symbol .(ignored_metabolites)),
@@ -165,14 +156,14 @@ function max_min_driving_force_analysis(
165
156
constraints =
166
157
fbc_log_concentration_constraints (
167
158
model,
168
- concentration_bound = met -> if met in zero_concentration_metabolites
159
+ concentration_bound = met -> if met in no_concentration_metabolites
169
160
C. EqualTo (0 )
170
161
else
171
162
mid = String (met)
172
163
if haskey (constant_concentrations, mid)
173
164
C. EqualTo (log (constant_concentrations[mid]))
174
165
else
175
- default_bound
166
+ default_concentration_bound
176
167
end
177
168
end ,
178
169
) + :max_min_driving_force ^ C. variable ()
@@ -181,7 +172,15 @@ function max_min_driving_force_analysis(
181
172
let r = Symbol (rid)
182
173
r => C. Constraint (
183
174
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 ,
185
184
)
186
185
end for (rid, dGr0) in reaction_standard_gibbs_free_energies
187
186
)
0 commit comments