Flux variability analysis (FVA)
Here we will use flux_variability_analysis
to analyze the E. coli core model.
As usual, if not already present, download the model and load the required packages. We picked the GLPK solver, but others may work as well:
!isfile("e_coli_core.xml") &&
download("http://bigg.ucsd.edu/static/models/e_coli_core.xml", "e_coli_core.xml")
using COBREXA, GLPK
model = load_model("e_coli_core.xml")
Metabolic model of type SBMLModel sparse([8, 10, 21, 43, 50, 51, 8, 9, 6, 12 … 33, 66, 68, 72, 23, 26, 33, 72, 22, 33], [1, 1, 1, 1, 1, 1, 2, 2, 3, 3 … 93, 93, 93, 93, 94, 94, 94, 94, 95, 95], [-1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0 … 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0], 72, 95) Number of reactions: 95 Number of metabolites: 72
The FVA implementation in flux_variability_analysis
returns maximized and minimized reaction fluxes in a 2-column matrix. The bounds parameter function here (constructed with objective_bounds
) sets that the objective value is allowed to vary by 1% from the optimum found by FBA on the same model:
flux_variability_analysis(model, GLPK.Optimizer; bounds = objective_bounds(0.99))
95×2 Matrix{Float64}: -0.254237 0.0 -0.254237 0.0 -0.381356 0.0 4.8143 7.56006 4.8143 7.56006 -0.381356 0.0 -1.11022e-15 1.7161 1.18233 6.62661 -0.143008 0.0 -0.221432 0.0 ⋮ 0.0 2.28813 1.84464e-15 2.28813 3.88085 1000.0 -6.62661 -1.18233 0.0691339 2.81489 -8.88178e-16 6.8644 0.0691339 2.81489 -0.243197 2.50256 6.16973 8.91549
(You may also use gamma_bounds
.)
Detailed variability analysis with modifications
A dictionary-returning variant in flux_variability_analysis_dict
, returns the result in a slightly more structured way. At the same time, we can specify additional modifications to be applied to the model:
min_fluxes, max_fluxes = flux_variability_analysis_dict(
model,
GLPK.Optimizer;
bounds = objective_bounds(0.99),
modifications = [
change_constraint("R_EX_glc__D_e"; lb = -10, ub = -10),
change_constraint("R_EX_o2_e"; lb = 0.0, ub = 0.0),
],
)
(Dict("R_EX_fum_e" => Dict("R_EX_fum_e" => 0.0, "R_ACONTb" => 0.22607952490472283, "R_GLNS" => 0.053580994084844846, "R_SUCOAS" => 6.225897942841894e-15, "R_TPI" => 9.791564275259212, "R_EX_pi_e" => -0.7708580482593426, "R_PPC" => 0.6004759352738883, "R_O2t" => 1.7763568394002587e-15, "R_G6PDH2r" => 2.438809336803311e-15, "R_TALA" => -0.03748783669056421…), "R_ACONTb" => Dict("R_EX_fum_e" => 0.0, "R_ACONTb" => 0.22607952490472283, "R_GLNS" => 0.053580994084844624, "R_SUCOAS" => 9.383674941524645e-15, "R_TPI" => 9.791564275259212, "R_EX_pi_e" => -0.7708580482593473, "R_PPC" => 0.6004759352738988, "R_O2t" => 2.6645352591003883e-15, "R_G6PDH2r" => 2.1553062906483042e-15, "R_TALA" => -0.03748783669056422…), "R_GLNS" => Dict("R_EX_fum_e" => 0.0, "R_ACONTb" => 0.22607952490472882, "R_GLNS" => 0.053580994084844895, "R_SUCOAS" => 0.0, "R_TPI" => 9.485804275258849, "R_EX_pi_e" => -0.7708580482593624, "R_PPC" => 0.6004759352738828, "R_O2t" => 0.0, "R_G6PDH2r" => 0.9172800000013737, "R_TALA" => 0.2682721633098879…), "R_SUCOAS" => Dict("R_EX_fum_e" => 0.0, "R_ACONTb" => 0.29557043399574195, "R_GLNS" => 0.05358099408484489, "R_SUCOAS" => -0.06949090909101316, "R_TPI" => 9.791564275259306, "R_EX_pi_e" => -0.7708580482593625, "R_PPC" => 0.669966844364897, "R_O2t" => 0.0, "R_G6PDH2r" => -9.39717574588439e-17, "R_TALA" => -0.03748783669057004…), "R_TPI" => Dict("R_EX_fum_e" => 0.0, "R_ACONTb" => 0.22607952490472882, "R_GLNS" => 0.053580994084844895, "R_SUCOAS" => 0.0, "R_TPI" => 9.485804275258849, "R_EX_pi_e" => -0.7708580482593624, "R_PPC" => 0.6004759352738828, "R_O2t" => 0.0, "R_G6PDH2r" => 0.9172800000013737, "R_TALA" => 0.2682721633098879…), "R_EX_pi_e" => Dict("R_EX_fum_e" => 0.0, "R_ACONTb" => 0.22836315646940947, "R_GLNS" => 0.054122216247316675, "R_SUCOAS" => 3.874791485706844e-15, "R_TPI" => 9.789458863898215, "R_EX_pi_e" => -0.7786444931912458, "R_PPC" => 0.6065413487614906, "R_O2t" => 1.7763568394002587e-15, "R_G6PDH2r" => -4.768316294366138e-15, "R_TALA" => -0.03786650170764047…), "R_PPC" => Dict("R_EX_fum_e" => 0.0, "R_ACONTb" => 0.2872315249048204, "R_GLNS" => 0.05358099408484489, "R_SUCOAS" => 0.0, "R_TPI" => 9.791564275259306, "R_EX_pi_e" => -0.7708580482593624, "R_PPC" => 0.6004759352738829, "R_O2t" => 0.0, "R_G6PDH2r" => -9.39717574588439e-17, "R_TALA" => -0.03748783669057004…), "R_O2t" => Dict("R_EX_fum_e" => 0.0, "R_ACONTb" => 0.29254909012221963, "R_GLNS" => 0.05358099408484489, "R_SUCOAS" => 0.0, "R_TPI" => 9.791564275259306, "R_EX_pi_e" => -0.7708580482593625, "R_PPC" => 0.6669455004913749, "R_O2t" => 0.0, "R_G6PDH2r" => -1.879435149176878e-16, "R_TALA" => -0.03748783669057007…), "R_G6PDH2r" => Dict("R_EX_fum_e" => 0.0, "R_ACONTb" => 0.22607952490472105, "R_GLNS" => 0.05358099408484448, "R_SUCOAS" => 4.9960036108132044e-15, "R_TPI" => 9.791564275259217, "R_EX_pi_e" => -0.7708580482593473, "R_PPC" => 0.7915759352734985, "R_O2t" => -1.7763568394002587e-15, "R_G6PDH2r" => -6.240482714761413e-15, "R_TALA" => -0.03748783669056543…), "R_TALA" => Dict("R_EX_fum_e" => 0.0, "R_ACONTb" => 0.22836315646942648, "R_GLNS" => 0.05412221624731889, "R_SUCOAS" => 0.0, "R_TPI" => 9.789458863898286, "R_EX_pi_e" => -0.778644493191287, "R_PPC" => 0.6065413487615077, "R_O2t" => 0.0, "R_G6PDH2r" => 0.0, "R_TALA" => -0.03786650170764705…)…), Dict("R_EX_fum_e" => Dict("R_EX_fum_e" => 0.0, "R_ACONTb" => 0.28723152490482035, "R_GLNS" => 0.05358099408484489, "R_SUCOAS" => 0.0, "R_TPI" => 9.791564275259306, "R_EX_pi_e" => -0.7708580482593624, "R_PPC" => 0.6004759352738829, "R_O2t" => 0.0, "R_G6PDH2r" => 0.0, "R_TALA" => -0.037487836690570014…), "R_ACONTb" => Dict("R_EX_fum_e" => 0.0, "R_ACONTb" => 0.29557043399574195, "R_GLNS" => 0.05358099408484489, "R_SUCOAS" => -0.06949090909101316, "R_TPI" => 9.791564275259306, "R_EX_pi_e" => -0.7708580482593625, "R_PPC" => 0.669966844364897, "R_O2t" => 0.0, "R_G6PDH2r" => -9.39717574588439e-17, "R_TALA" => -0.03748783669057004…), "R_GLNS" => Dict("R_EX_fum_e" => 0.0, "R_ACONTb" => 0.22607952490472868, "R_GLNS" => 0.24468099408513094, "R_SUCOAS" => 0.0, "R_TPI" => 9.791564275259308, "R_EX_pi_e" => -0.7708580482593625, "R_PPC" => 0.6004759352738851, "R_O2t" => 0.0, "R_G6PDH2r" => 2.664535259100375e-16, "R_TALA" => -0.0374878366905699…), "R_SUCOAS" => Dict("R_EX_fum_e" => 0.0, "R_ACONTb" => 0.22607952490472877, "R_GLNS" => 0.05358099408484488, "R_SUCOAS" => 0.0, "R_TPI" => 9.791564275259306, "R_EX_pi_e" => -0.7708580482593625, "R_PPC" => 0.600475935273883, "R_O2t" => 0.0, "R_G6PDH2r" => 0.0, "R_TALA" => -0.03748783669056999…), "R_TPI" => Dict("R_EX_fum_e" => 0.0, "R_ACONTb" => 0.28977952490482417, "R_GLNS" => 0.05358099408484488, "R_SUCOAS" => 0.0, "R_TPI" => 9.791564275259306, "R_EX_pi_e" => -0.7708580482593625, "R_PPC" => 0.6641759352739797, "R_O2t" => 0.0, "R_G6PDH2r" => 0.0, "R_TALA" => -0.03748783669056999…), "R_EX_pi_e" => Dict("R_EX_fum_e" => 0.0, "R_ACONTb" => 0.22607952490472874, "R_GLNS" => 0.05358099408484488, "R_SUCOAS" => 0.0, "R_TPI" => 9.791564275259306, "R_EX_pi_e" => -0.7708580482593625, "R_PPC" => 0.6004759352738848, "R_O2t" => 1.387778780781446e-17, "R_G6PDH2r" => 0.0, "R_TALA" => -0.03748783669056999…), "R_PPC" => Dict("R_EX_fum_e" => 0.0, "R_ACONTb" => 0.22607952490472877, "R_GLNS" => 0.05358099408484488, "R_SUCOAS" => 0.0, "R_TPI" => 9.791564275259306, "R_EX_pi_e" => -0.7708580482593625, "R_PPC" => 0.982675935274456, "R_O2t" => 0.0, "R_G6PDH2r" => 0.0, "R_TALA" => -0.03748783669056999…), "R_O2t" => Dict("R_EX_fum_e" => 0.0, "R_ACONTb" => 0.2897795249048397, "R_GLNS" => 0.053580994084844895, "R_SUCOAS" => 0.0, "R_TPI" => 9.79156427525938, "R_EX_pi_e" => -0.7708580482593625, "R_PPC" => 0.6641759352739937, "R_O2t" => 0.0, "R_G6PDH2r" => -2.2302160118670142e-13, "R_TALA" => -0.03748783669064436…), "R_G6PDH2r" => Dict("R_EX_fum_e" => 0.0, "R_ACONTb" => 0.22607952490472882, "R_GLNS" => 0.05358099408484489, "R_SUCOAS" => 0.0, "R_TPI" => 9.485804275258849, "R_EX_pi_e" => -0.7708580482593624, "R_PPC" => 0.6004759352738829, "R_O2t" => 0.0, "R_G6PDH2r" => 0.9172800000013739, "R_TALA" => 0.26827216330988796…), "R_TALA" => Dict("R_EX_fum_e" => 0.0, "R_ACONTb" => 0.22607952490472877, "R_GLNS" => 0.05358099408484488, "R_SUCOAS" => 0.0, "R_TPI" => 9.485804275258849, "R_EX_pi_e" => -0.7708580482593624, "R_PPC" => 0.6004759352738848, "R_O2t" => 0.0, "R_G6PDH2r" => 0.9172800000013748, "R_TALA" => 0.2682721633098883…)…))
The dictionaries can be easily used to explore the whole state of the model when certain reactions are maximized or minimized. For example, we can take the maximal acetate exchange flux when the acetate exchange is maximized:
max_fluxes["R_EX_ac_e"]["R_EX_ac_e"]
8.51854942518171
We can also check that the modifications really had the desired effect on oxygen consumption:
max_fluxes["R_EX_ac_e"]["R_O2t"]
0.0
...and see how much carbon dioxide would produced under at the given metabolic extreme:
max_fluxes["R_EX_ac_e"]["R_EX_co2_e"]
-0.5654964103694404
Summarizing the flux variability
A convenience function flux_variability_summary
is able to display this information in a nice overview:
flux_variability_summary((min_fluxes, max_fluxes))
Biomass Lower bound Upper bound R_BIOMASS_Ecoli_core_w_GAM: 0.2095 0.2095 Exchange R_EX_h_e: 28.2555 30.7398 R_EX_for_e: 16.2978 17.8266 R_EX_glc__D_e: -10.0 -10.0 R_EX_etoh_e: 8.0419 9.0611 R_EX_ac_e: 7.4484 8.5185 R_EX_h2o_e: -7.1446 -6.3802 R_EX_nh4_e: -1.2063 -1.1426 R_EX_co2_e: -0.5655 1.1544 R_EX_pi_e: -0.7786 -0.7709 R_EX_lac__D_e: 0.0 0.5096 R_EX_acald_e: 0.0 0.3058 R_EX_pyr_e: 0.0 0.2548 R_EX_succ_e: -0.0 0.1911 R_EX_akg_e: 0.0 0.0665 R_EX_glu__L_e: -0.0 0.0637 R_EX_o2_e: -0.0 -0.0 R_EX_fum_e: 0.0 0.0 R_EX_mal__L_e: 0.0 0.0 R_EX_gln__L_e: 0.0 0.0 R_EX_fru_e: 0.0 0.0
Retrieving details about FVA output
Parameter ret
of flux_variability_analysis
can be used to extract specific pieces of information from the individual solved (minimized and maximized) optimization problems. Here we show how to extract the value of biomass "growth" along with the minimized/maximized reaction flux.
First, find the index of biomass reaction in all reactions
biomass_idx = first(indexin(["R_BIOMASS_Ecoli_core_w_GAM"], reactions(model)))
13
Now run the FVA:
vs = flux_variability_analysis(
model,
GLPK.Optimizer;
bounds = objective_bounds(0.50), # objective can vary by up to 50% of the optimum
modifications = [
change_constraint("R_EX_glc__D_e"; lb = -10, ub = -10),
change_constraint("R_EX_o2_e"; lb = 0.0, ub = 0.0),
],
ret = optimized_model -> (
COBREXA.JuMP.objective_value(optimized_model),
COBREXA.JuMP.value(optimized_model[:x][biomass_idx]),
),
)
95×2 Matrix{Tuple{Float64, Float64}}: (-18.3915, 0.105831) (-1.77636e-15, 0.105831) (-15.288, 0.105831) (0.0, 0.105831) (-9.25179, 0.105831) (0.0, 0.105831) (0.114182, 0.105831) (3.4504, 0.105831) (0.114182, 0.105831) (3.4504, 0.105831) (-9.25179, 0.105831) (0.0, 0.105831) (7.18869e-15, 0.105831) (9.555, 0.105831) (3.48454e-15, 0.105831) (3.08393, 0.105831) (-3.09994, 0.105831) (0.0, 0.105831) (-18.3915, 0.105831) (9.54792e-15, 0.105831) ⋮ (0.0, 0.105831) (12.74, 0.105831) (0.0, 0.105831) (12.74, 0.105831) (0.0, 0.105831) (1000.0, 0.105831) (-3.08393, 0.105831) (4.44089e-16, 0.105831) (-0.0378665, 0.211663) (2.62444, 0.105831) (0.0, 0.207557) (20.9246, 0.105831) (-0.0378665, 0.211663) (2.62444, 0.105831) (-0.114277, 0.211663) (2.58623, 0.105831) (7.25136, 0.105831) (9.89473, 0.105831)
This page was generated using Literate.jl.