4. Optimizing thermodynamics
Probabilistic Metabolic Optimization (PMO) allows to run optimization problems using
both flux and thermodynamic constraints. This is done using the PmoProblem
class.
1# Create a PMO problem.
2problem = pta.PmoProblem(model, thermodynamic_space)
3
4# Solve the PMO problem. The object now contains the solution.
5status = problem.solve()
Internally, optimization problems are constructed using CVXPY as interface for different solvers. The CVXPY optimization
variables are problem.m
(the basis of the thermodynamic space),
problem.d
(the direction of the reactions constrained by thermodynamics) and
problem.vs
(the scaled fluxes). For convenience, we provide properties to access
predicted values of the biologically relevant variables v
(fluxes),
log_c
(log-concentrations), drg
(reaction energies), drg0
(standard reaction energies).
4.1. Setting the objective
By default, PMO maximizes the probability of the variables in the thermodynamic space. It is possible to set custom objective (e.g. on fluxes or concentrations) by passing a function creating the objective to the constructor.
1import cvxpy as cp
2objective = lambda p: cp.Minimize(p.vs[26])
3problem = pta.PmoProblem(model, thermodynamic_space, objective=objective)
4.2. Numerics
PMO uses the Big-M formulation to encode the directionality constraints in a MILP problem. While this is an efficient representation, it is also known to have numerical limitations. In particular, PMO may fail or give inaccurate solutions if fluxes and reaction energies span more than nine orders of magnitude.
For this reason, we internally transform the problem to use scaled fluxes and a
full-dimensional basis for the thermodynamic space. While we can automatically compute
optimal values for the Big-M coefficients of fluxes, PMO guidance for the reaction
energies. In practice, we assume that all reaction energies have magnitude between 0.1
and 1000 kJ/mol, which we believe is biologically reasonable. It is possible to change
these values in the constructor of PmoProblem
in case larger or smaller reaction
energies are expected. However, this should be done with care, keeping in mind that it
may lead to numerical issues.
Currently we optimized numerics-related solver parameters for Gurobi only. If you use
other solvers, you may need to use the solver_options
argument to set stricter
feasibility tolerances for your solver.