Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ versioning after the initial alpha releases.
- Site-aware aliases for selected Unimod accessions.
- Layerable JSON custom-modification registries, a JSON Schema, Python registration APIs, and
explicit override protection.
- Optional bilingual local workbench for one-at-a-time conversions, visual peptide modification,
fingerprints, descriptors, result history, and custom modification registries.
- English project homepage with linked Simplified Chinese documentation.
- Structural formula tests, registry validation tests, custom CLI examples, and modification-system
documentation.
Expand Down
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ command-line interface.
- Linear L/D peptide construction with explicit termini, backbone N-methylation, curated PTMs, and
site-aware Unimod aliases
- Layerable JSON registries and a Python API for custom side-chain and terminal structures
- Optional bilingual browser workbench for one-at-a-time conversion, visual peptide modification,
fingerprints, descriptors, result history, and custom registry editing
- Morgan, RDKit path, MACCS, Atom Pair, Topological Torsion, and sequence k-mer fingerprints
- Formula, exact mass, MolLogP, TPSA, HBD/HBA, rotatable-bond, heavy-atom, and charge descriptors
- Optional PubChem PUG-REST name resolution, kept separate from deterministic local conversion
Expand All @@ -51,6 +53,16 @@ pytest
ruff check .
```

Install the optional graphical workbench:

```bash
python -m pip install -e '.[gui]'
moltranscode gui
```

The interface opens locally at `http://localhost:8501`. It does not upload structures to a remote
service. Use `--no-browser`, `--host`, or `--port` when a different launch configuration is needed.

## Quick start

```bash
Expand Down Expand Up @@ -171,6 +183,26 @@ RDKit; registry provenance should be archived with generated data.
See [Modification system](docs/modifications.md) for the schema, attachment semantics, safety rules,
and Python registration API.

### Graphical single-entry workbench

Run `moltranscode gui` to open the optional English/Chinese interface. It is designed for manual,
non-batch work and provides:

- one-at-a-time input for peptides, sequences, SMILES, InChI, SELFIES, HELM, and structure blocks;
- visual residue-position PTM selection, N/C termini, backbone N-methylation, D-residue notation,
and an editable generated peptide annotation;
- structure-tested non-natural alpha-amino-acid presets including Nle, Orn, Dab, Dap, Hse, Hcy,
Sec, Cit, 4F-Phe, pAzF, Pra, Cha, and Tle;
- selectable molecular output formats, fingerprints, or descriptor calculation;
- responsive result cards with untruncated formula, exact mass, charge, canonical SMILES, a 2D
drawing, and downloads;
- persistent session history with JSON/CSV export while additional entries are submitted;
- custom side-chain/N-terminal/C-terminal forms with immediate validation and registry import/export.
- an in-app input guide, scope warnings, and links to the primary standards and reference databases.

The interface exports the same schema accepted by `--mod-config`; no separate GUI-only project
format is introduced. See the [GUI guide](docs/gui.md) for the complete workflow.

## Batch conversion

```bash
Expand Down
29 changes: 29 additions & 0 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
以及依赖单体元数据的 FASTA/sequence/HELM
- 肽结构:混合 L/D 氨基酸、端基、骨架 N-甲基化、常见 PTM、按残基位点解析的 Unimod 别名
- 自定义修饰:可叠加的 JSON 配置和 Python 注册 API,无需修改源代码
- 可选中英文单条转换工作台,支持可视化肽修饰、指纹、描述符、结果历史和自定义修饰库
- 指纹:Morgan、RDKit path、MACCS、Atom Pair、Topological Torsion、序列 k-mer
- 描述符:分子式、精确质量、MolLogP、TPSA、HBD/HBA、可旋转键、重原子数、电荷
- 可选 PubChem PUG-REST 名称解析;批处理中逐条保留 `status` 和 `error`
Expand All @@ -45,6 +46,16 @@ pytest
ruff check .
```

安装可选图形工作台:

```bash
python -m pip install -e '.[gui]'
moltranscode gui
```

界面默认在本机 `http://localhost:8501` 打开,不会把结构上传到远程服务。也可使用
`--no-browser`、`--host` 和 `--port` 调整启动方式。

