lacuna-pockets 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. lacuna_pockets-0.1.0/.github/workflows/ci.yml +33 -0
  2. lacuna_pockets-0.1.0/.github/workflows/publish.yml +39 -0
  3. lacuna_pockets-0.1.0/.gitignore +14 -0
  4. lacuna_pockets-0.1.0/CITATION.cff +33 -0
  5. lacuna_pockets-0.1.0/LICENSE +21 -0
  6. lacuna_pockets-0.1.0/LICENSE_COMMERCIAL +42 -0
  7. lacuna_pockets-0.1.0/PKG-INFO +341 -0
  8. lacuna_pockets-0.1.0/PREDICTIONS.md +144 -0
  9. lacuna_pockets-0.1.0/README.md +281 -0
  10. lacuna_pockets-0.1.0/benchmarks/boltz_nearmiss.py +213 -0
  11. lacuna_pockets-0.1.0/benchmarks/boltz_nearmiss_results.json +20 -0
  12. lacuna_pockets-0.1.0/benchmarks/compare_fpocket.py +313 -0
  13. lacuna_pockets-0.1.0/benchmarks/cryptic_benchmark.py +745 -0
  14. lacuna_pockets-0.1.0/benchmarks/cryptic_benchmark_results.json +419 -0
  15. lacuna_pockets-0.1.0/benchmarks/run_benchmarks.py +271 -0
  16. lacuna_pockets-0.1.0/examples/kras_cryptic.py +105 -0
  17. lacuna_pockets-0.1.0/lacuna/__init__.py +18 -0
  18. lacuna_pockets-0.1.0/lacuna/cli.py +326 -0
  19. lacuna_pockets-0.1.0/lacuna/ensemble/__init__.py +0 -0
  20. lacuna_pockets-0.1.0/lacuna/ensemble/base.py +31 -0
  21. lacuna_pockets-0.1.0/lacuna/ensemble/boltz_backend.py +161 -0
  22. lacuna_pockets-0.1.0/lacuna/ensemble/nma_backend.py +187 -0
  23. lacuna_pockets-0.1.0/lacuna/ensemble/openmm_backend.py +100 -0
  24. lacuna_pockets-0.1.0/lacuna/ensemble/random_backend.py +98 -0
  25. lacuna_pockets-0.1.0/lacuna/io/__init__.py +0 -0
  26. lacuna_pockets-0.1.0/lacuna/io/structure.py +299 -0
  27. lacuna_pockets-0.1.0/lacuna/io/writers.py +193 -0
  28. lacuna_pockets-0.1.0/lacuna/models.py +84 -0
  29. lacuna_pockets-0.1.0/lacuna/pockets/__init__.py +0 -0
  30. lacuna_pockets-0.1.0/lacuna/pockets/clusterer.py +137 -0
  31. lacuna_pockets-0.1.0/lacuna/pockets/detector.py +191 -0
  32. lacuna_pockets-0.1.0/lacuna/pockets/scorer.py +63 -0
  33. lacuna_pockets-0.1.0/paper.bib +124 -0
  34. lacuna_pockets-0.1.0/paper.md +133 -0
  35. lacuna_pockets-0.1.0/pyproject.toml +62 -0
  36. lacuna_pockets-0.1.0/run_5ht2a_boltz.py +90 -0
  37. lacuna_pockets-0.1.0/run_adra2a_boltz.py +89 -0
  38. lacuna_pockets-0.1.0/run_ctnnb1_boltz.py +134 -0
  39. lacuna_pockets-0.1.0/run_egfr_benchmark.py +107 -0
  40. lacuna_pockets-0.1.0/run_kras_g12d_boltz.py +95 -0
  41. lacuna_pockets-0.1.0/run_myc_benchmark.py +82 -0
  42. lacuna_pockets-0.1.0/run_sensitivity_analysis.py +68 -0
  43. lacuna_pockets-0.1.0/tests/__init__.py +0 -0
  44. lacuna_pockets-0.1.0/tests/test_cli.py +301 -0
  45. lacuna_pockets-0.1.0/tests/test_clusterer.py +88 -0
  46. lacuna_pockets-0.1.0/tests/test_detector.py +116 -0
  47. lacuna_pockets-0.1.0/tests/test_ensemble.py +186 -0
  48. lacuna_pockets-0.1.0/tests/test_homodimer.py +138 -0
  49. lacuna_pockets-0.1.0/tests/test_scorer.py +77 -0
  50. lacuna_pockets-0.1.0/tests/test_writers.py +111 -0
