glyco-gwstoolkit 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.
- glyco_gwstoolkit-0.1.0/.github/workflows/ci.yml +33 -0
- glyco_gwstoolkit-0.1.0/.github/workflows/workflow.yml +75 -0
- glyco_gwstoolkit-0.1.0/.gitignore +31 -0
- glyco_gwstoolkit-0.1.0/LICENSE +21 -0
- glyco_gwstoolkit-0.1.0/PKG-INFO +166 -0
- glyco_gwstoolkit-0.1.0/README.md +134 -0
- glyco_gwstoolkit-0.1.0/docs/images/.gitkeep +0 -0
- glyco_gwstoolkit-0.1.0/docs/images/snfg-example.png +0 -0
- glyco_gwstoolkit-0.1.0/pyproject.toml +89 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/__init__.py +20 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/__main__.py +5 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/cli/__init__.py +0 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/cli/enumerate_cmd.py +168 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/cli/fragment_cmd.py +243 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/cli/input_utils.py +196 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/cli/main.py +50 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/cli/pipeline_cmd.py +167 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/cli/render_cmd.py +135 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/cli/report_cmd.py +103 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/enumeration/__init__.py +267 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/enumeration/assignment.py +127 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/enumeration/canonical.py +66 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/enumeration/counter.py +58 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/enumeration/gws_builder.py +146 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/enumeration/trees.py +65 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/exporters/__init__.py +0 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/exporters/count_logger.py +74 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/exporters/json_writer.py +101 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/exporters/msp_writer.py +393 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/exporters/report/__init__.py +5 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/exporters/report/builder.py +611 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/exporters/report/static/report.css +488 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/exporters/report/static/report.js +531 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/exporters/report/templates/report.html.j2 +324 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/exporters/summary_writer.py +157 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/__init__.py +0 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/fragmenter.py +316 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/java_check.py +67 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/java_engine.py +405 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/renderer.py +170 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/GlycanFragmenter$1.class +0 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/GlycanFragmenter.class +0 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/GlycanFragmenter.java +298 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/GlycanSNFGRenderer$1.class +0 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/GlycanSNFGRenderer.class +0 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/GlycanSNFGRenderer.java +163 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/StrokeThickener.class +0 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/ThickGlycanRendererAWT.class +0 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/ThickLinkageRendererAWT.class +0 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/ThickPaintable.class +0 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/ThickResidueRendererAWT.class +0 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/ThickStroke.java +580 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/TopologyHasher.class +0 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/TopologyHasher.java +71 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/TreeHasher.class +0 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/TreeHasher.java +47 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/glycanbuilder2-jar-with-dependencies.jar +0 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/logging_config.py +46 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/models/__init__.py +0 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/models/composition.py +123 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/models/config.py +120 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/models/structure.py +43 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/models/sugar_types.py +137 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/pipeline/__init__.py +13 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/pipeline/checkpoint.py +200 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/pipeline/progress.py +108 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/pipeline/runner.py +318 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/pipeline/steps.py +384 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/py.typed +0 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/validation/__init__.py +13 -0
- glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/validation/gws_validator.py +249 -0
- glyco_gwstoolkit-0.1.0/tests/__init__.py +0 -0
- glyco_gwstoolkit-0.1.0/tests/conftest.py +19 -0
- glyco_gwstoolkit-0.1.0/tests/test_assignment.py +79 -0
- glyco_gwstoolkit-0.1.0/tests/test_canonical.py +56 -0
- glyco_gwstoolkit-0.1.0/tests/test_composition.py +96 -0
- glyco_gwstoolkit-0.1.0/tests/test_counter.py +37 -0
- glyco_gwstoolkit-0.1.0/tests/test_gws_builder.py +70 -0
- glyco_gwstoolkit-0.1.0/tests/test_gws_validation.py +200 -0
- glyco_gwstoolkit-0.1.0/tests/test_java_integration.py +104 -0
- glyco_gwstoolkit-0.1.0/tests/test_msp_writer.py +302 -0
- glyco_gwstoolkit-0.1.0/tests/test_pipeline.py +355 -0
- glyco_gwstoolkit-0.1.0/tests/test_summary_writer.py +223 -0
- glyco_gwstoolkit-0.1.0/tests/test_trees.py +81 -0
- glyco_gwstoolkit-0.1.0/uv.lock +933 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
|
|
14
|
+
- uses: astral-sh/setup-uv@v5
|
|
15
|
+
|
|
16
|
+
- uses: actions/setup-java@v4
|
|
17
|
+
with:
|
|
18
|
+
distribution: temurin
|
|
19
|
+
java-version: 17
|
|
20
|
+
|
|
21
|
+
- name: Install dependencies
|
|
22
|
+
run: uv sync --dev
|
|
23
|
+
|
|
24
|
+
- name: Lint
|
|
25
|
+
run: |
|
|
26
|
+
uv run ruff check src/ tests/
|
|
27
|
+
uv run ruff format --check src/ tests/
|
|
28
|
+
|
|
29
|
+
- name: Type check
|
|
30
|
+
run: uv run mypy src/
|
|
31
|
+
|
|
32
|
+
- name: Test (full suite, including Java slow tests)
|
|
33
|
+
run: uv run pytest
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
test:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
|
|
13
|
+
- uses: astral-sh/setup-uv@v5
|
|
14
|
+
|
|
15
|
+
- uses: actions/setup-java@v4
|
|
16
|
+
with:
|
|
17
|
+
distribution: temurin
|
|
18
|
+
java-version: 17
|
|
19
|
+
|
|
20
|
+
- name: Install dependencies
|
|
21
|
+
run: uv sync --dev
|
|
22
|
+
|
|
23
|
+
- name: Lint
|
|
24
|
+
run: |
|
|
25
|
+
uv run ruff check src/ tests/
|
|
26
|
+
uv run ruff format --check src/ tests/
|
|
27
|
+
|
|
28
|
+
- name: Type check
|
|
29
|
+
run: uv run mypy src/
|
|
30
|
+
|
|
31
|
+
- name: Test (full suite, including Java slow tests)
|
|
32
|
+
run: uv run pytest
|
|
33
|
+
|
|
34
|
+
build:
|
|
35
|
+
needs: test
|
|
36
|
+
runs-on: ubuntu-latest
|
|
37
|
+
steps:
|
|
38
|
+
- uses: actions/checkout@v4
|
|
39
|
+
|
|
40
|
+
- uses: astral-sh/setup-uv@v5
|
|
41
|
+
|
|
42
|
+
- name: Verify tag matches package version
|
|
43
|
+
run: |
|
|
44
|
+
pyproject_version=$(grep -m1 '^version' pyproject.toml | cut -d'"' -f2)
|
|
45
|
+
init_version=$(grep -m1 '__version__' src/glyco_gwstoolkit/__init__.py | cut -d'"' -f2)
|
|
46
|
+
if [ "v${pyproject_version}" != "${GITHUB_REF_NAME}" ]; then
|
|
47
|
+
echo "::error::tag ${GITHUB_REF_NAME} does not match pyproject.toml version v${pyproject_version}"
|
|
48
|
+
exit 1
|
|
49
|
+
fi
|
|
50
|
+
if [ "${pyproject_version}" != "${init_version}" ]; then
|
|
51
|
+
echo "::error::pyproject.toml version ${pyproject_version} != __init__.py __version__ ${init_version}"
|
|
52
|
+
exit 1
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
- name: Build sdist and wheel
|
|
56
|
+
run: uv build
|
|
57
|
+
|
|
58
|
+
- uses: actions/upload-artifact@v4
|
|
59
|
+
with:
|
|
60
|
+
name: dist
|
|
61
|
+
path: dist/
|
|
62
|
+
|
|
63
|
+
publish:
|
|
64
|
+
needs: build
|
|
65
|
+
runs-on: ubuntu-latest
|
|
66
|
+
environment: release
|
|
67
|
+
permissions:
|
|
68
|
+
id-token: write # PyPI Trusted Publishing (OIDC)
|
|
69
|
+
steps:
|
|
70
|
+
- uses: actions/download-artifact@v4
|
|
71
|
+
with:
|
|
72
|
+
name: dist
|
|
73
|
+
path: dist/
|
|
74
|
+
|
|
75
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
*.egg
|
|
6
|
+
build/
|
|
7
|
+
dist/
|
|
8
|
+
.venv/
|
|
9
|
+
venv/
|
|
10
|
+
|
|
11
|
+
# Tooling caches
|
|
12
|
+
.pytest_cache/
|
|
13
|
+
.mypy_cache/
|
|
14
|
+
.ruff_cache/
|
|
15
|
+
.coverage
|
|
16
|
+
htmlcov/
|
|
17
|
+
|
|
18
|
+
# Docs build output
|
|
19
|
+
docs/_build/
|
|
20
|
+
|
|
21
|
+
# IDE / OS
|
|
22
|
+
.idea/
|
|
23
|
+
.vscode/
|
|
24
|
+
.DS_Store
|
|
25
|
+
|
|
26
|
+
# AI
|
|
27
|
+
.claude
|
|
28
|
+
CLAUDE.md
|
|
29
|
+
|
|
30
|
+
# NOTE: vendored Java artifacts (src/glyco_gwstoolkit/java_bridge/vendor/*.jar,
|
|
31
|
+
# *.class) MUST be committed — do not add ignore rules for them.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 glyco-gwstoolkit contributors
|
|
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,166 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: glyco-gwstoolkit
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Enumerate glycan tree isomers, fragment via GlycanBuilder2, generate MSP spectral libraries with SNFG visualization
|
|
5
|
+
Project-URL: Homepage, https://github.com/sosyphe/glyco-gwstoolkit
|
|
6
|
+
Project-URL: Repository, https://github.com/sosyphe/glyco-gwstoolkit
|
|
7
|
+
Project-URL: Issues, https://github.com/sosyphe/glyco-gwstoolkit/issues
|
|
8
|
+
Author-email: Yee <76564061+sosyphe@users.noreply.github.com>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: bioinformatics,glycan,glycomics,mass-spectrometry,msp,snfg
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Chemistry
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Requires-Dist: jinja2>=3.1
|
|
22
|
+
Requires-Dist: networkx>=3.0
|
|
23
|
+
Requires-Dist: pillow>=10.0
|
|
24
|
+
Requires-Dist: rich>=13.0
|
|
25
|
+
Requires-Dist: typer>=0.9
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: mypy>=1.8; extra == 'dev'
|
|
28
|
+
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
30
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
# glyco-gwstoolkit
|
|
34
|
+
|
|
35
|
+