## 快速开始

```bash
Expand Down Expand Up @@ -153,6 +164,24 @@ sanitization,但用户仍需对自定义片段的化学含义负责,并随

完整字段、连接规则和 Python API 见[修饰系统说明](docs/modifications.md)。

### 图形化单条转换工作台

运行 `moltranscode gui` 可以打开中英文界面,适合手动处理非批量数据,支持:

- 逐条输入肽、序列、SMILES、InChI、SELFIES、HELM 或结构块;
- 按残基位置选择 PTM、N/C 端基、骨架 N-甲基化和 D-残基,并生成可编辑的肽表示;
- 选择经过结构测试的非天然 α-氨基酸预设,包括 Nle、Orn、Dab、Dap、Hse、Hcy、
Sec、Cit、4F-Phe、pAzF、Pra、Cha 和 Tle;
- 选择分子格式转换、指纹生成或描述符计算;
- 通过不会截断长分子式的响应式卡片查看精确质量、电荷、canonical SMILES、二维结构图
并下载结果;
- 连续添加下一条数据,并将当前会话历史导出为 JSON 或 CSV;
- 创建侧链/N 端/C 端自定义修饰,即时验证并导入或下载修饰库;
- 在界面内查看输入格式说明、当前结构限制和主要标准/数据库参考文献。

图形界面导出的文件与 `--mod-config` 使用相同格式,不会产生只能由 GUI 读取的项目文件。
完整操作说明见[图形界面指南](docs/gui.md)。

## 批处理与 Python API

```bash
Expand Down
86 changes: 86 additions & 0 deletions docs/gui.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Graphical single-entry workbench

The optional GUI is intended for manual, non-batch exploration. It runs locally, uses the same
conversion and modification APIs as the CLI, and keeps successful entries in an in-memory session
history. For large files or reproducible pipelines, use the CLI batch commands instead.

## Start the interface

```bash
python -m pip install -e '.[gui]'
moltranscode gui
```

The default address is `http://localhost:8501`. Closing the terminal or pressing `Ctrl+C` stops the
server. Alternative launch options include:

```bash
moltranscode gui --no-browser --host 127.0.0.1 --port 8765
```

## Convert entries one at a time

Open **Single-entry workbench** and repeat this workflow for each record:

1. Select the input format. Peptide, sequence, SMILES, InChI, SELFIES, FASTA, HELM, MOL, SDF, PDB,
and conservative automatic detection are available.
2. Enter exactly one value or structure block.
3. Choose **Convert representation**, **Generate fingerprint**, or **Calculate descriptors**.
4. Select the output format or fingerprint parameters and run the entry.
5. Inspect the result card and 2D drawing, then enter the next record.

Successful runs are added to **Entry history**. Individual results can be downloaded or removed,
and the complete session can be exported as JSON or CSV. History is stored in the current browser
session only; download it before stopping the application when it must be retained.

## Build a modified peptide visually

Choose `peptide` as the input format. Enter a one-letter sequence, using lowercase letters for D
residues. The editor then exposes:

- N- and C-terminal groups from the active registry;
- residue positions labeled as `position: residue`;
- only the side-chain modifications registered for the selected residue;
- backbone `NMe` at residues with an available backbone N-H;
- the generated bracketed peptide notation.

The **Non-natural / non-canonical residue presets** panel filters the built-in catalogue to the
selected carrier residue. For example, enter `AKM`, select its `K`, and apply **Ornithine (Orn)**;
or select `M` and apply **Norleucine (Nle)**. The generated structure-resolving notation is
`K[Ornithine]` or `M[Norleucine]`. The catalogue also includes Nva, Dab, Dap, Hse, Hcy, Sec, Cit,
4F-Phe, pAzF, Pra, Cha, and Tle. Lowercase carrier letters retain the same preset side chain on a
D-configured alpha carbon.

