{ "cells": [ { "cell_type": "markdown", "id": "cba4e00c", "metadata": {}, "source": [ "# Tutorial 13 — Extending the packer\n", "\n", "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/uw-ipd/tmol/blob/master/docs/tutorial/13_extending_the_packer.ipynb)\n", "\n", "Subclass `PackerPalette`, audit rotamer candidates, export their coordinates, and verify a packed structure. Complete [packing](04_packing_and_mutation_scan.ipynb) first.\n", "\n", "Rotamer enumeration is deterministic for a fixed task. Annealing searches candidate assignments stochastically; candidate counts do not predict the final sequence.\n" ] }, { "cell_type": "markdown", "id": "c5a2d1f0", "metadata": {}, "source": [ "## Setup\n", "\n", "In Colab, select **T4 GPU**, then **Run all**. For local execution, follow the [installation guide](../installation.md). Setup installs TMol and downloads the fixtures on first use.\n", "\n", "The notebook loads the first ten residues of the checked-in 1UBQ structure and optimizes polar hydrogens before interpreting all-atom scores. Only one internal position is designable, keeping CPU documentation execution practical.\n" ] }, { "cell_type": "code", "execution_count": 1, "id": "7ebcd4da", "metadata": {}, "outputs": [], "source": [ "try:\n", " import google.colab # noqa: F401\n", "except ImportError:\n", " IN_COLAB = False\n", "else:\n", " IN_COLAB = True\n", "\n", "if IN_COLAB:\n", " from urllib.request import urlopen\n", "\n", " exec(\n", " urlopen(\n", " \"https://raw.githubusercontent.com/uw-ipd/tmol/\"\n", " \"master/docs/tutorial/colab_setup.py\"\n", " ).read(),\n", " globals(),\n", " )\n", " setup_colab([\"tmol/tests/data/cif/1UBQ.cif\"])\n" ] }, { "cell_type": "code", "execution_count": 2, "id": "cb00cf14", "metadata": { "tags": [ "collapse-code" ] }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Environment variable CCD_MIRROR_PATH not set. Will not be able to use function requiring this variable. To set it you may:\n", " (1) add the line 'export VAR_NAME=path/to/variable' to your .bashrc or .zshrc file\n", " (2) set it in your current shell with 'export VAR_NAME=path/to/variable'\n", " (3) write it to a .env file in the root of the atomworks.io repository\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "Environment variable PDB_MIRROR_PATH not set. Will not be able to use function requiring this variable. To set it you may:\n", " (1) add the line 'export VAR_NAME=path/to/variable' to your .bashrc or .zshrc file\n", " (2) set it in your current shell with 'export VAR_NAME=path/to/variable'\n", " (3) write it to a .env file in the root of the atomworks.io repository\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "TMol 0.1.62; PyTorch 2.14.1+cpu; device=cpu; blocks=10\n" ] } ], "source": [ "from contextlib import redirect_stderr, redirect_stdout\n", "from io import StringIO\n", "from pathlib import Path\n", "import tempfile\n", "import warnings\n", "\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import pandas as pd\n", "import torch\n", "from IPython.display import display\n", "from biotite.structure.io import load_structure\n", "\n", "import tmol\n", "from tmol.database import ParameterDatabase\n", "from tmol.io import pose_stack_from_biotite\n", "from tmol.numeric import coord_dihedrals\n", "from tmol.ops import res_mask_to_coord_mask\n", "from tmol.pack import PackerPalette, PackerTask, SetPackerTask, pack_rotamers\n", "from tmol.pack.rotamer import FixedAAChiSampler, IncludeCurrentSampler, build_rotamers\n", "from tmol.pack.rotamer.dunbrack import create_dunbrack_sampler_from_database\n", "from tmol.score import beta2016_score_function\n", "\n", "SEED = 20260910\n", "np.random.seed(SEED)\n", "torch.manual_seed(SEED)\n", "if torch.cuda.is_available():\n", " torch.cuda.manual_seed_all(SEED)\n", "warnings.filterwarnings(\n", " \"ignore\", message=r\"Sparse invariant checks are implicitly disabled.*\"\n", ")\n", "\n", "device = (\n", " torch.device(\"cuda\", torch.cuda.current_device())\n", " if torch.cuda.is_available()\n", " else torch.device(\"cpu\")\n", ")\n", "repo_root = Path.cwd()\n", "if not (repo_root / \"tmol/tests/data/cif/1UBQ.cif\").exists():\n", " repo_root = Path(tmol.__file__).resolve().parents[1]\n", "cif_path = repo_root / \"tmol/tests/data/cif/1UBQ.cif\"\n", "\n", "parameter_db = ParameterDatabase.get_default()\n", "atom_array = load_structure(str(cif_path), model=1, include_bonds=True)\n", "protein_slice = atom_array[(atom_array.chain_id == \"A\") & (atom_array.res_id <= 10)]\n", "diagnostics = StringIO()\n", "try:\n", " with redirect_stdout(diagnostics), redirect_stderr(diagnostics):\n", " pose_stack = pose_stack_from_biotite(\n", " protein_slice,\n", " device,\n", " param_db=parameter_db,\n", " no_optH=False,\n", " )\n", "except Exception:\n", " print(diagnostics.getvalue())\n", " raise\n", "score_function = beta2016_score_function(device, param_db=parameter_db)\n", "\n", "\n", "def show_table(frame):\n", " try:\n", " from itables import show\n", " except ImportError:\n", " return display(frame)\n", " return show(frame)\n", "\n", "\n", "def total_score(pose):\n", " scorer = score_function.render_whole_pose_scoring_module(pose)\n", " return float(scorer(pose.coords).detach().cpu()[0])\n", "\n", "\n", "print(\n", " f\"TMol {tmol.__version__}; PyTorch {torch.__version__}; \"\n", " f\"device={device}; blocks={pose_stack.max_n_blocks}\"\n", ")\n" ] }, { "cell_type": "markdown", "id": "b9daef61", "metadata": {}, "source": [ "## Subclass `PackerPalette`\n", "\n", "Start from the default L-amino-acid compatibility rules, retain a hydrophobic alphabet, and always keep the original type. A palette or task may remove choices but must not re-enable rejected types.\n", "\n", "Only block 5 (LYS in the 1UBQ slice) is active. Every position retains at least one valid choice.\n" ] }, { "cell_type": "code", "execution_count": 3, "id": "abe86466", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", "\n", "
\n", " \n", " \n", " \n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "
ⓘchoice_slotblock_typename3allowed_after_paletteis_original
0ALAALATrueFalse
1ILEILETrueFalse
2LEULEUTrueFalse
3LYSLYSTrueTrue
4PHEPHETrueFalse
5VALVALTrueFalse
\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "class HydrophobicPalette(PackerPalette):\n", " \"\"\"Allow a small hydrophobic alphabet plus each original block type.\"\"\"\n", "\n", " def __init__(self, allowed_name3s=(\"ALA\", \"VAL\", \"LEU\", \"ILE\", \"PHE\")):\n", " super().__init__()\n", " self.allowed_name3s = frozenset(allowed_name3s)\n", "\n", " def block_types_from_original(self, pbt, orig):\n", " n_allowed, allowed, is_original = super().block_types_from_original(\n", " pbt, orig\n", " )\n", " in_alphabet = torch.tensor(\n", " [\n", " block_type.name3 in self.allowed_name3s\n", " for block_type in pbt.active_block_types\n", " ],\n", " dtype=torch.bool,\n", " device=pbt.device,\n", " )\n", " real_choice = allowed >= 0\n", " keep = torch.zeros_like(allowed, dtype=torch.bool)\n", " keep[real_choice] = in_alphabet[allowed[real_choice]]\n", " keep = (keep | is_original) & real_choice\n", "\n", " order = torch.argsort((~keep).to(torch.int64), dim=2, stable=True)\n", " allowed = torch.gather(allowed, 2, order)\n", " is_original = torch.gather(is_original, 2, order)\n", " keep = torch.gather(keep, 2, order)\n", " allowed = torch.where(keep, allowed, torch.full_like(allowed, -1))\n", " is_original = is_original & keep\n", " n_allowed = keep.sum(dim=2)\n", " return n_allowed, allowed, is_original\n", "\n", "\n", "target_block = 5\n", "palette = HydrophobicPalette()\n", "design_task = PackerTask(pose_stack, palette)\n", "design_region = torch.zeros(\n", " (pose_stack.n_poses, pose_stack.max_n_blocks),\n", " dtype=torch.bool,\n", " device=device,\n", ")\n", "design_region[:, target_block] = True\n", "design_task.disable_packing_by_block_mask(~design_region)\n", "\n", "design_task.add_conformer_sampler(\n", " create_dunbrack_sampler_from_database(parameter_db, device)\n", ")\n", "design_task.add_conformer_sampler(FixedAAChiSampler())\n", "design_task.add_conformer_sampler(IncludeCurrentSampler())\n", "\n", "considered = design_task.per_block_considered_block_types[0, target_block]\n", "allowed_mask = design_task.per_block_is_block_type_allowed[0, target_block]\n", "identity_rows = []\n", "for slot, (type_index, is_allowed) in enumerate(\n", " zip(considered.detach().cpu().tolist(), allowed_mask.detach().cpu().tolist())\n", "):\n", " if type_index < 0:\n", " continue\n", " block_type = pose_stack.packed_block_types.active_block_types[type_index]\n", " identity_rows.append(\n", " {\n", " \"choice_slot\": slot,\n", " \"block_type\": block_type.name,\n", " \"name3\": block_type.name3,\n", " \"allowed_after_palette\": bool(is_allowed),\n", " \"is_original\": type_index == int(pose_stack.block_type_ind64[0, target_block]),\n", " }\n", " )\n", "identity_frame = pd.DataFrame(identity_rows)\n", "show_table(identity_frame)\n", "assert identity_frame.loc[identity_frame.allowed_after_palette, \"name3\"].isin(\n", " palette.allowed_name3s | {pose_stack.block_type(0, target_block).name3}\n", ").all()\n" ] }, { "cell_type": "code", "execution_count": 4, "id": "2f151196", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Orange target: block 5, LYS\n" ] }, { "data": { "application/3dmoljs_load.v0": "
\n

3Dmol.js failed to load for some reason. Please check your browser console for error messages.

\n
\n", "text/html": [ "
\n", "

3Dmol.js failed to load for some reason. Please check your browser console for error messages.

\n", "
\n", "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "target_mask = torch.zeros_like(design_region)\n", "target_mask[:, target_block] = True\n", "target_atom_mask = res_mask_to_coord_mask(pose_stack, target_mask)\n", "try:\n", " target_viewer = tmol.view(\n", " pose_stack,\n", " highlighted=target_atom_mask[pose_stack.real_atoms],\n", " highlight_color=\"#f58518\",\n", " width=720,\n", " height=390,\n", " )\n", " print(\n", " f\"Orange target: block {target_block}, \"\n", " f\"{pose_stack.block_type(0, target_block).name3}\"\n", " )\n", " target_viewer.show()\n", "except ImportError as exc:\n", " print(\"Interactive target viewer unavailable:\", exc)\n" ] }, { "cell_type": "markdown", "id": "1aa41496", "metadata": {}, "source": [ "The table distinguishes considered choices from choices still allowed after applying the palette. Only the whitelist and the original LYS remain. Terminal or chemically incompatible variants are absent because the default palette rejected them before the subclass filtered the set.\n" ] }, { "cell_type": "markdown", "id": "b7bc9a9f", "metadata": {}, "source": [ "## Enumerate and audit rotamers before annealing\n", "\n", "`SetPackerTask` freezes the task masks. `build_rotamers()` then combines every configured sampler into a coordinate ensemble. This is the right stage for auditing whether a custom alphabet and sampling policy produced the intended search space.\n", "\n", "The identity-count plot answers how many candidates each residue type contributes. The χ plot shows their geometry. It does not show probabilities, energies, an annealing trajectory, or statistically independent samples.\n" ] }, { "cell_type": "code", "execution_count": 5, "id": "1dfa21bf", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", "\n", "
\n", " \n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "
ⓘname3candidate_rotamers
3LYS41
4PHE11
2LEU6
1ILE6
5VAL3
0ALA1
\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "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dQr/+Mc/MHLkSNx4440AgJ9//hnbtm3D7NmzvR4kERERkScuXryI8ePHu5SPHz8ec+fO9UFERERERN7hdkLn0k+2Bg8ejLfeeguTJ092qrN+/Xps3rzZa8ERERER1UTnzp3x448/YsiQIU7le/fuxfXXX++jqIiIiIhqzu2EzqX279+PDz74wKV89OjRePzxx2scFBEREZE3DB8+HOPGjcOMGTNw4403QgiB5ORkvP7661iwYAG++eYbR90BAwb4MFIiIiKi6vEooaPVarFz506MHDnSqXznzp3Q6XTeiIuIiIioxubPnw8ASEpKctk2b948p+dCiFqJiYiIiMgbPErozJo1CxMmTMD999/v9GnX22+/jWeffdbbMRIRERF5hEkaIiIiaqg8SujMnTsXrVu3xsqVK7Fx40YAQPv27bFhwwaMGTPGqwESEREREREREZEzjxI6ADB27FiMHTvWm7EQERERed0vv/yCVatW4fjx4wDsH0LNnDkTN9xwg28DIyIiIqoBha8DICIiIrpW3n//fdx4443Izs7GoEGDMGjQIGRlZSExMRGbNm3ydXhEREREHvOoh05WVhbmz5+PH3/8Ebm5uS7bL168WOPAiIiIiGrqqaeewuuvv45p06Y5la9evRoLFizAuHHjfBQZUFBQgJKSEqcytVqN0NBQl7pWqxVFRUUwGAy1FB0RERHVdR4ldKZOnYpz587h8ccfR0hIiLdjIiIiIvKKixcvYvz48S7l48ePx9y5c30Q0f/MnTsX69evd0rSxMXFYffu3Y7nQgjMmzcPr732GmRZRnh4OF577TWMGDGi9gMmIiKiOsWjhM53332H48ePo1mzZt6Oh4iIiMhrOnfujB9//BFDhgxxKt+7dy+uv/56H0X1P8OGDcOHH35Y5faVK1fin//8J7777jt06dIFq1atwtixY/Hbb78hNja2FiMlIiKiusajOXTCw8Oh1+u9HQsRERGRVw0fPhzjxo3DggULsHXrVnz00UeOoVbDhw/HN9984/jvK/n5+bBarZVue/XVVzF16lQkJiZCqVRi1qxZaNasGdasWVPLURIREVFd41EPnYkTJ+K5557DihUroFBwXmUiIiKqm+bPnw8ASEpKctk2b948p+dCiFqJ6VLbtm3DV199BYvFgptvvhmvvPKKY/WtCxcu4K+//kKvXr2c9unduzcO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E5teCzoKhQKFhYXIz88HABQUFCA3Nxfm5uYwNzcHAMydOxdhYWEICAhAz5498cknn6CgoACvvfaaPkMnIiKiBiQyMhLXr1+vtM/o0aNhY2Oj1f6ysrIAlP149ThHR0dpnTZ9NNHlpee1RalUIicnB0KIBlHQqwrzoY45UcecqGI+1DEn6owhJ9W59FyvBZ1t27Zh5syZAIDGjRtj7NixAMquF58/fz4AYNKkScjPz8fixYulpzv88ccf0uVYRERERHUtISEBkZGRlfYZMmSI1gUdKysrAEBeXp5Ke05OjrROmz6a6PLS89pSfn9EBwcHgx1g6xLzoY45UcecqGI+1DEn6owhJ9W59FyvBZ2JEydi4sSJVfabMWMGZsyYoYOIiIiIiNSFhYVVerl3dbm6usLMzAw3b95Uab958yaeeeYZrftoostLz2uTTCYz+Bh1iflQx5yoY05UMR/qmBN1hp6T6sRlmEdAREREVI+Zm5sjMDAQ27Ztk9rS09Px559/YtiwYVr3ISIioobLoG+KTERERGSMrl+/jsjISGRmZgIADh8+jJs3b6Jz587o3LkzAGDFihXw9/fHuHHj0KNHD6xbtw6dO3dGaGiotB9t+hAREVHDxBk6RERERLUsLS0Nx44dw4ULFxAaGiotP375lI+PDy5cuAAvLy8kJiZi5syZOHbsGMzMzKrVh4iIiBomztAhIiIiqmW9evVCr169quzXpk0bfPTRR0/dh4iIiBoeztAhIiIiIiIiIjIyLOgQERERERERERkZFnSIiIiIiIiIiIwMCzpEREREREREREaGBR0iIiIiIiIiIiPDgg4RERERERERkZFhQYeIiIiIiIiIyMiwoENEREREREREZGRY0CEiIiIiIiIiMjIs6BARERERERERGRkWdIiIiIiIiIiIjAwLOkRERERERERERoYFHSIiIiIiIiIiI8OCDhERERERERGRkWFBh4iIiIiIiIjIyLCgQ0RERERERERkZFjQISIiIiIiIiIyMizoEBEREREREREZGRZ0iIiIiIiIiIiMDAs6RERERERERERGhgUdIiIiIiIiIiIjw4IOEREREREREZGRYUGHiIiIiIiIiMjIsKBDRERERERERGRkTPUdABFpZ/i8bfoOQS/2LQ9+qu2ZNyIiIiIiqo84Q4eIiIiIiIiIyMiwoENEREREREREZGQM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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "rotamer_pose, rotamer_set = build_rotamers(\n", " pose_stack,\n", " SetPackerTask.from_packer_task(design_task),\n", " pose_stack.packed_block_types.chem_db,\n", ")\n", "target_rotamer_count = int(rotamer_set.n_rots_for_block[0, target_block])\n", "target_rotamer_offset = int(rotamer_set.rot_offset_for_block[0, target_block])\n", "\n", "rotamer_rows = []\n", "for local_rotamer in range(target_rotamer_count):\n", " rotamer_index = target_rotamer_offset + local_rotamer\n", " block_type_index = int(rotamer_set.block_type_ind_for_rot[rotamer_index])\n", " block_type = rotamer_pose.packed_block_types.active_block_types[\n", " block_type_index\n", " ]\n", " coordinate_offset = int(rotamer_set.coord_offset_for_rot[rotamer_index])\n", " row = {\n", " \"local_rotamer\": local_rotamer,\n", " \"rotamer_index\": rotamer_index,\n", " \"block_type\": block_type.name,\n", " \"name3\": block_type.name3,\n", " }\n", " for torsion_index in block_type.sc_torsions:\n", " atom_indices = block_type.ordered_torsions[torsion_index, :, 0]\n", " if np.any(atom_indices < 0):\n", " continue\n", " coordinates = rotamer_set.coords[\n", " coordinate_offset\n", " + torch.as_tensor(atom_indices, dtype=torch.long, device=device)\n", " ].double()\n", " radians = coord_dihedrals(\n", " coordinates[0:1],\n", " coordinates[1:2],\n", " coordinates[2:3],\n", " coordinates[3:4],\n", " )[0]\n", " name = block_type.torsions[torsion_index].name\n", " row[f\"{name}_degrees\"] = float(torch.rad2deg(radians).detach().cpu())\n", " rotamer_rows.append(row)\n", "\n", "rotamer_frame = pd.DataFrame(rotamer_rows)\n", "identity_counts = (\n", " rotamer_frame.groupby(\"name3\", as_index=False)\n", " .size()\n", " .rename(columns={\"size\": \"candidate_rotamers\"})\n", " .sort_values(\"candidate_rotamers\", ascending=False)\n", ")\n", "show_table(identity_counts)\n", "\n", "fig, axes = plt.subplots(1, 2, figsize=(11.5, 4.6))\n", "axes[0].bar(identity_counts.name3, identity_counts.candidate_rotamers, color=\"#4c78a8\")\n", "axes[0].set(\n", " xlabel=\"allowed residue identity\",\n", " ylabel=\"candidate rotamers\",\n", " title=f\"Search-space composition at block {target_block}\",\n", ")\n", "axes[0].grid(axis=\"y\", alpha=0.25)\n", "\n", "if {\"chi1_degrees\", \"chi2_degrees\"}.issubset(rotamer_frame.columns):\n", " for name3, values in rotamer_frame.dropna(\n", " subset=[\"chi1_degrees\", \"chi2_degrees\"]\n", " ).groupby(\"name3\"):\n", " axes[1].scatter(\n", " (values.chi1_degrees + 180.0) % 360.0 - 180.0,\n", " (values.chi2_degrees + 180.0) % 360.0 - 180.0,\n", " label=name3,\n", " alpha=0.75,\n", " )\n", " axes[1].legend(fontsize=8, ncol=2)\n", "axes[1].set(\n", " xlim=(-180, 180),\n", " ylim=(-180, 180),\n", " xlabel=\"wrapped χ1 (degrees)\",\n", " ylabel=\"wrapped χ2 (degrees)\",\n", " title=\"Candidate side-chain geometry\",\n", ")\n", "axes[1].grid(alpha=0.25)\n", "plt.tight_layout()\n", "plt.show()\n", "\n", "assert target_rotamer_count == int(identity_counts.candidate_rotamers.sum())\n" ] }, { "cell_type": "markdown", "id": "98ee079c", "metadata": {}, "source": [ "## Inspect and export candidates\n", "\n", "The helper converts each target rotamer's packed coordinates into a single-residue PDB model and joins them into a multi-model file. Neighbors and energies are excluded.\n", "\n", "The viewer shows up to twelve candidates. `rotamer_ensemble_pdb` and the temporary file contain the full ensemble.\n" ] }, { "cell_type": "code", "execution_count": 6, "id": "0ddf176a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "wrote 68 models to block5_rotamer_ensemble.pdb; bytes=112728\n", "MODEL 1\n", "ATOM 1 N ALA A 6 27.751 35.867 13.740 1.00 0.00 N\n", "ATOM 2 CA ALA A 6 27.691 37.315 14.143 1.00 0.00 C\n", "ATOM 3 C ALA A 6 28.469 37.475 15.420 1.00 0.00 C\n", "ATOM 4 O ALA A 6 28.213 36.753 16.411 1.00 0.00 O\n", "ATOM 5 CB ALA A 6 26.260 37.797 14.331 1.00 0.00 C\n", "ATOM 6 H ALA A 6 27.087 35.218 14.137 1.00 0.00 H\n", "ATOM 7 HA ALA A 6 28.141 37.914 13.350 1.00 0.00 H\n" ] }, { "data": { "text/html": [ "\n", "
\n", " \n", "
\n", " \n", "
\n", "
One enumerated side-chain candidate; no packing score applied
\n", "
\n", "

3Dmol.js failed to load for some reason. Please check your browser console for error messages.

\n", "
\n", "\n", "
\n", "
\n", "
One enumerated side-chain candidate; no packing score applied
\n", "
\n", "

3Dmol.js failed to load for some reason. Please check your browser console for error messages.

\n", "
\n", "\n", "
\n", "
\n", "
One enumerated side-chain candidate; no packing score applied
\n", "
\n", "

3Dmol.js failed to load for some reason. Please check your browser console for error messages.

\n", "
\n", "\n", "
\n", "
\n", "
One enumerated side-chain candidate; no packing score applied
\n", "
\n", "

3Dmol.js failed to load for some reason. Please check your browser console for error messages.

\n", "
\n", "\n", "
\n", "
\n", "
One enumerated side-chain candidate; no packing score applied
\n", "
\n", "

3Dmol.js failed to load for some reason. Please check your browser console for error messages.

\n", "
\n", "\n", "
\n", "
\n", "
One enumerated side-chain candidate; no packing score applied
\n", "
\n", "

3Dmol.js failed to load for some reason. Please check your browser console for error messages.

\n", "
\n", "\n", "
\n", "
\n", "
One enumerated side-chain candidate; no packing score applied
\n", "
\n", "

3Dmol.js failed to load for some reason. Please check your browser console for error messages.

\n", "
\n", "\n", "
\n", "
\n", "
One enumerated side-chain candidate; no packing score applied
\n", "
\n", "

3Dmol.js failed to load for some reason. Please check your browser console for error messages.

\n", "
\n", "\n", "
\n", "
\n", "
One enumerated side-chain candidate; no packing score applied
\n", "
\n", "

3Dmol.js failed to load for some reason. Please check your browser console for error messages.

\n", "
\n", "\n", "
\n", "
\n", "
One enumerated side-chain candidate; no packing score applied
\n", "
\n", "

3Dmol.js failed to load for some reason. Please check your browser console for error messages.

\n", "
\n", "\n", "
\n", "
\n", "
One enumerated side-chain candidate; no packing score applied
\n", "
\n", "

3Dmol.js failed to load for some reason. Please check your browser console for error messages.

\n", "
\n", "\n", "
\n", "
\n", "
One enumerated side-chain candidate; no packing score applied
\n", "
\n", "

3Dmol.js failed to load for some reason. Please check your browser console for error messages.

\n", "
\n", "\n", "
\n", "
\n", "
\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "def rotamer_pdb_body(rotamer_index):\n", " block_type_index = int(rotamer_set.block_type_ind_for_rot[rotamer_index])\n", " block_type = rotamer_pose.packed_block_types.active_block_types[\n", " block_type_index\n", " ]\n", " coordinate_offset = int(rotamer_set.coord_offset_for_rot[rotamer_index])\n", " lines = []\n", " for atom_index, atom in enumerate(block_type.atoms, start=1):\n", " x, y, z = rotamer_set.coords[\n", " coordinate_offset + atom_index - 1\n", " ].detach().cpu().tolist()\n", " element = \"\".join(character for character in atom.name if character.isalpha())[:1]\n", " lines.append(\n", " f\"ATOM {atom_index:5d} {atom.name:<4} {block_type.name3:>3} A\"\n", " f\"{target_block + 1:4d} {x:8.3f}{y:8.3f}{z:8.3f}\"\n", " f\" 1.00 0.00 {element:>2}\"\n", " )\n", " return block_type.name3, \"\\n\".join(lines) + \"\\n\"\n", "\n", "\n", "models = []\n", "candidate_views = {}\n", "candidate_notes = {}\n", "for local_rotamer in range(target_rotamer_count):\n", " rotamer_index = target_rotamer_offset + local_rotamer\n", " name3, body = rotamer_pdb_body(rotamer_index)\n", " models.append(f\"MODEL {local_rotamer + 1:4d}\\n{body}ENDMDL\\n\")\n", " if local_rotamer < 12:\n", " label = f\"{local_rotamer:02d}: {name3}\"\n", " candidate_views[label] = body + \"END\\n\"\n", " candidate_notes[label] = \"One enumerated side-chain candidate; no packing score applied\"\n", "\n", "rotamer_ensemble_pdb = \"\".join(models)\n", "export_dir = Path(tempfile.mkdtemp(prefix=\"tmol-rotamer-tutorial-\"))\n", "export_path = export_dir / \"block5_rotamer_ensemble.pdb\"\n", "export_path.write_text(rotamer_ensemble_pdb)\n", "print(\n", " f\"wrote {target_rotamer_count} models to {export_path.name}; \"\n", " f\"bytes={export_path.stat().st_size}\"\n", ")\n", "print(\"\\n\".join(rotamer_ensemble_pdb.splitlines()[:8]))\n", "\n", "try:\n", " display(\n", " tmol.switchable_view(\n", " candidate_views,\n", " notes=candidate_notes,\n", " width=620,\n", " height=360,\n", " )\n", " )\n", "except ImportError as exc:\n", " print(\"Interactive rotamer selector unavailable:\", exc)\n" ] }, { "cell_type": "markdown", "id": "b48c1dd1", "metadata": {}, "source": [ "Switching candidates changes side-chain identity and/or χ geometry while preserving the local backbone frame used to construct the rotamers. The multi-model file is a geometry audit artifact. It is not a trajectory, an ordered energy ranking, or a collection of independently packed structures.\n" ] }, { "cell_type": "markdown", "id": "dc9e1b9f", "metadata": {}, "source": [ "## Run the assignment search and verify the result\n", "\n", "Only now does `pack_rotamers()` score interacting candidates and run the annealer. The result must belong to the audited palette, every non-target identity must remain unchanged, and backbone coordinates must remain fixed. CPU and CUDA use different stochastic search implementations, so the chosen identity and score need not match across devices.\n" ] }, { "cell_type": "code", "execution_count": 7, "id": "44717ac7", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", "\n", "
\n", " \n", " \n", " \n", " \n", " \n", "\n", "\n", "
ⓘstagetarget_identityweighted_score_unitsscore_change
inputLYS28.7787110.000000
custom-palette packingILE27.658930-1.119781
\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "maximum backbone coordinate change: 0.000000 Å\n" ] } ], "source": [ "input_score = total_score(pose_stack)\n", "torch.manual_seed(SEED)\n", "packed_pose = pack_rotamers(\n", " pose_stack, score_function, design_task, verbose=False\n", ")\n", "packed_score = total_score(packed_pose)\n", "original_identity = pose_stack.block_type(0, target_block).name3\n", "packed_identity = packed_pose.block_type(0, target_block).name3\n", "\n", "result_frame = pd.DataFrame(\n", " [\n", " {\n", " \"stage\": \"input\",\n", " \"target_identity\": original_identity,\n", " \"weighted_score_units\": input_score,\n", " \"score_change\": 0.0,\n", " },\n", " {\n", " \"stage\": \"custom-palette packing\",\n", " \"target_identity\": packed_identity,\n", " \"weighted_score_units\": packed_score,\n", " \"score_change\": packed_score - input_score,\n", " },\n", " ]\n", ")\n", "show_table(result_frame)\n", "\n", "for block in range(pose_stack.max_n_blocks):\n", " if block != target_block:\n", " assert packed_pose.block_type(0, block).name3 == pose_stack.block_type(0, block).name3\n", "assert packed_identity in palette.allowed_name3s | {original_identity}\n", "\n", "# N, CA, C, and O coordinates are unaffected by side-chain packing.\n", "max_backbone_change = 0.0\n", "for block in range(pose_stack.max_n_blocks):\n", " before_type = pose_stack.block_type(0, block)\n", " after_type = packed_pose.block_type(0, block)\n", " before_offset = int(pose_stack.block_coord_offset64[0, block])\n", " after_offset = int(packed_pose.block_coord_offset64[0, block])\n", " for atom_name in (\"N\", \"CA\", \"C\", \"O\"):\n", " delta = (\n", " packed_pose.coords[0, after_offset + after_type.atom_to_idx[atom_name]]\n", " - pose_stack.coords[0, before_offset + before_type.atom_to_idx[atom_name]]\n", " )\n", " max_backbone_change = max(\n", " max_backbone_change,\n", " float(torch.linalg.vector_norm(delta).detach().cpu()),\n", " )\n", "print(f\"maximum backbone coordinate change: {max_backbone_change:.6f} Å\")\n", "assert max_backbone_change < 1e-4\n" ] }, { "cell_type": "code", "execution_count": 8, "id": "1dbf3080", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "
\n", " \n", "
\n", " \n", "
\n", "
weighted score 28.779
\n", "
\n", "

3Dmol.js failed to load for some reason. Please check your browser console for error messages.

\n", "
\n", "\n", "
\n", "
\n", "
weighted score 27.659; change -1.120
\n", "
\n", "

3Dmol.js failed to load for some reason. Please check your browser console for error messages.

\n", "
\n", "\n", "
\n", "
\n", "
\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "try:\n", " display(\n", " tmol.switchable_view(\n", " {\n", " f\"input ({original_identity})\": pose_stack,\n", " f\"packed ({packed_identity})\": packed_pose,\n", " },\n", " notes={\n", " f\"input ({original_identity})\": f\"weighted score {input_score:.3f}\",\n", " f\"packed ({packed_identity})\": (\n", " f\"weighted score {packed_score:.3f}; \"\n", " f\"change {packed_score - input_score:+.3f}\"\n", " ),\n", " },\n", " width=720,\n", " height=400,\n", " )\n", " )\n", "except ImportError as exc:\n", " print(\"Interactive packed comparison unavailable:\", exc)\n" ] }, { "cell_type": "markdown", "id": "4725f66f", "metadata": {}, "source": [ "The packed target is either one hydrophobic alphabet member or the retained original LYS. The rest of the sequence and all backbone coordinates remain fixed. The table reports the score change for this packing outcome.\n", "\n", "## Validation\n", "\n", "1. Start from `super().block_types_from_original()` so chemical compatibility is preserved.\n", "2. Only remove `True` choices; never manufacture a block-type index that was not considered.\n", "3. Retain at least one valid choice at every real block.\n", "4. Audit identity and rotamer counts before annealing.\n", "5. Distinguish deterministic candidate enumeration from stochastic assignment search.\n", "6. Verify unchanged identities and coordinates outside the intended region.\n", "\n", "## Exercises\n", "\n", "1. Add TYR and TRP to the palette and compare how identity and rotamer counts change.\n", "2. Apply `or_expand_chi(0)` only at the target and compare χ-space before and after expansion.\n", "3. Pack several identical poses in one batch and summarize the distribution of selected identities without treating CPU and CUDA outcomes as the same protocol.\n", "\n", "## References\n", "\n", "- [Tutorial 04 — Packing and a Small Mutation Scan](04_packing_and_mutation_scan.ipynb)\n", "- [Tutorial 06 — FastRelax](06_fast_relax.ipynb)\n", "- [Packing API](../api/pack.rst)\n", "- [Pose API](../api/pose.rst)\n" ] } ], "metadata": { "accelerator": "GPU", "colab": { "gpuType": "T4" }, "language_info": { "name": "python" } }, "nbformat": 4, "nbformat_minor": 5 }