grasp-library-designer 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.
- grasp_library_designer-0.1.0/LICENSE +26 -0
- grasp_library_designer-0.1.0/MANIFEST.in +10 -0
- grasp_library_designer-0.1.0/PKG-INFO +216 -0
- grasp_library_designer-0.1.0/README.md +177 -0
- grasp_library_designer-0.1.0/THIRD_PARTY_LICENSES.md +11 -0
- grasp_library_designer-0.1.0/grasp_library/__init__.py +123 -0
- grasp_library_designer-0.1.0/grasp_library/binder.py +76 -0
- grasp_library_designer-0.1.0/grasp_library/codon_tables.py +145 -0
- grasp_library_designer-0.1.0/grasp_library/codon_validation.py +299 -0
- grasp_library_designer-0.1.0/grasp_library/colab_forms.py +65 -0
- grasp_library_designer-0.1.0/grasp_library/control_panel.py +497 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/README.md +32 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/GRASP_-1.gb +4651 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_14A_LD5N.gb +132 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_14A_LD5T.gb +132 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_14A_LN5N.gb +131 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_14A_LN5T.gb +131 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_14E_LD5N.gb +115 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_14E_LD5T.gb +115 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_14E_LN5N.gb +115 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_14E_LN5T.gb +115 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_19A_LD5N.gb +132 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_19A_LD5T.gb +131 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_19A_LN5N.gb +131 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_19A_LN5T.gb +131 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_19E_LD5N.gb +115 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_19E_LD5T.gb +115 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_19E_LN5N.gb +115 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_19E_LN5T.gb +116 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_1A_5N_AATG.gb +128 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_1A_5N_AGGT.gb +128 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_1A_5T_AATG.gb +129 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_1A_5T_AGGT.gb +129 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_1E_LD5N.gb +131 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_1E_LD5T.gb +131 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_1E_LN5N.gb +131 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_1E_LN5T.gb +131 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_2A_LD5N.gb +136 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_2A_LD5T.gb +127 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_2A_LN5N.gb +136 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_2A_LN5T.gb +141 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_2E_LD.gb +132 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_2E_LN.gb +131 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_B_LD5N.gb +129 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_B_LD5T.gb +136 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_B_LN5N.gb +136 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_B_LN5T.gb +124 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_C_LD5N.gb +115 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_C_LD5T.gb +115 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_C_LN5N.gb +115 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_C_LN5T.gb +115 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_D_LD5N.gb +115 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_D_LD5T.gb +115 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_D_LN5N.gb +115 -0
- grasp_library_designer-0.1.0/grasp_library/data/profiles/grasp_nar2025/genbank/pPR-1_D_LN5T.gb +115 -0
- grasp_library_designer-0.1.0/grasp_library/dna.py +145 -0
- grasp_library_designer-0.1.0/grasp_library/gga_split.py +221 -0
- grasp_library_designer-0.1.0/grasp_library/import_grasp.py +705 -0
- grasp_library_designer-0.1.0/grasp_library/ligation_fidelity.py +95 -0
- grasp_library_designer-0.1.0/grasp_library/notebook_ui.py +199 -0
- grasp_library_designer-0.1.0/grasp_library/objectives.py +418 -0
- grasp_library_designer-0.1.0/grasp_library/oneshot.py +232 -0
- grasp_library_designer-0.1.0/grasp_library/optimizer.py +507 -0
- grasp_library_designer-0.1.0/grasp_library/pareto.py +223 -0
- grasp_library_designer-0.1.0/grasp_library/paths.py +60 -0
- grasp_library_designer-0.1.0/grasp_library/plotting.py +276 -0
- grasp_library_designer-0.1.0/grasp_library/py.typed +0 -0
- grasp_library_designer-0.1.0/grasp_library/sample_codon_tables.py +224 -0
- grasp_library_designer-0.1.0/grasp_library/synthesis_vendors.py +265 -0
- grasp_library_designer-0.1.0/grasp_library/workflows.py +609 -0
- grasp_library_designer-0.1.0/grasp_library_designer.egg-info/PKG-INFO +216 -0
- grasp_library_designer-0.1.0/grasp_library_designer.egg-info/SOURCES.txt +89 -0
- grasp_library_designer-0.1.0/grasp_library_designer.egg-info/dependency_links.txt +1 -0
- grasp_library_designer-0.1.0/grasp_library_designer.egg-info/requires.txt +15 -0
- grasp_library_designer-0.1.0/grasp_library_designer.egg-info/top_level.txt +2 -0
- grasp_library_designer-0.1.0/grasp_library_designer.ipynb +520 -0
- grasp_library_designer-0.1.0/grasp_oneshot_designer.ipynb +295 -0
- grasp_library_designer-0.1.0/pyproject.toml +74 -0
- grasp_library_designer-0.1.0/requirements.txt +9 -0
- grasp_library_designer-0.1.0/setup.cfg +4 -0
- grasp_library_designer-0.1.0/third_party/dawdlib_golden_gate/__init__.py +2 -0
- grasp_library_designer-0.1.0/third_party/dawdlib_golden_gate/gate_data.py +252 -0
- grasp_library_designer-0.1.0/third_party/dawdlib_golden_gate/resources/.ipynb_checkpoints/BsaI-HFv2-checkpoint.csv +257 -0
- grasp_library_designer-0.1.0/third_party/dawdlib_golden_gate/resources/BsaI-HFv2.csv +257 -0
- grasp_library_designer-0.1.0/third_party/dawdlib_golden_gate/resources/BsaI-HFv2_T4_constant_37.csv +257 -0
- grasp_library_designer-0.1.0/third_party/dawdlib_golden_gate/resources/BsmBI-v2_T4_constant_42.csv +257 -0
- grasp_library_designer-0.1.0/third_party/dawdlib_golden_gate/resources/FileS_T4_01h_25C.csv +257 -0
- grasp_library_designer-0.1.0/third_party/dawdlib_golden_gate/resources/FileS_T4_18h_25C.csv +257 -0
- grasp_library_designer-0.1.0/third_party/dawdlib_golden_gate/resources/FileS_T4_18h_37C.csv +257 -0
- grasp_library_designer-0.1.0/third_party/dawdlib_golden_gate/resources/SapI.csv +65 -0
- grasp_library_designer-0.1.0/third_party/dawdlib_golden_gate/resources/__init__.py +7 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
GNU AFFERO GENERAL PUBLIC LICENSE
|
|
2
|
+
Version 3, 19 November 2007
|
|
3
|
+
|
|
4
|
+
Copyright (C) 2026 JustABiologist and contributors
|
|
5
|
+
|
|
6
|
+
This program is free software: you can redistribute it and/or modify
|
|
7
|
+
it under the terms of the GNU Affero General Public License as published
|
|
8
|
+
by the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
(at your option) any later version.
|
|
10
|
+
|
|
11
|
+
This program is distributed in the hope that it will be useful,
|
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
GNU Affero General Public License for more details.
|
|
15
|
+
|
|
16
|
+
You should have received a copy of the GNU Affero General Public License
|
|
17
|
+
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
18
|
+
|
|
19
|
+
---------------------------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
This distribution includes vendored ligation-fidelity code and Potapov
|
|
22
|
+
frequency matrices from Fleishman-Lab / GGAssembler (dawdlib), licensed
|
|
23
|
+
under AGPL-3.0. See THIRD_PARTY_LICENSES.md.
|
|
24
|
+
|
|
25
|
+
The full AGPL-3.0 text is available at:
|
|
26
|
+
https://www.gnu.org/licenses/agpl-3.0.html
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
include README.md
|
|
2
|
+
include LICENSE
|
|
3
|
+
include THIRD_PARTY_LICENSES.md
|
|
4
|
+
include pyproject.toml
|
|
5
|
+
include requirements.txt
|
|
6
|
+
include grasp_library_designer.ipynb
|
|
7
|
+
include grasp_oneshot_designer.ipynb
|
|
8
|
+
recursive-include grasp_library/data *.gb *.md
|
|
9
|
+
recursive-include third_party/dawdlib_golden_gate *.py *.csv
|
|
10
|
+
global-exclude __pycache__ *.py[cod] .ipynb_checkpoints* *.checkpoint.*
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: grasp-library-designer
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Codon-optimize GRASP binder DNA for Golden Gate assembly (library + one-shot).
|
|
5
|
+
Author: JustABiologist
|
|
6
|
+
License: AGPL-3.0-only
|
|
7
|
+
Project-URL: Homepage, https://github.com/JustABiologist/grasp-library-designer
|
|
8
|
+
Project-URL: Repository, https://github.com/JustABiologist/grasp-library-designer
|
|
9
|
+
Project-URL: Issues, https://github.com/JustABiologist/grasp-library-designer/issues
|
|
10
|
+
Keywords: GRASP,Golden Gate,codon optimization,synthetic biology,PPR,ligation fidelity
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: License :: OSI Approved :: GNU Affero General Public License v3
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: pandas>=2.0
|
|
26
|
+
Requires-Dist: numpy>=1.24
|
|
27
|
+
Requires-Dist: biopython>=1.81
|
|
28
|
+
Requires-Dist: pyyaml>=6.0
|
|
29
|
+
Requires-Dist: openpyxl>=3.1
|
|
30
|
+
Requires-Dist: matplotlib>=3.7
|
|
31
|
+
Requires-Dist: ipywidgets>=8.0
|
|
32
|
+
Provides-Extra: notebook
|
|
33
|
+
Requires-Dist: jupyter>=1.0; extra == "notebook"
|
|
34
|
+
Requires-Dist: ipykernel>=6.0; extra == "notebook"
|
|
35
|
+
Provides-Extra: dev
|
|
36
|
+
Requires-Dist: build>=1.0; extra == "dev"
|
|
37
|
+
Requires-Dist: twine>=5.0; extra == "dev"
|
|
38
|
+
Dynamic: license-file
|
|
39
|
+
|
|
40
|
+
# GRASP Library Designer
|
|
41
|
+
|
|
42
|
+
Codon-optimize [GRASP](https://academic.oup.com/nar/article/53/20/gkaf1169/8321212) (Farley et al., *NAR* 2025) binder DNA for Golden Gate assembly.
|
|
43
|
+
|
|
44
|
+
**PyPI package:** `grasp-library-designer`
|
|
45
|
+
**Import name:** `grasp_library`
|
|
46
|
+
|
|
47
|
+
Two Colab Forms notebooks:
|
|
48
|
+
|
|
49
|
+
| Notebook | Purpose |
|
|
50
|
+
|---|---|
|
|
51
|
+
| [`grasp_oneshot_designer.ipynb`](grasp_oneshot_designer.ipynb) | **One target RNA** → binder protein → free GGA cut sites → oligos |
|
|
52
|
+
| [`grasp_library_designer.ipynb`](grasp_library_designer.ipynb) | Redesign / anneal the **42-module combinatorial library**, then GAP-compile a target |
|
|
53
|
+
|
|
54
|
+
Hard constraints (library path): protein sequence fixed (synonymous codons only); coding Golden Gate overhang bases stay locked in `coding_mask`. Objectives: ligation fidelity (Potapov / GGAssembler), codon optimality, synthesis fitness.
|
|
55
|
+
|
|
56
|
+
> **License:** AGPL-3.0 (required by the vendored GGAssembler / dawdlib ligation engine). See [`LICENSE`](LICENSE) and [`THIRD_PARTY_LICENSES.md`](THIRD_PARTY_LICENSES.md).
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Install (PyPI)
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
pip install grasp-library-designer
|
|
64
|
+
# optional notebook extras
|
|
65
|
+
pip install "grasp-library-designer[notebook]"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Minimal API check:
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from grasp_library import materialize_project, build_default_config, LigationFidelityCalculator
|
|
72
|
+
|
|
73
|
+
project = materialize_project() # creates ./grasp_library_project + GenBank
|
|
74
|
+
config = build_default_config(project / "input")
|
|
75
|
+
print(LigationFidelityCalculator(25, 18).set_fidelity(["AATG", "GATA"]))
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Until the package is published on PyPI, install from GitHub (private repo needs a PAT):
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
pip install "git+https://<TOKEN>@github.com/JustABiologist/grasp-library-designer.git@main"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Or clone and install editable:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
git clone https://github.com/JustABiologist/grasp-library-designer.git
|
|
88
|
+
cd grasp-library-designer
|
|
89
|
+
python3 -m venv .venv
|
|
90
|
+
source .venv/bin/activate
|
|
91
|
+
pip install -e ".[notebook,dev]"
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Run in Google Colab
|
|
97
|
+
|
|
98
|
+
Both notebooks use **Colab Forms** (`#@title` / `#@param`, `{display-mode: "form"}`).
|
|
99
|
+
|
|
100
|
+
### 1. Open a notebook
|
|
101
|
+
|
|
102
|
+
From GitHub → **Open in Colab**, or upload the `.ipynb`.
|
|
103
|
+
|
|
104
|
+
### 2. Install
|
|
105
|
+
|
|
106
|
+
In **0 · Install**, choose:
|
|
107
|
+
|
|
108
|
+
| Mode | When |
|
|
109
|
+
|---|---|
|
|
110
|
+
| **PyPI** | After the package is on PyPI (`pip install grasp-library-designer`) |
|
|
111
|
+
| **Private GitHub** | Clone this private repo with a `repo`-scoped PAT |
|
|
112
|
+
| **Local editable** | Notebook already lives in a checkout |
|
|
113
|
+
|
|
114
|
+
### 3a. One-shot
|
|
115
|
+
|
|
116
|
+
Settings → Preview binder → Design oligos → Export Excel
|
|
117
|
+
Outputs: `grasp_library_project/output/oneshot/{RNA}/`
|
|
118
|
+
|
|
119
|
+
### 3b. Combinatorial library
|
|
120
|
+
|
|
121
|
+
Settings → Import → Redesign overhangs → Anneal → Pareto plot → Export → Compile target
|
|
122
|
+
Outputs: `grasp_library_project/output/`
|
|
123
|
+
|
|
124
|
+
Bundled Farley et al. GenBank modules are copied into the project folder on first run via `materialize_project()`.
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Run locally (Cursor / Jupyter / VS Code)
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
pip install -e ".[notebook]"
|
|
132
|
+
python -m ipykernel install --user --name grasp-library-designer --display-name "grasp-library-designer"
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Select that kernel, open either notebook, run top-to-bottom.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Package layout
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
grasp_library/ # installable Python package
|
|
143
|
+
data/profiles/.../genbank/ # bundled GRASP GenBank modules
|
|
144
|
+
paths.py # materialize_project()
|
|
145
|
+
...
|
|
146
|
+
third_party/dawdlib_golden_gate/ # Potapov ligation fidelity (AGPL; also installed)
|
|
147
|
+
grasp_*_designer.ipynb # Colab Forms UIs (also in sdist)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Build / publish (maintainers)
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
pip install -e ".[dev]"
|
|
156
|
+
python -m build
|
|
157
|
+
twine check dist/*
|
|
158
|
+
# Test PyPI first (recommended):
|
|
159
|
+
twine upload --repository testpypi dist/*
|
|
160
|
+
# Production:
|
|
161
|
+
twine upload dist/*
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Requires a PyPI API token (`TWINE_USERNAME=__token__`, `TWINE_PASSWORD=pypi-...`).
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Hiding code (Colab / Jupyter / VS Code)
|
|
169
|
+
|
|
170
|
+
| Frontend | How |
|
|
171
|
+
|---|---|
|
|
172
|
+
| **Google Colab** | Forms: `#@title … {display-mode: "form"}` + `#@param` |
|
|
173
|
+
| **Cursor / VS Code** | **Notebook: Collapse All Cell Inputs** |
|
|
174
|
+
|
|
175
|
+
**Hide ≠ protect.** Source remains in the `.ipynb`.
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## License notes
|
|
180
|
+
|
|
181
|
+
- Distributed package license: **AGPL-3.0** (see [`LICENSE`](LICENSE)).
|
|
182
|
+
- Vendored ligation engine under `third_party/dawdlib_golden_gate/` is AGPL-3.0 (Fleishman-Lab / GGAssembler).
|
|
183
|
+
- GRASP sequences: Farley et al., *Nucleic Acids Res.* 2025.
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Quick smoke test
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
python - <<'PY'
|
|
191
|
+
from pathlib import Path
|
|
192
|
+
from grasp_library import (
|
|
193
|
+
materialize_project,
|
|
194
|
+
build_default_config,
|
|
195
|
+
run_oneshot_design,
|
|
196
|
+
LigationFidelityCalculator,
|
|
197
|
+
)
|
|
198
|
+
from grasp_library.codon_tables import apply_organism_codon_table, load_codon_usage
|
|
199
|
+
|
|
200
|
+
project = materialize_project()
|
|
201
|
+
input_dir = project / "input"
|
|
202
|
+
cfg = build_default_config(input_dir)
|
|
203
|
+
cfg["optimizer"]["iterations_per_part"] = 200
|
|
204
|
+
apply_organism_codon_table("Escherichia coli (Kazusa)", input_dir / "codon_usage.csv")
|
|
205
|
+
_, codon_data = load_codon_usage(input_dir / "codon_usage.csv", genetic_code=1)
|
|
206
|
+
run_oneshot_design(
|
|
207
|
+
target_rna="UUACACGUG",
|
|
208
|
+
codon_data=codon_data,
|
|
209
|
+
config=cfg,
|
|
210
|
+
output_dir=project / "output" / "oneshot" / "UUACACGUG",
|
|
211
|
+
n_fragments=4,
|
|
212
|
+
fidelity=LigationFidelityCalculator(25, 18),
|
|
213
|
+
)
|
|
214
|
+
print("ok")
|
|
215
|
+
PY
|
|
216
|
+
```
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# GRASP Library Designer
|
|
2
|
+
|
|
3
|
+
Codon-optimize [GRASP](https://academic.oup.com/nar/article/53/20/gkaf1169/8321212) (Farley et al., *NAR* 2025) binder DNA for Golden Gate assembly.
|
|
4
|
+
|
|
5
|
+
**PyPI package:** `grasp-library-designer`
|
|
6
|
+
**Import name:** `grasp_library`
|
|
7
|
+
|
|
8
|
+
Two Colab Forms notebooks:
|
|
9
|
+
|
|
10
|
+
| Notebook | Purpose |
|
|
11
|
+
|---|---|
|
|
12
|
+
| [`grasp_oneshot_designer.ipynb`](grasp_oneshot_designer.ipynb) | **One target RNA** → binder protein → free GGA cut sites → oligos |
|
|
13
|
+
| [`grasp_library_designer.ipynb`](grasp_library_designer.ipynb) | Redesign / anneal the **42-module combinatorial library**, then GAP-compile a target |
|
|
14
|
+
|
|
15
|
+
Hard constraints (library path): protein sequence fixed (synonymous codons only); coding Golden Gate overhang bases stay locked in `coding_mask`. Objectives: ligation fidelity (Potapov / GGAssembler), codon optimality, synthesis fitness.
|
|
16
|
+
|
|
17
|
+
> **License:** AGPL-3.0 (required by the vendored GGAssembler / dawdlib ligation engine). See [`LICENSE`](LICENSE) and [`THIRD_PARTY_LICENSES.md`](THIRD_PARTY_LICENSES.md).
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Install (PyPI)
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install grasp-library-designer
|
|
25
|
+
# optional notebook extras
|
|
26
|
+
pip install "grasp-library-designer[notebook]"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Minimal API check:
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from grasp_library import materialize_project, build_default_config, LigationFidelityCalculator
|
|
33
|
+
|
|
34
|
+
project = materialize_project() # creates ./grasp_library_project + GenBank
|
|
35
|
+
config = build_default_config(project / "input")
|
|
36
|
+
print(LigationFidelityCalculator(25, 18).set_fidelity(["AATG", "GATA"]))
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Until the package is published on PyPI, install from GitHub (private repo needs a PAT):
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install "git+https://<TOKEN>@github.com/JustABiologist/grasp-library-designer.git@main"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Or clone and install editable:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
git clone https://github.com/JustABiologist/grasp-library-designer.git
|
|
49
|
+
cd grasp-library-designer
|
|
50
|
+
python3 -m venv .venv
|
|
51
|
+
source .venv/bin/activate
|
|
52
|
+
pip install -e ".[notebook,dev]"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Run in Google Colab
|
|
58
|
+
|
|
59
|
+
Both notebooks use **Colab Forms** (`#@title` / `#@param`, `{display-mode: "form"}`).
|
|
60
|
+
|
|
61
|
+
### 1. Open a notebook
|
|
62
|
+
|
|
63
|
+
From GitHub → **Open in Colab**, or upload the `.ipynb`.
|
|
64
|
+
|
|
65
|
+
### 2. Install
|
|
66
|
+
|
|
67
|
+
In **0 · Install**, choose:
|
|
68
|
+
|
|
69
|
+
| Mode | When |
|
|
70
|
+
|---|---|
|
|
71
|
+
| **PyPI** | After the package is on PyPI (`pip install grasp-library-designer`) |
|
|
72
|
+
| **Private GitHub** | Clone this private repo with a `repo`-scoped PAT |
|
|
73
|
+
| **Local editable** | Notebook already lives in a checkout |
|
|
74
|
+
|
|
75
|
+
### 3a. One-shot
|
|
76
|
+
|
|
77
|
+
Settings → Preview binder → Design oligos → Export Excel
|
|
78
|
+
Outputs: `grasp_library_project/output/oneshot/{RNA}/`
|
|
79
|
+
|
|
80
|
+
### 3b. Combinatorial library
|
|
81
|
+
|
|
82
|
+
Settings → Import → Redesign overhangs → Anneal → Pareto plot → Export → Compile target
|
|
83
|
+
Outputs: `grasp_library_project/output/`
|
|
84
|
+
|
|
85
|
+
Bundled Farley et al. GenBank modules are copied into the project folder on first run via `materialize_project()`.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Run locally (Cursor / Jupyter / VS Code)
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
pip install -e ".[notebook]"
|
|
93
|
+
python -m ipykernel install --user --name grasp-library-designer --display-name "grasp-library-designer"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Select that kernel, open either notebook, run top-to-bottom.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Package layout
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
grasp_library/ # installable Python package
|
|
104
|
+
data/profiles/.../genbank/ # bundled GRASP GenBank modules
|
|
105
|
+
paths.py # materialize_project()
|
|
106
|
+
...
|
|
107
|
+
third_party/dawdlib_golden_gate/ # Potapov ligation fidelity (AGPL; also installed)
|
|
108
|
+
grasp_*_designer.ipynb # Colab Forms UIs (also in sdist)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Build / publish (maintainers)
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
pip install -e ".[dev]"
|
|
117
|
+
python -m build
|
|
118
|
+
twine check dist/*
|
|
119
|
+
# Test PyPI first (recommended):
|
|
120
|
+
twine upload --repository testpypi dist/*
|
|
121
|
+
# Production:
|
|
122
|
+
twine upload dist/*
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Requires a PyPI API token (`TWINE_USERNAME=__token__`, `TWINE_PASSWORD=pypi-...`).
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Hiding code (Colab / Jupyter / VS Code)
|
|
130
|
+
|
|
131
|
+
| Frontend | How |
|
|
132
|
+
|---|---|
|
|
133
|
+
| **Google Colab** | Forms: `#@title … {display-mode: "form"}` + `#@param` |
|
|
134
|
+
| **Cursor / VS Code** | **Notebook: Collapse All Cell Inputs** |
|
|
135
|
+
|
|
136
|
+
**Hide ≠ protect.** Source remains in the `.ipynb`.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## License notes
|
|
141
|
+
|
|
142
|
+
- Distributed package license: **AGPL-3.0** (see [`LICENSE`](LICENSE)).
|
|
143
|
+
- Vendored ligation engine under `third_party/dawdlib_golden_gate/` is AGPL-3.0 (Fleishman-Lab / GGAssembler).
|
|
144
|
+
- GRASP sequences: Farley et al., *Nucleic Acids Res.* 2025.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Quick smoke test
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
python - <<'PY'
|
|
152
|
+
from pathlib import Path
|
|
153
|
+
from grasp_library import (
|
|
154
|
+
materialize_project,
|
|
155
|
+
build_default_config,
|
|
156
|
+
run_oneshot_design,
|
|
157
|
+
LigationFidelityCalculator,
|
|
158
|
+
)
|
|
159
|
+
from grasp_library.codon_tables import apply_organism_codon_table, load_codon_usage
|
|
160
|
+
|
|
161
|
+
project = materialize_project()
|
|
162
|
+
input_dir = project / "input"
|
|
163
|
+
cfg = build_default_config(input_dir)
|
|
164
|
+
cfg["optimizer"]["iterations_per_part"] = 200
|
|
165
|
+
apply_organism_codon_table("Escherichia coli (Kazusa)", input_dir / "codon_usage.csv")
|
|
166
|
+
_, codon_data = load_codon_usage(input_dir / "codon_usage.csv", genetic_code=1)
|
|
167
|
+
run_oneshot_design(
|
|
168
|
+
target_rna="UUACACGUG",
|
|
169
|
+
codon_data=codon_data,
|
|
170
|
+
config=cfg,
|
|
171
|
+
output_dir=project / "output" / "oneshot" / "UUACACGUG",
|
|
172
|
+
n_fragments=4,
|
|
173
|
+
fidelity=LigationFidelityCalculator(25, 18),
|
|
174
|
+
)
|
|
175
|
+
print("ok")
|
|
176
|
+
PY
|
|
177
|
+
```
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Third-party components
|
|
2
|
+
|
|
3
|
+
## Fleishman-Lab / GGAssembler (dawdlib golden-gate fidelity)
|
|
4
|
+
|
|
5
|
+
- Path: `third_party/dawdlib_golden_gate/`
|
|
6
|
+
- Upstream: https://github.com/Fleishman-Lab/GGAssembler
|
|
7
|
+
- Related package: https://github.com/Fleishman-Lab/dawdlib
|
|
8
|
+
- License: AGPL-3.0
|
|
9
|
+
- What was vendored: `gate_data.py` and Potapov/NEB ligation frequency CSVs used by `GGData.reaction_fidelity`
|
|
10
|
+
|
|
11
|
+
Ligation frequency data originate from Potapov et al., ACS Synth. Biol. (2018).
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"""GRASP library designer: masked codon optimization with Pareto trade-offs."""
|
|
2
|
+
|
|
3
|
+
from .ligation_fidelity import LigationFidelityCalculator
|
|
4
|
+
from .objectives import ObjectiveScores, evaluate_design
|
|
5
|
+
from .pareto import (
|
|
6
|
+
ParetoPoint,
|
|
7
|
+
dominates,
|
|
8
|
+
knee_point,
|
|
9
|
+
optimize_pareto_overhangs,
|
|
10
|
+
pareto_front,
|
|
11
|
+
)
|
|
12
|
+
from .sample_codon_tables import (
|
|
13
|
+
SAMPLE_CODON_TABLES,
|
|
14
|
+
codon_table_dataframe,
|
|
15
|
+
sample_names,
|
|
16
|
+
write_sample_codon_table,
|
|
17
|
+
)
|
|
18
|
+
from .import_grasp import (
|
|
19
|
+
compile_target_gap,
|
|
20
|
+
import_grasp_profile,
|
|
21
|
+
pick_parts_for_target,
|
|
22
|
+
)
|
|
23
|
+
from .synthesis_vendors import (
|
|
24
|
+
ASSEMBLY_ENZYMES,
|
|
25
|
+
LIGATION_TABLES,
|
|
26
|
+
SYNTHESIS_VENDORS,
|
|
27
|
+
apply_enzyme_to_config,
|
|
28
|
+
apply_ligation_table_to_config,
|
|
29
|
+
apply_vendor_to_config,
|
|
30
|
+
enzyme_names,
|
|
31
|
+
ligation_table_names,
|
|
32
|
+
twist_length_advice,
|
|
33
|
+
vendor_names,
|
|
34
|
+
)
|
|
35
|
+
from .control_panel import GraspControlPanel, build_default_config, wire_reload_button
|
|
36
|
+
from .workflows import (
|
|
37
|
+
run_overhang_redesign,
|
|
38
|
+
run_library_optimize,
|
|
39
|
+
rescore_pareto_front_after_anneal,
|
|
40
|
+
load_and_validate_parts,
|
|
41
|
+
ensure_grasp_imported,
|
|
42
|
+
export_optimized_library,
|
|
43
|
+
compile_and_assemble_target,
|
|
44
|
+
plot_library_pareto_after_anneal,
|
|
45
|
+
run_library_redesign_and_anneal,
|
|
46
|
+
)
|
|
47
|
+
from .codon_tables import load_codon_usage, apply_organism_codon_table, validate_parts_for_organism
|
|
48
|
+
from .codon_validation import analyze_cut_site_aa_risks, validate_codon_table_aas
|
|
49
|
+
from .plotting import plot_pareto_front
|
|
50
|
+
from .optimizer import (
|
|
51
|
+
optimize_coding_sequence,
|
|
52
|
+
optimize_library,
|
|
53
|
+
synthesis_qc,
|
|
54
|
+
simulate_assembled_cds,
|
|
55
|
+
)
|
|
56
|
+
from .oneshot import run_oneshot_design, sanitize_rna_name
|
|
57
|
+
from .binder import rna_to_binder_aa, describe_binder, normalize_target_rna
|
|
58
|
+
from .gga_split import plan_gga_from_optimized_cds, suggest_fragment_count
|
|
59
|
+
from .paths import (
|
|
60
|
+
bundled_profile_genbank,
|
|
61
|
+
materialize_project,
|
|
62
|
+
project_paths,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
__all__ = [
|
|
66
|
+
"LigationFidelityCalculator",
|
|
67
|
+
"ObjectiveScores",
|
|
68
|
+
"evaluate_design",
|
|
69
|
+
"ParetoPoint",
|
|
70
|
+
"dominates",
|
|
71
|
+
"pareto_front",
|
|
72
|
+
"optimize_pareto_overhangs",
|
|
73
|
+
"knee_point",
|
|
74
|
+
"SAMPLE_CODON_TABLES",
|
|
75
|
+
"codon_table_dataframe",
|
|
76
|
+
"sample_names",
|
|
77
|
+
"write_sample_codon_table",
|
|
78
|
+
"import_grasp_profile",
|
|
79
|
+
"compile_target_gap",
|
|
80
|
+
"pick_parts_for_target",
|
|
81
|
+
"SYNTHESIS_VENDORS",
|
|
82
|
+
"ASSEMBLY_ENZYMES",
|
|
83
|
+
"LIGATION_TABLES",
|
|
84
|
+
"vendor_names",
|
|
85
|
+
"enzyme_names",
|
|
86
|
+
"ligation_table_names",
|
|
87
|
+
"apply_vendor_to_config",
|
|
88
|
+
"apply_enzyme_to_config",
|
|
89
|
+
"apply_ligation_table_to_config",
|
|
90
|
+
"twist_length_advice",
|
|
91
|
+
"GraspControlPanel",
|
|
92
|
+
"build_default_config",
|
|
93
|
+
"wire_reload_button",
|
|
94
|
+
"run_overhang_redesign",
|
|
95
|
+
"run_library_optimize",
|
|
96
|
+
"rescore_pareto_front_after_anneal",
|
|
97
|
+
"load_and_validate_parts",
|
|
98
|
+
"ensure_grasp_imported",
|
|
99
|
+
"export_optimized_library",
|
|
100
|
+
"compile_and_assemble_target",
|
|
101
|
+
"plot_library_pareto_after_anneal",
|
|
102
|
+
"run_library_redesign_and_anneal",
|
|
103
|
+
"load_codon_usage",
|
|
104
|
+
"apply_organism_codon_table",
|
|
105
|
+
"validate_parts_for_organism",
|
|
106
|
+
"analyze_cut_site_aa_risks",
|
|
107
|
+
"validate_codon_table_aas",
|
|
108
|
+
"plot_pareto_front",
|
|
109
|
+
"optimize_coding_sequence",
|
|
110
|
+
"optimize_library",
|
|
111
|
+
"synthesis_qc",
|
|
112
|
+
"simulate_assembled_cds",
|
|
113
|
+
"run_oneshot_design",
|
|
114
|
+
"sanitize_rna_name",
|
|
115
|
+
"rna_to_binder_aa",
|
|
116
|
+
"describe_binder",
|
|
117
|
+
"normalize_target_rna",
|
|
118
|
+
"plan_gga_from_optimized_cds",
|
|
119
|
+
"suggest_fragment_count",
|
|
120
|
+
"bundled_profile_genbank",
|
|
121
|
+
"materialize_project",
|
|
122
|
+
"project_paths",
|
|
123
|
+
]
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""RNA → GRASP binder protein (PPR recognition code), no library parts required."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import List, Sequence, Tuple
|
|
6
|
+
|
|
7
|
+
# Classic PPR code: (5th AA, last AA) of each repeat
|
|
8
|
+
_RNA_TO_CODE = {
|
|
9
|
+
"A": ("T", "N"),
|
|
10
|
+
"C": ("N", "N"),
|
|
11
|
+
"G": ("T", "D"),
|
|
12
|
+
"U": ("N", "D"),
|
|
13
|
+
"T": ("N", "D"),
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
# Solvating N-helix from Farley et al. GRASP 9S native assemblies
|
|
17
|
+
NTERM_HELIX = "QGGNSEEPRKSFDERPERGVVS"
|
|
18
|
+
|
|
19
|
+
# One ~31-aa PPR-like repeat; only the W?AM 5th and PER? last positions vary
|
|
20
|
+
REPEAT_TEMPLATE = "W{fifth}AMISGYAQNGRIDEARELFDKMPER{last}VVS"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def normalize_target_rna(sequence: str) -> str:
|
|
24
|
+
rna = str(sequence).upper().replace("T", "U")
|
|
25
|
+
rna = "".join(b for b in rna if b in "ACGU")
|
|
26
|
+
if not rna:
|
|
27
|
+
raise ValueError("Empty target RNA")
|
|
28
|
+
if len(rna) not in (9, 14, 19):
|
|
29
|
+
raise ValueError(
|
|
30
|
+
f"Target RNA length must be 9, 14, or 19 (got {len(rna)}). "
|
|
31
|
+
"GRASP binder scaffolds are defined for those sizes."
|
|
32
|
+
)
|
|
33
|
+
if any(b not in _RNA_TO_CODE for b in rna):
|
|
34
|
+
raise ValueError(f"Non-ACGU base in target RNA: {sequence!r}")
|
|
35
|
+
return rna
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def rna_to_ppr_pairs(target_rna: str) -> List[Tuple[str, str]]:
|
|
39
|
+
"""Return [(5th, last), ...] recognition pairs for each RNA base."""
|
|
40
|
+
rna = normalize_target_rna(target_rna)
|
|
41
|
+
return [_RNA_TO_CODE[b] for b in rna]
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def rna_to_binder_aa(target_rna: str) -> str:
|
|
45
|
+
"""
|
|
46
|
+
Build the continuous GRASP binder protein for a target RNA.
|
|
47
|
+
|
|
48
|
+
Does **not** use combinatorial library modules — only the PPR code and
|
|
49
|
+
the validated GRASP repeat scaffold (matches oh-bounded native 9S assemblies).
|
|
50
|
+
"""
|
|
51
|
+
pairs = rna_to_ppr_pairs(target_rna)
|
|
52
|
+
parts = [NTERM_HELIX]
|
|
53
|
+
for fifth, last in pairs:
|
|
54
|
+
parts.append(REPEAT_TEMPLATE.format(fifth=fifth, last=last))
|
|
55
|
+
return "".join(parts)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def ppr_code_string(target_rna: str) -> str:
|
|
59
|
+
"""Classic concatenated code, e.g. UUACACGUG → NDNDTNNNTNNNTDNDTD."""
|
|
60
|
+
return "".join(f"{a}{b}" for a, b in rna_to_ppr_pairs(target_rna))
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def describe_binder(target_rna: str) -> dict:
|
|
64
|
+
rna = normalize_target_rna(target_rna)
|
|
65
|
+
aa = rna_to_binder_aa(rna)
|
|
66
|
+
pairs = rna_to_ppr_pairs(rna)
|
|
67
|
+
return {
|
|
68
|
+
"target_rna": rna,
|
|
69
|
+
"n_bases": len(rna),
|
|
70
|
+
"ppr_code": ppr_code_string(rna),
|
|
71
|
+
"ppr_pairs": [f"{a}{b}" for a, b in pairs],
|
|
72
|
+
"aa_sequence": aa,
|
|
73
|
+
"aa_length": len(aa),
|
|
74
|
+
"cds_length": 3 * len(aa),
|
|
75
|
+
"n_repeats": len(pairs),
|
|
76
|
+
}
|