These presets are deliberately limited to alpha-amino acids that can be represented by replacing
only a side chain on the current backbone template. Aib and other alpha,alpha-disubstituted
residues, beta/gamma amino acids, cyclic backbones, cross-links, and glycans require a different
monomer/backbone model. Supply an explicit SMILES/MOL/SDF structure or an applicable HELM record
instead of approximating those molecules as ordinary side-chain replacements.

One side-chain modification plus `NMe` may be applied to a residue. Applying a new side-chain
modification at the same position replaces the previous side-chain selection. Changing the base
sequence clears position-based modifications to avoid silently moving a PTM to another residue.

Enable **Edit annotated notation manually** when direct notation entry is more convenient. The
final notation is still validated by the peptide parser before conversion.

Open **Guide & references** for the complete input-format table, the non-natural-residue catalogue,
current structural limits, and links to ProForma 2.0, HELM, SwissSidechain, Unimod, and IUPAC
amino-acid nomenclature.

## Add laboratory-specific modifications

Open **Custom modification library** to add side-chain, N-terminal, or C-terminal definitions. New
definitions become available immediately in the peptide editor. The sidebar imports an existing
registry, while **Registry export** downloads the current schema-versioned JSON for later CLI use.

Custom fragments are validated for SMILES syntax, connectivity, wildcard use, site collisions, and
schema fields. This does not establish that a chemically valid graph matches the intended
experimental modification; review the attachment semantics in [Modification system](modifications.md).

## Local-data and network behavior

Molecular processing runs in the local Python process and MolTranscode does not upload structures
to a hosted service. The default `localhost` binding is accessible only from the local machine.
Binding to another interface can expose the workbench to the network; apply authentication and
network controls before doing so with confidential structures.
48 changes: 48 additions & 0 deletions docs/modifications.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,27 @@ The built-in structures include aliases for selected records in the
These aliases resolve to MolTranscode's explicit structural conventions; they do not mean that all
specificities or neutral losses recorded by Unimod are implemented.

## Built-in non-natural residue presets

The GUI exposes a conservative catalogue of alpha-amino acids whose structures can be generated by
replacing a side chain without changing MolTranscode's standard peptide backbone:

| Preset | Carrier notation | Preset | Carrier notation |
|---|---|---|---|
| Norvaline (Nva) | `V[Norvaline]` | Norleucine (Nle) | `M[Norleucine]` |
| Ornithine (Orn) | `K[Ornithine]` | Diaminobutyric acid (Dab) | `K[Dab]` |
| Diaminopropionic acid (Dap) | `K[Dap]` | Homoserine (Hse) | `S[Hse]` |
| Homocysteine (Hcy) | `C[Hcy]` | Selenocysteine (Sec) | `C[Sec]` |
| Citrulline (Cit) | `R[Cit]` | 4-Fluorophenylalanine | `F[4F-Phe]` |
| 4-Azidophenylalanine (pAzF) | `F[pAzF]` | Propargylglycine (Pra) | `A[Pra]` |
| Cyclohexylalanine (Cha) | `F[Cha]` | tert-Leucine (Tle) | `L[Tle]` |

