diff --git a/.gitignore b/.gitignore index b56ff3c..d1a1d19 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,6 @@ cloudmol/__pycache__ *dist* -*build* \ No newline at end of file +*build* + +test.ipynb \ No newline at end of file diff --git a/cloudmol/cloudmol.py b/cloudmol/cloudmol.py index 0ca037f..fa805b9 100644 --- a/cloudmol/cloudmol.py +++ b/cloudmol/cloudmol.py @@ -26,7 +26,7 @@ class PymolFold(): def __init__(self, base_url: str = "http://region-8.seetacloud.com:42711/", abs_path: str = "PymolFold_workdir", verbose: bool = True): self.BASE_URL = base_url self.ABS_PATH = os.path.join(os.path.expanduser("~"), abs_path) - print(f"Results will be saved to {self.ABS_PATH}") + print(f"Results will be saved to {self.ABS_PATH} by default") if not os.path.exists(self.ABS_PATH): os.makedirs(self.ABS_PATH) self.verbose = verbose @@ -36,7 +36,7 @@ def set_base_url(self, url): def set_path(self, path): self.ABS_PATH = path - + print(f"Results will be saved to {self.ABS_PATH}") def query_pymolfold(self, sequence: str, num_recycle: int = 3, name: str = None): num_recycle = int(num_recycle) diff --git a/cloudmol/utils/utils.py b/cloudmol/utils/utils.py new file mode 100644 index 0000000..07fdeda --- /dev/null +++ b/cloudmol/utils/utils.py @@ -0,0 +1,44 @@ +import numpy as np +import matplotlib.pyplot as plt +import matplotlib.patches as mpatches + +def plot_ca_plddt(pdb_file, size=(5,3), dpi=120): + plddts = [] + with open(pdb_file, "r") as f: + lines = f.readlines() + for line in lines: + if " CA " in line: + plddt = float(line[60:66]) + plddts.append(plddt) + if max(plddts) <= 1.0: + y = np.array([plddt * 100 for plddt in plddts]) + print("Guessing the scale is [0,1], we scale it to [0, 100]") + else: + y = np.array(plddts) + x = np.arange(len(y)) + 1 + + # Create color array based on conditions + colors = np.where(y > 90, 'blue', + np.where((y > 70) & (y <= 90), 'lightblue', + np.where((y > 50) & (y <= 70), 'yellow', 'orange'))) + + plt.figure(figsize=size, dpi=dpi) + + # Create scatter plot with colored markers + plt.plot(x, y, color='black') + plt.scatter(x, y, color=colors, zorder=10, edgecolors='black') + + plt.ylim(0, 100) # Make sure y axis is in range 0-100 + plt.xlabel('Residue') + plt.ylabel('pLDDT') + plt.title('Predicted LDDT per residue') + + # Create legend + legend_elements = [mpatches.Patch(color='blue', label='Very high'), + mpatches.Patch(color='lightblue', label='Confident'), + mpatches.Patch(color='yellow', label='Low'), + mpatches.Patch(color='orange', label='Very low')] + plt.legend(handles=legend_elements, title='Confidence', loc='upper left', bbox_to_anchor=(1, 1)) + + plt.tight_layout() # Make sure nothing gets cropped off + plt.show() diff --git a/cloudmol_demo.ipynb b/cloudmol_demo.ipynb index 81da50f..fc62dbd 100644 --- a/cloudmol_demo.ipynb +++ b/cloudmol_demo.ipynb @@ -1,26 +1,11 @@ { - "nbformat": 4, - "nbformat_minor": 0, - "metadata": { - "colab": { - "provenance": [], - "authorship_tag": "ABX9TyP3hM2vE4uupz+QGJQ6Q5KK", - "include_colab_link": true - }, - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - }, - "language_info": { - "name": "python" - } - }, "cells": [ { + "attachments": {}, "cell_type": "markdown", "metadata": { - "id": "view-in-github", - "colab_type": "text" + "colab_type": "text", + "id": "view-in-github" }, "source": [ "\"Open" @@ -38,8 +23,8 @@ }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ " Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n" ] @@ -53,11 +38,7 @@ }, { "cell_type": "code", - "source": [ - "from cloudmol.cloudmol import PymolFold\n", - "pf = PymolFold() \n", - "pf.query_esmfold(\"MTYKLILNGKTLKGETTTEAVDAATAEKVFKQYANDNGVDGEWTYDDATKTFTVTE\", '1pga')" - ], + "execution_count": 1, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -65,32 +46,53 @@ "id": "3-rYiXFx7fms", "outputId": "8f701f6a-d3d2-4464-db42-8be6d7447d82" }, - "execution_count": 2, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ - "Results will be saved to /root/PymolFold_workdir\n", - "Results saved to /root/PymolFold_workdir/1pga.pdb\n", - "Guessing the scale is [0,1], we scale it to [0, 100]\n", - "====================\n", - " pLDDT: 88.36\n", - "====================\n" + "Results will be saved to /Users/jsun/PymolFold_workdir by default\n" ] } + ], + "source": [ + "from cloudmol.cloudmol import PymolFold\n", + "from cloudmol.utils.utils import plot_ca_plddt\n", + "pf = PymolFold()\n", + "pf.set_path(\"./\")\n", + "pf.query_esmfold(\"MTYKLILNGKTLKGETTTEAVDAATAEKVFKQYANDNGVDGEWTYDDATKTFTVTE\", '1pga')" ] }, { "cell_type": "code", - "source": [ - "view = py3Dmol.view()\n", - "view.addModel(open('/root/PymolFold_workdir/1pga.pdb', 'r').read(),'pdb')\n", - "view.setBackgroundColor('white')\n", - "view.setStyle({'chain':'A'}, {'cartoon': {'color':'purple'}})\n", - "view.zoomTo()\n", - "view.show()" + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Guessing the scale is [0,1], we scale it to [0, 100]\n" + ] + }, + { + "data": { + "image/png": "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/vvviYyM1NW5c+cOGo2GWbNmsWTJEt0+ffbZZ5w6dUpXz9PTk59++gnQjquNfiUX+RkvklXWrFlp06YNq1atYtOmTfzzzz9kyZKFw4cPc/fuXQC+/fZbXF1dMTY2pmLFiuTJkyeNoxZCiPRt69atFChQgKpVq76zbo8ePVi5ciWtW7dm8ODBnDhxgunTp3P16lU2bdqkV/fmzZu0bt2a7t2706VLF5YtW4anpycVKlTAxcWFli1bkjVrVgYNGkT79u1p1KgR1lGPt4rPuHHjmDJlCo0aNaJRo0acOXOGevXq8fbtW716r1+/pnr16jx48IDevXvj4ODA0aNHGTlyJP7+/sybN0+vvpeXFy9fvqR3795oNBpmzJhBy5Yt+eeffzA1NaV37948fPiQPXv2sHr16sQf2ESSZEkku06dOrFq1SrCw8MpWLAgAKam2lPN2tqacePGkSVLlrQMUQghMoygoCAePHjAl19++c6658+fZ+XKlfTo0YOff/4ZgL59+2JnZ8esWbPYv38/NWvW1NW/fv06hw4dws3NDfjvKsDy5cuZNWsWpUuXxsbGhkGDBlG+fHk6duyY4LafPHnCjBkzaNy4MVu3btX17IwePVrvOaEAc+bM4datW5w9e5bChbWTFffu3Zs8efIwc+ZMBg8eTP78+XX17927h6+vL9myZQPQPWN09+7dNGnShCpVqlCkSBH27NljMMb3JZfhRLIKCgpiwoTxAGTODB4e0LMnODpqB35HRIRz/fr1tAxRCCEylKCgIAAyZ878zro7duwAtD34MQ0ePBggzrimEiVK6BIlAFtbW4oWLco///yT5Dj37t3L27dv6d+/v94lsIEDB8ap6+3tjZubG9myZePp06e6V506dYiIiODQoUN69du2batLlABdzO8T5/uQniWRrDp37syRI0cZOBAmT4bo3trISPj9d+jSJZTGjRtx5cpVbG1t0zRWIYTICGxsbAB4+fLlO+vevXsXIyMjChUqpFeeO3dusmbNqhsOEc3BwSFOG9myZeP58+dJjjO67eieomi2trZ6iQ5o5226cOFCgt8DAQEBBuOMbu994nwfkiyJZHP58uWoh+7CnDkQc2ydkRG0bg2vXik8Pf9l6dKljBw5Mu2CFUKIDMLGxoY8efJw6dKlRK+T2MHNCd3NppRK9LbeR2RkJHXr1mXYsGHxLi9SpIjev9MqzmhyGU4km+iZWQcP1k+UYurQAeztNSxfviz1AhNCiAyuSZMm3Lp1i2PHjhms5+joSGRkJL6+vnrljx8/JjAwMEXnRIpuO/a2nzx5EqcHqGDBggQHB1OnTp14X/H1eL1Lct79FpskSyLZ3Lt3D4DKlROuY2oK5csr7t69l0pRCSFExjds2DAyZcpEjx49ePz4cZzlt27d4ocffqBRo0YAce4mmzNnDgCNGzdOsRjr1KmDqakp8+fP1+vxiR0LaAeSHzt2jN27d8dZFhgYSHh40mddz5Qpk2795CaX4USysbCwACAwEHLmTLje8+dgaWmROkEJIcRHoGDBgnh5edG2bVuKFy9O586dKVmyJG/fvuXo0aN4e3vj6enJgAED6NKlC0uWLCEwMJDq1atz8uRJVq5cSfPmzfXuhEtutra2DBkyhOnTp9OkSRMaNWrE2bNn2blzJzljfSkMHTqUP/74gyZNmuimKnj16hUXL15k48aN3LlzJ84671KhQgUAvvnmG+rXr4+xsTHt2rVLln2TZEkkm7p167Jq1SpWr4ZBg+Kvc/MmHD0KrVrVTd3ghBCfpEym6WeG6Q+NpVmzZly4cIGZM2eyZcsW/ve//2Fubk7p0qWZPXs2PXv2BLQTAhcoUIAVK1awadMmcufOzciRIxk/fnxy7IZBU6ZMwcLCgkWLFrF//34qV67Mn3/+GadHy8rKioMHDzJt2jS8vb1ZtWoVNjY2FClShIkTJ77X9DItW7akf//+rF+/njVr1qCUSrZkSaNSa3TUR+jy5cuULFmSS5cu4eLiktbhpLmQkBDy588HPOPwYUXRorGXQ7NmsGcP/PXXXyn6C0cI8fFIzGdt9C3kBQoUSM3QRAaV1PNFxiyJZGNhYcEvvyzj2TMNVapoGDcOrlyBu3dhxQqoVEmbKPXs2ZMaNWqkdbhCCCFEokiyJJJVs2bN2Lp1K5kz52PyZHBxAScn6NoVbt2yZPTo0SxatChF71oQQgghkpOMWRLJrlGjRvzzz2127tzJ4cOHCQsLo1ChQrRv3z7OU6uFEEKI9E6SJZEijI2NadKkCU2aNEnrUIQQQogPIpfhhBBCCCEMkGRJCCGEEMIASZaEEEIIIQyQZEkIIYQQwgBJloQQQgghDPhokqUzZ87QrFkzsmfPjpWVFSVLluTHH3/Uq3P06FFcXV2xsrIid+7cfPPNNwQHB6dRxEIIIYTICD6KqQP+/PNPmjZtSrly5Rg7dizW1tbcunULPz8/XZ1z585Ru3Ztihcvzpw5c/Dz82PWrFn4+vqyc+fONIxeCCGEEOlZhk+WgoKC6Ny5M40bN2bjxo0YGcXfWTZq1CiyZcvGgQMHsLGxAcDJyYmePXvy559/Uq9evdQMWwghRKpoBtxK6yCiFAT+SOsgxHvI8MmSl5cXjx8/ZurUqRgZGfHq1SssLS31kqagoCD27NnDoEGDdIkSQOfOnRk0aBAbNmyQZEkIIT5Kt4AraR3EB1uxYgVdu3bl1KlTVKxYMa3D+eRk+DFLe/fuxcbGhgcPHlC0aFGsra2xsbGhT58+hISEAHDx4kXCw8PjnGBmZmaULVuWs2fPvnM7AQEBXL58We918+bNFNknIYQQQqQf750s1apVi3379iVnLO/F19eX8PBwvvzyS+rXr89vv/1Gt27dWLRoEV27dgXA398fAHt7+zjr29vb8/Dhw3duZ+HChZQsWVLv1bx582TdFyGEEEKkP++dLB04cIDHjx8nZyzvJTg4mNevX9O5c2d+/PFHWrZsyY8//kjv3r1Zv349vr6+vHnzBgBzc/M461tYWOiWG9K3b18uXbqk99q8eXNy744QQgjxXs6ePUvDhg2xsbHB2tqa2rVrc/z4cd3ywMBAjI2N9e4Uf/r0KUZGRuTIkQOllK68T58+5M6dO1XjT88y/GU4S0tLANq3b69X3qFDBwCOHTumqxMaGhpn/ZCQEN1yQ+zs7HBxcdF7FSpU6EPDF0IIIT7Y5cuXcXNz4/z58wwbNoyxY8dy+/ZtatSowYkTJwDImjUrJUuW5NChQ7r1Dh8+jEaj4dmzZ1y58t/YLh8fH9zc3FJ9P9KrDJ8s5cmTB4BcuXLpldvZ2QHw/Plz3eW36MtxMfn7++vaEEIIITKiMWPGEBYWxuHDhxkzZgzDhw/nyJEjmJmZMWzYMF09Nzc3Dh8+rPu3j48Prq6u2NnZ4ePjA6BLnCRZ+s8H3Q33+++/J3qQs0ajYezYsR+yuXhVqFCBPXv26AZ4R4seh2Rra0vJkiUxMTHh9OnTuLu76+q8ffuWc+fO6ZUJIYQQGUlERAR//vknzZs3p0CBArpye3t7OnTowM8//0xQUBA2Nja4ubnx008/cf36dYoWLYqPjw/169fH1tYWHx8fvvrqKw4fPoxSSpKlGD44Wfr9998TVTelkiV3d3e+++47fvnlF2rVqqUrX7p0KSYmJtSoUYMsWbJQp04d1qxZw9ixY8mcOTMAq1evJjg4mDZt2iR7XEIIIURqePLkCa9fv9brMIhWvHhxIiMjuX//Pi4uLroEyMfHh3z58nH27FmmTJmCra0ts2bN0i2zsbGhTJkyqbof6dkHJUuLFi2iVatWyRXLeylXrhzdunVj2bJlhIeHU716dQ4cOIC3tzcjR47UXWKbOnUqVatWpXr16vTq1Qs/Pz9mz55NvXr1aNCgQZrugxBCCJEa8uTJg7OzM4cOHcLJyQmlFFWqVMHW1pYBAwZw9+5dfHx8qFq1aoKTPH+KPihZsra2JkeOHMkVy3tbtGgRDg4OLF++nE2bNuHo6MjcuXMZOHCgrk758uXZu3cvw4cPZ9CgQWTOnJnu3bszffr0tAtcCCGE+EC2trZYWVlx/fr1OMuuXbuGkZER+fPn15W5ublx6NAhnJ2dKVu2LJkzZ6ZMmTJkyZKFXbt2cebMGSZOnJiau5DuZfgZvAFMTU0ZP34848ePN1jP1dWVI0eOpFJUQgghRMozNjamXr16bNmyhTt37uDk5ATA48eP8fLywtXVVe/pFW5ubqxatYpff/2Vhg0bAmBkZETVqlWZM2cOYWFhMl4plo8iWRJCCCE+BcuWLWPXrl1xyidMmMCePXtwdXWlb9++mJiYsHjxYkJDQ5kxY4Ze3ehE6Pr160ybNk1XXq1aNXbu3Im5uTmfffZZyu5IBvPeydL48eMpXbp0csYihBBCJLOCaR1ADB8ey//+9794yz09PfHx8WHkyJFMnz6dyMhIKleuzJo1a6hcubJe3aJFi2JnZ0dAQACurq668ugkqlKlSvFO4vwp06iYU3a+p5cvX3L48GFu3brFy5cvyZw5M4UKFcLV1RVra+vkiDNdunz5MiVLluTSpUu4uLikdThCCPFRSsxn7T///AOgd+u8EAlJ6vnyQZfhIiIiGDNmDAsWLOD169d6U6VrNBqsrKwYMGAAkyZNklH1QgghhMiQPihZ8vDwYMOGDZQoUYL27dtTsmRJrK2tCQ4O5uLFi3h5eTF9+nTu3LnDmjVrkitmIYQQQohU897J0t69e9mwYQNff/01P/zwQ5yeoy+//JJRo0bRv39/Fi1aRLdu3fQmjRRCCCGEyAje+9rYqlWrKFiwID/++GOCl9iMjIyYP38+BQoUYOXKle8dpBBCCCFEWnnvZOnkyZO0bNkSjUZjeANGRrRs2VL31GMhhBBCiIzkvZMlf39/ChUqlKi6hQoVwt/f/303JYQQQgiRZt47WQoODiZTpkyJqmtlZUVwcPD7bkoIIYQQIs28d7KklHrnJTghhBBCiIzug6YOGDFiRKIeRPvixYsP2YwQQgghRJp572SpWrVqie5ZypEjh8yqKoQQQogM6b2TpQMHDiRjGEIIIYQQ6ZM8g0QIIYQQyUKj0TBhwoS0DiPZfdCYpWg3b95kz549cR6kW7duXQoWTE9PfBZCCPFJOdgMgm+ldRRa1gWh+h9JWqVZs2bs3buXx48fkzlz5njreHh44O3tjb+/Pzly5EiOSEUsH5QsBQcH07NnT7y9vYmMjIyz3MjIiHbt2rF48eJETzMghBBCJJvgW/DiSlpH8d48PDzYunUrmzZtonPnznGWv379mi1bttCgQQNJlFLQeydLSimaNWvGgQMHqFevHp06ddJ7kO6lS5dYtWoVXl5ePH78mD179iRn3EIIIcRHr1mzZmTOnBkvL694k6UtW7bw6tUrPDw8Pmg74eHhREZGYmZm9kHtfKzee8zSpk2bOHDgAN999x27du3Cw8ODMmXKULBgQcqUKYOHhwe7d+9m2rRp/PXXX2zevDkZwxZCCCE+fpaWlrRs2ZJ9+/YREBAQZ7mXlxeZM2emWbNmAAQGBjJw4EDy58+Pubk5hQoV4vvvv9e7+nPnzh00Gg2zZs1i3rx5FCxYEHNzc06ePEmmTJkYMGBAnO34+flhbGycqOmCYjt79iwNGzbExsYGa2trateuzfHjx3XLAwMDMTY25scff9SVPX36FCMjI3LkyIFSSlfep08fcufOneQYPtR7J0vr1q2jTJkyDBs2zGC9ESNGUKpUKby8vN53U0IIIcQny8PDg/DwcDZs2KBX/uzZM3bv3k2LFi2wtLTk9evXVK9enTVr1tC5c2d+/PFHvvjiC0aOHMm3334bp93ly5czf/58evXqxezZs3FwcKBFixb8+uuvRERE6NVdt24dSqkk92BdvnwZNzc3zp8/z7Bhwxg7diy3b9+mRo0aumfGZs2alZIlS3Lo0CHdeocPH0aj0fDs2TOuXPnvMqqPjw9ubm5JiiE5vPdluDNnziT6oDVr1oy1a9e+76aEEEKIT1atWrWwt7fHy8uLfv366cq9vb0JCwvTfRfPmTOHW7ducfbsWQoXLgxA7969yZMnDzNnzmTw4MHkz59ft76fnx83b97E1tZWV9a5c2fWrl3Lnj17aNCgga58zZo1VKtWDQcHhyTFPmbMGMLCwjh8+LBuvsXOnTtTtGhRhg0bxsGDBwFwc3Nj48aNuvV8fHxwdXXl2rVr+Pj44OLiokucevXqlaQYksN79ywFBATg6OiYqLqOjo7xdh8KIYQQwjBjY2PatWvHsWPHuHPnjq7cy8uLXLlyUbt2bUCbPLm5uZEtWzaePn2qe9WpU4eIiAi9nhuAVq1a6SVKAHXq1CFPnjx6HRyXLl3iwoULdOzYMUlxR0RE8Oeff9K8eXO9iant7e3p0KEDhw8fJigoCNAmS48fP+b69euANlmqVq0abm5u+Pj4ANreJqVUmvQsvXey9OrVKywtLRNV18LCgtevX7/vpoQQQohPWnTvUfSQFj8/P3x8fGjXrh3GxsYA+Pr6smvXLmxtbfVederUAYjTaeHs7BxnO0ZGRnh4eLB582bd9/batWuxsLCgTZs2SYr5yZMnvH79mqJFi8ZZVrx4cSIjI7l//z6ALgHy8fHh1atXnD17Fjc3N6pVq6ZLlnx8fLCxsaFMmTJJiiM5fNDUAfIgXSGEECLlVahQgWLFirFu3TpGjRoV7xiiyMhI6tatm+BY4iJFiuj9O6EOj86dOzNz5kw2b95M+/bt8fLyokmTJmTJkiX5diiWPHny4OzszKFDh3ByckIpRZUqVbC1tWXAgAHcvXsXHx8fqlatipFR6s+n/UHJUvfu3endu/c764WHh3/IZoQQQohPnoeHB2PHjuXChQt4eXlRuHBhPvvsM93yggULEhwcrOtJel8lS5akXLlyrF27lnz58nHv3j3mz5+f5HZsbW2xsrLSXVqL6dq1axgZGemNoXJzc+PQoUM4OztTtmxZMmfOTJkyZciSJQu7du3izJkzTJw48YP27X29d7LUpUuX5IxDCCGEEAZEJ0vjxo3j3LlzcR4r4u7uzoQJE9i9ezf169fXWxYYGIi1tTUmJon72u/UqRPDhg3D3NycHDly0LBhwyTHa2xsTL169diyZQt37tzByckJgMePH+Pl5YWrqys2Nja6+m5ubqxatYpff/1Vtz0jIyOqVq3KnDlzCAsLS5PxSvABydLy5cuTMw4hhBBCGODs7EzVqlXZsmULQJw70ocOHcoff/xBkyZN8PT0pEKFCrx69YqLFy+yceNG7ty5Q86cORO1rQ4dOjBs2DA2bdpEnz59MDU1fa+Yp0yZwp49e3B1daVv376YmJiwePFiQkNDmTFjhl7d6ETo+vXrTJs2TVderVo1du7cibm5uV5PWmpKlmfDvcuOHTvYvHkzS5YsSY3NCSGEEFrW6ej5pMkQi4eHB0ePHqVSpUoUKlRIb5mVlRUHDx5k2rRpeHt7s2rVKmxsbChSpAgTJ05M0pijXLlyUa9ePXbs2EGnTp3eO14XFxd8fHwYOXIk06dPJzIyksqVK7NmzRoqV66sV7do0aLY2dkREBCAq6urrjw6iapUqRLm5ubvHcuH0KiYU2OmkKlTpzJu3Lg4k1xldJcvX6ZkyZJcunQJFxeXtA5HCCE+Son5rP3nn38A9G5RFx+mRYsWXLx4kZs3b6Z1KMkuqedL6g8pF0IIIUS65u/vz/bt2z+oV+ljkiqX4YQQQgiR/t2+fZsjR46wdOlSTE1NE3XH+6dAepaEEEIIAcDBgwfp1KkTt2/fZuXKlWny0Nr0SHqWhBBCCAGAp6cnnp6eaR1GuvPeyVKzZs0SXfdjHBwmhBBCiE/DeydLFy5cSNLjTpL6pGIhhBAiKVLh5m7xkVBKJSmHee9kKeaTj9ObqVOnMmbMGFxcXLh06ZLesqNHjzJs2DDOnDmDjY0N7u7uTJs2DWtr6zSKVgghxIcyMjLi7du3Sf4SFJ8epRQRERGYmZklep1kHbN06dIlduzYoUuknJ2dadiwISVLlkzOzRjk5+fHtGnTyJQpU5xl586do3bt2hQvXpw5c+bg5+fHrFmz8PX1ZefOnakWoxBCiORlbm7OmzdvCAgIwM7OThImES+lFAEBAURERCRpgstkSZZCQ0Pp3bs3q1evRimleyJwZGQkI0aMwMPDg6VLlyYpi3tfQ4YM4fPPPyciIoKnT5/qLRs1ahTZsmXjwIEDuufRODk50bNnT/7880/q1auX4vEJIYRIfrly5SI0NJRnz57x4sULjI2NJWESeqJ7lCIiIrC0tCRXrlyJXjdZpg4YPnw4q1atok+fPly9epWQkBBCQ0O5evUqX331FWvWrGHYsGHJsSmDDh06xMaNG5k3b16cZUFBQezZs4eOHTvqPbivc+fOWFtbs2HDhhSPTwghRMowMjLCwcGBrFmzYmZmJomSiEOj0WBmZkbWrFlxcHDQdewkRrL0LK1Zs4ZOnTqxYMECvfKiRYvy008/ERQUxJo1a+JNYpJLREQE/fv3p0ePHpQqVSrO8osXLxIeHk7FihX1ys3MzChbtixnz5412H5AQABPnjzRK5O7/IQQIv0wMjLC3t4+rcMQH6FkSZbCwsL4/PPPE1xetWpVtm7dmhybStCiRYu4e/cue/fujXe5v78/QLx/SPb29vj4+Bhsf+HChUycOPHDAxVCCCFEhpIsl+Hq16/P7t27E1y+a9euFB0P9O+//zJu3DjGjh2Lra1tvHXevHkDEO+ALgsLC93yhPTt25dLly7pvTZv3vzBsQshhBAifUuWnqXJkyfj7u5Oy5Yt+frrrylUqBAAvr6+/PTTT9y9e5dff/2VZ8+e6a2XPXv25Ng8Y8aMIXv27PTv3z/BOpaWloB2MHpsISEhuuUJsbOzw87O7sMCFUIIIUSGkyzJUvHixQHtuKAtW7boLYueJKxEiRJx1ouIiPjgbfv6+rJkyRLmzZvHw4cPdeUhISGEhYVx584dbGxsdJffoi/HxeTv70+ePHk+OBYhhBBCfHySJVkaN25cmt158ODBAyIjI/nmm2/45ptv4ix3dnZmwIABTJw4ERMTE06fPo27u7tu+du3bzl37pxemRBCCCFEtGRJliZMmJAczbyXkiVLsmnTpjjlY8aM4eXLl/zwww8ULFiQLFmyUKdOHdasWcPYsWPJnDkzAKtXryY4OJg2bdqkduhCCCGEyACSdQbvtJAzZ06aN28epzx6moKYy6ZOnUrVqlWpXr06vXr1ws/Pj9mzZ1OvXj0aNGiQOgELIYQQIkNJlrvhMory5cuzd+9eLC0tGTRoEEuWLKF79+5s3LgxrUMTQgghRDqV4XuWEnLgwIF4y11dXTly5EjqBiOEEEKIDOuT6lkSQgghhEgqSZaEEEIIIQyQZEkIIYQQwgBJloQQQgghDJBkSQghhBDCAEmWhBBCCCEMkGRJCCGEEMIASZaEEEIIIQyQZEkIIYQQwgBJloQQQgghDJBkSQghhBDCAEmWhBBCCCEMkGRJCCGEEMIASZaEEEIIIQyQZEkIIYQQwgBJloQQQgghDJBkSQghhBDCAEmWhBBCCCEMkGRJCCGEEMIASZaEEEIIIQyQZEkIIYQQwgBJloQQQgghDJBkSQghhBDCAEmWhBBCCCEMkGRJCCGEEMIASZaEEEIIIQyQZEkIIYQQwgBJloQQQgghDJBkSQghhBDCAEmWhBBCCCEMkGRJCCGEEMIASZaEEEIIIQyQZEkIIYQQwgBJloQQQgghDJBkSQghhBDCgAyfLJ06dYp+/frh4uJCpkyZcHBwwN3dnRs3bsSpe/XqVRo0aIC1tTXZs2enU6dOPHnyJA2iFkIIIURGYZLWAXyo77//niNHjtCmTRtKly7No0ePWLBgAeXLl+f48eOULFkSAD8/P6pVq0aWLFmYNm0awcHBzJo1i4sXL3Ly5EnMzMzSeE+EEEIIkR5l+GTp22+/xcvLSy/Zadu2LaVKleK7775jzZo1AEybNo1Xr17x999/4+DgAEClSpWoW7cuK1asoFevXmkSvxBCCCHStwx/Ga5q1apxeoUKFy6Mi4sLV69e1ZX99ttvNGnSRJcoAdSpU4ciRYqwYcOGVItXCCGEEBlLhu9Zio9SisePH+Pi4gLAgwcPCAgIoGLFinHqVqpUiR07dryzzYCAgDjjm27evJk8AQshhBAi3fook6W1a9fy4MEDJk2aBIC/vz8A9vb2cera29vz7NkzQkNDMTc3T7DNhQsXMnHixJQJWAghhBDp1keXLF27do2vv/6aKlWq0KVLFwDevHkDEG8yZGFhoatjKFnq27cvbdq00Su7efMmzZs3T6bIhRBCCJEefVTJ0qNHj2jcuDFZsmRh48aNGBsbA2BpaQlAaGhonHVCQkL06iTEzs4OOzu7ZI5YCCGEEOndR5MsvXjxgoYNGxIYGIiPjw958uTRLYu+/BZ9OS4mf39/smfPbrBXSQghhBCfro8iWQoJCaFp06bcuHGDvXv3UqJECb3lefPmxdbWltOnT8dZ9+TJk5QtWzaVIhVCCCFERpPhpw6IiIigbdu2HDt2DG9vb6pUqRJvvVatWrFt2zbu37+vK9u3bx83btyIMxZJCCGEECJahu9ZGjx4MH/88QdNmzbl2bNnukkoo3Xs2BGAUaNG4e3tTc2aNRkwYADBwcHMnDmTUqVK0bVr17QIXQghhBAZQIZPls6dOwfA1q1b2bp1a5zl0clS/vz5OXjwIN9++y0jRozAzMyMxo0bM3v2bBmvJIQQQogEZfhk6cCBA4mu6+Liwu7du1MuGCGEEEJ8dDL8mCUhhBBCiJQkyZIQQgghhAGSLAkhhBBCGCDJkhBCCCGEAZIsCSGEEEIYIMmSEEIIIYQBkiwJIYQQQhggyZIQQgghhAGSLAkhhBBCGCDJkhBCCCGEAZIsCSGEEEIYIMmSEEIIIYQBkiwJIYQQQhggyZIQQgghhAGSLAkhhBBCGCDJkhBCCCGEAZIsCSGEEEIYIMmSEEIIIYQBkiwJIYQQQhggyZIQQgghhAGSLAkhhBBCGCDJkhBCCCGEAZIsCSGEEEIYIMmSEEIIIYQBkiwJIYQQQhggyZIQQgghhAGSLAkhhBBCGCDJkhBCCCGEAZIsCSGEEEIYIMmSEEIIIYQBkiwJIYQQQhggyZIQQgghhAGSLAkhhBBCGCDJkhBCCCGEAZIsCSGEEEIY8MklS6GhoQwfPpw8efJgaWlJ5cqV2bNnT1qHJYQQQoh06pNLljw9PZkzZw4eHh788MMPGBsb06hRIw4fPpzWoQkhhBAiHTJJ6wBS08mTJ1m/fj0zZ85kyJAhAHTu3JmSJUsybNgwjh49msYRCiGEECK9+aR6ljZu3IixsTG9evXSlVlYWNC9e3eOHTvG/fv30zA6IYQQQqRHn1TP0tmzZylSpAg2NjZ65ZUqVQLg3Llz5M+fP951AwICePLkiV7ZlStXALh582YKRCuEEAL++4wNDQ1N40jEp+qTSpb8/f2xt7ePUx5d9vDhwwTXXbhwIRMnTox3WfPmzZMlPiGEEAm7f/8+5cuXT+swxCfok0qW3rx5g7m5eZxyCwsL3fKE9O3blzZt2uiVBQUFcePGDUqVKhVvu9Fu3rxJ8+bN2bx5M4UKFXrP6EV6IO/lx0Pey4wjNDSU+/fvU7169bQORXyiPqlkydLSMt5u3JCQEN3yhNjZ2WFnZxenvEqVKonefqFChXBxcUl0fZF+yXv58ZD3MmOQHiWRlj6pAd729vb4+/vHKY8uy5MnT2qHJIQQQoh07pNKlsqWLcuNGzcICgrSKz9x4oRuuRBCCCFETJ9UstS6dWsiIiJYsmSJriw0NJTly5dTuXLlBO+EE0IIIcSn65Mas1S5cmXatGnDyJEjCQgIoFChQqxcuZI7d+7wyy+/pNh2bW1tGT9+PLa2tim2DZE65L38eMh7KYRILI1SSqV1EKkpJCSEsWPHsmbNGp4/f07p0qWZPHky9evXT+vQhBBCCJEOfXLJkhBCCCFEUnxSY5aEEEIIIZJKkiUhhBBCCAMkWRJCCCGEMECSJSGEEEIIAyRZSkGhoaEMHz6cPHnyYGlpSeXKldmzZ09ahyUMOHXqFP369cPFxYVMmTLh4OCAu7s7N27ciFP36tWrNGjQAGtra7Jnz06nTp148uRJGkQtEmPq1KloNBpKliwZZ9nRo0dxdXXFysqK3Llz88033xAcHJwGUQoh0iO5Gy4FtW/fno0bNzJw4EAKFy7MihUrOHXqFPv378fV1TWtwxPxaN26NUeOHKFNmzaULl2aR48esWDBAoKDgzl+/Ljui9bPz49y5cqRJUsW3RfrrFmzcHBw4OTJk5iZmaXxnoiY/Pz8KFq0KBqNBicnJy5duqRbdu7cOapUqULx4sXp1asXfn5+zJo1i5o1a7Jz5840jFoIkW4okSJOnDihADVz5kxd2Zs3b1TBggVVlSpV0jAyYciRI0dUaGioXtmNGzeUubm58vDw0JX16dNHWVpaqrt37+rK9uzZowC1ePHiVItXJE7btm1VrVq1VPXq1ZWLi4vesoYNGyp7e3v14sULXdnPP/+sALV79+7UDlUIkQ7JZbgUsnHjRoyNjenVq5euzMLCgu7du3Ps2DHu37+fhtGJhFStWjVOr1DhwoVxcXHh6tWrurLffvuNJk2a4ODgoCurU6cORYoUYcOGDakWr3i3Q4cOsXHjRubNmxdnWVBQEHv27KFjx47Y2Njoyjt37oy1tbW8l0IIQMYspZizZ89SpEgRvQ9ggEqVKgHarn+RMSilePz4MTlz5gTgwYMHBAQEULFixTh1K1WqxNmzZ1M7RJGAiIgI+vfvT48ePShVqlSc5RcvXiQ8PDzOe2lmZkbZsmXlvRRCAJIspRh/f3/s7e3jlEeXPXz4MLVDEu9p7dq1PHjwgLZt2wLa9xZI8P199uwZoaGhqRqjiN+iRYu4e/cukydPjnf5u95L+TsVQoAkSynmzZs3mJubxym3sLDQLRfp37Vr1/j666+pUqUKXbp0Af577+T9Td/+/fdfxo0bx9ixYxN8WO673kt5H4UQIMlSirG0tIy3dyEkJES3XKRvjx49onHjxmTJkkU3Bg3+e+/k/U3fxowZQ/bs2enfv3+Cdd71Xsr7KIQAMEnrAD5W9vb2PHjwIE55dLd/njx5UjskkQQvXrygYcOGBAYG4uPjo/d+RV+yiX4vY/L39yd79uzx9lSI1OPr68uSJUuYN2+e3qW0kJAQwsLCuHPnDjY2Nu98L+XvVAgB0rOUYsqWLcuNGzcICgrSKz9x4oRuuUifQkJCaNq0KTdu3GDbtm2UKFFCb3nevHmxtbXl9OnTcdY9efKkvLfpwIMHD4iMjOSbb77B2dlZ9zpx4gQ3btzA2dmZSZMmUbJkSUxMTOK8l2/fvuXcuXPyXgohAEmWUkzr1q2JiIhgyZIlurLQ0FCWL19O5cqVyZ8/fxpGJxISERFB27ZtOXbsGN7e3lSpUiXeeq1atWLbtm16U0Ds27ePGzdu0KZNm9QKVySgZMmSbNq0Kc7LxcUFBwcHNm3aRPfu3cmSJQt16tRhzZo1vHz5Urf+6tWrCQ4OlvdSCAHIDN4pyt3dnU2bNjFo0CAKFSrEypUrOXnyJPv27aNatWppHZ6Ix8CBA/nhhx9o2rQp7u7ucZZ37NgRgPv371OuXDmyZs3KgAEDCA4OZubMmeTLl49Tp07JZbh0qkaNGjx9+lRvBu8zZ85QtWpVSpQooZvBe/bs2VSrVo3du3enYbRCiPRCkqUUFBISwtixY1mzZg3Pnz+ndOnSTJ48mfr166d1aCIBNWrU4ODBgwkuj/nncvnyZb799lsOHz6MmZkZjRs3Zvbs2eTKlSs1QhXvIb5kCeDw4cMMHz6cM2fOkDlzZtzd3Zk+fTqZM2dOo0iFEOmJJEtCCCGEEAbImCUhhBBCCAMkWRJCCCGEMECSJSGEEEIIAyRZEkIIIYQwQJIlIYQQQggDJFkSQgghhDBAkiUhhBBCCAMkWRJCCCGEMECSJSGEEEIIAyRZEkIIIYQwQJIlIT4REyZMQKPRJKquRqNhwoQJKRuQEEJkEJIsCZEGVqxYgUaj0b1MTEzImzcvnp6ePHjwIK3DE0IIEYNJWgcgxKds0qRJODs7ExISwvHjx1mxYgWHDx/m0qVLWFhYJOu2xowZw4gRI5K1TSGE+BRIsiREGmrYsCEVK1YEoEePHuTMmZPvv/+eP/74A3d392TdlomJCSYm8icvhBBJJZfhhEhH3NzcALh165au7Nq1a7Ru3Zrs2bNjYWFBxYoV+eOPP/TWCwsLY+LEiRQuXBgLCwty5MiBq6sre/bs0dWJb8xSaGgogwYNwtbWlsyZM9OsWTP8/PzixOXp6YmTk1Oc8oTGQa1Zs4YKFSpgaWlJ9uzZadeuHffv30/SsRBCiPRCkiUh0pE7d+4AkC1bNgAuX77M559/ztWrVxkxYgSzZ88mU6ZMNG/enE2bNunWmzBhAhMnTqRmzZosWLCA0aNH4+DgwJkzZwxur0ePHsybN4969erx3XffYWpqSuPGjT9oH6ZOnUrnzp0pXLgwc+bMYeDAgezbt49q1aoRGBj4QW0LIURakD55IdLQixcvePr0KSEhIZw4cYKJEydibm5OkyZNABgwYAAODg6cOnUKc3NzAPr27YurqyvDhw+nRYsWAGzfvp1GjRqxZMmSRG/7/PnzrFmzhr59+/LTTz8B8PXXX+Ph4cGFCxfea3/u3r3L+PHjmTJlCqNGjdKVt2zZknLlyrFw4UK9ciGEyAikZ0mINFSnTh1sbW3Jnz8/rVu3JlOmTPzxxx/ky5ePZ8+e8ddff+Hu7s7Lly95+vQpT58+5d9//6V+/fr4+vrq7pzLmjUrly9fxtfXN9Hb3rFjBwDffPONXvnAgQPfe39+//13IiMjcXd318X79OlTcufOTeHChdm/f/97ty2EEGlFepaESEM//fQTRYoU4cWLFyxbtoxDhw7pepBu3ryJUoqxY8cyduzYeNcPCAggb968TJo0iS+//JIiRYpQsmRJGjRoQKdOnShdunSC27579y5GRkYULFhQr7xo0aLvvT++vr4opShcuHC8y01NTd+7bSGESCuSLAmRhipVqqS7G6558/+3cz+hsL1xHMc/mijNEGOjLMSZkCilLDRpFkqKslFYKMKGZjUWVkONLEn5V4qF5UhWasrago3llAlRk2QxJSLmexe3puYO5y78fnLr/VqdM8/3mfN06tSnp+85AwoGgxoZGVEymVQ2m5UkRSIR9fT0fDg/EAhIkrq6upRKpXR4eKhEIqHt7W0tLy9rc3NTExMTX17nZx+zfH9/zzvPZrMqKirS0dGRPB5PQb3P5/vyWgDguxGWgB/C4/FoaWkp16Q9Pj4u6fduTHd391/n+/1+jY2NaWxsTI+Pj+rq6tL8/PynYam2tlbZbFapVCpvNymZTBbUVlZWfticfX19nXfuOI7MTHV1dWpoaPjrmgHgX0DPEvCDhEIhdXR0aGVlReXl5QqFQtra2lI6nS6ovb+/zx0/PDzkjfl8PgUCAb28vHx6rd7eXknS6upq3u8rKysFtY7jKJPJ5DV+p9PpvDfypN+N3B6PRwsLCzKzvDEzK1gnAPwL2FkCfpjZ2VkNDg5qd3dXa2trCgaDam1t1eTkpOrr63V3d6eTkxPd3t7q/PxcktTc3KxQKKT29nb5/X6dnZ0pHo9rZmbm0+u0tbVpeHhY6+vrymQy6uzs1PHxsS4uLgpqh4aGcm/fhcNhPT09aWNjQw0NDXmfJ3AcR7FYTHNzc7q6utLAwIDKysp0eXmpg4MDTU1NKRKJ/Pc3DQD+Twbg2+3s7JgkOz09LRh7f383x3HMcRx7e3uzVCplo6OjVl1dbcXFxVZTU2N9fX0Wj8dzc2KxmHV0dFhFRYWVlpZaU1OTLS4u2uvra64mGo3an4/88/OzhcNhq6qqMq/Xa/39/XZzc2OSLBqN5tUmEglraWmxkpISa2xstL29vQ//08xsf3/fgsGgeb1e83q91tTUZNPT05ZMJr945wDg+xWZ/bFXDgAAgBx6lgAAAFwQlgAAAFwQlgAAAFwQlgAAAFwQlgAAAFwQlgAAAFwQlgAAAFwQlgAAAFwQlgAAAFwQlgAAAFwQlgAAAFwQlgAAAFwQlgAAAFwQlgAAAFz8Aq/oeU2El+mNAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } ], + "source": [ + "plot_ca_plddt('./1pga.pdb')" + ] + }, + { + "cell_type": "code", + "execution_count": 4, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -99,10 +101,8 @@ "id": "6278FRTI7lfW", "outputId": "8e63d4e9-8276-4ffa-debf-bc78f7f40f1e" }, - "execution_count": 4, "outputs": [ { - "output_type": "display_data", "data": { "application/3dmoljs_load.v0": "
\n

