# -*- coding: utf-8 -*-
from __future__ import absolute_import
import logging
from itertools import chain
from warnings import warn
from optlang.symbolics import Zero
from cobra.core.solution import get_solution
from cobra.util import solver as sutil
[docs]LOGGER = logging.getLogger(__name__)
[docs]def optimize_minimal_flux(*args, **kwargs):
warn("optimize_minimal_flux has been renamed to pfba", DeprecationWarning)
return pfba(*args, **kwargs)
[docs]def pfba(model, fraction_of_optimum=1.0, objective=None, reactions=None):
"""Perform basic pFBA (parsimonious Enzyme Usage Flux Balance Analysis)
to minimize total flux.
pFBA [1] adds the minimization of all fluxes the the objective of the
model. This approach is motivated by the idea that high fluxes have a
higher enzyme turn-over and that since producing enzymes is costly,
the cell will try to minimize overall flux while still maximizing the
original objective function, e.g. the growth rate.
Parameters
----------
model : cobra.Model
The model
fraction_of_optimum : float, optional
Fraction of optimum which must be maintained. The original objective
reaction is constrained to be greater than maximal_value *
fraction_of_optimum.
objective : dict or model.problem.Objective
A desired objective to use during optimization in addition to the
pFBA objective. Dictionaries (reaction as key, coefficient as value)
can be used for linear objectives.
reactions : iterable
List of reactions or reaction identifiers. Implies `return_frame` to
be true. Only return fluxes for the given reactions. Faster than
fetching all fluxes if only a few are needed.
Returns
-------
cobra.Solution
The solution object to the optimized model with pFBA constraints added.
References
----------
.. [1] Lewis, N. E., Hixson, K. K., Conrad, T. M., Lerman, J. A.,
Charusanti, P., Polpitiya, A. D., Palsson, B. O. (2010). Omic data
from evolved E. coli are consistent with computed optimal growth from
genome-scale models. Molecular Systems Biology, 6,
390. doi:10.1038/msb.2010.47
"""
reactions = (
model.reactions if reactions is None else model.reactions.get_by_any(reactions)
)
with model as m:
add_pfba(m, objective=objective, fraction_of_optimum=fraction_of_optimum)
m.slim_optimize(error_value=None)
solution = get_solution(m, reactions=reactions)
return solution
[docs]def add_pfba(model, objective=None, fraction_of_optimum=1.0):
"""Add pFBA objective
Add objective to minimize the summed flux of all reactions to the
current objective.
See Also
-------
pfba
Parameters
----------
model : cobra.Model
The model to add the objective to
objective :
An objective to set in combination with the pFBA objective.
fraction_of_optimum : float
Fraction of optimum which must be maintained. The original objective
reaction is constrained to be greater than maximal_value *
fraction_of_optimum.
"""
if objective is not None:
model.objective = objective
if model.solver.objective.name == "_pfba_objective":
raise ValueError("The model already has a pFBA objective.")
sutil.fix_objective_as_constraint(model, fraction=fraction_of_optimum)
reaction_variables = (
(rxn.forward_variable, rxn.reverse_variable) for rxn in model.reactions
)
variables = chain(*reaction_variables)
model.objective = model.problem.Objective(
Zero, direction="min", sloppy=True, name="_pfba_objective"
)
model.objective.set_linear_coefficients({v: 1.0 for v in variables})