{ "cells": [ { "cell_type": "markdown", "id": "2993576b", "metadata": {}, "source": [ "# TMol How-To Guide — Advanced Topics\n", "\n", "[](https://colab.research.google.com/github/RosettaCommons/tmol/blob/main/docs/tutorial/08_advanced_topics.ipynb)" ] }, { "cell_type": "markdown", "id": "9e4ac368", "metadata": {}, "source": [ "## 8. Advanced Topics" ] }, { "cell_type": "markdown", "id": "e9396449", "metadata": {}, "source": [ "Two unrelated deep-end topics: customizing which identities the packer offers at a position (beyond the single-target `restrict_absent_name3s` from section 1), and building a `PoseStack` directly from fixed-width atom37 tensors -- the representation most structure-prediction models output -- while keeping the whole thing differentiable." ] }, { "cell_type": "markdown", "id": "ecb35447", "metadata": {}, "source": [ "### Setup" ] }, { "cell_type": "markdown", "id": "043e6177", "metadata": {}, "source": [ "Wheel install, imports, seeding, and device selection live in [notebook_setup.py](https://github.com/RosettaCommons/tmol/blob/main/docs/tutorial/notebook_setup.py)." ] }, { "cell_type": "code", "execution_count": 1, "id": "8c6870ce", "metadata": { "execution": { "iopub.execute_input": "2026-10-20T00:49:10.229411Z", "iopub.status.busy": "2026-10-20T00:49:10.229039Z", "iopub.status.idle": "2026-10-20T00:51:18.530593Z", "shell.execute_reply": "2026-10-20T00:51:18.523949Z" }, "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" ] } ], "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 urlretrieve\n", "\n", " urlretrieve(\n", " \"https://raw.githubusercontent.com/RosettaCommons/tmol/\"\n", " \"main/docs/tutorial/notebook_setup.py\",\n", " \"notebook_setup.py\",\n", " )\n", "\n", "from notebook_setup import * # noqa: F401,F403\n", "\n", "device, param_db = setup()\n" ] }, { "cell_type": "markdown", "id": "145a7b46", "metadata": {}, "source": [ "### Extending the packer for design" ] }, { "cell_type": "markdown", "id": "0b3e9313", "metadata": {}, "source": [ "#### PackerPalette" ] }, { "cell_type": "markdown", "id": "3e086a33", "metadata": {}, "source": [ "`PackerPalette` decides, per position, which identities are ever candidates; `restrict_absent_name3s` (section 1) then narrows that set further from outside. Subclass `PackerPalette` and override `block_types_from_original` to change the candidate set itself -- call `super().block_types_from_original(pbt, orig)` for the defaults, then filter or reorder them. Unlike `restrict_absent_name3s`, this applies uniformly everywhere the palette is used, not one position at a time." ] }, { "cell_type": "markdown", "id": "e4ba09ed", "metadata": {}, "source": [ "#### A worked design example" ] }, { "cell_type": "markdown", "id": "6068daf4", "metadata": {}, "source": [ "A palette that only ever offers a small hydrophobic alphabet (plus whatever the position's own original identity is, so a non-matching position can still \"keep its own\"):" ] }, { "cell_type": "code", "execution_count": 2, "id": "035b1d0e", "metadata": { "execution": { "iopub.execute_input": "2026-10-20T00:51:18.546396Z", "iopub.status.busy": "2026-10-20T00:51:18.545957Z", "iopub.status.idle": "2026-10-20T00:51:18.603502Z", "shell.execute_reply": "2026-10-20T00:51:18.602696Z" } }, "outputs": [], "source": [ "class HydrophobicPalette(PackerPalette):\n", " \"\"\"Allow a small hydrophobic alphabet plus each position's own identity.\"\"\"\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(pbt, orig)\n", " in_alphabet = torch.tensor(\n", " [block_type.name3 in self.allowed_name3s for block_type in pbt.active_block_types],\n", " dtype=torch.bool, 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" ] }, { "cell_type": "code", "execution_count": 3, "id": "670583bf", "metadata": { "execution": { "iopub.execute_input": "2026-10-20T00:51:18.605331Z", "iopub.status.busy": "2026-10-20T00:51:18.605106Z", "iopub.status.idle": "2026-10-20T00:51:45.903364Z", "shell.execute_reply": "2026-10-20T00:51:45.902323Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/runner/work/tmol/tmol/.venv/lib/python3.12/site-packages/biotite/structure/io/pdb/file.py:629: DeprecationWarning: The chararray class is deprecated and will be removed in a future release. Use an ndarray with a string or bytes dtype instead.\n", " record = np.char.array(np.where(array.hetero, \"HETATM\", \"ATOM\"))\n" ] }, { "data": { "application/3dmoljs_load.v0": "
3Dmol.js failed to load for some reason. Please check your browser console for error messages.
3Dmol.js failed to load for some reason. Please check your browser console for error messages.
3Dmol.js failed to load for some reason. Please check your browser console for error messages.
3Dmol.js failed to load for some reason. Please check your browser console for error messages.