You appear to be running in JupyterLab (or JavaScript failed to load for some other reason). You need to install the 3dmol extension:
\n jupyter labextension install jupyterlab_3dmol

\n
\n", "text/html": [ @@ -156,18 +156,52 @@ "" ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" } + ], + "source": [ + "view = py3Dmol.view()\n", + "view.addModel(open('/root/PymolFold_workdir/1pga.pdb', 'r').read(),'pdb')\n", + "view.setBackgroundColor('white')\n", + "view.setStyle({'chain':'A'}, {'cartoon': {'color':'purple'}})\n", + "view.zoomTo()\n", + "view.show()" ] }, { "cell_type": "code", - "source": [], + "execution_count": null, "metadata": { "id": "WeyDnykt8Aj1" }, - "execution_count": null, - "outputs": [] + "outputs": [], + "source": [] } - ] -} \ No newline at end of file + ], + "metadata": { + "colab": { + "authorship_tag": "ABX9TyP3hM2vE4uupz+QGJQ6Q5KK", + "include_colab_link": true, + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "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.8.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/pf_plugin.py b/pf_plugin.py index 36827c1..2259751 100644 --- a/pf_plugin.py +++ b/pf_plugin.py @@ -5,8 +5,16 @@ import json BASE_URL = "http://region-8.seetacloud.com:42711/" +ESMFOLD_API = "https://api.esmatlas.com/foldSequence/v1/pdb/" ABS_PATH = os.path.abspath("./") +def set_workdir(path): + global ABS_PATH + ABS_PATH = path + if ABS_PATH[0] == "~": + ABS_PATH = os.path.join(os.path.expanduser("~"), ABS_PATH[2:]) + print(f"Results will be saved to {ABS_PATH}") + def set_base_url(url): global BASE_URL BASE_URL = url @@ -47,7 +55,7 @@ def cal_plddt(pdb_string: str): return sum(plddts) / len(plddts) -def query_pymolfold(sequence: str, num_recycle: int = 3, name: str = None): +def query_pymolfold(sequence: str, name: str = None, num_recycle: int = 3): num_recycle = int(num_recycle) data = { 'sequence': sequence, @@ -93,9 +101,7 @@ def query_esmfold(sequence: str, name: str = None): "Content-Type": "application/x-www-form-urlencoded", } - response = requests.post( - "https://api.esmatlas.com/foldSequence/v1/pdb/", headers=headers, data=sequence - ) + response = requests.post(ESMFOLD_API, headers=headers, data=sequence) if not name: name = sequence[:3] + sequence[-3:] pdb_filename = os.path.join(ABS_PATH, name) + ".pdb" @@ -142,7 +148,6 @@ def query_mpnn(path_to_pdb: str, fix_pos=None, chain=None, rm_aa=None, inverse=F response = requests.post( f"{BASE_URL}mpnn/", headers=headers, files=files, params=params) - # print(response.content.decode("utf-8")) res = response.content.decode("utf-8") d = json.loads(res) @@ -214,7 +219,7 @@ def query_dms(path_to_pdb: str): ofile.write('mutation,002,010,020,030,ensemble\n') for name, s1, s2, s3, s4, s5 in zip(d['mutation'], d['002'], d['010'], d['020'], d['030'], d['ensemble']): ofile.write(f'{name},{s1},{s2},{s3},{s4},{s5}\n') - p = os.path.join(os.getcwd(), 'dms_results.csv') + p = os.path.join(ABS_PATH, 'dms_results.csv') print(f"Results save to '{p}'") @@ -317,3 +322,4 @@ def dms(selection, name='./target_bb.pdb'): cmd.extend("singlemut", singlemut) cmd.extend("dms", dms) cmd.extend("ls_fix", ls_fix) +cmd.extend("set_workdir", set_workdir)