Download staplebridge/hydrocarbon/geometry.py from ChatterjeeLab/StapleBridge: direct link, hf CLI and curl.
- Browser
- Download file 3.63 kB
-
https://huggingface.co/ChatterjeeLab/StapleBridge/resolve/main/staplebridge/hydrocarbon/geometry.py
- Command line
-
hf download hf://ChatterjeeLab/StapleBridge/staplebridge/hydrocarbon/geometry.py
-
curl -L -o geometry.py https://huggingface.co/ChatterjeeLab/StapleBridge/resolve/main/staplebridge/hydrocarbon/geometry.py
3.63 kB
| """Hydrocarbon geometry oracle. | |
| The lactam oracles in :mod:`staplebridge.oracles.geometry` (``MockGeometryOracle``, | |
| ``CPComposerStapledOracle``) are **not modified**. This is a separate oracle for | |
| the hydrocarbon branch, because the two chemistries have genuinely different | |
| feasibility criteria: | |
| * lactam K-D/E closes at i,i+3 / i,i+4 with a 4.0-6.5 A Cα window; | |
| * hydrocarbon RCM staples span one helical turn (i,i+4) or two (i,i+7), so the | |
| i,i+7 window sits much further out. | |
| ``ctype`` here additionally requires that the anchor residues really are the | |
| anchor monomers the block names, which the lactam oracle has no notion of. | |
| """ | |
| from __future__ import annotations | |
| import math | |
| from typing import Any | |
| from staplebridge.data.schemas import BuildingBlock | |
| from staplebridge.hydrocarbon.actions import FailureReason, validate_hydrocarbon_staple | |
| from staplebridge.hydrocarbon.catalog import is_hydrocarbon_block | |
| from staplebridge.oracles.base import GeometryOracleBase | |
| def _ca_distance( | |
| coords: list[tuple[float, float, float]] | None, i: int, j: int | |
| ) -> float | None: | |
| """Cα(i)-Cα(j) distance, or ``None`` when coordinates are unavailable.""" | |
| if coords is None or i < 0 or j < 0 or i >= len(coords) or j >= len(coords): | |
| return None | |
| xi, yi, zi = coords[i] | |
| xj, yj, zj = coords[j] | |
| return math.sqrt((xi - xj) ** 2 + (yi - yj) ** 2 + (zi - zj) ** 2) | |
| class HydrocarbonGeometryOracle(GeometryOracleBase): | |
| """Feasibility for hydrocarbon staples. | |
| Args: | |
| catalog: the hydrocarbon blocks in play, used for topology validation. | |
| sentinel_cgeom: penalty returned when the staple is not even | |
| type-feasible. Matches the lactam oracles' convention of a large | |
| sentinel so that stage-aware geometry can detect it. | |
| """ | |
| def __init__( | |
| self, | |
| catalog: list[BuildingBlock] | None = None, | |
| sentinel_cgeom: float = 10.0, | |
| ) -> None: | |
| self.catalog = list(catalog or []) | |
| self.sentinel_cgeom = float(sentinel_cgeom) | |
| def ctype( | |
| self, | |
| sequence: list[str], | |
| anchor_pair: tuple[int, int] | None, | |
| block: BuildingBlock | None, | |
| *, | |
| peptide_ca: Any = None, | |
| ) -> bool: | |
| """True when ``(sequence, anchor_pair, block)`` is a legal hydrocarbon staple. | |
| Sequence-level only; the Cα window is scored by :meth:`cgeom`. | |
| """ | |
| del peptide_ca | |
| if block is None or not is_hydrocarbon_block(block): | |
| return False | |
| catalog = self.catalog or [block] | |
| verdict = validate_hydrocarbon_staple(sequence, anchor_pair, block, catalog) | |
| return verdict is FailureReason.OK | |
| def cgeom( | |
| self, | |
| sequence: list[str], | |
| anchor_pair: tuple[int, int] | None, | |
| block: BuildingBlock | None, | |
| *, | |
| peptide_ca: Any = None, | |
| ) -> float: | |
| """Distance of Cα(i)-Cα(j) from the block's allowed window, in Å. | |
| Returns ``0.0`` inside the window. Without coordinates, falls back to a | |
| sequence-only verdict: ``0.0`` when type-feasible, else the sentinel. | |
| """ | |
| if not self.ctype(sequence, anchor_pair, block): | |
| return self.sentinel_cgeom | |
| assert anchor_pair is not None and block is not None # ctype guarantees | |
| i, j = anchor_pair | |
| distance = _ca_distance(peptide_ca, i, j) | |
| if distance is None: | |
| return 0.0 | |
| low, high = block.ca_window | |
| if distance < low: | |
| return float(low - distance) | |
| if distance > high: | |
| return float(distance - high) | |
| return 0.0 | |