The carrier is an internal attachment template, not a claim that the preset is a modification of
that biological residue. Bracketed names are used because there is no universal one-letter code for
arbitrary non-natural amino acids. For a broader curated side-chain resource, see
[SwissSidechain](https://doi.org/10.1093/nar/gks991) and the scope discussion in
[Scientific basis](scientific-basis.md).

## JSON registry schema

Use [`examples/custom_modifications.json`](../examples/custom_modifications.json) as a working
Expand Down Expand Up @@ -144,6 +165,33 @@ result = convert("AK[AzK]", "peptide", "smiles", modification_registry=registry)
Registry instances are mutable by design. Create one during application initialization and treat it
as read-only while conversions run; call `clone()` before making request-specific changes.

## Graphical workbench and registry builder

Install and launch the optional local interface:

```bash
python -m pip install -e '.[gui]'
moltranscode gui
```

The Streamlit application supports English and Simplified Chinese. Its main workbench accepts one
input at a time, includes a residue-position peptide modification editor, and can convert formats or
generate descriptors and fingerprints. A separate library tab validates each custom definition
against the same runtime loader used by the CLI, imports existing registries, and downloads
schema-versioned JSON. See the [GUI guide](gui.md).

All processing occurs in the local Python process; the application does not send molecular
structures to MolTranscode or another hosted service.

For a headless or remote development environment:

```bash
moltranscode gui --no-browser --host 127.0.0.1 --port 8765
```

Binding to a non-loopback interface may expose the application to other machines. Add appropriate
network access controls before doing so, especially when working with confidential structures.

## Provenance and contribution rules

Archive custom JSON files alongside generated outputs and record the MolTranscode and RDKit
Expand Down
11 changes: 11 additions & 0 deletions docs/scientific-basis.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,17 @@ Structure Representation,” *J. Chem. Inf. Model.* (2012),
[RDKit molecule file API](https://rdkit.org/docs/source/rdkit.Chem.rdmolfiles.html) for the exact
FASTA/HELM capabilities of the installed RDKit release.

MolTranscode's non-natural-residue presets are a small, structure-tested convenience catalogue,
not a comprehensive monomer ontology. They cover alpha-amino acids whose side chains can be
substituted without changing the standard peptide-backbone template. SwissSidechain provides a
broader curated molecular and structural resource for non-natural side chains: Gfeller et al.,
“SwissSidechain: a molecular and structural database of non-natural sidechains,” *Nucleic Acids
Research* (2013), [doi:10.1093/nar/gks991](https://doi.org/10.1093/nar/gks991). IUPAC-IUB
[amino-acid nomenclature recommendations](https://iupac.qmul.ac.uk/AminoAcid/) are the reference
for conventional symbols and also document the limits of the one-letter system. There is no
universal one-letter alphabet for arbitrary non-natural monomers, so MolTranscode emits explicit
bracketed names such as `M[Norleucine]` rather than inventing new single-letter codes.

### Structural conventions in version 0.2

- uppercase residues are L and lowercase residues are D;
Expand Down
4 changes: 4 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,13 @@ dev = [
"pytest-cov>=5.0",
"ruff>=0.5",
]
gui = [
"streamlit>=1.60",
]

[project.scripts]
moltranscode = "moltranscode.cli:main"
moltranscode-gui = "moltranscode.gui:main"

[project.urls]
Homepage = "https://github.com/PerinMu/MolTranscode"
Expand Down
2 changes: 2 additions & 0 deletions src/moltranscode/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
ModificationRegistry,
default_modification_registry,
load_modification_registry,
modification_registry_from_dict,
)
from .peptide import parse_peptide, peptide_to_smiles

Expand All @@ -27,6 +28,7 @@
"describe",
"fingerprint",
"load_modification_registry",
"modification_registry_from_dict",
"parse_peptide",
"peptide_to_smiles",
]
Expand Down
20 changes: 20 additions & 0 deletions src/moltranscode/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,16 @@ def _base_parser() -> argparse.ArgumentParser:
formats_parser.add_argument("--json", action="store_true", help="emit machine-readable JSON")
_add_modification_config_argument(formats_parser)
formats_parser.set_defaults(handler=_handle_formats)

gui_parser = subparsers.add_parser(
"gui", help="launch the optional single-entry conversion workbench"
)
gui_parser.add_argument("--host", default="localhost", help="interface to bind (localhost)")
gui_parser.add_argument("--port", type=int, default=8501, help="local web interface port")
gui_parser.add_argument(
"--no-browser", action="store_true", help="do not open a browser automatically"
)
gui_parser.set_defaults(handler=_handle_gui)
return parser


Expand Down Expand Up @@ -251,6 +261,16 @@ def _handle_formats(args: argparse.Namespace) -> int:
return 0


def _handle_gui(args: argparse.Namespace) -> int:
from .gui import launch_gui

return launch_gui(
host=args.host,
port=args.port,
open_browser=not args.no_browser,
)


def main(argv: list[str] | None = None) -> int:
parser = _base_parser()
args = parser.parse_args(argv)
Expand Down
Loading
Loading