@@ -0,0 +1,33 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.10", "3.11", "3.12"]
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - name: Set up Python ${{ matrix.python-version }}
20
+ uses: actions/setup-python@v5
21
+ with:
22
+ python-version: ${{ matrix.python-version }}
23
+
24
+ - name: Install dependencies
25
+ run: |
26
+ python -m pip install --upgrade pip
27
+ pip install -e ".[dev]"
28
+
29
+ - name: Run tests
30
+ run: python -m pytest tests/ -v --tb=short
31
+
32
+ - name: Check import
33
+ run: python -c "import lacuna; print('lacuna', lacuna.__version__)"
@@ -0,0 +1,39 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ build:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+
13
+ - uses: actions/setup-python@v5
14
+ with:
15
+ python-version: "3.11"
16
+
17
+ - name: Build
18
+ run: |
19
+ python -m pip install build
20
+ python -m build
21
+
22
+ - uses: actions/upload-artifact@v4
23
+ with:
24
+ name: dist
25
+ path: dist/
26
+
27
+ publish:
28
+ needs: build
29
+ runs-on: ubuntu-latest
30
+ environment: pypi
31
+ permissions:
32
+ id-token: write # required for OIDC trusted publishing
33
+ steps:
34
+ - uses: actions/download-artifact@v4
35
+ with:
36
+ name: dist
37
+ path: dist/
38
+
39
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,14 @@
1
+ __pycache__/
2
+ *.pyc
3
+ *.pyo
4
+ .pytest_cache/
5
+ *.egg-info/
6
+ dist/
7
+ build/
8
+ .venv/
9
+ venv/
10
+ *_lacuna/
11
+ *.npz
12
+ *.npy
13
+ *.log
14
+ benchmarks/pdb_cache/
@@ -0,0 +1,33 @@
1
+ cff-version: 1.2.0
2
+ message: "If you use Lacuna in your research, please cite it as below."
3
+ type: software
4
+ title: "Lacuna: Cryptic Binding Pocket Discovery via Conformational Ensemble Analysis"
5
+ authors:
6
+ - family-names: Moore
7
+ given-names: Clayton W.
8
+ version: 0.1.0
9
+ date-released: 2026-06-02
10
+ url: "https://github.com/mooreneural/lacuna"
11
+ repository-code: "https://github.com/mooreneural/lacuna"
12
+ license: "LicenseRef-Lacuna-NonCommercial"
13
+ abstract: >
14
+ Lacuna discovers cryptic binding pockets in proteins by generating a
15
+ conformational ensemble, detecting pockets per conformer, clustering
16
+ across the ensemble, and ranking by persistence and druggability.
17
+ Validated on 20 cryptic-pocket targets (14/20, 70%), matching the
18
+ CryptoSite benchmark. Supports RandomBackend (CPU, ~1–4 s/protein)
19
+ and Boltz-2 partial diffusion for harder targets.
20
+ keywords:
21
+ - drug-discovery
22
+ - cryptic-pockets
23
+ - protein-structure
24
+ - conformational-ensemble
25
+ - computational-biology
26
+ preferred-citation:
27
+ type: software
28
+ title: "Lacuna: Cryptic Binding Pocket Discovery via Conformational Ensemble Analysis"
29
+ authors:
30
+ - family-names: Moore
31
+ given-names: Clayton W.
32
+ year: 2026
33
+ url: "https://github.com/mooreneural/lacuna"
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Clayton Moore
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,42 @@
1
+ Lacuna Commercial License Agreement
2
+
3
+ Copyright (c) 2026 Clayton Moore. All rights reserved.
4
+
5
+ This Commercial License Agreement ("Agreement") governs use of the Lacuna
6
+ software ("Software") by for-profit entities and organizations requiring terms
7
+ beyond those provided by the MIT license.
8
+
9
+ Lacuna is available at no cost under the MIT License for any use. This
10
+ Commercial License provides additional terms — warranties, indemnification,
11
+ support SLAs, and custom integration rights — for organizations that require
12
+ them.
13
+
14
+ COMMERCIAL LICENSE PROVIDES:
15
+
16
+ 1. INDEMNIFICATION. Licensor will defend and indemnify Licensee against third-
17
+ party intellectual property claims arising from Licensee's authorized use of
18
+ the Software, subject to the terms of a separately executed agreement.
19
+
20
+ 2. WARRANTY. Licensor provides a limited warranty that the Software will
21
+ perform materially as described in the documentation for 90 days from
22
+ delivery, with remedies defined in the separately executed agreement.
23
+
24
+ 3. SUPPORT. Licensee receives priority bug fixes, direct email/phone support,
25
+ and guaranteed response times as specified in the separately executed
26
+ agreement.
27
+
28
+ 4. CUSTOM DEVELOPMENT. Licensor will develop custom features, integrations, or
29
+ validated workflows for Licensee under a statement of work.
30
+
31
+ 5. DEPLOYMENT RIGHTS. For organizations requiring deployment in air-gapped or
32
+ restricted environments, Licensor provides deployment assistance and
33
+ site-specific licensing under this agreement.
34
+
35
+ TO OBTAIN A COMMERCIAL LICENSE:
36
+ Contact: claytonwaynemoore@gmail.com
37
+
38
+ Subject line: "Lacuna Commercial License Inquiry"
39
+
40
+ The MIT License remains the operative license for all use not covered by a
41
+ separately executed commercial agreement. Nothing in this document restricts
42
+ any rights granted by the MIT License.
@@ -0,0 +1,341 @@
1
+ Metadata-Version: 2.4
2
+ Name: lacuna-pockets
3
+ Version: 0.1.0
4
+ Summary: Cryptic binding pocket discovery via conformational ensemble analysis
5
+ Project-URL: Homepage, https://github.com/mooreneural/lacuna
6
+ Project-URL: Repository, https://github.com/mooreneural/lacuna
7
+ Project-URL: Issues, https://github.com/mooreneural/lacuna/issues
8
+ Author: Clayton Moore
9
+ License: MIT License
10
+
11
+ Copyright (c) 2026 Clayton Moore
12
+
13
+ Permission is hereby granted, free of charge, to any person obtaining a copy
14
+ of this software and associated documentation files (the "Software"), to deal
15
+ in the Software without restriction, including without limitation the rights
16
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
+ copies of the Software, and to permit persons to whom the Software is
18
+ furnished to do so, subject to the following conditions:
19
+
20
+ The above copyright notice and this permission notice shall be included in all
21
+ copies or substantial portions of the Software.
22
+
23
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
+ SOFTWARE.
30
+ License-File: LICENSE
31
+ License-File: LICENSE_COMMERCIAL
32
+ Keywords: cheminformatics,cryptic-pockets,drug-discovery,protein-structure
33
+ Classifier: Development Status :: 3 - Alpha
34
+ Classifier: Intended Audience :: Science/Research
35
+ Classifier: License :: OSI Approved :: MIT License
36
+ Classifier: Programming Language :: Python :: 3
37
+ Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
38
+ Classifier: Topic :: Scientific/Engineering :: Chemistry
39
+ Requires-Python: >=3.10
40
+ Requires-Dist: biopython>=1.81
41
+ Requires-Dist: click>=8.1
42
+ Requires-Dist: numpy>=1.24
43
+ Requires-Dist: rich>=13.0
44
+ Requires-Dist: scipy>=1.10
45
+ Provides-Extra: all
46
+ Requires-Dist: boltz>=0.4; extra == 'all'
47
+ Requires-Dist: openmm>=8.0; extra == 'all'
48
+ Requires-Dist: pdbfixer>=1.9; extra == 'all'
49
+ Provides-Extra: boltz
50
+ Requires-Dist: boltz>=0.4; extra == 'boltz'
51
+ Provides-Extra: dev
52
+ Requires-Dist: mypy; extra == 'dev'
53
+ Requires-Dist: pytest-cov; extra == 'dev'
54
+ Requires-Dist: pytest>=7.0; extra == 'dev'
55
+ Requires-Dist: ruff; extra == 'dev'
56
+ Provides-Extra: openmm
57
+ Requires-Dist: openmm>=8.0; extra == 'openmm'
58
+ Requires-Dist: pdbfixer>=1.9; extra == 'openmm'
59
+ Description-Content-Type: text/markdown
60
+
61
+ # Lacuna
62
+
63
+ **Cryptic binding pocket discovery via conformational ensemble analysis.**
64
+
65
+ Most protein structure predictors (AlphaFold, Boltz, Chai) give you one static structure. But ~70% of disease-relevant proteins are considered "undruggable" not because they're biologically intractable - it's because no pocket is visible in their ground state. K-Ras was "undruggable" for 30 years until a transient cryptic pocket was found in its switch-II region. That pocket now backs sotorasib and adagrasib.
66
+
67
+ Lacuna finds those pockets. It generates a conformational ensemble from any input structure, detects pockets per conformer, and clusters them across the ensemble to surface sites that only appear transiently - ranked by druggability and persistence.
68
+
69
+ ```
70
+ lacuna discover kras.pdb --conformers 20 --emit-boltz-constraints --emit-vina-boxes
71
+ ```
72
+
73
+ ---
74
+
75
+ ## Install
76
+
77
+ ```bash
78
+ pip install lacuna-pockets
79
+ ```
80
+
81
+ **Optional backends** (better conformational sampling):
82
+ ```bash
83
+ pip install "lacuna-pockets[openmm]" # 100ps implicit-solvent MD
84
+ pip install "lacuna-pockets[boltz]" # Boltz-2 partial diffusion (best quality, GPU recommended)
85
+ pip install "lacuna-pockets[all]" # everything
86
+ ```
87
+
88
+ Requires Python 3.10+.
89
+
90
+ ---
91
+
92
+ ## Quick start
93
+
94
+ ### CLI
95
+
96
+ ```bash
97
+ # Discover pockets with defaults (NMA backend - physically grounded, no GPU needed)
98
+ lacuna discover protein.pdb --conformers 20
99
+
100
+ # Filter and limit output
101
+ lacuna discover protein.pdb --min-druggability 0.5 --min-persistence 0.3 --top 5
102
+
103
+ # Analyze a homodimer - detects pockets at the dimer interface (e.g. Caspase-1, IDH1)
104
+ # Reads BIOMT records from PDB; for best results use the biological assembly download from RCSB
105
+ lacuna discover protein.pdb --homodimer --conformers 20
106
+
107
+ # Use Boltz-2 partial diffusion for highest-quality sampling
108
+ lacuna discover protein.pdb --backend boltz --conformers 30
109
+
110
+ # Emit all docking file formats
111
+ lacuna discover protein.pdb --emit-boltz-constraints --emit-vina-boxes --emit-pocket-pdbs
112
+
113
+ # Generate docking files from a previous report
114
+ lacuna dock-prep kras_lacuna/pocket_report.json kras.pdb --format all
115
+ ```
116
+
117
+ ### Python API
118
+
119
+ ```python
120
+ from lacuna import load_structure, detect_pockets, cluster_pockets
121
+ from lacuna.ensemble.nma_backend import NMABackend
122
+ from lacuna.io.structure import coords_array
123
+ from lacuna.io.writers import write_report, write_boltz_constraint
124
+
125
+ structure = load_structure("protein.pdb")
126
+ backend = NMABackend(seed=42)
127
+ coord_sets = backend.generate("protein.pdb", n_conformers=20)
128
+
129
+ all_coords = [coords_array(structure)] + coord_sets
130
+ pocket_lists = []
131
+ for ci, coords in enumerate(all_coords):
132
+ pockets = detect_pockets(coords, structure)
133
+ for p in pockets:
134
+ p.conformer_idx = ci
135
+ pocket_lists.append(pockets)
136
+
137
+ clusters = cluster_pockets(pocket_lists, n_conformers=len(all_coords))
138
+ for c in clusters[:5]:
139
+ print(f"Rank {c.rank} druggability={c.druggability:.3f} "
140
+ f"persistence={c.persistence:.0%} cryptic={c.cryptic}")
141
+ print(f" Residues: {', '.join(c.lining_residues[:5])}")
142
+ ```
143
+
144
+ ---
145
+
146
+ ## How it works
147
+
148
+ 1. **Ensemble generation** - Generate N conformers via elastic network model normal mode analysis (built-in), OpenMM implicit-solvent MD, or Boltz-2 partial diffusion at varying noise levels
149
+ 2. **Pocket detection** - Grid-based alpha-point analysis per conformer: compute distance transform, find local maxima within the 1.4–5.5 Å interaction zone, cluster nearby alpha-points into pocket candidates
150
+ 3. **Cross-ensemble clustering** - Greedy centroid merging clusters corresponding pockets across all conformers
151
+ 4. **Druggability scoring** - Gaussian volume reward centered at 300 ų + enclosure + hydrophobicity + aromaticity (Halgren 2009)
152
+ 5. **Cryptic flagging** - Pockets present in <90% of conformers are marked `cryptic: true`
153
+
154
+ ---
155
+
156
+ ## Outputs
157
+
158
+ | File | Description |
159
+ |------|-------------|
160
+ | `pocket_report.json` | Ranked pocket metadata: centroid, volume, druggability, persistence, lining residues |
161
+ | `pocket_N_site.pdb` | Pseudoatom PDB for PyMOL/ChimeraX visualization |
162
+ | `pocket_N_constraint.yaml` | Boltz YAML - add a SMILES and run `boltz predict` to dock into this site |
163
+ | `pocket_N_vina.conf` | AutoDock Vina / Gnina / QuickVina box config |
164
+
165
+ ---
166
+
167
+ ## Backends
168
+
169
+ | Backend | Install | Quality | Speed | Notes |
170
+ |---------|---------|---------|-------|-------|
171
+ | `nma` | built-in | good | ~0.1s/conf | Anisotropic Network Model normal mode analysis - hinge bending, breathing, twist motions |
172
+ | `openmm` | `lacuna[openmm]` | good | ~2s/conf | 100ps Langevin MD, GBn2 implicit solvent |
173
+ | `boltz` | `lacuna[boltz]` | best | ~30s/conf (GPU) | Boltz-2 partial diffusion at varying noise fractions |
174
+ | `random` | built-in | baseline | ~0.04s/conf | Correlated Gaussian backbone perturbation |
175
+
176
+ **Auto-selection order:** `boltz` → `openmm` → `nma` → `random`. On a plain `pip install lacuna`, the NMA backend runs automatically.
177
+
178
+ The `nma` backend samples physically meaningful collective motions — the same hinge-bending and breathing modes that open cryptic pockets in nature — without requiring a GPU or force field. It replaces `random` as the zero-dependency default. For large-scale loop rearrangements or very deep cryptic sites, `boltz` remains the best option.
179
+
180
+ ---
181
+
182
+ ## Benchmarks
183
+
184
+ **14 / 20 cryptic pockets detected (70%, NMABackend, 20 conformers)** - matching the CryptoSite published benchmark rate on a statistically defensible N=20 set.
185
+
186
+ Success criterion: pocket centroid within 4 Å of the known binding-site centroid (field standard) **or** ≥30% residue overlap in top-5 pockets.
187
+
188
+ ### Cryptic pockets - 14 / 20 (70%)
189
+
190
+ | Protein | Apo PDB | Drug target | Overlap | Time |
191
+ |---------|---------|-------------|---------|------|
192
+ | ✅ T4L L99A hydrophobic cavity | 1L90 | - | 100% | 0.9s |
193
+ | ✅ K-Ras switch-II pocket | 4OBE | sotorasib / adagrasib | 93% | 0.9s |
194
+ | ✅ MDM2 p53-binding cleft | 1Z1M | nutlin-3 | 95% | 1.1s |
195
+ | ✅ BCL-XL BH3 groove | 1LXL | navitoclax | 91% | 2.9s |
196
+ | ✅ BCL-2 BH3 groove | 1G5M | venetoclax | 73% | 1.2s |
197
+ | ✅ c-ABL myristate pocket | 3CS9 | asciminib | 44% | 1.7s |
198
+ | ✅ PTP1B allosteric helix site | 1A5Y | benzofuran inhibitors | 41% | 2.1s |
199
+ | ✅ p38α DFG-out pocket | 1P38 | BIRB 796 | 38% | 3.0s |
200
+ | ✅ HIV-1 RT NNRTI pocket | 1HMV | nevirapine | 38% | 8.3s |
201
+ | ✅ HCV NS5B thumb-site I | 1NB4 | VXR class | 33% | 4.4s |
202
+ | ✅ PKM2 allosteric activator | 1ZJH | TEPP-46 class | 33% | 4.3s |
203
+ | ✅ PPARγ allosteric AF-2 site | 2PRG | metaglidasen | 35% | 1.7s |
204
+ | ✅ Glucokinase allosteric site | 1V4S | B84 activator | 30% | 3.7s |
205
+ | ✅ MMP-13 S1′ allosteric tunnel | 2OZR | non-zinc inhibitors | 50% | 1.1s |
206
+ | ❌ IL-2 helix-α1 site *(Boltz-2 → 71% ✅)* | 1M47 | - | 21% | 0.7s |
207
+ | ❌ Src myristate pocket | 2SRC | - | 28% | 4.1s |
208
+ | ❌ SHP-2 allosteric tunnel | 2SHP | SHP099 class | 24% | 6.0s |
209
+ | ❌ ERK2 allosteric site | 2ERK | - | 27% | 2.9s |
210
+ | ❌ Caspase-1 dimer interface | 2HBQ | - | 8% | 1.6s |
211
+ | ❌ IDH1 R132H dimer interface | 3MAP | ivosidenib | 0% | 3.7s |
212
+
213
+ The six misses fall into two mechanistic classes: **near-misses** (IL-2, Src, SHP-2, ERK2 all 21–28%) where a physics-based backend closes the gap, and **dimer-interface pockets** (Caspase-1, IDH1 R132H) where the pocket forms between two chains.
214
+
215
+ Dimer-interface pockets are now addressable with the `--homodimer` flag, which reads BIOMT symmetry records from the PDB and constructs the full biological assembly before analysis:
216
+
217
+ ```bash
218
+ lacuna discover 2HBQ.pdb --homodimer --conformers 20 # Caspase-1 dimer interface
219
+ lacuna discover 3MAP.pdb --homodimer --conformers 20 # IDH1 R132H dimer interface
220
+ ```
221
+
222
+ IL-2 is confirmed at 71% rank 1 with Boltz-2 partial diffusion.
223
+
224
+ ### Boltz-2 re-evaluation of near-misses
225
+
226
+ | Protein | RandomBackend | Boltz-2 | Notes |
227
+ |---------|--------------|---------|-------|
228
+ | IL-2 (1M47) | 21% - ❌ | **71% rank 1 - ✅** | Boltz samples the helix-α1 open state |
229
+ | Src myristate (2SRC) | 28% - ❌ | 8% - ❌ | Requires SH2-kinase linker rearrangement; needs MD |
230
+
231
+ ### Conformational and orthosteric controls
232
+
233
+ | Category | Result | Notable entries |
234
+ |----------|--------|-----------------|
235
+ | Conformational | 1 / 1 (100%) | Adenylate kinase open→closed (35%, rank 1) |
236
+ | Orthosteric | 4 / 6 (67%) | HIV protease 100%, DHFR 100%, HIF-2α 100% |
237
+ | Orthosteric miss | - | Trypsin (residue numbering offset); thrombin (940-residue complex) |
238
+
239
+ **Overall across all 27 proteins: 19 / 27 (70%).**
240
+
241
+ ### Speed (NMABackend, no GPU)
242
+
243
+ | Protein size | Time |
244
+ |-------------|------|
245
+ | ~130 residues (lysozyme) | 0.6s |
246
+ | ~170 residues (MDM2) | 1.1s |
247
+ | ~350 residues (K-Ras) | 0.9s |
248
+ | ~530 residues (HIV-1 RT chain A) | 8.3s |
249
+
250
+ ### Head-to-head: Lacuna vs fpocket
251
+
252
+ fpocket detects pockets on a single static structure. Lacuna generates a conformational ensemble - the critical difference for cryptic sites that are absent in the apo crystal.
253
+
254
+ | Target | fpocket 4.2 | Lacuna (NMABackend) |
255
+ |--------|------------|----------------------|
256
+ | 1HEL hen lysozyme (orthosteric) | ✅ rank 1 | ✅ 100%, rank 2 |
257
+ | 1L90 T4L L99A **(cryptic)** | ❌ not in top 5 | ✅ 100%, rank 1 |
258
+ | 4OBE K-Ras switch-II **(cryptic)** | ❌ not in top 5 | ✅ 93%, rank 4 |
259
+ | 1HPV HIV-1 protease (orthosteric) | ✅ rank 1 | ✅ 100%, rank 1 |
260
+ | **Score** | **2 / 4** | **4 / 4** |
261
+
262
+ T4L L99A and K-Ras switch-II are the canonical single-structure benchmark failures: the T4L cavity is physically absent in the apo crystal (<100 ų), and the K-Ras switch-II pocket only opens during nucleotide exchange.
263
+
264
+ > **Reproduce:**
265
+ > ```bash
266
+ > python benchmarks/cryptic_benchmark.py # full 27-protein run, NMA backend (~5 min)
267
+ > python benchmarks/cryptic_benchmark.py --quick # 10 conformers (~2 min)
268
+ > python benchmarks/cryptic_benchmark.py --category cryptic # cryptic only
269
+ > python benchmarks/boltz_nearmiss.py # Boltz-2 near-miss eval (GPU)
270
+ > python benchmarks/compare_fpocket.py # fpocket head-to-head
271
+ > ```
272
+
273
+ ---
274
+
275
+ ## Example: K-Ras switch-II
276
+
277
+ ```bash
278
+ # Download K-Ras apo (from RCSB)
279
+ # Run with Boltz backend for highest-quality switch-II sampling
280
+ lacuna discover 4OBE.pdb \
281
+ --backend boltz \
282
+ --conformers 30 \
283
+ --emit-boltz-constraints \
284
+ --output kras_pockets/
285
+
286
+ # pocket_0_constraint.yaml is ready - add your SMILES:
287
+ # - ligand:
288
+ # id: L
289
+ # smiles: YOUR_SMILES_HERE
290
+ boltz predict kras_pockets/pocket_0_constraint.yaml
291
+ ```
292
+
293
+ See [`examples/kras_cryptic.py`](examples/kras_cryptic.py) for a full annotated Python workflow.
294
+
295
+ ---
296
+
297
+ ## Input formats
298
+
299
+ Accepts PDB or mmCIF from any predictor or database:
300
+ - AlphaFold 2 / AlphaFold 3
301
+ - Boltz-1 / Boltz-2
302
+ - Chai-1
303
+ - RCSB PDB
304
+ - ESMFold, RoseTTAFold, OpenFold, etc.
305
+
306
+ ---
307
+
308
+ ## Citation
309
+
310
+ If you use Lacuna in published research, please cite:
311
+
312
+ > Moore, C.W. (2026). *Lacuna: Cryptic Binding Pocket Discovery via Conformational Ensemble Analysis.* https://github.com/mooreneural/lacuna
313
+
314
+ **BibTeX:**
315
+ ```bibtex
316
+ @software{moore2026lacuna,
317
+ author = {Moore, Clayton W.},
318
+ title = {Lacuna: Cryptic Binding Pocket Discovery
319
+ via Conformational Ensemble Analysis},
320
+ year = {2026},
321
+ url = {https://github.com/mooreneural/lacuna},
322
+ version = {0.1.0}
323
+ }
324
+ ```
325
+
326
+ **Methodology papers Lacuna builds on:**
327
+
328
+ - Atilgan et al. (2001) *Biophys. J.* 80(1):505–515 - Anisotropic Network Model (NMA backend)
329
+ - Halgren (2009) *J. Chem. Inf. Model.* 49(2):377–389 - SiteMap druggability scoring
330
+ - Le Guilloux et al. (2009) *BMC Bioinformatics* 10:168 - fpocket alpha-sphere approach
331
+ - Schmidtke & Barril (2010) *J. Med. Chem.* 53(15):5858–5867 - enclosure scoring
332
+
333
+ ---
334
+
335
+ ## License
336
+
337
+ **[MIT License](LICENSE)** — free for any use, including commercial.
338
+
339
+ A [commercial license](LICENSE_COMMERCIAL) is available for organizations that
340
+ require indemnification, warranty coverage, support SLAs, or custom development
341
+ agreements. Contact claytonwaynemoore@gmail.com.
@@ -0,0 +1,144 @@
1
+ # Lacuna Prospective Predictions
2
+
3
+ Pockets predicted computationally from apo structures, with no prior knowledge
4
+ of small-molecule binding at these sites. Each entry is a testable hypothesis:
5
+ if the pocket is real, a fragment screen or thermal shift assay targeting the
6
+ listed residues should show a hit rate above background.
7
+
8
+ ---
9
+
10
+ ## Prediction 1: Beta-catenin ARM7 cryptic sub-pocket
11
+
12
+ **Date:** 2026-06-02
13
+ **Target:** Beta-catenin / CTNNB1 (UniProt P35222)
14
+ **Structure used:** PDB 2Z6H (apo armadillo repeat domain, residues 149–691)
15
+ **Backend:** Boltz-2 partial diffusion, 30 conformers
16
+ **Status:** Prospective — no small molecule known to bind this surface
17
+
18
+ ### Why this matters
19
+
20
+ Beta-catenin is the central effector of the WNT signalling pathway and is
21
+ constitutively active in ~70% of colorectal cancers, ~30% of hepatocellular
22
+ carcinomas, and many other solid tumours. Despite 40 years of effort, no
23
+ approved small molecule directly inhibits beta-catenin. The primary
24
+ therapeutic interface — the TCF/LEF binding groove — spans ~3000 Ų and
25
+ has been considered too large and flat for drug-like molecules.
26
+
27
+ ### What Lacuna found
28
+
29
+ Running Boltz-2 on the apo structure surfaces a cryptic sub-pocket that is:
30
+
31
+ | Property | Value |
32
+ |----------|-------|
33
+ | Rank | 12 of 109 clusters |
34
+ | Druggability score | **0.855** (high; optimal pocket volume ~300 ų) |
35
+ | Persistence | 16% (opens in ~5 of 31 conformers — genuinely cryptic) |
36
+ | Volume | 241 ų (drug-like range: 200–500 ų) |
37
+ | Centroid | (−3.2, −25.5, 10.7) Å |
38
+
39
+ **Lining residues (ARM7–8 interface):**
40
+
41
+ | Residue | ARM repeat | Chemical character |
42
+ |---------|------------|--------------------|
43
+ | ARG515 | ARM7 | Positive (also contacts TCF/LEF at surface) |
44
+ | ARG542 | ARM7–8 loop | Positive |
45
+ | ALA543 | ARM8 | Hydrophobic |
46
+ | ARG549 | ARM8 | Positive |
47
+ | ARG550 | ARM8 | Positive |
48
+ | ARG565 | ARM8 | Positive |
49
+ | CYS573 | ARM8 | Nucleophilic — covalent warhead opportunity |
50
+ | ALA576 | ARM8 | Hydrophobic |
51
+
52
+ **Key observation:** CYS573 is partially buried in the cryptic state and
53
+ becomes solvent-exposed in ~16% of Boltz-2 conformers. This makes it a
54
+ candidate for covalent fragment screening (electrophilic warheads:
55
+ acrylamide, chloroacetamide).
56
+
57
+ ### Structural context
58
+
59
+ The pocket sits on the concave face of ARM repeats 7–8, adjacent to but
60
+ distinct from the canonical TCF/LEF groove (which centres on ARM1–4 around
61
+ K312, R469, K508). The nearest pharmacological interface is the APC/axin
62
+ binding region (ARM6, ~residues 382–395); the predicted pocket shares no
63
+ lining residues with it.
64
+
65
+ This region corresponds to the "third face" of the ARM domain described in
66
+ structural biology literature as a potential protein–protein interaction
67
+ surface. No crystal structure shows a small molecule bound here.
68
+
69
+ ### Validation strategy
70
+
71
+ **Tier 1 — biophysical (2–4 weeks, ~$10K):**
72
+ 1. Express and purify CTNNB1 ARM domain (residues 149–691, well-established protocol)
73
+ 2. Run a commercial DNA-encoded chemical library (DEL) screen against the ARM domain
74
+ 3. Thermal shift assay (TSA/DSF) with 500–1000 fragment library, look for
75
+ ΔTm ≥ 1°C hits that do NOT compete with a TCF peptide (ruling out
76
+ canonical groove binders)
77
+ 4. SPR or ITC to confirm direct binding of confirmed hits
78
+
79
+ **Tier 2 — structural (4–8 weeks if hits found):**
80
+ - Co-crystallise or cryo-EM of hit compounds with CTNNB1 ARM domain
81
+ - Confirm binding to ARM7–8 residues predicted by Lacuna
82
+
83
+ **Tier 3 — cellular (parallel with Tier 2):**
84
+ - STF luciferase reporter assay (WNT pathway readout) in HCT116 or SW480
85
+ cells (both have CTNNB1-activating mutations)
86
+ - Look for inhibition of TOPFlash signal at non-cytotoxic concentrations
87
+
88
+ ### Why CYS573 is actionable
89
+
90
+ Covalent fragment libraries targeting cysteines are now commercially available
91
+ (Enamine, Chembridge) and have yielded clinical candidates in KRAS (G12C),
92
+ BTK, and other targets. CYS573 is a non-catalytic cysteine with no known
93
+ function — an ideal covalent handle if the pocket is accessible.
94
+
95
+ ### Docking files
96
+
97
+ Lacuna output files for this prediction:
98
+
99
+ ```
100
+ ctnnb1_boltz_lacuna/
101
+ pocket_report.json — full ranked pocket list
102
+ pocket_11_site.pdb — pseudoatom PDB for PyMOL/ChimeraX (rank 12 = index 11)
103
+ pocket_11_constraint.yaml — Boltz YAML: add a SMILES and run boltz predict
104
+ pocket_11_vina.conf — AutoDock Vina / Gnina box centred on prediction
105
+ ```
106
+
107
+ To dock a fragment into this pocket:
108
+ ```yaml
109
+ # pocket_11_constraint.yaml — add your fragment SMILES:
110
+ version: 1
111
+ sequences:
112
+ - protein:
113
+ id: A
114
+ sequence: "..." # from output file
115
+ - ligand:
116
+ id: L
117
+ smiles: "YOUR_FRAGMENT_SMILES"
118
+ constraints:
119
+ pocket:
120
+ - [A, 515]
121
+ - [A, 542]
122
+ - [A, 543]
123
+ - [A, 549]
124
+ - [A, 573]
125
+ ```
126
+
127
+ ---
128
+
129
+ ## Adding predictions
130
+
131
+ To add a new prospective prediction, run:
132
+
133
+ ```bash
134
+ lacuna discover YOUR_TARGET.pdb \
135
+ --backend boltz \
136
+ --conformers 30 \
137
+ --emit-boltz-constraints \
138
+ --emit-vina-boxes \
139
+ --output predictions/YOUR_TARGET/
140
+ ```
141
+
142
+ Then document the novel pockets (not overlapping known interfaces) in this
143
+ file with the residue list, druggability score, persistence, and proposed
144
+ validation assay.