Metadata-Version: 2.4
Name: grasp-library-designer
Version: 0.1.7
Summary: Codon-optimize GRASP binder DNA for Golden Gate assembly (library + one-shot).
Author: JustABiologist
License: AGPL-3.0-only
Project-URL: Homepage, https://github.com/JustABiologist/grasp-library-designer
Project-URL: Repository, https://github.com/JustABiologist/grasp-library-designer
Project-URL: Issues, https://github.com/JustABiologist/grasp-library-designer/issues
Keywords: GRASP,Golden Gate,codon optimization,synthetic biology,PPR,ligation fidelity
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: GNU Affero General Public License v3
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pandas>=2.0
Requires-Dist: numpy>=1.24
Requires-Dist: biopython>=1.81
Requires-Dist: pyyaml>=6.0
Requires-Dist: openpyxl>=3.1
Requires-Dist: matplotlib>=3.7
Requires-Dist: ipywidgets>=8.0
Provides-Extra: notebook
Requires-Dist: jupyter>=1.0; extra == "notebook"
Requires-Dist: ipykernel>=6.0; extra == "notebook"
Provides-Extra: dev
Requires-Dist: build>=1.0; extra == "dev"
Requires-Dist: twine>=5.0; extra == "dev"
Requires-Dist: pytest>=8.0; extra == "dev"
Dynamic: license-file

# GRASP Library Designer

Codon-optimize [GRASP](https://academic.oup.com/nar/article/53/20/gkaf1169/8321212) (Farley et al., *NAR* 2025) binder DNA for Golden Gate assembly.

**PyPI:** [`grasp-library-designer`](https://pypi.org/project/grasp-library-designer/) · **Import:** `grasp_library` · **Python:** ≥3.10 · **License:** AGPL-3.0

---

## What this is

GRASP is a modular PPR (pentatricopeptide repeat) RNA-binding protein platform. Binders are assembled from level −1 DNA modules with fixed Golden Gate overhangs. This package redesigns those DNA sequences (synonymous codons only) so that:

1. **Ligation fidelity** of the Golden Gate overhang set is high (Potapov / GGAssembler tables)
2. **Codon usage** matches a chosen organism table (Kazusa or custom)
3. **Synthesis fitness** stays within vendor constraints (GC, homopolymers, repeats, forbidden sites)

Protein sequence is never changed. Coding Golden Gate overhang bases stay locked via a per-part `coding_mask`.

Two entry points:

| Path | When to use |
|---|---|
| **One-shot** | One target RNA → continuous binder protein → free GGA cut sites → oligos |
| **Library** | Redesign the 42-module combinatorial catalog, then GAP-compile any target RNA |

---

## Open in Google Colab

Click a badge → run **0 · Install** (PyPI) → fill the forms top to bottom. No GitHub token needed.

| Notebook | Open |
|---|---|
| **One-shot** (one RNA → free GGA oligos) | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/JustABiologist/grasp-library-designer/blob/main/grasp_oneshot_designer.ipynb) |
| **Library** (42-module redesign → GAP compile) | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/JustABiologist/grasp-library-designer/blob/main/grasp_library_designer.ipynb) |

Each notebook installs with:

```python
%pip install -q -U "grasp-library-designer>=0.1.5"
```

Bundled GenBank modules and Potapov ligation tables ship inside the PyPI package (`materialize_project()`).

---

## Install locally

```bash
pip install grasp-library-designer
# optional notebook extras
pip install "grasp-library-designer[notebook]"
```

```python
from grasp_library import materialize_project, build_default_config, LigationFidelityCalculator

project = materialize_project()  # ./grasp_library_project + GenBank
config = build_default_config(project / "input")
print(LigationFidelityCalculator(25, 18).set_fidelity(["AATG", "GATA"]))
```

Write the Forms notebooks to disk from a blank environment:

```python
%pip install -q -U grasp-library-designer
from grasp_library import write_notebook
write_notebook("oneshot")   # or "library"
```

---

## Repository layout

```
grasp_library/                      # installable Python package
  binder.py                         # RNA → PPR code → binder AA
  oneshot.py                        # one-shot design pipeline
  workflows.py                      # library redesign / anneal / GAP compile
  optimizer.py                      # masked codon + synthesis anneal
  objectives.py                     # fidelity / codon / synthesis scores
  pareto.py                         # multi-objective overhang search
  ligation_fidelity.py              # Potapov table wrapper
  import_grasp.py                   # GenBank → parts / junctions / GAP
  gga_split.py                      # free cut-site planner (one-shot)
  codon_*.py / kazusa.py            # codon tables & organism validation
  control_panel.py                  # notebook widgets + default config
  paths.py                          # materialize_project()
  data/profiles/grasp_nar2025/      # bundled GenBank modules
  notebooks/                        # Colab Forms notebooks
third_party/dawdlib_golden_gate/    # vendored GGAssembler fidelity (AGPL)
grasp_library_project/              # writable working tree (created locally)
  input/                            # parts, junctions, codon table, config
  output/                           # oligos, Pareto CSVs, assembly plans
  profiles/.../genbank/             # copied GenBank for import
grasp_oneshot_designer.ipynb        # Colab / Jupyter UI (one-shot)
grasp_library_designer.ipynb        # Colab / Jupyter UI (library)
```

