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.
Files changed (85) hide show
  1. glyco_gwstoolkit-0.1.0/.github/workflows/ci.yml +33 -0
  2. glyco_gwstoolkit-0.1.0/.github/workflows/workflow.yml +75 -0
  3. glyco_gwstoolkit-0.1.0/.gitignore +31 -0
  4. glyco_gwstoolkit-0.1.0/LICENSE +21 -0
  5. glyco_gwstoolkit-0.1.0/PKG-INFO +166 -0
  6. glyco_gwstoolkit-0.1.0/README.md +134 -0
  7. glyco_gwstoolkit-0.1.0/docs/images/.gitkeep +0 -0
  8. glyco_gwstoolkit-0.1.0/docs/images/snfg-example.png +0 -0
  9. glyco_gwstoolkit-0.1.0/pyproject.toml +89 -0
  10. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/__init__.py +20 -0
  11. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/__main__.py +5 -0
  12. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/cli/__init__.py +0 -0
  13. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/cli/enumerate_cmd.py +168 -0
  14. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/cli/fragment_cmd.py +243 -0
  15. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/cli/input_utils.py +196 -0
  16. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/cli/main.py +50 -0
  17. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/cli/pipeline_cmd.py +167 -0
  18. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/cli/render_cmd.py +135 -0
  19. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/cli/report_cmd.py +103 -0
  20. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/enumeration/__init__.py +267 -0
  21. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/enumeration/assignment.py +127 -0
  22. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/enumeration/canonical.py +66 -0
  23. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/enumeration/counter.py +58 -0
  24. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/enumeration/gws_builder.py +146 -0
  25. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/enumeration/trees.py +65 -0
  26. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/exporters/__init__.py +0 -0
  27. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/exporters/count_logger.py +74 -0
  28. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/exporters/json_writer.py +101 -0
  29. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/exporters/msp_writer.py +393 -0
  30. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/exporters/report/__init__.py +5 -0
  31. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/exporters/report/builder.py +611 -0
  32. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/exporters/report/static/report.css +488 -0
  33. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/exporters/report/static/report.js +531 -0
  34. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/exporters/report/templates/report.html.j2 +324 -0
  35. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/exporters/summary_writer.py +157 -0
  36. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/__init__.py +0 -0
  37. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/fragmenter.py +316 -0
  38. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/java_check.py +67 -0
  39. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/java_engine.py +405 -0
  40. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/renderer.py +170 -0
  41. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/GlycanFragmenter$1.class +0 -0
  42. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/GlycanFragmenter.class +0 -0
  43. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/GlycanFragmenter.java +298 -0
  44. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/GlycanSNFGRenderer$1.class +0 -0
  45. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/GlycanSNFGRenderer.class +0 -0
  46. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/GlycanSNFGRenderer.java +163 -0
  47. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/StrokeThickener.class +0 -0
  48. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/ThickGlycanRendererAWT.class +0 -0
  49. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/ThickLinkageRendererAWT.class +0 -0
  50. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/ThickPaintable.class +0 -0
  51. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/ThickResidueRendererAWT.class +0 -0
  52. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/ThickStroke.java +580 -0
  53. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/TopologyHasher.class +0 -0
  54. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/TopologyHasher.java +71 -0
  55. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/TreeHasher.class +0 -0
  56. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/TreeHasher.java +47 -0
  57. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/java_bridge/vendor/glycanbuilder2-jar-with-dependencies.jar +0 -0
  58. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/logging_config.py +46 -0
  59. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/models/__init__.py +0 -0
  60. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/models/composition.py +123 -0
  61. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/models/config.py +120 -0
  62. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/models/structure.py +43 -0
  63. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/models/sugar_types.py +137 -0
  64. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/pipeline/__init__.py +13 -0
  65. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/pipeline/checkpoint.py +200 -0
  66. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/pipeline/progress.py +108 -0
  67. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/pipeline/runner.py +318 -0
  68. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/pipeline/steps.py +384 -0
  69. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/py.typed +0 -0
  70. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/validation/__init__.py +13 -0
  71. glyco_gwstoolkit-0.1.0/src/glyco_gwstoolkit/validation/gws_validator.py +249 -0
  72. glyco_gwstoolkit-0.1.0/tests/__init__.py +0 -0
  73. glyco_gwstoolkit-0.1.0/tests/conftest.py +19 -0
  74. glyco_gwstoolkit-0.1.0/tests/test_assignment.py +79 -0
  75. glyco_gwstoolkit-0.1.0/tests/test_canonical.py +56 -0
  76. glyco_gwstoolkit-0.1.0/tests/test_composition.py +96 -0
  77. glyco_gwstoolkit-0.1.0/tests/test_counter.py +37 -0
  78. glyco_gwstoolkit-0.1.0/tests/test_gws_builder.py +70 -0
  79. glyco_gwstoolkit-0.1.0/tests/test_gws_validation.py +200 -0
  80. glyco_gwstoolkit-0.1.0/tests/test_java_integration.py +104 -0
  81. glyco_gwstoolkit-0.1.0/tests/test_msp_writer.py +302 -0
  82. glyco_gwstoolkit-0.1.0/tests/test_pipeline.py +355 -0
  83. glyco_gwstoolkit-0.1.0/tests/test_summary_writer.py +223 -0
  84. glyco_gwstoolkit-0.1.0/tests/test_trees.py +81 -0
  85. 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
+ ![Python](https://img.shields.io/badge/python-≥3.10-blue)
36
+ [![PyPI Version](https://img.shields.io/pypi/v/glyco-gwstoolkit)](https://pypi.org/project/glyco-gwstoolkit)
37
+ [![PyPI Downloads](https://static.pepy.tech/badge/glyco-gwstoolkit)](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 ![GlycanBuilder2](https://github.com/glycoinfo/GlycanBuilder2) — 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
+ ![Python](https://img.shields.io/badge/python-≥3.10-blue)
4
+ [![PyPI Version](https://img.shields.io/pypi/v/glyco-gwstoolkit)](https://pypi.org/project/glyco-gwstoolkit)
5
+ [![PyPI Downloads](https://static.pepy.tech/badge/glyco-gwstoolkit)](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 ![GlycanBuilder2](https://github.com/glycoinfo/GlycanBuilder2) — 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
@@ -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
+ ]
@@ -0,0 +1,5 @@
1
+ """Entry point for `python -m glyco_gwstoolkit`."""
2
+
3
+ from glyco_gwstoolkit.cli.main import app
4
+
5
+ app()