from cameo import models

model = models.bigg.e_coli_core.copy()
model.solver = "cplex"

from cameo import phenotypic_phase_plane

ppp = phenotypic_phase_plane(model, variables=[model.reactions.BIOMASS_Ecoli_core_w_GAM], objective=model.reactions.EX_ac_e)
ppp.plot()

"""
Explanation: Predict gene knockout strategies
In cameo we have two ways of predicting gene knockout targets: using evolutionary algorithms (OptGene) or linear programming (OptKnock)
End of explanation
"""


from cameo.strain_design.heuristic.evolutionary_based import OptGene

optgene = OptGene(model)

result = optgene.run(target="EX_ac_e", 
                     biomass=model.reactions.BIOMASS_Ecoli_core_w_GAM,
                     substrate=model.metabolites.glc__D_e,
                     max_evaluations=5000,
                     plot=False)

result

result.plot(0)

result.display_on_map(0, "e_coli_core.Core metabolism")

"""
Explanation: OptGene
OptGene is an approach to search for gene or reaction knockouts that relies on evolutionary algorithms[1]. The following image from authors summarizes the OptGene workflow.
<img src="http://static-content.springer.com/image/art%3A10.1186%2F1471-2105-6-308/MediaObjects/12859_2005_Article_632_Fig1_HTML.jpg"/>
Every iteration we keep the best 50 individuals so we can generate a library of targets.
End of explanation
"""


from cameo.strain_design.deterministic.linear_programming import OptKnock

optknock = OptKnock(model, fraction_of_optimum=0.1)

"""
Explanation: OptKnock
OptKnock uses a bi-level mixed integer linear programming approach to identify reaction knockouts[2]:
$$
\begin{matrix}
maximize & \mathit{v_{chemical}} & & (\mathbf{OptKnock}) \
\mathit{y_j} & & & \
subject~to & maximize & \mathit{v_{biomass}} & (\mathbf{Primal}) \
& \mathit{v_j} & & & & \
\end{matrix}\
\begin{bmatrix}
subject~to  & \sum_{j=1}^{M}S_{ij}v_{j} = 0,\ 
& v_{carbon_uptake} = v_{carbon~target}\ 
& v_{apt} \ge v_{apt_main}\ 
& v_{biomass} \ge v_{target_biomass}\ 
& v_{j}^{min} \cdot y_j \le v_j \le v_{j}^{max} \cdot y_j, \forall j \in \boldsymbol{M} \
\end{bmatrix}\
\begin{align}
 & y_j = {0, 1}, & & \forall j \in \boldsymbol{M} & \
 & \sum_{j \in M} (1 - y_j) \le K& & & \
\end{align}
$$
End of explanation
"""


result = optknock.run(max_knockouts=1, target="EX_ac_e", biomass="BIOMASS_Ecoli_core_w_GAM")

result

result.plot(0)

result.display_on_map(0, "e_coli_core.Core metabolism")

"""
Explanation: Running multiple knockouts with OptKnock can take a few hours or days...
End of explanation
"""