---

## Project folder (`grasp_library_project/`)

Created by `materialize_project()`. Standard paths:

| Path | Role |
|---|---|
| `input/parts.csv` | Module AA sequences, coding masks, oligo flanks |
| `input/parts_full.csv` | Native CDS + overhang coordinates (sidecar) |
| `input/junction_map.csv` | Fixed `mask_start_0based` for shared 9S junctions |
| `input/overhang_candidates.csv` | Native + synonym-compatible 4-mers |
| `input/target_map.csv` | Module catalog for GAP part picking |
| `input/codon_usage.csv` | Organism codon table in use |
| `input/config.yaml` | Optimizer, ligation, synthesis, Pareto settings |
| `output/` | Redesigned oligos, Pareto fronts, assembly plans |

Regenerate notebook inputs from GenBank:

```bash
python -m grasp_library.import_grasp
```

Or in Python:

```python
from grasp_library import project_paths, ensure_grasp_imported

paths = project_paths()
tables = ensure_grasp_imported(
    profile_genbank_dir=paths["profile_genbank"],
    input_dir=paths["input"],
)
```

### GRASP profile (Farley et al., NAR 2025)

- Paper: https://academic.oup.com/nar/article/53/20/gkaf1169/8321212
- Upstream data: https://github.com/farleykvdg/GRASP
- Bundled: `GRASP_-1.gb` (42 modules) + individual `pPR-1_*.gb` plasmids

Default 9S overhang set (cut indices are fixed; bases may be synonym-swapped):

`AGGT – ACTC – AAGA – GCAC – TGAA – CTTC – ACTC – AAGA – GCAC – TGAA – TTCG`

B/C/D junctions are shared across CDS1/CDS2, so redesign uses **7 unique junction variables** (`J_Nterm` … `J_Cterm`). Prefer `1A_*_AGGT` for MoClo N-terminal fusion; `AATG` variants are kept as alternate parts.

---

## Pipelines

### One-shot (`run_oneshot_design`)

No combinatorial library. Builds a continuous binder from the PPR recognition code.

1. **RNA → protein** — target length must be 9, 14, or 19 nt; classic PPR pairs `(5th, last)` fill a GRASP repeat scaffold
2. **Anneal full CDS** — synonymous codon + synthesis optimization (`coding_mask` all `N`)
3. **Plan GGA cuts** — choose codon-aligned overhangs already present in the DNA that form a high-fidelity set
4. **Export oligos** — flanks + fragment DNA (FASTA / CSV)

```python
from grasp_library import (
    materialize_project,
    build_default_config,
    apply_organism_codon_table,
    run_oneshot_design,
)

project = materialize_project()
config = build_default_config(project / "input")
codon_data = apply_organism_codon_table(
    project / "input",
    "Chlamydomonas reinhardtii nuclear (Kazusa)",
)
result = run_oneshot_design(
    target_rna="UUACACGUG",
    codon_data=codon_data,
    config=config,
    output_dir=project / "output",
)
```

### Library (`run_library_redesign_and_anneal` → GAP compile)

Redesigns the shared module catalog, then picks parts for a target RNA.

1. **Import** GenBank → `parts.csv`, junction map, overhang candidates
2. **Pareto overhang redesign** (optional) — search synonym-compatible 4-mers; score ligation fidelity, codon optimality, synthesis; pick knee / max-fidelity
3. **Write overhangs into masks** — lock chosen 4-mers at fixed cut indices
4. **Anneal library** — masked CDS optimization for every module → oligos
5. **Rescore / plot Pareto** (optional) — uniform post-anneal scores
6. **GAP compile** — pick modules for a target RNA and stitch assembled CDS + ordered oligos

```python
from grasp_library import (
    project_paths,
    build_default_config,
    apply_organism_codon_table,
    ensure_grasp_imported,
    run_library_redesign_and_anneal,
    export_optimized_library,
    compile_and_assemble_target,
)

paths = project_paths()
config = build_default_config(paths["input"])
codon_data = apply_organism_codon_table(
    paths["input"],
    "Chlamydomonas reinhardtii nuclear (Kazusa)",
)
tables = ensure_grasp_imported(
    profile_genbank_dir=paths["profile_genbank"],
    input_dir=paths["input"],
)
result = run_library_redesign_and_anneal(
    parts=tables["parts"],
    codon_data=codon_data,
    config=config,
    input_dir=paths["input"],
    output_dir=paths["output"],
)
export_optimized_library(
    result["optimized_library"],
    paths["output"],
    selected_overhangs=result["selected_overhangs"],
)
assembly = compile_and_assemble_target(
    target_rna="UUACACGUG",
    optimized_library=result["optimized_library"],
    config=config,
    input_dir=paths["input"],
    output_dir=paths["output"],
    codon_data=codon_data,
)
```

