<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Simulating with FBA
Simulations using flux balance analysis can be solved using Model.optimize(). This will maximize or minimize (maximizing is the default) flux through the objective reactions.
Step1:  Running FBA
Step2:  The Model.optimize() function will return a Solution object. A solution object has several attributes
Step3:  The solvers that can be used with cobrapy are so fast that for many small to mid-size models computing the solution can be even faster than it takes to collect the values from the solver and convert to them python objects. With model.optimize, we gather values for all reactions and metabolites and that can take a significant amount of time if done repeatedly. If we are only interested in the flux value of a single reaction or the objective, it is faster to instead use model.slim_optimize which only does the optimization and returns the objective value leaving it up to you to fetch other values that you may need.
Step4:  Analyzing FBA solutions
Models solved using FBA can be further analyzed by using summary methods, which output printed text to give a quick representation of model behavior. Calling the summary method on the entire model displays information on the input and output behavior of the model, along with the optimized objective.
Step5:  In addition, the input-output behavior of individual metabolites can also be inspected using summary methods. For instance, the following commands can be used to examine the overall redox balance of the model
Step6:  Or to get a sense of the main energy production and consumption reactions
Step7:  Changing the Objectives
The objective function is determined from the objective_coefficient attribute of the objective reaction(s). Generally, a "biomass" function which describes the composition of metabolites which make up a cell is used.
Step8:  Currently in the model, there is only one reaction in the objective (the biomass reaction), with an linear coefficient of 1.
Step9:  The objective function can be changed by assigning Model.objective, which can be a reaction object (or just it's name), or a dict of {Reaction
Step10:  We can also have more complicated objectives including quadratic terms.
Running FVA
FBA will not give always give unique solution, because multiple flux states can achieve the same optimum. FVA (or flux variability analysis) finds the ranges of each metabolic flux at the optimum.
Step11:  Setting parameter fraction_of_optimium=0.90 would give the flux ranges for reactions at 90% optimality.
Step12:  The standard FVA may contain loops, i.e. high absolute flux values that only can be high if they are allowed to participate in loops (a mathematical artifact that cannot happen in vivo). Use the loopless argument to avoid such loops. Below, we can see that FRD7 and SUCDi reactions can participate in loops but that this is avoided when using the looplesss FVA.
Step13:  Running FVA in summary methods
Flux variability analysis can also be embedded in calls to summary methods. For instance, the expected variability in substrate consumption and product formation can be quickly found by
Step14:  Similarly, variability in metabolite mass balances can also be checked with flux variability analysis.
Step15:  In these summary methods, the values are reported as a the center point +/- the range of the FVA solution, calculated from the maximum and minimum values.
Running pFBA
Parsimonious FBA (often written pFBA) finds a flux distribution which gives the optimal growth rate, but minimizes the total sum of flux. This involves solving two sequential linear programs, but is handled transparently by cobrapy. For more details on pFBA, please see Lewis et al. (2010).
Step16:  These functions will likely give completely different objective values, because the objective value shown from pFBA is defined as sum(abs(pfba_solution.fluxes.values)), while the objective value for standard FBA is defined as the weighted flux through the reactions being optimized for (e.g. fba_solution.fluxes["Biomass_Ecoli_core"]).
Both pFBA and FBA should return identical results within solver tolerances for the objective being optimized. E.g. for a FBA problem which maximizes the reaction Biomass_Ecoli_core
Step17:  Running geometric FBA
Geometric FBA finds a unique optimal flux distribution which is central to the range of possible fluxes. For more details on geometric FBA, please see K Smallbone, E Simeonidis (2009).
<ASSISTANT_TASK:>
Python Code:
from cobra.io import load_model
model = load_model("textbook")
Explanation: Simulating with FBA
Simulations using flux balance analysis can be solved using Model.optimize(). This will maximize or minimize (maximizing is the default) flux through the objective reactions.
End of explanation
solution = model.optimize()
print(solution)
Explanation: Running FBA
End of explanation
solution.objective_value
Explanation: The Model.optimize() function will return a Solution object. A solution object has several attributes:
objective_value: the objective value
status: the status from the linear programming solver
fluxes: a pandas series with flux indexed by reaction identifier. The flux for a reaction variable is the difference of the primal values for the forward and reverse reaction variables.
shadow_prices: a pandas series with shadow price indexed by the metabolite identifier.
For example, after the last call to model.optimize(), if the optimization succeeds it's status will be optimal. In case the model is infeasible an error is raised.
End of explanation
%%time
model.optimize().objective_value
%%time
model.slim_optimize()
Explanation: The solvers that can be used with cobrapy are so fast that for many small to mid-size models computing the solution can be even faster than it takes to collect the values from the solver and convert to them python objects. With model.optimize, we gather values for all reactions and metabolites and that can take a significant amount of time if done repeatedly. If we are only interested in the flux value of a single reaction or the objective, it is faster to instead use model.slim_optimize which only does the optimization and returns the objective value leaving it up to you to fetch other values that you may need.
End of explanation
model.summary()
Explanation: Analyzing FBA solutions
Models solved using FBA can be further analyzed by using summary methods, which output printed text to give a quick representation of model behavior. Calling the summary method on the entire model displays information on the input and output behavior of the model, along with the optimized objective.
End of explanation
model.metabolites.nadh_c.summary()
Explanation: In addition, the input-output behavior of individual metabolites can also be inspected using summary methods. For instance, the following commands can be used to examine the overall redox balance of the model
End of explanation
model.metabolites.atp_c.summary()
Explanation: Or to get a sense of the main energy production and consumption reactions
End of explanation
biomass_rxn = model.reactions.get_by_id("Biomass_Ecoli_core")
Explanation: Changing the Objectives
The objective function is determined from the objective_coefficient attribute of the objective reaction(s). Generally, a "biomass" function which describes the composition of metabolites which make up a cell is used.
End of explanation
from cobra.util.solver import linear_reaction_coefficients
linear_reaction_coefficients(model)
Explanation: Currently in the model, there is only one reaction in the objective (the biomass reaction), with an linear coefficient of 1.
End of explanation
# change the objective to ATPM
model.objective = "ATPM"
# The upper bound should be 1000, so that we get
# the actual optimal value
model.reactions.get_by_id("ATPM").upper_bound = 1000.
linear_reaction_coefficients(model)
model.optimize().objective_value
Explanation: The objective function can be changed by assigning Model.objective, which can be a reaction object (or just it's name), or a dict of {Reaction: objective_coefficient}.
End of explanation
from cobra.flux_analysis import flux_variability_analysis
flux_variability_analysis(model, model.reactions[:10])
Explanation: We can also have more complicated objectives including quadratic terms.
Running FVA
FBA will not give always give unique solution, because multiple flux states can achieve the same optimum. FVA (or flux variability analysis) finds the ranges of each metabolic flux at the optimum.
End of explanation
cobra.flux_analysis.flux_variability_analysis(
    model, model.reactions[:10], fraction_of_optimum=0.9)
Explanation: Setting parameter fraction_of_optimium=0.90 would give the flux ranges for reactions at 90% optimality.
End of explanation
loop_reactions = [model.reactions.FRD7, model.reactions.SUCDi]
flux_variability_analysis(model, reaction_list=loop_reactions, loopless=False)
flux_variability_analysis(model, reaction_list=loop_reactions, loopless=True)
Explanation: The standard FVA may contain loops, i.e. high absolute flux values that only can be high if they are allowed to participate in loops (a mathematical artifact that cannot happen in vivo). Use the loopless argument to avoid such loops. Below, we can see that FRD7 and SUCDi reactions can participate in loops but that this is avoided when using the looplesss FVA.
End of explanation
model.optimize()
model.summary(fva=0.95)
Explanation: Running FVA in summary methods
Flux variability analysis can also be embedded in calls to summary methods. For instance, the expected variability in substrate consumption and product formation can be quickly found by
End of explanation
model.metabolites.pyr_c.summary(fva=0.95)
Explanation: Similarly, variability in metabolite mass balances can also be checked with flux variability analysis.
End of explanation
model.objective = 'Biomass_Ecoli_core'
fba_solution = model.optimize()
pfba_solution = cobra.flux_analysis.pfba(model)
Explanation: In these summary methods, the values are reported as a the center point +/- the range of the FVA solution, calculated from the maximum and minimum values.
Running pFBA
Parsimonious FBA (often written pFBA) finds a flux distribution which gives the optimal growth rate, but minimizes the total sum of flux. This involves solving two sequential linear programs, but is handled transparently by cobrapy. For more details on pFBA, please see Lewis et al. (2010).
End of explanation
abs(fba_solution.fluxes["Biomass_Ecoli_core"] - pfba_solution.fluxes[
    "Biomass_Ecoli_core"])
import numpy as np
np.isclose(
    fba_solution.fluxes["Biomass_Ecoli_core"], 
    pfba_solution.fluxes["Biomass_Ecoli_core"]
)
Explanation: These functions will likely give completely different objective values, because the objective value shown from pFBA is defined as sum(abs(pfba_solution.fluxes.values)), while the objective value for standard FBA is defined as the weighted flux through the reactions being optimized for (e.g. fba_solution.fluxes["Biomass_Ecoli_core"]).
Both pFBA and FBA should return identical results within solver tolerances for the objective being optimized. E.g. for a FBA problem which maximizes the reaction Biomass_Ecoli_core:
End of explanation
geometric_fba_sol = cobra.flux_analysis.geometric_fba(model)
geometric_fba_sol
Explanation: Running geometric FBA
Geometric FBA finds a unique optimal flux distribution which is central to the range of possible fluxes. For more details on geometric FBA, please see K Smallbone, E Simeonidis (2009).
End of explanation
<END_TASK>