{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "relative-strip",
   "metadata": {},
   "source": [
    "## A basic strain design tutorial using MEWpy"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "elect-johnson",
   "metadata": {},
   "source": [
    "Let's start by loading our model..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "numerous-senate",
   "metadata": {},
   "outputs": [],
   "source": [
    "from reframed import load_cbmodel\n",
    "\n",
    "model = load_cbmodel(\"models/e_coli_core.xml.gz\", flavor=\"bigg\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "swiss-conspiracy",
   "metadata": {},
   "source": [
    "We will define two optimization objectives:\n",
    "\n",
    "* Maximize the flux of our target reaction (succinate production)\n",
    "* Maximize the Biomass-Product Coupled Yield (finds an optimal trade-off between growth and production)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "experimental-frontier",
   "metadata": {},
   "outputs": [],
   "source": [
    "from mewpy.optimization.evaluation import BPCY, TargetFlux\n",
    "\n",
    "objs = [\n",
    "    TargetFlux(\"R_EX_succ_e\"), \n",
    "    BPCY(model.biomass_reaction, \"R_EX_succ_e\")\n",
    "]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "south-blackberry",
   "metadata": {},
   "source": [
    "Now we define our optimization problem:\n",
    "* Type of modifications we are searching for (reaction knockouts)\n",
    "* Environmental conditions (anaerobic growth)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "peripheral-exercise",
   "metadata": {},
   "outputs": [],
   "source": [
    "from mewpy.problems import RKOProblem\n",
    "\n",
    "anaerobic = {'R_EX_o2_e': (0, 0)}\n",
    "problem = RKOProblem(model, fevaluation=objs, envcond=anaerobic)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "disciplinary-lecture",
   "metadata": {},
   "source": [
    "And now we can run the optimization an evolutionary algorithm (EA)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "excessive-jason",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "from mewpy.optimization import EA\n",
    "\n",
    "solutions = EA(problem, max_generations=100).run()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "streaming-momentum",
   "metadata": {},
   "source": [
    "By default, MEWpy calculates a population of the best 100 solutions.\n",
    "\n",
    "To make our life easier, let's convert the result to a Pandas DataFrame:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "typical-easter",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "\n",
    "get_list = lambda x: [r_id[2:] for r_id in x.values]\n",
    "table = [[get_list(x), len(get_list(x)), x.fitness[0], x.fitness[1]] for x in solutions]\n",
    "df = pd.DataFrame(table, columns=[\"reactions\", \"knockouts\", \"target\", \"BPCY\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "saved-northern",
   "metadata": {},
   "source": [
    "We can now sort the results, for instance by the total number of required knockouts:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "widespread-victoria",
   "metadata": {},
   "outputs": [],
   "source": [
    "df.sort_values(\"knockouts\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "voluntary-steps",
   "metadata": {},
   "source": [
    "We can also look at the trade-off between our two objectives (the so-called Pareto front)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "funded-lightning",
   "metadata": {},
   "outputs": [],
   "source": [
    "df.plot.scatter(\"BPCY\", \"target\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "requested-hostel",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}