|
|
36
|
+
[](https://pypi.org/project/glyco-gwstoolkit)
|
|
37
|
+
[](https://pepy.tech/project/glyco-gwstoolkit)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
A Python toolkit for enumerating glycan tree topologies from sugar compositions and generating GWS/MSP libraries with SNFG visualization.
|
|
41
|
+
|
|
42
|
+
## Features
|
|
43
|
+
|
|
44
|
+
- **Combinatorial enumeration** of all unique glycan tree topologies for arbitrary sugar compositions
|
|
45
|
+
- **GlycoWorkbench-exact fragmentation** via embedded  — multi-charge, multi-adduct, pos/neg modes
|
|
46
|
+
- **SNFG rendering + interactive HTML reports** with Plotly charts and sortable tables
|
|
47
|
+
- **One-command pipeline** with checkpointing, resume, and multi-worker parallelism
|
|
48
|
+
|
|
49
|
+
## Installation
|
|
50
|
+
|
|
51
|
+
Prerequisites: Python ≥ 3.10, Java JDK ≥ 11
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
git clone https://github.com/sosyphe/glyco-gwstoolkit.git
|
|
55
|
+
cd glyco-gwstoolkit
|
|
56
|
+
uv sync
|
|
57
|
+
gwstoolkit check # verify Python + Java dependencies
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Quick Start
|
|
61
|
+
|
|
62
|
+
One command — enumerate, fragment, render, and report:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
gwstoolkit pipeline \
|
|
66
|
+
--composition "Glc:2,Gal:2" \
|
|
67
|
+
--output-dir output/ \
|
|
68
|
+
--workers 4
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Output:
|
|
72
|
+
|
|
73
|
+
- `data/structures.json` — 18 unique glycan tree isomers
|
|
74
|
+
- `library.msp` — theoretical fragmentation spectra (MSP format)
|
|
75
|
+
- `images/` — SNFG diagrams for each unique topology
|
|
76
|
+
- `report.html` — interactive report with Plotly charts
|
|
77
|
+
|
|
78
|
+
### Input: Sugar Composition
|
|
79
|
+
|
|
80
|
+
Composition is specified as `Sugar:Count` pairs, comma-separated.
|
|
81
|
+
|
|
82
|
+
| Example | Meaning |
|
|
83
|
+
|---------|---------|
|
|
84
|
+
| `Glc:3,Gal:6` | 3 glucose + 6 galactose |
|
|
85
|
+
| `Man:3,GlcNAc:4,Fuc:2` | N-glycan core composition |
|
|
86
|
+
| `Gal:2,NeuAc:2` | Sialylated galactose |
|
|
87
|
+
|
|
88
|
+
### Options
|
|
89
|
+
|
|
90
|
+
**Ion modes and adducts:**
|
|
91
|
+
|
|
92
|
+
| Mode | Adducts | Precursor Types |
|
|
93
|
+
|------|---------|----------------|
|
|
94
|
+
| Positive (`pos`) | H, Na, K | [M+H]⁺, [M+Na]⁺, [M+K]⁺ |
|
|
95
|
+
| Negative (`neg`) | H only | [M-H]⁻ |
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
gwstoolkit pipeline -c "Glc:2,Gal:2" --mode pos,neg --adducts H,Na
|
|
99
|
+
# → [M+H]⁺, [M+Na]⁺, [M-H]⁻ (Na auto-skipped in neg mode)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Fragmentation presets:** GWB_default · CID_low · CID_high · HCD · BY_only
|
|
103
|
+
|
|
104
|
+
### Pipeline
|
|
105
|
+
|
|
106
|
+
```mermaid
|
|
107
|
+
flowchart LR
|
|
108
|
+
A["Glc:2,Gal:2"] --> B["① Enumerate"]
|
|
109
|
+
B --> C["② Fragment"]
|
|
110
|
+
C --> D["③ Render"]
|
|
111
|
+
D --> E["④ Report"]
|
|
112
|
+
|
|
113
|
+
B -.-> F["structures.json"]
|
|
114
|
+
C -.-> G["library.msp"]
|
|
115
|
+
D -.-> H["images/*.png"]
|
|
116
|
+
E -.-> I["report.html"]
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
<p align="center"><img src="https://raw.githubusercontent.com/sosyphe/glyco-gwstoolkit/main/docs/images/snfg-example.png" alt="SNFG Example" width="400"></p>
|
|
120
|
+
|
|
121
|
+
### Run steps individually
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# 1. Enumerate all unique structures
|
|
125
|
+
gwstoolkit enumerate -c "Glc:3,Gal:6" -o structures.json
|
|
126
|
+
|
|
127
|
+
# 2. Fragment → MSP library
|
|
128
|
+
gwstoolkit fragment -i structures.json -o library.msp \
|
|
129
|
+
--preset GWB_default --charges 1,2,3,4 --adducts H,Na,K
|
|
130
|
+
|
|
131
|
+
# 3. Render SNFG diagrams
|
|
132
|
+
gwstoolkit render -i structures.json --output-dir images/
|
|
133
|
+
|
|
134
|
+
# 4. Generate HTML report
|
|
135
|
+
gwstoolkit report -i output/ -o report.html
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
> **Tip:** `fragment` and `render` also accept GWS strings directly — use `--gws "..."` for a single structure or `--gws-file gws_list.txt` for batch input (one GWS per line).
|
|
139
|
+
|
|
140
|
+
## Performance
|
|
141
|
+
|
|
142
|
+
Structure counts grow **exponentially** with residue count — plan compositions carefully:
|
|
143
|
+
|
|
144
|
+
| Composition | Residues | Structures | Enum | Fragment |
|
|
145
|
+
|-------------|----------|-----------|------|----------|
|
|
146
|
+
| `Glc:2,Gal:3` | 5 | 63 | <0.01s | ~2s |
|
|
147
|
+
| `Glc:3,Gal:3` | 6 | 268 | 0.02s | ~6s |
|
|
148
|
+
| `Glc:3,Gal:6` | 9 | 14,684 | 1.4s | ~31min |
|
|
149
|
+
| `Man:5,GlcNAc:4,Fuc:1` | 10 | 464,364 | 63s | ~5h |
|
|
150
|
+
|
|
151
|
+
Use `--workers N` for parallel acceleration.
|
|
152
|
+
|
|
153
|
+
## Limitations
|
|
154
|
+
|
|
155
|
+
Current enumeration is purely **combinatorial** — no biochemical constraints:
|
|
156
|
+
|
|
157
|
+
- **No anomeric configuration** (α/β) — tree connectivity only, no stereochemistry
|
|
158
|
+
- **No linkage position** (1→3, 1→4, 1→6) — branching structure only
|
|
159
|
+
- **No ring form** (pyranose/furanose) distinction
|
|
160
|
+
- **No biochemical rule filtering** — biologically unlikely structures are included
|
|
161
|
+
|
|
162
|
+
Output is a **superset** of biologically plausible structures. Filter based on domain knowledge.
|
|
163
|
+
|
|
164
|
+
## License
|
|
165
|
+
|
|
166
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# glyco-gwstoolkit
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
[](https://pypi.org/project/glyco-gwstoolkit)
|
|
5
|
+
[](https://pepy.tech/project/glyco-gwstoolkit)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
A Python toolkit for enumerating glycan tree topologies from sugar compositions and generating GWS/MSP libraries with SNFG visualization.
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- **Combinatorial enumeration** of all unique glycan tree topologies for arbitrary sugar compositions
|
|
13
|
+
- **GlycoWorkbench-exact fragmentation** via embedded  — multi-charge, multi-adduct, pos/neg modes
|
|
14
|
+
- **SNFG rendering + interactive HTML reports** with Plotly charts and sortable tables
|
|
15
|
+
- **One-command pipeline** with checkpointing, resume, and multi-worker parallelism
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
Prerequisites: Python ≥ 3.10, Java JDK ≥ 11
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
git clone https://github.com/sosyphe/glyco-gwstoolkit.git
|
|
23
|
+
cd glyco-gwstoolkit
|
|
24
|
+
uv sync
|
|
25
|
+
gwstoolkit check # verify Python + Java dependencies
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
One command — enumerate, fragment, render, and report:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
gwstoolkit pipeline \
|
|
34
|
+
--composition "Glc:2,Gal:2" \
|
|
35
|
+
--output-dir output/ \
|
|
36
|
+
--workers 4
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Output:
|
|
40
|
+
|
|
41
|
+
- `data/structures.json` — 18 unique glycan tree isomers
|
|
42
|
+
- `library.msp` — theoretical fragmentation spectra (MSP format)
|
|
43
|
+
- `images/` — SNFG diagrams for each unique topology
|
|
44
|
+
- `report.html` — interactive report with Plotly charts
|
|
45
|
+
|
|
46
|
+
### Input: Sugar Composition
|
|
47
|
+
|
|
48
|
+
Composition is specified as `Sugar:Count` pairs, comma-separated.
|
|
49
|
+
|
|
50
|
+
| Example | Meaning |
|
|
51
|
+
|---------|---------|
|
|
52
|
+
| `Glc:3,Gal:6` | 3 glucose + 6 galactose |
|
|
53
|
+
| `Man:3,GlcNAc:4,Fuc:2` | N-glycan core composition |
|
|
54
|
+
| `Gal:2,NeuAc:2` | Sialylated galactose |
|
|
55
|
+
|
|
56
|
+
### Options
|
|
57
|
+
|
|
58
|
+
**Ion modes and adducts:**
|
|
59
|
+
|
|
60
|
+
| Mode | Adducts | Precursor Types |
|
|
61
|
+
|------|---------|----------------|
|
|
62
|
+
| Positive (`pos`) | H, Na, K | [M+H]⁺, [M+Na]⁺, [M+K]⁺ |
|
|
63
|
+
| Negative (`neg`) | H only | [M-H]⁻ |
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
gwstoolkit pipeline -c "Glc:2,Gal:2" --mode pos,neg --adducts H,Na
|
|
67
|
+
# → [M+H]⁺, [M+Na]⁺, [M-H]⁻ (Na auto-skipped in neg mode)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Fragmentation presets:** GWB_default · CID_low · CID_high · HCD · BY_only
|
|
71
|
+
|
|
72
|
+
### Pipeline
|
|
73
|
+
|
|
74
|
+
```mermaid
|
|
75
|
+
flowchart LR
|
|
76
|
+
A["Glc:2,Gal:2"] --> B["① Enumerate"]
|
|
77
|
+
B --> C["② Fragment"]
|
|
78
|
+
C --> D["③ Render"]
|
|
79
|
+
D --> E["④ Report"]
|
|
80
|
+
|
|
81
|
+
B -.-> F["structures.json"]
|
|
82
|
+
C -.-> G["library.msp"]
|
|
83
|
+
D -.-> H["images/*.png"]
|
|
84
|
+
E -.-> I["report.html"]
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
<p align="center"><img src="https://raw.githubusercontent.com/sosyphe/glyco-gwstoolkit/main/docs/images/snfg-example.png" alt="SNFG Example" width="400"></p>
|
|
88
|
+
|
|
89
|
+
### Run steps individually
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# 1. Enumerate all unique structures
|
|
93
|
+
gwstoolkit enumerate -c "Glc:3,Gal:6" -o structures.json
|
|
94
|
+
|
|
95
|
+
# 2. Fragment → MSP library
|
|
96
|
+
gwstoolkit fragment -i structures.json -o library.msp \
|
|
97
|
+
--preset GWB_default --charges 1,2,3,4 --adducts H,Na,K
|
|
98
|
+
|
|
99
|
+
# 3. Render SNFG diagrams
|
|
100
|
+
gwstoolkit render -i structures.json --output-dir images/
|
|
101
|
+
|
|
102
|
+
# 4. Generate HTML report
|
|
103
|
+
gwstoolkit report -i output/ -o report.html
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
> **Tip:** `fragment` and `render` also accept GWS strings directly — use `--gws "..."` for a single structure or `--gws-file gws_list.txt` for batch input (one GWS per line).
|
|
107
|
+
|
|
108
|
+
## Performance
|
|
109
|
+
|
|
110
|
+
Structure counts grow **exponentially** with residue count — plan compositions carefully:
|
|
111
|
+
|
|
112
|
+
| Composition | Residues | Structures | Enum | Fragment |
|
|
113
|
+
|-------------|----------|-----------|------|----------|
|
|
114
|
+
| `Glc:2,Gal:3` | 5 | 63 | <0.01s | ~2s |
|
|
115
|
+
| `Glc:3,Gal:3` | 6 | 268 | 0.02s | ~6s |
|
|
116
|
+
| `Glc:3,Gal:6` | 9 | 14,684 | 1.4s | ~31min |
|
|
117
|
+
| `Man:5,GlcNAc:4,Fuc:1` | 10 | 464,364 | 63s | ~5h |
|
|
118
|
+
|
|
119
|
+
Use `--workers N` for parallel acceleration.
|
|
120
|
+
|
|
121
|
+
## Limitations
|
|
122
|
+
|
|
123
|
+
Current enumeration is purely **combinatorial** — no biochemical constraints:
|
|
124
|
+
|
|
125
|
+
- **No anomeric configuration** (α/β) — tree connectivity only, no stereochemistry
|
|
126
|
+
- **No linkage position** (1→3, 1→4, 1→6) — branching structure only
|
|
127
|
+
- **No ring form** (pyranose/furanose) distinction
|
|
128
|
+
- **No biochemical rule filtering** — biologically unlikely structures are included
|
|
129
|
+
|
|
130
|
+
Output is a **superset** of biologically plausible structures. Filter based on domain knowledge.
|
|
131
|
+
|
|
132
|
+
## License
|
|
133
|
+
|
|
134
|
+
[MIT](LICENSE)
|
|
File without changes
|
|
Binary file
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "glyco-gwstoolkit"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Enumerate glycan tree isomers, fragment via GlycanBuilder2, generate MSP spectral libraries with SNFG visualization"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Yee", email = "76564061+sosyphe@users.noreply.github.com" }
|
|
14
|
+
]
|
|
15
|
+
keywords = ["glycan", "mass-spectrometry", "msp", "snfg", "glycomics", "bioinformatics"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 3 - Alpha",
|
|
18
|
+
"Intended Audience :: Science/Research",
|
|
19
|
+
"Topic :: Scientific/Engineering :: Bio-Informatics",
|
|
20
|
+
"Topic :: Scientific/Engineering :: Chemistry",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
"Programming Language :: Python :: 3.13",
|
|
25
|
+
]
|
|
26
|
+
dependencies = [
|
|
27
|
+
"typer>=0.9",
|
|
28
|
+
"rich>=13.0",
|
|
29
|
+
"networkx>=3.0",
|
|
30
|
+
"jinja2>=3.1",
|
|
31
|
+
"pillow>=10.0",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
[project.optional-dependencies]
|
|
35
|
+
dev = [
|
|
36
|
+
"pytest>=7.0",
|
|
37
|
+
"pytest-cov>=4.0",
|
|
38
|
+
"ruff>=0.4",
|
|
39
|
+
"mypy>=1.8",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[project.scripts]
|
|
43
|
+
gwstoolkit = "glyco_gwstoolkit.cli.main:app"
|
|
44
|
+
|
|
45
|
+
[project.urls]
|
|
46
|
+
Homepage = "https://github.com/sosyphe/glyco-gwstoolkit"
|
|
47
|
+
Repository = "https://github.com/sosyphe/glyco-gwstoolkit"
|
|
48
|
+
Issues = "https://github.com/sosyphe/glyco-gwstoolkit/issues"
|
|
49
|
+
|
|
50
|
+
[tool.hatch.build]
|
|
51
|
+
artifacts = [
|
|
52
|
+
"**/*.class",
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
[tool.hatch.build.targets.wheel]
|
|
56
|
+
packages = ["src/glyco_gwstoolkit"]
|
|
57
|
+
|
|
58
|
+
[tool.hatch.build.targets.sdist]
|
|
59
|
+
artifacts = [
|
|
60
|
+
"**/*.class",
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
[tool.pytest.ini_options]
|
|
64
|
+
testpaths = ["tests"]
|
|
65
|
+
markers = [
|
|
66
|
+
"slow: marks tests that require Java (deselect with -m 'not slow')",
|
|
67
|
+
"integration: marks integration tests",
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
[tool.ruff]
|
|
71
|
+
target-version = "py310"
|
|
72
|
+
line-length = 100
|
|
73
|
+
|
|
74
|
+
[tool.mypy]
|
|
75
|
+
python_version = "3.10"
|
|
76
|
+
strict = true
|
|
77
|
+
|
|
78
|
+
[[tool.mypy.overrides]]
|
|
79
|
+
# networkx ships no type information and networkx-stubs is incomplete
|
|
80
|
+
module = "networkx.*"
|
|
81
|
+
ignore_missing_imports = true
|
|
82
|
+
|
|
83
|
+
[dependency-groups]
|
|
84
|
+
dev = [
|
|
85
|
+
"mypy>=2.3.1",
|
|
86
|
+
"pytest>=9.1.1",
|
|
87
|
+
"pytest-cov>=7.1.0",
|
|
88
|
+
"ruff>=0.16.8",
|
|
89
|
+
]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""glyco-gwstoolkit: Enumerate glycan tree isomers, fragment via GlycanBuilder2,
|
|
2
|
+
generate MSP spectral libraries with SNFG visualization."""
|
|
3
|
+
|
|
4
|
+
__version__ = "0.1.0"
|
|
5
|
+
|
|
6
|
+
# Public API
|
|
7
|
+
from glyco_gwstoolkit.enumeration import enumerate_structures
|
|
8
|
+
from glyco_gwstoolkit.models.composition import SugarComposition
|
|
9
|
+
from glyco_gwstoolkit.models.structure import GlycanStructure, SugarCounts
|
|
10
|
+
from glyco_gwstoolkit.models.sugar_types import SugarType, SugarTypeRegistry
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"GlycanStructure",
|
|
14
|
+
"SugarComposition",
|
|
15
|
+
"SugarCounts",
|
|
16
|
+
"SugarType",
|
|
17
|
+
"SugarTypeRegistry",
|
|
18
|
+
"__version__",
|
|
19
|
+
"enumerate_structures",
|
|
20
|
+
]
|
|
File without changes
|