### Typical library outputs

| File | Contents |
|---|---|
| `pareto_front.csv` | Evaluated overhang sets and objective scores |
| `selected_overhangs.csv` | Chosen junction → overhang mapping |
| `parts_with_redesigned_junctions.csv` | Parts with updated coding masks |
| `optimized_library.csv` / `optimized_grasp_oligos.*` | Annealed CDS + GGA oligos |
| `assembly_plan_<RNA>.csv` | GAP part order for one target |
| `assembled_<RNA>.fasta` | Stitched coding sequence |
| `oligos_<RNA>.csv` / `.fasta` | Ordered oligos for that assembly |

---

## Design constraints and objectives

**Hard constraints**

- Synonymous redesign only (protein fixed)
- Coding overhang bases locked in `coding_mask` (`N` = free, `A/C/G/T` = fixed)
- Forbidden restriction sites from config (default BsaI / BpiI / BsmBI)
- Translation must match the organism codon table / genetic code

**Objectives** (all maximized)

| Objective | Meaning |
|---|---|
| `ligation_fidelity` | Potapov set fidelity for the overhang collection |
| `codon_optimality` | Mean log relative adaptiveness vs organism table |
| `synthesis` | Weighted GC / local GC / homopolymer / repeat / library-similarity score |

Weights and anneal schedule live under `weights:` and `optimizer:` in `config.yaml`.

---

## Config highlights (`input/config.yaml`)

| Section | Controls |
|---|---|
| `forbidden_sites` | Enzyme → recognition sequence |
| `synthesis` | Global/window GC, max homopolymer, repeat *k*, oligo length bounds |
| `codon_optimization` | Minimum relative adaptiveness |
| `weights` | Objective component weights for anneal |
| `optimizer` | Simulated-annealing iterations, temperature, orthogonal versions |
| `ligation` | Temperature, hours, min efficiency/fidelity, Potapov table |
| `overhang_redesign` | `enabled`, `selection` (`knee` / `max_fidelity` / exact overhang string) |
| `pareto` | `max_evaluations`, `beam_width`, junction flank |
| `target_rna` | Default RNA for GAP compile |
| `selected_organism` | Label of active codon table |

Notebook control panels write this file via `GraspControlPanel` / `build_default_config`.

---

## Binder protein (PPR code)

Classic recognition pairs (5th AA, last AA of each ~31-aa repeat):

| RNA | Code |
|---|---|
| A | TN |
| C | NN |
| G | TD |
| U / T | ND |

Scaffold: N-terminal solvating helix + one repeat per base (`W{fifth}AM…PER{last}VVS`), matching Farley et al. 9S native assemblies. Target RNA length must be **9, 14, or 19**.

```python
from grasp_library import describe_binder
print(describe_binder("UUACACGUG"))
```

---

## Package API (selected)

| Symbol | Role |
|---|---|
| `materialize_project` / `project_paths` | Create writable project + copy GenBank |
| `build_default_config` | Default YAML-backed config |
| `ensure_grasp_imported` / `import_grasp_profile` | GenBank → CSV tables |
| `run_oneshot_design` | One-shot RNA → oligos |
| `run_library_redesign_and_anneal` | Pareto overhangs + library anneal |
| `run_overhang_redesign` / `run_library_optimize` | Pipeline steps separately |
| `compile_and_assemble_target` | GAP compile + stitch CDS |
| `export_optimized_library` | CSV / FASTA / Excel export |
| `optimize_coding_sequence` / `optimize_library` | Low-level anneal |
| `LigationFidelityCalculator` | Potapov fidelity queries |
| `plot_pareto_front` / `plot_library_pareto_after_anneal` | Visualization |
| `apply_organism_codon_table` / `fetch_kazusa_codon_table` | Codon tables |
| `write_notebook` | Drop Colab Forms notebooks to disk |

Full public surface is listed in `grasp_library.__all__`.

---

## Develop from source

```bash
git clone https://github.com/JustABiologist/grasp-library-designer.git
cd grasp-library-designer
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[notebook,dev]"
```

Build / publish (maintainers):

```bash
python -m build
twine check dist/*
```

---

## Citation and license

**Software:** AGPL-3.0 (required by the vendored GGAssembler / dawdlib ligation engine). See [`LICENSE`](LICENSE) and [`THIRD_PARTY_LICENSES.md`](THIRD_PARTY_LICENSES.md).

**GRASP sequences / biology:** Farley et al., *Nucleic Acids Research* 2025 — https://academic.oup.com/nar/article/53/20/gkaf1169/8321212

**Ligation frequency data:** Potapov et al., *ACS Synthetic Biology* (2018), via [Fleishman-Lab/GGAssembler](https://github.com/Fleishman-Lab/GGAssembler).
