{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Optimize co-factor swap" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Many metabolic enzymes depend on co-factors to function. Keeping balance between co-factors is important for homeostasis and that balance might interact unfavorable with metabolic engineering. And example of such balance is that between the two similar co-factor pairs NAD+/NADH and NADP+/NADPH. These co-factors are not only similar there are even enzymes that catalyze the same reaction but depend on different co-factors. Enzymes can also be enigneered to change their co-factor preference.\n", "\n", "This opens an opportunity for using co-factor swaps to optimize production of a target metabolite. Figuring out which reactions should be subjected to co-factor swap can be done using the [OptSwap algorithm](http://www.sciencedirect.com/science/article/pii/S1096717614000688). Briefly, the algorithm uses a genetic algorithm to test combinations of reactions to co-factor swap and then reports those that results in higher theoretical maximum yield.\n", "\n", "We have implemented a variant of OptSwap in cameo and here we test it to reproduce the results in that paper for the aerobic yeast metabolism.\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Get the model and import modules." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "\n", "(function(global) {\n", " function now() {\n", " return new Date();\n", " }\n", "\n", " if (typeof (window._bokeh_onload_callbacks) === \"undefined\") {\n", " window._bokeh_onload_callbacks = [];\n", " }\n", "\n", " function run_callbacks() {\n", " window._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n", " delete window._bokeh_onload_callbacks\n", " console.info(\"Bokeh: all callbacks have finished\");\n", " }\n", "\n", " function load_libs(js_urls, callback) {\n", " window._bokeh_onload_callbacks.push(callback);\n", " if (window._bokeh_is_loading > 0) {\n", " console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", " return null;\n", " }\n", " if (js_urls == null || js_urls.length === 0) {\n", " run_callbacks();\n", " return null;\n", " }\n", " console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", " window._bokeh_is_loading = js_urls.length;\n", " for (var i = 0; i < js_urls.length; i++) {\n", " var url = js_urls[i];\n", " var s = document.createElement('script');\n", " s.src = url;\n", " s.async = false;\n", " s.onreadystatechange = s.onload = function() {\n", " window._bokeh_is_loading--;\n", " if (window._bokeh_is_loading === 0) {\n", " console.log(\"Bokeh: all BokehJS libraries loaded\");\n", " run_callbacks()\n", " }\n", " };\n", " s.onerror = function() {\n", " console.warn(\"failed to load library \" + url);\n", " };\n", " console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.getElementsByTagName(\"head\")[0].appendChild(s);\n", " }\n", " };\n", "\n", " var js_urls = ['https://cdn.pydata.org/bokeh/release/bokeh-0.12.0.min.js', 'https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.0.min.js', 'https://cdn.pydata.org/bokeh/release/bokeh-compiler-0.12.0.min.js'];\n", "\n", " var inline_js = [\n", " function(Bokeh) {\n", " Bokeh.set_log_level(\"info\");\n", " },\n", " \n", " function(Bokeh) {\n", " Bokeh.$(\"#7ac44bba-9b1a-4785-9b37-ffb8df6fe99f\").text(\"BokehJS successfully loaded\");\n", " },\n", " function(Bokeh) {\n", " console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-0.12.0.min.css\");\n", " Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-0.12.0.min.css\");\n", " console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.0.min.css\");\n", " Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.0.min.css\");\n", " }\n", " ];\n", "\n", " function run_inline_js() {\n", " for (var i = 0; i < inline_js.length; i++) {\n", " inline_js[i](window.Bokeh);\n", " }\n", " }\n", "\n", " if (window._bokeh_is_loading === 0) {\n", " console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", " run_inline_js();\n", " } else {\n", " load_libs(js_urls, function() {\n", " console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n", " run_inline_js();\n", " });\n", " }\n", "}(this));" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "\n", "(function(global) {\n", " function now() {\n", " return new Date();\n", " }\n", "\n", " if (typeof (window._bokeh_onload_callbacks) === \"undefined\") {\n", " window._bokeh_onload_callbacks = [];\n", " }\n", "\n", " function run_callbacks() {\n", " window._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n", " delete window._bokeh_onload_callbacks\n", " console.info(\"Bokeh: all callbacks have finished\");\n", " }\n", "\n", " function load_libs(js_urls, callback) {\n", " window._bokeh_onload_callbacks.push(callback);\n", " if (window._bokeh_is_loading > 0) {\n", " console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", " return null;\n", " }\n", " if (js_urls == null || js_urls.length === 0) {\n", " run_callbacks();\n", " return null;\n", " }\n", " console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", " window._bokeh_is_loading = js_urls.length;\n", " for (var i = 0; i < js_urls.length; i++) {\n", " var url = js_urls[i];\n", " var s = document.createElement('script');\n", " s.src = url;\n", " s.async = false;\n", " s.onreadystatechange = s.onload = function() {\n", " window._bokeh_is_loading--;\n", " if (window._bokeh_is_loading === 0) {\n", " console.log(\"Bokeh: all BokehJS libraries loaded\");\n", " run_callbacks()\n", " }\n", " };\n", " s.onerror = function() {\n", " console.warn(\"failed to load library \" + url);\n", " };\n", " console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.getElementsByTagName(\"head\")[0].appendChild(s);\n", " }\n", " };\n", "\n", " var js_urls = ['https://cdn.pydata.org/bokeh/release/bokeh-0.12.0.min.js', 'https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.0.min.js', 'https://cdn.pydata.org/bokeh/release/bokeh-compiler-0.12.0.min.js'];\n", "\n", " var inline_js = [\n", " function(Bokeh) {\n", " Bokeh.set_log_level(\"info\");\n", " },\n", " \n", " function(Bokeh) {\n", " Bokeh.$(\"#1a354198-df61-4bcc-9d36-e93c52ecd18b\").text(\"BokehJS successfully loaded\");\n", " },\n", " function(Bokeh) {\n", " console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-0.12.0.min.css\");\n", " Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-0.12.0.min.css\");\n", " console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.0.min.css\");\n", " Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.0.min.css\");\n", " }\n", " ];\n", "\n", " function run_inline_js() {\n", " for (var i = 0; i < inline_js.length; i++) {\n", " inline_js[i](window.Bokeh);\n", " }\n", " }\n", "\n", " if (window._bokeh_is_loading === 0) {\n", " console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", " run_inline_js();\n", " } else {\n", " load_libs(js_urls, function() {\n", " console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n", " run_inline_js();\n", " });\n", " }\n", "}(this));" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from cameo import models\n", "model_orig = models.bigg.iJO1366\n" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from cameo.strain_design.heuristic.evolutionary.optimization import CofactorSwapOptimization\n", "from cameo.strain_design.heuristic.evolutionary.objective_functions import product_yield\n", "from cameo.strain_design.heuristic.evolutionary.objective_functions import biomass_product_coupled_yield\n", "from cameo.util import TimeMachine\n", "from cameo.flux_analysis.analysis import flux_variability_analysis as fva" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We make a copy of the model for easy testing." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": true }, "outputs": [], "source": [ "model = model_orig.copy()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Make model changes as indicated in the paper." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [], "source": [ "for rid in ['FHL', 'CAT', 'SPODM', 'SPODMpp']:\n", " model.reactions.get_by_id(rid).knock_out()\n", "model.reactions.POR5.lower_bound = 0\n", "model.reactions.EX_glc__D_e.lower_bound = -10\n", "model.reactions.EX_o2_e.lower_bound = -10" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [], "source": [ "model.reactions.BIOMASS_Ec_iJO1366_core_53p95M.lower_bound = 0.1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the paper they get 0.77 maximum product yield for l-threonine, which we also get" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "-0.7697175225044568" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model.objective = model.reactions.EX_thr__L_e\n", "(model.solve().f * 4) / (model.reactions.EX_glc__D_e.flux * 6)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's run optswap using the `CofactorSwapOptimization` class in cameo. We use a product-yield function to evaluate how good a solution is, but there are other possibilities like `biomass_coupled_product_yield`.\n", "\n", "GAPD is suggested in the paper as a suitable reactions" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [], "source": [ "py = product_yield(model.reactions.EX_thr__L_e, model.reactions.EX_glc__D_e)\n", "optswap = CofactorSwapOptimization(model=model, objective_function=py)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We also observe GAPD among the best options even though we considered many more reactions than in the original paper" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Starting optimization at Fri, 23 Sep 2016 10:03:41\n" ] }, { "data": { "text/html": [ "\n", "\n", "
\n", "
\n", "
\n", "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stderr", "output_type": "stream", "text": [ "The installed widget Javascript is the wrong version.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Finished after 00:03:20\n" ] }, { "data": { "text/html": [ "\n", "

Result:

\n", "