{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "*This notebook contains material from [PyRosetta](https://RosettaCommons.github.io/PyRosetta);\n", "content is available [on Github](https://github.com/RosettaCommons/PyRosetta.notebooks.git).*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "< [PyData Integration](http://nbviewer.jupyter.org/github/RosettaCommons/PyRosetta.notebooks/blob/master/notebooks/11.00-PyData-integration.ipynb) | [Contents](toc.ipynb) | [Index](index.ipynb) |

\"Open" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Distributed analysis example: exhaustive ddG PSSM\n", "\n", "## Notes\n", "This tutorial will walk you through how to generate an exhaustive ddG PSSM in PyRosetta using the PyData stack for analysis and distributed computing.\n", "\n", "## Citation\n", "[Integration of the Rosetta Suite with the Python Software Stack via reproducible packaging and core programming interfaces for distributed simulation](https://doi.org/10.1002/pro.3721)\n", "\n", "Alexander S. Ford, Brian D. Weitzner, Christopher D. Bahl\n", "\n", "## Manual\n", "Documentation for the `pyrosetta.distributed` namespace can be found here: https://nbviewer.jupyter.org/github/proteininnovation/Rosetta-PyData_Integration/blob/master/distributed_overview.ipynb" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import logging\n", "logging.basicConfig(level=logging.INFO)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import pandas\n", "import seaborn\n", "import matplotlib" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "import Bio.SeqUtils\n", "import Bio.Data.IUPACData as IUPACData" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "import pyrosetta\n", "import pyrosetta.distributed.io as io\n", "import pyrosetta.distributed.packed_pose as packed_pose\n", "import pyrosetta.distributed.tasks.rosetta_scripts as rosetta_scripts\n", "import pyrosetta.distributed.tasks.score as score" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Create test pose, initialize rosetta and pack" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "input_protocol = \"\"\"\n", "\n", " \n", " \n", " \n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "scrolled": true }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:pyrosetta.distributed:maybe_init performing pyrosetta initialization: {'extra_options': '-out:levels all:warning'}\n", "INFO:pyrosetta.rosetta:Found rosetta database at: /home/lexaf/.conda/envs/rosetta_pydata_integration/lib/python3.7/site-packages/pyrosetta/database; using it....\n", "INFO:pyrosetta.rosetta:PyRosetta-4 2019 [Rosetta PyRosetta4.conda.linux.CentOS.python37.Release 2019.22+release.d8f9b4a90a8f2caa32948bacdb6e551591facd5f 2019-05-30T13:47:16] retrieved from: http://www.pyrosetta.org\n", "(C) Copyright Rosetta Commons Member Institutions. Created in JHU by Sergey Lyskov and PyRosetta Team.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "PyRosetta-4 2019 [Rosetta PyRosetta4.conda.linux.CentOS.python37.Release 2019.22+release.d8f9b4a90a8f2caa32948bacdb6e551591facd5f 2019-05-30T13:47:16] retrieved from: http://www.pyrosetta.org\n", "(C) Copyright Rosetta Commons Member Institutions. Created in JHU by Sergey Lyskov and PyRosetta Team.\n" ] } ], "source": [ "input_relax = rosetta_scripts.SingleoutputRosettaScriptsTask(input_protocol)\n", "# Syntax check via setup\n", "input_relax.setup()" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "raw_input_pose = score.ScorePoseTask()(io.pose_from_sequence(\"TESTESTEST\"))\n", "input_pose = input_relax(raw_input_pose)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Perform exhaustive point mutation and pack" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "def mutate_residue(input_pose, res_index, new_aa, res_label = None):\n", " import pyrosetta.rosetta.core.pose as pose\n", " \n", " work_pose = packed_pose.to_pose(input_pose)\n", " \n", " # Annotate strucure with reslabel, for use in downstream protocol\n", " # Add parameters as score, for use in downstream analysis\n", " if res_label:\n", " work_pose.pdb_info().add_reslabel(res_index, res_label)\n", " pose.setPoseExtraScore(work_pose, \"mutation_index\", res_index)\n", " pose.setPoseExtraScore(work_pose, \"mutation_aa\", new_aa)\n", " \n", " if len(new_aa) == 1:\n", " new_aa = str.upper(Bio.SeqUtils.seq3(new_aa))\n", " assert new_aa in map(str.upper, IUPACData.protein_letters_3to1)\n", " \n", " protocol = \"\"\"\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", "\n", " \"\"\" % locals()\n", " \n", " return rosetta_scripts.SingleoutputRosettaScriptsTask(protocol)(work_pose)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "refine = \"\"\"\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n", " \"\"\"\n", " \n", "refine_mutation = rosetta_scripts.SingleoutputRosettaScriptsTask(refine)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Mutation and pack" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Job distribution via `multiprocessing`" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "scrolled": true }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:root:mutating\n" ] } ], "source": [ "from multiprocessing import Pool\n", "import itertools\n", "with pyrosetta.distributed.utility.log.LoggingContext(logging.getLogger(\"rosetta\"), level=logging.WARN):\n", " with Pool() as p:\n", " work = [\n", " (input_pose, i, aa, \"mutation\")\n", " for i, aa in itertools.product(range(1, len(packed_pose.to_pose(input_pose).residues) + 1), IUPACData.protein_letters)\n", " ]\n", " logging.info(\"mutating\")\n", " mutations = p.starmap(mutate_residue, work)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Job distribution via `dask`" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:root:refining\n" ] } ], "source": [ "import dask.distributed\n", "cluster = dask.distributed.LocalCluster(n_workers=2, threads_per_worker=2)\n", "client = dask.distributed.Client(cluster)\n", "\n", "refinement_tasks = [client.submit(refine_mutation, mutant) for mutant in mutations]\n", "logging.info(\"refining\")\n", "refinements = [task.result() for task in refinement_tasks]\n", "\n", "client.close()\n", "cluster.close()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Analysis of delta score" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "scrolled": false }, "outputs": [], "source": [ "result_frame = pandas.DataFrame.from_records(packed_pose.to_dict(refinements))\n", "result_frame[\"delta_total_score\"] = result_frame[\"total_score\"] - input_pose.scores[\"total_score\"] \n", "result_frame[\"mutation_index\"] = list(map(int, result_frame[\"mutation_index\"]))" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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qMgaN25cjBs3LiIiTj755Lj55pvjqKOO2ivBAAAAAAAAqGwtKrI+7KmnniplDgAAAAAAAGii6CLrw9avXx9btmzZ4XiPHj1KsTwAAAAAAAAVaI+KrNmzZ8ePf/zj2LBhw07PL126tNk1Lr300t2+X5Ikceutt+729QAAAAAAAOy7ii6yHnjggbj99tvjoosuiptuuikuvfTSKBQK8fDDD0fbtm3joosu2q11nn766ejQoUP079+/2CgAAAAAAAD7nCSfSztC5hVdZN17771xySWXNBZZp5xySgwYMCAuu+yyGD9+fLzzzju7tc6wYcPiN7/5Tbzxxhtx+umnR01NTfTt27fYWAAAAAAAAJSJoqu+P/3pT3HMMcdELve3JbZt2xYREe3atYtJkybFfffdt1vr3H777fHMM8/E5MmTY/HixXHmmWfG2LFj47bbbovVq1cXGw8AAAAAACDTknwutR/7iqKTVlX9bZgrSZLYb7/94s0332w817lz51izZs1ur9W5c+cYN25c3HvvvfHkk09GTU1N1NbWxsiRI2PcuHHxxBNPFBsTAAAAAACAfVTRRdZhhx3WWF4NHDgw7r///ti2bVvU19fHvHnzomfPnkWt27Nnz7jkkkti3rx5ceGFF8YLL7wQDz/8cLExAQAAAAAA2EcV/Y6s4cOHx/PPPx9nnnlmXHzxxTF58uQYMmRI5PP52Lx5c1x//fUtXnP79u3xP//zPzF//vz45S9/GR06dIhx48bFF77whWJjAgAAAAAAsI8qusiaMmVK48+PO+64+OlPfxqPPvpoJEkSI0aMiKFDh+72Wr/73e9i/vz58fjjj0d9fX2MGjUqbr755jj++OMb38EFAAAAAABAZSm6yPp7gwYNikGDBrX4+0aMGBHvvPNODB8+PGbOnBknn3xyVFdXlyoWAAAAAABAJiWGeZpVdJHVr1+/mDdv3k7Lq5deeinOOeecWLp0abPrrFmzJqqqquLZZ5+NX//61x95bZIksXjx4mIjAwAAAAAAsA8pusgqFAq7PNfQ0BBJkuzWOh9+RCEAAAAAAAB8oGSPFvywl19+OTp27Lhb1yqyAAAAAAAA2JkWFVl33XVX3H333RHxt8f8XX755Tu8z6quri7efvvtOPXUU0uXEgAAAAAAgIrToiKra9eu8YlPfCIiIt54443o1atXdOrUqck11dXV8clPfjImTJhQupQAAAAAAABlJsnn0o6QeS0qsmpqaqKmpiYiIs4///z49re/HX369NkrwQAAAAAAAKhsRb8j68c//nEpcwAAAAAAAEATRRdZzz//fLPXDBkypNjl95p81x5pR6CM1OXbph2BMlOVb5N2BMrM9jCeDmRXVdui/zoCO2XfA7LO3kepFXL5tCMAFWjBggVRW1sbL7/8cmzcuDF69eoVX/7yl+NLX/pS5HL//5/JFy1aFDfeeGMsX748DjrooJg4cWKMHz++xfcrevc8//zzI0mSj7xm6dKlxS4PAAAAAABAxtx5553Ro0ePuOqqq6Jr167xu9/9Lq677rpYtWpVXH311RER8fvf/z6++tWvxuc///mYMWNGLFmyJL773e9GdXV1nHPOOS26X9FF1t13373DsXfeeScWLlwYS5YsiWuvvbbYpQEAAAAAAMpekt/3niowZ86c6NKlS+PXQ4cOjc2bN8c999wT06ZNi+rq6rjllluif//+cf311zde89e//jVmzZoVZ599dpPJreYUXWR9+tOf3unxU089Na699tp45plnYvjw4cUuDwAAAAAAQMZ8uMT6QL9+/aKuri42bNgQBxxwQPz2t7+Nr3/9602uGTt2bNx3333xyiuvxNFHH73b99srD+Y95ZRTYsaMGfEv//Ive2N5AAAAAAAA9sDIkSM/8vzChQt3e63FixfHAQccEF27do2VK1fGtm3bonfv3k2uOfLIIyMiYvny5S0qsvbKzNqmTZti69ate2NpAAAAAAAAMuLFF1+Mn/3sZ3HBBRdEPp+PjRs3RkREp06dmlz3wdcfnN9dRU9krV69eodjW7dujVdffTV+8IMfxDHHHFPs0gAAAAAAAOxFLZm42pV169bFFVdcEQMHDoyLLrqoybkkSXb6Pbs6vitFF1knn3zyTm9WKBTiiCOOiGuvvbbYpQEAAAAAAMpektsrD85rFe+++25cdNFF0a5du7j11lujTZs2ERGx//77R8SOk1ebNm2KiB0ntZpTdJF1/fXX71BktW3bNnr27BkDBw6M3D784QMAAAAAALBzdXV1cdlll8Vbb70V8+bNi86dOzeeO/TQQ6NNmzaxYsWKGD58eOPxP/zhDxER0adPnxbdq+gi66yzzir2WwEAAAAAANgHbd++Pb72ta/FsmXL4ic/+Un07Nmzyfnq6uoY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9eoVI0eOjFWrViUdjSpizZo1cdxxx0Xr1q3j3XffTToOldCkSZOidevWW9xuu+22pKNRyU2cODFOPvnk6NChQ3Tp0iUuuOCCpCNRSfXv33+rP6dat24dzzzzTNLxqIReeOGFOOOMM6KwsDC6du0aQ4cOjYULFyYdi0rsxRdfjFNPPTUOPfTQ6NatW9x9992xadOmpGNRSWzve5uTJ0+O733ve9GhQ4fo06dPPPvssxWcFNhRNZIOQHrMnz8/Zs6cGQUFBVFaWhrZbDbpSFRiv/3tb2O//faLa665JvbZZ5+YNWtW3HzzzfHJJ5/Etddem3Q8KqGVK1dGx44dY+DAgVG/fv2YP39+3HPPPTF//vx4+OGHk45HFXDffff5I5mcePDBB2OvvfYqu/+tb30rwTRUdvfcc0+MGzcuLrjggigoKIiVK1fGyy+/nHQsKqnhw4fH6tWry2175JFH4vnnn48uXboklIrK6tVXX42hQ4fGySefHJdddlkUFxdHUVFRnHvuufHMM8/EnnvumXREKpm33norLrroojjppJPiiiuuiAULFsSdd94Z69at8z4C22V73tt87rnn4rrrrovBgwfH0UcfHS+88EJcfvnlsddee8UxxxyTQGpge2Sy2gr+T2lpaeTl/XNI77rrrov33nsvpk6dmnAqKqtly5ZFo0aNym0bOXJkPPHEE/HGG29ErVq1EkpGVTJhwoS44YYb4k9/+pM3itklCxYsiNNPPz2uvfbaGD58ePzud7+LDh06JB2LSmbSpEkxbNiweO2117ZYA2FnLFiwIPr27Rv333+/N1bYbXr16hUtW7aM+++/P+koVDI///nP47XXXovp06dHJpOJiIh33nknzjjjjLj//vujW7duCSekshk0aFAsX748Jk2aVLbtoYceijvvvDNeeumlaNy4cYLpqAy2573N3r17R6tWreKuu+4q2zZo0KBYtWpVTJgwoULzAtvPqQUps/kHPeTC1t7Aa9u2bXz11VexYsWKBBJRFTVs2DAiIkpKShJOQmV38803x49+9KM46KCDko4CUGbSpEnRrFkzJRa7zdy5c2PRokXRt2/fpKNQCZWUlMQee+xRVmJFRLmJZNhRH3zwwRZr3rHHHhsbN26MP//5zwmlojLZ1nubn3zySSxcuHCLUw726dMn3nnnnVi2bNnujAfsAs0FUGHmzJkTDRs2jH322SfpKFRimzZtiq+++ir+8pe/xL333hs9evSI/fffP+lYVGLPPfdczJs3L4YMGZJ0FKqIPn36RNu2baNXr14xduxYp6xkp7399tvRqlWruPfee6NLly5x6KGHxk9+8pP44IMPko5GFTF16tSoW7du9OrVK+koVEKnn356LFy4MB599NEoLi6ORYsWxa9//eto2bKlU1WyU7766quoWbNmuW2bz+ayYMGCJCJRxWy+hl+LFi3KbW/ZsmVks1nX+IMUc40soEK8++67MWnSpBgyZEjk5+cnHYdKrEePHvH5559HxD8/nXfHHXcknIjKbN26dfGrX/0qrrjiCtdxYJc1adIkLr744igoKIhMJhMzZsyIUaNGxeeffx433nhj0vGohJYsWRJ/+ctfYv78+fGLX/wiatasWXb9meeffz7q16+fdEQqsZKSknjuueeiV69eUa9evaTjUAkdeeSRUVRUFFdeeWWMGDEiIiIOPvjgePjhh51Knp1y4IEHxjvvvFNu21tvvRUR/7xmMuyqzf+Pvv47VIMGDco9DqSPIgvY7ZYsWRKXXHJJdOjQIc4///yk41DJ3X///bF27dr46KOP4r777osLLrggfvvb3ypI2SmjR4+OffbZJ0477bSko1AFHHvssXHssceW3T/mmGOidu3a8cgjj8QFF1wQTZs2TTAdlVE2m421a9fGPffcE4ccckhERLRv3z569eoVTz75pN+r2CWvvPJKLF26dIvTK8H2mjt3blx99dXxwx/+MHr27BmrV6+OMWPGxPnnnx9PPPGEDwmxw/r16xfDhg2LRx55JH7wgx/ERx99FKNGjYr8/Pxyp7CEXfX1/0/ZbHar24H0cGpBYLdatWpVnH/++VGnTp0YPXr0FqcJgB3Vpk2bKCwsjDPPPDOKiopi1qxZ8cc//jHpWFRCixcvjocffjguueSSWL16dRQXF8fatWsjImLt2rWxZs2ahBNSFfTu3Ts2bdrkVHDslAYNGkTjxo3LSqyIiKZNm0aLFi3io48+SjAZVcHUqVOjYcOGrsHGThsxYkQcddRR8fOf/zy6dOkSJ5xwQjzwwAPxt7/9LSZOnJh0PCqhU089Nc4999y49dZbo3PnznHOOefEj370o2jQoEE0adIk6XhUAd80eVVcXBwRW05qAelhIgvYbb766qu48MIL48svv4wnn3wy9t5776QjUcW0bds28vPz4+OPP046CpXQokWLYuPGjTF48OAtHhswYEAUFBTEhAkTEkgG8E8tW7aMf/zjH1tsz2az27yYOfw769evj+nTp0ffvn190IydtmDBgujZs2e5bY0aNYqmTZv6/Zydkslk4rrrroshQ4bE4sWLY7/99ouSkpK48847o6CgIOl4VAGbr421cOHCaNmyZdn2BQsWRCaT2eLaWUB6KLKA3aKkpCQuvfTSmDdvXjz22GOx//77Jx2JKujNN9+MTZs2xXe+852ko1AJtW3bNsaPH19u2wcffBAjR46MX/ziF9GhQ4eEklGVTJs2LfLz86Ndu3ZJR6ES6t69e0yePDn++te/RqtWrSIi4vPPP4+FCxc6JSq7ZMaMGbFmzZro27dv0lGoxPbbb7/4y1/+Um7bkiVL4osvvvD3H7tkr732ijZt2kRExF133RX7779/dO3aNeFUVAXNmjWLFi1axLRp0+KEE04o2z516tQ47LDDolGjRgmmA/4dRRZl1q1bFzNnzoyIf55uafXq1fHcc89FRESnTp38MGeH/PKXv4wXX3wxrr766li/fn3ZBVoj/nkBYOdLZ0cNHTo0Dj300GjdunXUqVMn5s2bFw8++GC0bt06jj/++KTjUQnVr18/OnfuvNXH2rdvH+3bt6/gRFR2gwYNiqOOOqqscJg+fXpMmDAhBgwY4HQ47JQTTjgh2rdvHxdffHFceumlUatWrbj33nujUaNGceaZZyYdj0rs6aefjv322y+OOOKIpKNQifXr1y9uuumm+OUvfxm9evWK4uLiGDt2bNSrVy9OPvnkpONRCb3zzjsxe/bsaNu2baxfvz5mzJgRf/jDH+KBBx5wTWS2y/a8t3nJJZfE5ZdfHs2bN4+uXbvG9OnT45VXXokHH3wwyejANmSym69mR7W3aNGi6NWr11YfGz9+/De+2Qdb07Nnz1i8ePFWH/P/iZ1x//33x7Rp0+Ljjz+ObDYb+++/f5xwwgkxaNAgxSg5M2vWrBgwYED87ne/M5HFDhsxYkS8/PLL8dlnn0VpaWkceOCBccYZZ0T//v1dOJqdtnTp0rjlllti5syZUVJSEkceeWQMGzbMqW/YaStXroyjjz46Bg4cGFdffXXScajEstlsTJgwIR5//PH4+OOPo169etGhQ4e4/PLLo3Xr1knHoxL64IMPYvjw4TF//vyIiCgoKIhLL700OnbsmHAyKovtfW9z8uTJMWbMmFi8eHEccMABMXTo0Ojdu3dFRgV2kCILAAAAAACAVHKFYAAAAAAAAFJJkQUAAAAAAEAqKbIAAAAAAABIJUUWAAAAAAAAqaTIAgAAAAAAIJUUWQAAAAAAAKSSIgsAAAAAAIBUUmQBAAAAAACQSoosAACoJp5++ukYN27cLu3jP//zP2PSpElbbF+0aFG0bt16q49VpEmTJkXr1q1j0aJFOdvnrFmzonXr1jFr1qyc7RMAAIDto8gCAIBqYurUqTF+/Phd2scTTzwRkydP3mJ706ZN48knn4zu3bvv0v53Vffu3ePJJ5+Mpk2bJpoDAACA3KiRdAAAAKDyq1WrVhx++OFJx4hGjRpFo0aNko4BAABAjpjIAgCAhN1zzz3RunXrmDdvXlxyySVxxBFHRKdOnWLkyJFRUlISCxcujEGDBkXHjh2jZ8+e8cADD5R97TedSu/rp8Pr379/vPTSS7F48eJo3bp12W2zoqKiOOOMM6JTp05RWFgYp556akycODGy2WzZc3r27Bnz58+P2bNnl319z549I+KbTy34xhtvxMCBA6Njx45RUFAQP/rRj+Kll14q95zN38P//M//xPDhw6Nz587RuXPnGDp0aHz++ec79Fpu7fXo379/9OnTJ95555348Y9/HAUFBdGrV6+4//77o7S0tNzXL1iwIAYNGhQFBQXRuXPnuPHGG2PNmjVbPdarr74aAwcOjMLCwrLv7bXXXit7/KuvvopTTjklTjjhhFi1alXZ9iVLlsTRRx8d/fv3j02bNu3Q9wcAAFDdKLIAACAlLrvssmjTpk3cc889ccYZZ8S4ceNi5MiRMWTIkOjevXvce++90blz57jtttvi+eef36F9Dx8+PAoLC6NJkybx5JNPlt02W7x4cZx11lkxatSoKCoqihNOOCFGjBgR9957b9lzioqKolmzZtGuXbuyry8qKvrGY86ePTvOOeecWLVqVdx8881x++23xx577BEXXHBBTJs2bYvnX3/99VGzZs24/fbb46qrrorZs2fH1VdfvUPf5zdZsmRJXH311XHyySfH6NGj47jjjovbb789nnrqqbLnfPnll9G/f/+YP39+DB8+PG699dZYu3Zt3HTTTVvs7w9/+EOcd955seeee8avf/3rGDVqVDRs2DAGDRpUVmbVrl07Ro0aFUuXLo2f/exnERFRWloaV111VWSz2bj99tsjPz8/J98fAABAVeXUggAAkBJnnXVWnHvuuRER0bVr13jllVfiscceKyuWIiI6deoUL730Ujz99NPx3e9+d7v3ffDBB0f9+vW/8RSAI0eOLPt3aWlpdOrUKbLZbIwfPz6GDBkSmUwm2rVrF3Xq1Ik999xzu04jePvtt0f9+vXj0UcfjT322CMiInr06BGnnHJK/PrXv47evXtHJpMpe/6xxx4b119/fdn9lStXxm9+85tYsmRJNGnSZLu/161ZsWJFPPDAA3HYYYdFxD9f39mzZ8fTTz8dp5xySkREjBs3LpYtWxZTpkyJNm3aREREt27d4rzzzot//OMfZftat25d3HLLLWXl4mbdunWLU089Ne64446YOHFiREQceOCBMWLEiLj88svjkUceiZUrV8bs2bPjwQcfdB0vAACA7WAiCwAAUqJ79+7l7rds2TIymUwcd9xxZdtq1KgRBxxwQCxevDinx37ttdfinHPOiSOOOCLatm0b7du3j7vvvjtWrFgRS5cu3eH9rV27Nt5+++048cQTy0qsiIj8/Pw4+eST47PPPouFCxeW+5rNpyncbPOpD/+1RNpZTZo0KSux/nX//7rvWbNmxSGHHFJWYm3Wp0+fcvfffPPNWLFiRZx66qlRUlJSdistLY1jjz023n333Vi7dm3Z80866aQ4++yz4ze/+U2MHj06fvrTn8bRRx+9y98TAABAdWAiCwAAUqJBgwbl7tesWTPq1q0btWvX3mL76tWrc3bcd955JwYNGhSdOnWKm266Kfbdd9+oWbNmvPDCCzFmzJhYv379Du+zuLg4stnsViepNk8irVixotz2hg0blrtfq1atiIidOv7XfX3fm/f/1Vdfld1fsWJFfOc739nieY0bNy53/8svv4yIiEsuueQbj7dy5cqoV69e2f0f/vCH8cQTT0TNmjVjwIABO5wfAACgulJkAQBAJba55NqwYUO57cuXL9/ufTzzzDNRo0aNGDt2bLnS7IUXXtjpXPXr14+8vLxYsmTJFo998cUXERGx99577/T+d4eGDRuWlVT/6uvbNue+4YYboqCgYKv72meffcr+vXbt2rjmmmviwAMPjKVLl8bPf/7zGD16dA6TAwAAVF1OLQgAAJXY/vvvHxERH374YbntM2bM2OK5tWrV2up0UyaTifz8/MjL+/9/Hqxfvz6eeuqp7d7H19WrVy8KCgrij3/8Y7nnl5aWxlNPPRX77rtvHHTQQdvcT0Xq3LlzzJ8/P+bNm1du+9SpU8vdLywsjPr168dHH30UHTp02Opt8zRZRMTw4cPj008/jaKiorj55ptjxowZMW7cuIr4lgAAACo9E1kAAFCJdejQIQ466KC49dZbY9OmTVG/fv144YUXYs6cOVs8t1WrVvH888/H448/HoceemhkMpno0KFDdOvWLX7729/GlVdeGWeddVasWLEiHnrooXJlzL/u45lnnolp06bFd77znahdu3bZtay+7oorrojzzjsvBgwYEOedd17UrFkzHn/88Zg/f37ccccdkclkcv567IqBAwfG73//+xg8eHBcdtllsc8++8TTTz+9xbW89thjj7j++uvjuuuui5UrV8aJJ54Y++yzTyxbtizmzZsXy5Yti1/84hcRETFx4sR46qmnYuTIkXHIIYfEIYccEj/5yU/itttui8LCwi2u2wUAAEB5JrIAAKASy8/PjzFjxkSLFi1i+PDhce2110atWrXixhtv3OK5AwYQcW8NAAABrklEQVQMiBNPPDHuvPPOOPPMM+P000+PiIguXbrELbfcEn/961/jggsuiDvvvDO+973vxfnnn7/FPi6++OLo1KlTXH/99XHGGWfEhRde+I3ZOnXqFOPGjYu6devGsGHD4oorrojVq1fH6NGj46STTsrdi5AjTZo0icceeywOPvjg+I//+I+45ppronbt2nHDDTds8dwf/OAHMX78+Fi7dm0MHz48zj333Lj55pvj/fffjy5dukTEP6fkRowYEaeeemqcdtppZV977bXXRqtWreKyyy6L4uLiCvv+AAAAKqNMNpvNJh0CAAAAAAAAvs5EFgAAAAAAAKnkGlkAAEDqlZaWRmlp6b99To0a/rwBAACoavylBwAApN69994bRf+vvTu0AhgEgijIi6AKPA3TDgVBFWkgD0lWzOgT67+4MY43c87SWru0CAAAgBv8yAIAAOKttcre+3jTey+11kuLAAAAuEHIAgAAAAAAINLz9wAAAAAAAAD4ImQBAAAAAAAQScgCAAAAAAAgkpAFAAAAAABAJCELAAAAAACASEIWAAAAAAAAkYQsAAAAAAAAIr2kWshGfExjHgAAAABJRU5ErkJggg==\n", "text/plain": [ "

" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "matplotlib.rcParams['figure.figsize'] = [24.0, 8.0]\n", "seaborn.heatmap(\n", " result_frame.pivot(\"mutation_aa\", \"mutation_index\", \"delta_total_score\"),\n", " cmap=\"RdBu_r\", center=0, vmax=50)" ] } ], "metadata": { "_draft": { "nbviewer_url": "https://gist.github.com/a3118b776957d03bc4c789493bb541fe" }, "gist": { "data": { "description": "pyrosetta_distributed_mutation_demo.ipynb", "public": true }, "id": "a3118b776957d03bc4c789493bb541fe" }, "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.7.3" }, "toc": { "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": false, "toc_cell": false, "toc_position": {}, "toc_section_display": "block", "toc_window_display": false } }, "nbformat": 4, "nbformat_minor": 2 }