@datagrok/sequence-translator 1.10.16 → 1.10.18
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.
- package/CHANGELOG.md +5 -0
- package/CLAUDE.md +274 -253
- package/CREDITS.md +236 -0
- package/detectors.js +8 -0
- package/dist/package-test.js +1 -1
- package/dist/package-test.js.map +1 -1
- package/dist/package.js +1 -1
- package/dist/package.js.map +1 -1
- package/package.json +3 -3
- package/src/apps/common/model/oligo-toolkit-package.ts +13 -1
- package/src/oligo-renderer/analog-cache.ts +48 -0
- package/src/oligo-renderer/canvas-renderer.ts +129 -15
- package/src/oligo-renderer/cell-renderer.ts +8 -2
- package/src/oligo-renderer/helm-parser.ts +3 -2
- package/src/oligo-renderer/legend-panel.ts +31 -6
- package/src/oligo-renderer/types.ts +21 -0
- package/src/package-api.ts +11 -0
- package/src/package-test.ts +1 -0
- package/src/package.g.ts +14 -0
- package/src/package.ts +60 -2
- package/src/polytool/pt-chem-enum-dialog.ts +50 -10
- package/src/polytool/pt-chem-enum.ts +76 -7
- package/src/polytool/pt-enumerate-seq-dialog.ts +18 -4
- package/src/tests/oligo-cell-editor-tests.ts +83 -0
- package/src/tests/oligo-renderer-tests.ts +64 -1
- package/test-console-output-1.log +196 -147
- package/test-record-1.mp4 +0 -0
package/CLAUDE.md
CHANGED
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
## Overview
|
|
4
4
|
|
|
5
|
-
**Package:** `@datagrok/sequence-translator` (v1.10.
|
|
5
|
+
**Package:** `@datagrok/sequence-translator` (v1.10.16)
|
|
6
6
|
**Category:** Bioinformatics
|
|
7
7
|
**Author:** Davit Rizhinashvili
|
|
8
|
-
**Description:** Translates oligonucleotide sequences between different representations (Axolabs, BioSpring, GCRS, Mermade, HELM, nucleotides, etc.).
|
|
8
|
+
**Description:** Translates oligonucleotide sequences between different representations (Axolabs, BioSpring, GCRS, Mermade, HELM, nucleotides, etc.). Provides pattern design, structure visualization, advanced polymer conversion (PolyTool), and a dedicated **OligoNucleotide** semantic type / cell renderer for siRNA / ASO duplex visualization on top of HELM.
|
|
9
9
|
|
|
10
10
|
## Dependencies
|
|
11
11
|
|
|
12
12
|
| Dependency | Purpose |
|
|
13
13
|
|------------|---------|
|
|
14
14
|
| `datagrok-api` | Core Datagrok platform API |
|
|
15
|
-
| `@datagrok-libraries/bio` | HELM helper, sequence handler, macromolecule utils, monomer
|
|
15
|
+
| `@datagrok-libraries/bio` | HELM helper, sequence handler, macromolecule utils, central monomer library |
|
|
16
16
|
| `@datagrok-libraries/chem-meta` | RDKit JS API, molfile parsing |
|
|
17
17
|
| `@datagrok-libraries/utils` | Error handling, common utilities |
|
|
18
18
|
| `@datagrok-libraries/tutorials` | Tutorial creation helpers |
|
|
@@ -28,11 +28,13 @@
|
|
|
28
28
|
|
|
29
29
|
- **MonomersPath** (string): Path to additional monomer libraries. Default: `System:AppData/SequenceTranslator/monomers`. Fallback: `System:AppData/SequenceTranslator/monomers-sample`.
|
|
30
30
|
|
|
31
|
+
> The OligoNucleotide subsystem (under `src/oligo-renderer/`) deliberately uses the **central Bio monomer library** (`HELMCoreLibrary.json` + the new `oligo-conjugates.json` shipped in `packages/Bio/files/monomer-libraries/`), not the ST-internal one. ST's monomer-lib stays scoped to translator/pattern/structure apps.
|
|
32
|
+
|
|
31
33
|
---
|
|
32
34
|
|
|
33
35
|
## Architecture
|
|
34
36
|
|
|
35
|
-
The package is organized into **four main applications
|
|
37
|
+
The package is organized into **four main applications**, a **PolyTool subsystem**, the **OligoNucleotide renderer subsystem**, and shared infrastructure:
|
|
36
38
|
|
|
37
39
|
```
|
|
38
40
|
src/
|
|
@@ -45,26 +47,31 @@ src/
|
|
|
45
47
|
│
|
|
46
48
|
├── apps/
|
|
47
49
|
│ ├── common/ # Shared model, data loading, validation, UI base
|
|
48
|
-
│ │ ├── model/ # Core domain logic
|
|
49
|
-
│ │ └── view/ # Shared UI components
|
|
50
50
|
│ ├── translator/ # Format conversion app
|
|
51
|
-
│ │ ├── model/ # Conversion logic
|
|
52
|
-
│ │ └── view/ # Translator UI
|
|
53
51
|
│ ├── pattern/ # Pattern design app
|
|
54
|
-
│ │ ├── model/ # Pattern state, persistence, translation
|
|
55
|
-
│ │ └── view/ # Pattern editor UI + SVG rendering
|
|
56
52
|
│ └── structure/ # Molecular structure app
|
|
57
|
-
│
|
|
58
|
-
|
|
53
|
+
│
|
|
54
|
+
├── oligo-renderer/ # OligoNucleotide semType, cell renderer, panels, converters
|
|
55
|
+
│ ├── types.ts # Constants, parsed-model types, modification dictionary
|
|
56
|
+
│ ├── helm-parser.ts # Lightweight RNA/DNA HELM duplex parser + canonicalizer
|
|
57
|
+
│ ├── canvas-renderer.ts # Pure-fn canvas drawing of duplex, hit-testing
|
|
58
|
+
│ ├── cell-renderer.ts # OligoNucleotideCellRenderer (extends DG.GridCellRenderer)
|
|
59
|
+
│ ├── tooltip.ts # Hover tooltip with cached RDKit structures
|
|
60
|
+
│ ├── legend-panel.ts # Per-cell summary + filtered color legend
|
|
61
|
+
│ ├── structures-panel.ts # Sense/antisense full molecular structures (Bio:toAtomicLevelPanel)
|
|
62
|
+
│ └── converters.ts # convertHelmColumnToOligo / combineSenseAntisenseToOligo / tagAsOligoNucleotide
|
|
59
63
|
│
|
|
60
64
|
├── polytool/ # Advanced polymer conversion subsystem
|
|
61
65
|
│ ├── conversion/ # Core algorithms (chain, rules, reactions)
|
|
62
|
-
│
|
|
66
|
+
│ └── *.ts # Dialogs, enumeration, handlers
|
|
63
67
|
│
|
|
64
68
|
├── plugins/ # External plugin integration (MerMade)
|
|
65
69
|
├── utils/ # Cyclized/dimerized notation providers, error handling
|
|
66
70
|
├── demo/ # Demo entry points
|
|
67
71
|
└── tests/ # Test suite
|
|
72
|
+
|
|
73
|
+
prototypes/ # Off-tree dev tooling for the OligoNucleotide subsystem
|
|
74
|
+
detectors.js # Autostart bootstrap + context-menu wiring (no semType detector)
|
|
68
75
|
```
|
|
69
76
|
|
|
70
77
|
---
|
|
@@ -79,302 +86,247 @@ export const _package: OligoToolkitPackage = new OligoToolkitPackage({debug: tru
|
|
|
79
86
|
|
|
80
87
|
### Initialization Flow
|
|
81
88
|
|
|
82
|
-
1. `init()` → gets HELM helper from bio library, calls `completeInit()`
|
|
89
|
+
1. `init()` (decorator `@init`) → gets HELM helper from bio library, calls `completeInit()`
|
|
83
90
|
2. `completeInit()` → sets up monomer library wrapper
|
|
84
91
|
3. `initLibData()` → lazy-loads JSON data files (called on app open)
|
|
85
92
|
|
|
86
93
|
### Registered Functions
|
|
87
94
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
|
93
|
-
|
|
94
|
-
| `
|
|
95
|
-
| `
|
|
96
|
-
| `
|
|
97
|
-
| `
|
|
98
|
-
| `
|
|
99
|
-
| `
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
|
104
|
-
|
|
105
|
-
| `
|
|
106
|
-
| `
|
|
95
|
+
The table below lists every function/app/panel registered by `PackageFunctions`. **Method name** is the TypeScript identifier; **registered name** is what the platform sees (defaults to method name when no `name:` decorator option is given).
|
|
96
|
+
|
|
97
|
+
#### Apps
|
|
98
|
+
|
|
99
|
+
| Method | Registered name | browsePath | Description |
|
|
100
|
+
|---|---|---|---|
|
|
101
|
+
| `oligoToolkitApp` | Oligo Toolkit | `Peptides \| Oligo Toolkit` | Combined tabbed app (translator + pattern + structure + plugins) |
|
|
102
|
+
| `oligoTranslatorApp` | Oligo Translator | `Peptides \| Oligo Toolkit` | Standalone translator |
|
|
103
|
+
| `oligoPatternApp` | Oligo Pattern | `Peptides \| Oligo Toolkit` | Standalone pattern designer |
|
|
104
|
+
| `oligoStructureApp` | Oligo Structure | `Peptides \| Oligo Toolkit` | Standalone structure viewer |
|
|
105
|
+
| `ptEnumeratorHelmApp` | HELM Enumerator | `Peptides \| PolyTool` | HELM enumerator app |
|
|
106
|
+
| `ptEnumeratorChemApp` | Chem Enumerator | `Chem \| PolyTool` | Chem enumerator app |
|
|
107
|
+
|
|
108
|
+
#### Top-Menu Functions
|
|
109
|
+
|
|
110
|
+
| Method | Registered name | top-menu | Description |
|
|
111
|
+
|---|---|---|---|
|
|
112
|
+
| `polyToolConvertTopMenu` | polyToolConvert | `Bio \| PolyTool \| Convert...` | Open convert dialog |
|
|
113
|
+
| `polyToolEnumerateHelmTopMenu` | polyToolEnumerateHelm | `Bio \| PolyTool \| Enumerate HELM...` | HELM enumerate dialog |
|
|
114
|
+
| `polyToolEnumerateChemTopMenu` | polyToolEnumerateChem | `Bio \| PolyTool \| Enumerate Chem...` | Chem enumerate dialog |
|
|
115
|
+
| `chemEnumerateReactionsTopMenu` | chemEnumerateReactions | `Chem \| Transform \| Reactions \| Enumerate...` | Alternate menu for chem enumeration |
|
|
116
|
+
| `getPolyToolCombineDialog` | Combine Sequences | `Bio \| PolyTool \| Combine Sequences...` | Cartesian-product combine |
|
|
117
|
+
|
|
118
|
+
#### Cell Renderer
|
|
119
|
+
|
|
120
|
+
| Method | cellType / columnTags | Description |
|
|
121
|
+
|---|---|---|
|
|
122
|
+
| `oligoNucleotideCellRenderer` | `cellType: OligoNucleotide`, `columnTags: quality=OligoNucleotide` | Duplex view for HELM-backed OligoNucleotide columns |
|
|
123
|
+
|
|
124
|
+
#### Panels (`tags: panel, widgets`)
|
|
125
|
+
|
|
126
|
+
| Method | Registered name | Input semType | Description |
|
|
127
|
+
|---|---|---|---|
|
|
128
|
+
| `oligoNucleotidePanel` | Oligo-Nucleotide | OligoNucleotide | Per-cell summary, conjugate counts, color legend filtered to the cell |
|
|
129
|
+
| `oligoNucleotideStructuresPanel` | Oligo Structures | OligoNucleotide | Lazy accordion: sense / antisense full structures via `Bio:toAtomicLevelPanel` |
|
|
130
|
+
|
|
131
|
+
#### Public API & Helpers
|
|
132
|
+
|
|
133
|
+
| Method | Registered name | Notes |
|
|
134
|
+
|---|---|---|
|
|
135
|
+
| `getTranslationHelper` | getTranslationHelper | Returns `ITranslationHelper` (calls `_package.initLibData()` first) |
|
|
136
|
+
| `getCodeToWeightsMap` | getCodeToWeightsMap | Code → MW lookup map |
|
|
137
|
+
| `validateSequence` | validateSequence | Boolean validation against detected format |
|
|
138
|
+
| `getMolfileFromGcrsSequence` | **`validateSequence`** ⚠️ | GCRS → V3000 molfile. **Note:** the `name:` decorator currently mis-registers this as `validateSequence`, colliding with the previous entry. Method name still works for in-package callers. |
|
|
139
|
+
| `linkStrands` | linkStrands | Multi-strand assembly (V3000) |
|
|
140
|
+
| `translateOligonucleotideSequence` | translateOligonucleotideSequence | Format-to-format conversion |
|
|
141
|
+
| `polyToolConvert2` | polyToolConvert2 | Bulk conversion (uses editor `getPolyToolConvertEditor`) |
|
|
142
|
+
| `getPolyToolConvertEditor` | getPolyToolConvertEditor | Function-call editor for `polyToolConvert2` (`@editor` decorator) |
|
|
143
|
+
| `polyToolColumnChoice` | polyToolColumnChoice | Mark macromolecule column + redetect semantic types |
|
|
144
|
+
| `createMonomerLibraryForPolyTool` | createMonomerLibraryForPolyTool | CSV → JSON monomer library |
|
|
145
|
+
| `enumerateSingleHelmSequence` | Enumerate Single HELM Sequence | Programmatic single-HELM enumeration → DataFrame |
|
|
146
|
+
| `enumerateSingleHelmSequenceWithNaturalAAs` | Enumerate Single HELM Sequence with natural amino acids | All-positions natural-AA enumeration |
|
|
147
|
+
|
|
148
|
+
#### Context-Menu Wrappers (invoked from `detectors.js`)
|
|
149
|
+
|
|
150
|
+
| Method | Registered name | Trigger | Description |
|
|
151
|
+
|---|---|---|---|
|
|
152
|
+
| `getPtHelmEnumeratorDialog` | Polytool Helm Enumerator dialog | Right-click Macromolecule cell | HELM enumerator dialog seeded by clicked cell |
|
|
153
|
+
| `getPtChemEnumeratorDialog` | Polytool Chem Enumerator dialog | Right-click Molecule cell | Chem enumerator dialog seeded by clicked cell |
|
|
154
|
+
| `getPtOligoEnumeratorDialog` | Polytool Oligo Enumerator dialog | Right-click OligoNucleotide cell | Wraps oligo HELM in a temp Macromolecule cell, runs HELM enumerator with `outputAsOligo=true` so the result column is tagged OligoNucleotide |
|
|
155
|
+
| `convertHelmToOligoNucleotide` | convertHelmToOligoNucleotide | Submenu `Oligo` on HELM cell | Clones a HELM column and tags it as OligoNucleotide |
|
|
156
|
+
| `combineSenseAntisenseToOligoNucleotide` | combineSenseAntisenseToOligoNucleotide | Submenu `Oligo` on Macromolecule cell | Opens `.prepare(...).edit()` to pick antisense; produces combined Oligo column |
|
|
157
|
+
|
|
158
|
+
#### Notation Provider Glue
|
|
159
|
+
|
|
160
|
+
| Method | Registered name | Notes |
|
|
161
|
+
|---|---|---|
|
|
162
|
+
| `applyNotationProviderForCyclized` | **`applyNotationProviderForHarmonizedSequence`** | Tags column + attaches `CyclizedNotationProvider` |
|
|
163
|
+
| `harmonizedSequenceNotationProviderConstructor` | harmonizedSequenceNotationProviderConstructor | `meta.role: notationProviderConstructor`; returns the provider class |
|
|
164
|
+
|
|
165
|
+
#### Demo Entries
|
|
166
|
+
|
|
167
|
+
| Method | Registered name | demoPath |
|
|
168
|
+
|---|---|---|
|
|
169
|
+
| `demoTranslateSequence` | demoOligoTranslator | `Bioinformatics \| Oligo Toolkit \| Translator` |
|
|
170
|
+
| `demoOligoPattern` | demoOligoPattern | `Bioinformatics \| Oligo Toolkit \| Pattern` |
|
|
171
|
+
| `demoOligoStructure` | demoOligoStructure | `Bioinformatics \| Oligo Toolkit \| Structure` |
|
|
107
172
|
|
|
108
173
|
---
|
|
109
174
|
|
|
110
|
-
##
|
|
111
|
-
|
|
112
|
-
### apps/common/model/ — Core Domain Model
|
|
113
|
-
|
|
114
|
-
**`oligo-toolkit-package.ts`** — `OligoToolkitPackage` class (extends `DG.Package`, implements `ITranslationHelper`)
|
|
115
|
-
- Central facade managing initialization, monomer libraries, JSON data
|
|
116
|
-
- Factory for `SequenceValidator`, `FormatConverter`, `FormatDetector`
|
|
117
|
-
- Lazy init with promise caching
|
|
118
|
-
|
|
119
|
-
**`data-loader/json-loader.ts`** — `JsonData` class
|
|
120
|
-
- Loads 4 JSON files in parallel from `MonomersPath`:
|
|
121
|
-
- `monomer-lib.json` — full monomer library with molfiles
|
|
122
|
-
- `formats-to-helm.json` — format code → HELM mappings
|
|
123
|
-
- `codes-to-symbols.json` — format code → monomer symbol mappings
|
|
124
|
-
- `pattern-app-data.json` — color maps for pattern app
|
|
125
|
-
- `linkers.json` — monomers with phosphate groups
|
|
126
|
-
|
|
127
|
-
**`monomer-lib/lib-wrapper.ts`** — `MonomerLibWrapper` class
|
|
128
|
-
- Adapter between `IMonomerLib` (from bio library) and the application
|
|
129
|
-
- Lookups: by symbol, by format, by code
|
|
130
|
-
- Molecular weight aggregation, DataFrame generation for viewer
|
|
131
|
-
|
|
132
|
-
**`parsing-validation/format-detector.ts`** — `FormatDetector` class
|
|
133
|
-
- Infers sequence format from content (checks HELM prefix, then scans for matching codes)
|
|
134
|
-
- Validates candidates using `SequenceValidator`
|
|
135
|
-
|
|
136
|
-
**`parsing-validation/format-handler.ts`** — `FormatHandler` class
|
|
137
|
-
- Bidirectional mapping between source formats and HELM notation
|
|
138
|
-
- Regex generation with negative lookaround for accurate code matching
|
|
139
|
-
- Phosphate linkage extraction
|
|
140
|
-
|
|
141
|
-
**`parsing-validation/sequence-validator.ts`** — `SequenceValidator` class
|
|
142
|
-
- Greedy longest-match-first validation
|
|
143
|
-
- Returns index of first invalid code or -1 for valid
|
|
175
|
+
## detectors.js — Bootstrap & Context-Menu Wiring
|
|
144
176
|
|
|
145
|
-
|
|
177
|
+
`SequenceTranslatorPackageDetectors extends DG.Package`. **No live `semTypeDetector` is registered** — only an autostart bootstrap and a `notationRefiner`.
|
|
146
178
|
|
|
147
|
-
|
|
179
|
+
### `autostart()` (`tags: autostart, meta.role: autostart`)
|
|
180
|
+
Subscribes once to `grok.events.onContextMenu` and dispatches by `tableColumn.semType`.
|
|
148
181
|
|
|
149
|
-
|
|
182
|
+
For `DG.GridCell` items with a `tableColumn`:
|
|
150
183
|
|
|
151
|
-
|
|
184
|
+
- **`semType === Macromolecule`**:
|
|
185
|
+
- top-level item **`PolyTool-Enumerate`** → calls `${pkg}:getPtHelmEnumeratorDialog`
|
|
186
|
+
- submenu **`Oligo`**:
|
|
187
|
+
- `Convert HELM to Oligo` (only when `col.meta.units === 'helm'`) → `${pkg}:convertHelmToOligoNucleotide`
|
|
188
|
+
- `Combine sense+antisense to Oligo...` → `DG.Func.find(...).prepare({table, senseCol: col}).edit()` for `combineSenseAntisenseToOligoNucleotide`
|
|
189
|
+
- **`semType === Molecule`**:
|
|
190
|
+
- `PolyTool-Enumerate` → `${pkg}:getPtChemEnumeratorDialog`
|
|
191
|
+
- **`semType === 'OligoNucleotide'`**:
|
|
192
|
+
- `PolyTool-Enumerate` → `${pkg}:getPtOligoEnumeratorDialog`
|
|
152
193
|
|
|
153
|
-
|
|
194
|
+
Errors are stashed on `window.$sequenceTranslator.contextMenuError` for postmortem.
|
|
154
195
|
|
|
155
|
-
|
|
196
|
+
### `refineNotationProviderForHarmonizedSequence` (`meta.role: notationRefiner, tags: notationRefiner`)
|
|
197
|
+
Auto-detects cyclized (`^.+\(\d+\)$`) and dimerized (`^\(#\d\).+$`) sequences from `stats.freq` and applies the cyclized notation provider via `${pkg}:applyNotationProviderForCyclized`.
|
|
156
198
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
**`components/colored-input/`** — `ColoredTextInput` — Textarea with syntax highlighting overlay
|
|
160
|
-
- `input-painters.ts` — `highlightInvalidSubsequence()` painter (red for invalid portions)
|
|
161
|
-
|
|
162
|
-
**`components/molecule-img.ts`** — `MoleculeImage` — Canvas-based V3000 molfile renderer
|
|
163
|
-
|
|
164
|
-
**`components/draw-molecule.ts`** — Molecule drawing utilities
|
|
165
|
-
|
|
166
|
-
**`components/router.ts`** — URL routing for combined app tabs
|
|
167
|
-
|
|
168
|
-
**`components/app-info-dialog.ts`** — App metadata dialog
|
|
199
|
+
A commented-out `detectHarmonizedSequence` is a placeholder; not active.
|
|
169
200
|
|
|
170
201
|
---
|
|
171
202
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
**Model:**
|
|
175
|
-
- `format-converter.ts` — `FormatConverter` class — Converts between formats using HELM as pivot
|
|
176
|
-
- `convertTo(targetFormat)` → helmToFormat / formatToHelm / format→HELM→format
|
|
177
|
-
- `conversion-utils.ts` — `getTranslatedSequences()` — Translates to ALL supported formats at once
|
|
178
|
-
- `getNucleotidesSequence()` — Extracts nucleotides from HELM
|
|
179
|
-
- `convert()` — Legacy single-conversion wrapper
|
|
180
|
-
- `const.ts` — `GROUP_TYPE` (NUCLEOSIDE/LINKAGE), `PHOSPHATE_SYMBOL` ('p'), `UNKNOWN_SYMBOL` ('<?>')
|
|
181
|
-
|
|
182
|
-
**View:**
|
|
183
|
-
- `ui.ts` — `OligoTranslatorUI` + `TranslatorAppLayout`
|
|
184
|
-
- **Single mode:** Text input → format detection → all-format output table with copy buttons
|
|
185
|
-
- **Bulk mode:** Table/column selection → batch conversion → new column added
|
|
186
|
-
- `EventBus` (local) — RxJS BehaviorSubjects for table/column/format state
|
|
187
|
-
- Debounced input (300ms), real-time validation via `ColoredTextInput`
|
|
188
|
-
- SDF export and SMILES conversion support
|
|
203
|
+
## Module Details
|
|
189
204
|
|
|
190
|
-
|
|
205
|
+
### `src/oligo-renderer/` — OligoNucleotide subsystem
|
|
191
206
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
**Model:**
|
|
195
|
-
- `event-bus.ts` — `EventBus` — Central RxJS state manager for entire pattern app
|
|
196
|
-
- BehaviorSubjects: pattern name, nucleotide sequences, PTO flags, terminal modifications, table selection, etc.
|
|
197
|
-
- Computed observables: `patternStateChanged$`, `strandsUpdated$`, `uniqueNucleotidesChanged$()`
|
|
198
|
-
- Change tracking (last-loaded config vs current)
|
|
199
|
-
- `data-manager.ts` — `DataManager` (singleton) — Pattern CRUD via Datagrok user storage
|
|
200
|
-
- SHA1 hashing for pattern identity
|
|
201
|
-
- Current user vs other users pattern management
|
|
202
|
-
- Pattern uniqueness validation
|
|
203
|
-
- `translator.ts` — `bulkTranslate()` — Applies pattern to table columns
|
|
204
|
-
- `applyPatternToRawSequence()` — Single-sequence pattern application
|
|
205
|
-
- `router.ts` — `URLRouter` — URL ↔ EventBus synchronization (shareable pattern links)
|
|
206
|
-
- `subscription-manager.ts` — `SubscriptionManager` — RxJS subscription cleanup
|
|
207
|
-
- `types.ts` — `PatternConfiguration`, `PatternConfigRecord`, error classes
|
|
208
|
-
- `const.ts` — Strands (SENSE/ANTISENSE), termini (5'/3'), `MAX_SEQUENCE_LENGTH = 34`, storage name
|
|
209
|
-
- `utils.ts` — Nucleotide analysis, strand truncation/extension helpers
|
|
210
|
-
|
|
211
|
-
**View:**
|
|
212
|
-
- `ui.ts` — `OligoPatternUI` — Main orchestrator (DI wiring, layout composition)
|
|
213
|
-
- Left section: Load/Edit controls, table selection for bulk conversion
|
|
214
|
-
- Right section: SVG visualization, save/download/share buttons
|
|
215
|
-
- `components/left-section.ts` — Load controls, edit controls, bulk convert controls
|
|
216
|
-
- `components/edit-block-controls.ts` — Strand length, nucleobase choice, name/comment editing
|
|
217
|
-
- `components/load-block-controls.ts` — Author/pattern dropdowns, delete button
|
|
218
|
-
- `components/strand-editor/dialog.ts` — Per-position nucleotide + PTO editing
|
|
219
|
-
- `components/terminal-modification-editor.ts` — 5'/3' terminal modification editing
|
|
220
|
-
- `components/bulk-convert/` — Table + column selection for batch pattern application
|
|
221
|
-
- `components/numeric-label-visibility-controls.ts` — Toggle numeric labels per nucleotide
|
|
222
|
-
- `components/translation-examples-block.ts` — Live input→output examples
|
|
223
|
-
|
|
224
|
-
**SVG Rendering (`view/svg-utils/`):**
|
|
225
|
-
- `svg-renderer.ts` — `NucleotidePatternSVGRenderer` — Orchestrates SVG generation
|
|
226
|
-
- Composes: `TitleBlock` + `StrandsBlock` + `LegendBlock`
|
|
227
|
-
- `strands-block.ts` — Nucleotide circles, PTO stars, terminal mods, strand labels
|
|
228
|
-
- `title-block.ts` — Pattern name + strand lengths
|
|
229
|
-
- `legend-block.ts` — Color-coded legend with PTO indicator
|
|
230
|
-
- `svg-element-factory.ts` — SVG element creation (circles, text, stars, rectangles)
|
|
231
|
-
- `svg-display-manager.ts` — Debounced (100ms) SVG updates + PNG export
|
|
232
|
-
- `text-dimensions-calculator.ts` — Canvas-based text measurement
|
|
233
|
-
- `const.ts` — Radii, fonts, colors, Y-positions, dimension constants
|
|
207
|
+
A self-contained renderer + panels + converters for siRNA/ASO duplex HELM cells. Cell value is HELM under the hood; the `OligoNucleotide` semType + `quality=OligoNucleotide` tag selects the duplex renderer.
|
|
234
208
|
|
|
235
|
-
|
|
209
|
+
| File | Purpose |
|
|
210
|
+
|---|---|
|
|
211
|
+
| `types.ts` | `OLIGO_SEM_TYPE` / `OLIGO_UNITS` constants, `ParsedNucleotide` / `ParsedConjugate` / `ParsedStrand` / `ParsedDuplex` interfaces, modification dictionary (`SUGAR_MODS`, `PHOSPHATE_MODS`, `CONJUGATE_MODS`), HELMCore-canonical alias maps (`SUGAR_ALIASES`, `PHOSPHATE_ALIASES`), color resolvers, hash-color fallback for unknowns |
|
|
212
|
+
| `helm-parser.ts` | `parseHelmDuplex(helm)` returns `{sense, antisense, raw}`. Parses `RNA1{...}\|RNA2{...}$$$$` shape with bracketed/unbracketed monomers and standalone-conjugate units. Also `canonicalizeHelm()` / `canonicalizeChainBody()` for rewriting aliased symbols (`mR`, `fR`, `LR`, `sP`, …) to HELMCore canonical (`m`, `fl2r`, `lna`, `sp`) before sending HELM to Bio's library-driven pipelines. Custom (not bio's `HelmHelper.parse`) for hot-path performance |
|
|
213
|
+
| `canvas-renderer.ts` | Pure functions: `computeLayout(cellW, cellH, model, opts)`, `drawDuplex()`, `hitTest()`. Variable chip widths (conjugates take their own width), antisense reversal for pair-alignment, leading-conjugate shift on each strand, sugar-mod stripe at chip bottom, PS bar in inter-chip gap (any non-canonical phosphate gets its own colored bar with deterministic color) |
|
|
214
|
+
| `cell-renderer.ts` | `OligoNucleotideCellRenderer extends DG.GridCellRenderer`. Per-value parse cache, per-cell layout cache keyed by `colName@col.version::rowIdx` (column-version invalidates on edits), `onMouseMove` resolves hover via `hitTest` → tooltip |
|
|
215
|
+
| `tooltip.ts` | `showMonomerTooltip(hit, x, y)`. Builds details synchronously, async-loads sugar / base / 3'-linkage RDKit structures from the **central Bio monomer library** (`getMonomerLibHelper().getMonomerLib()`), with alias resolution and structure caching (`Map<kind:canonicalSymbol, HTMLElement>`, reused across hovers) |
|
|
216
|
+
| `legend-panel.ts` | `buildOligoPanel(value)` widget — per-cell sense/antisense lengths, modification counts (collapsed by canonical symbol), conjugates, color legend filtered to mods actually present in the cell |
|
|
217
|
+
| `structures-panel.ts` | `buildOligoStructuresPanel(value)` widget — splits duplex HELM into two single-strand HELMs, runs `canonicalizeHelm` on each, places into a temp Macromolecule DataFrame, wraps each row's cell as `DG.SemanticValue.fromTableCell(cell)` and forwards to `Bio:toAtomicLevelPanel` inside lazy `ui.accordion()` panes ("Sense" / "Antisense") |
|
|
218
|
+
| `converters.ts` | `tagAsOligoNucleotide(col)`, `convertHelmColumnToOligo(table, helmCol)` (creates a tagged clone), `combineSenseAntisenseToOligo(table, senseCol, antiCol)` (renumbers each chain to RNA1{…}, joins with `\|`) |
|
|
236
219
|
|
|
237
|
-
### apps/
|
|
238
|
-
|
|
239
|
-
**Model:**
|
|
240
|
-
- `sequence-to-molfile.ts` — `SequenceToMolfileConverter` — Parses sequence → retrieves monomer molfiles → links → V3000 molfile
|
|
241
|
-
- `monomer-code-parser.ts` — `MonomerSequenceParser` — Greedy longest-match parsing, auto-inserts phosphate linkers
|
|
242
|
-
- `mol-transformations.ts` — V3000 molfile manipulation:
|
|
243
|
-
- `linkStrandsV3000()` — Links sense/antisense strands with coordinate transformation
|
|
244
|
-
- `getNucleotidesMol()` — Combines nucleotide molblocks with linkage
|
|
245
|
-
- Rotation, reflection, inversion functions for strand alignment
|
|
246
|
-
- Atom/bond renumbering, stereo configuration handling
|
|
247
|
-
- `oligo-structure.ts` — High-level API:
|
|
248
|
-
- `getMolfileForStrand()` — Single strand molfile
|
|
249
|
-
- `getLinkedMolfile()` — Multi-strand assembly
|
|
250
|
-
- `saveSdf()` — SDF file download with metadata
|
|
251
|
-
|
|
252
|
-
**View:**
|
|
253
|
-
- `ui.ts` — `OligoStructureUI` + `StructureAppLayout`
|
|
254
|
-
- Three strand inputs (sense, antisense, antisense2) with direction choice (5'→3' / 3'→5')
|
|
255
|
-
- Chirality toggle, SDF save, real-time molecule visualization
|
|
256
|
-
- Canvas rendering (650x150) with 300ms debounce
|
|
220
|
+
### `apps/common/model/` — Core Domain Model
|
|
257
221
|
|
|
258
|
-
|
|
222
|
+
**`oligo-toolkit-package.ts`** — `OligoToolkitPackage` (extends `DG.Package`, implements `ITranslationHelper`)
|
|
223
|
+
- Central facade managing initialization, monomer libraries, JSON data
|
|
224
|
+
- Factory for `SequenceValidator`, `FormatConverter`, `FormatDetector`
|
|
225
|
+
- Lazy init with promise caching
|
|
259
226
|
|
|
260
|
-
|
|
227
|
+
**`data-loader/json-loader.ts`** — `JsonData` class — Loads (in parallel from `MonomersPath`):
|
|
228
|
+
- `monomer-lib.json`, `formats-to-helm.json`, `codes-to-symbols.json`, `pattern-app-data.json`, `linkers.json`
|
|
261
229
|
|
|
262
|
-
|
|
230
|
+
**`monomer-lib/lib-wrapper.ts`** — `MonomerLibWrapper` — Adapter between `IMonomerLib` (from bio library) and the application; lookups by symbol/format/code; molecular-weight aggregation.
|
|
263
231
|
|
|
264
|
-
|
|
232
|
+
**`parsing-validation/format-detector.ts`** — `FormatDetector` — infers format from content (HELM prefix first, then code-scan).
|
|
265
233
|
|
|
266
|
-
**`
|
|
267
|
-
- `fromSeparator(notation)` — Parse separator notation (e.g., "A-B-{C}-D")
|
|
268
|
-
- `fromHelm(helm)` — Parse HELM notation
|
|
269
|
-
- `getNotation()` — Output harmonized notation
|
|
270
|
-
- `getHelm()` — Output HELM string
|
|
271
|
-
- `applyRules(rules)` — Apply link/reaction rules, create position mappings
|
|
234
|
+
**`parsing-validation/format-handler.ts`** — `FormatHandler` — bidirectional format ↔ HELM mapping with regex/negative-lookaround.
|
|
272
235
|
|
|
273
|
-
**`
|
|
274
|
-
- Parses separator notation → applies rules → outputs HELM
|
|
275
|
-
- Returns `[helms[], isLinear[], positionMaps[]]`
|
|
236
|
+
**`parsing-validation/sequence-validator.ts`** — `SequenceValidator` — greedy longest-match validation.
|
|
276
237
|
|
|
277
|
-
**`
|
|
278
|
-
|
|
279
|
-
- `parseHelm()` — Extracts peptide definitions and linkages
|
|
280
|
-
- `fromObjectsToHelm()` — Serializes monomers + linkages → HELM
|
|
281
|
-
- `handleDuplicated()` — Homo/hetero dimer expansion
|
|
282
|
-
- `handleLinkRules()` / `handleReactionRules()` — Rule application
|
|
238
|
+
**`helpers.ts`** — `sortByReverseLength()`, `download()`, `tryCatch()`.
|
|
239
|
+
**`const.ts`** — `NUCLEOTIDES`, `TECHNOLOGIES`, `DEFAULT_FORMATS` enum.
|
|
283
240
|
|
|
284
|
-
|
|
241
|
+
### `apps/common/view/` — Shared UI
|
|
285
242
|
|
|
286
|
-
|
|
243
|
+
`AppUIBase`, `CombinedAppUI`, `IsolatedAppUIBase`, `MonomerLibViewer`, `ColoredTextInput` (textarea with syntax highlighting via `input-painters.ts`), `MoleculeImage` (canvas V3000 renderer), `draw-molecule.ts`, URL `router.ts`, `app-info-dialog.ts`.
|
|
287
244
|
|
|
288
|
-
|
|
245
|
+
### `apps/translator/` — Format Conversion App
|
|
289
246
|
|
|
290
|
-
|
|
291
|
-
- `RuleLink` type — Linkage rules (monomer pairs, R-groups)
|
|
292
|
-
- `RuleReaction` type — Synthesis rules (monomer pairs, SMARTS reactions)
|
|
247
|
+
**Model:** `format-converter.ts` (`FormatConverter` — HELM-pivot conversion), `conversion-utils.ts` (`getTranslatedSequences`, `getNucleotidesSequence`), `const.ts`.
|
|
293
248
|
|
|
294
|
-
|
|
249
|
+
**View:** `ui.ts` (`OligoTranslatorUI`, `TranslatorAppLayout`) — single + bulk modes, debounced input, EventBus state, SDF/SMILES export.
|
|
295
250
|
|
|
296
|
-
|
|
251
|
+
### `apps/pattern/` — Pattern Design App
|
|
297
252
|
|
|
298
|
-
|
|
253
|
+
**Model:** `event-bus.ts` (RxJS BehaviorSubjects), `data-manager.ts` (singleton CRUD via user storage, SHA1 identity), `translator.ts` (`bulkTranslate`, `applyPatternToRawSequence`), `router.ts` (URL ↔ EventBus), `subscription-manager.ts`, `types.ts`, `const.ts` (strands, termini, `MAX_SEQUENCE_LENGTH = 34`), `utils.ts`.
|
|
299
254
|
|
|
300
|
-
|
|
255
|
+
**View:** `ui.ts` (`OligoPatternUI`), `components/` (left-section, right-section, edit-block, load-block, strand-editor dialog, terminal-modification editor, bulk-convert, numeric-label visibility, translation-examples).
|
|
301
256
|
|
|
302
|
-
|
|
257
|
+
**SVG Rendering** (`view/svg-utils/`): `svg-block-base.ts` (`SVGBlockBase` — base class for composable SVG blocks, see Design Pattern #7), `svg-renderer.ts` (`NucleotidePatternSVGRenderer`), `strands-block.ts`, `title-block.ts`, `legend-block.ts`, `svg-element-factory.ts`, `svg-display-manager.ts` (debounced 100ms + PNG export), `text-dimensions-calculator.ts`, `utils.ts`, `const.ts`.
|
|
303
258
|
|
|
304
|
-
|
|
305
|
-
- `getPolyToolConvertDialog()` — Column selector, flags, rule file, history
|
|
306
|
-
- `polyToolConvert()` — Execution: validates → applies rules → generates HELM → converts to molfiles
|
|
259
|
+
### `apps/structure/` — Molecular Structure App
|
|
307
260
|
|
|
308
|
-
|
|
309
|
-
- `getPolyToolEnumerateDialog()` — HELM editor, placeholder grids, enumeration type selector
|
|
310
|
-
- `polyToolEnumerateSeq()` — Execution with single/parallel/matrix/breadth strategies
|
|
261
|
+
**Model:** `sequence-to-molfile.ts` (`SequenceToMolfileConverter`), `monomer-code-parser.ts` (greedy longest-match, auto-inserts phosphate linkers), `mol-transformations.ts` (`linkStrandsV3000`, `getNucleotidesMol`, rotation/reflection helpers), `oligo-structure.ts` (`getMolfileForStrand`, `getLinkedMolfile`, `saveSdf`).
|
|
311
262
|
|
|
312
|
-
|
|
313
|
-
- Single, Parallel, Matrix, Breadth strategies
|
|
263
|
+
**View:** `ui.ts` (`OligoStructureUI`, `StructureAppLayout`) — three strand inputs, chirality toggle, SDF save, 650×150 canvas with 300ms debounce.
|
|
314
264
|
|
|
315
|
-
|
|
265
|
+
### `polytool/` — Advanced Polymer Conversion Subsystem
|
|
316
266
|
|
|
317
|
-
|
|
267
|
+
#### Top-level
|
|
318
268
|
|
|
319
|
-
|
|
269
|
+
`const.ts`, `types.ts` (`PolyToolEnumeratorParams`, `PolyToolEnumeratorTypes`), `utils.ts` (`_setPeptideColumn`, helpers).
|
|
320
270
|
|
|
321
|
-
|
|
271
|
+
#### Core Conversion (`conversion/`)
|
|
322
272
|
|
|
323
|
-
|
|
273
|
+
`pt-chain.ts` (`Chain`), `pt-conversion.ts` (`doPolyToolConvert`), `pt-tools-parse.ts` (`parseSeparator`, `parseHelm`, `fromObjectsToHelm`, `handleDuplicated`, `handleLinkRules`, `handleReactionRules`), `pt-tools-helmmol.ts` (`getHelmMol`, `helmMolToNotation`), `pt-atomic.ts` (`helmToMol`), `pt-synthetic.ts` (`getOverriddenLibrary`, RDKit reactions), `pt-rules.ts` (`Rules`, `RuleInputs`, `RuleLink`, `RuleReaction`), `pt-rule-cards.ts`, `rule-manager.ts`, `rule-reaction-editor.ts`, `pt-misc.ts` (`Linkage`, index helpers), `style.css`.
|
|
324
274
|
|
|
325
|
-
|
|
275
|
+
#### Dialogs
|
|
326
276
|
|
|
327
|
-
|
|
277
|
+
| File | Purpose |
|
|
278
|
+
|---|---|
|
|
279
|
+
| `pt-dialog.ts` | Main convert dialog; `polyToolConvertUI()`, `polyToolConvert()` |
|
|
280
|
+
| `pt-enumerate-seq-dialog.ts` | HELM enumeration dialog; `polyToolEnumerateHelmUI(cell?, outputAsOligo=false)`, `getPolyToolEnumerateDialog`, `polyToolEnumerateSeq`. The `outputAsOligo` flag tags the result column as OligoNucleotide so the duplex renderer picks it up |
|
|
281
|
+
| `pt-chem-enum.ts` | Chem enumeration core (formerly `pt-enumeration-chem.ts` in older docs). Pure logic — RDKit module only, no Datagrok/UI deps. Normalizes 5 R-label spellings (`[N*]`, `[*:N]`, `[*N]`, `[RN]`, `[R:N]`) to `[*:N]`. `Zip` and `Cartesian` modes; `CHEM_ENUM_MAX_RESULTS = 1_000_000` cap. **Two-path SMILES assembly** (`buildJoinedSmiles`): atom-substitution R-groups (no `[*:N]` in their SMILES — single-atom mode) are spliced into the core via plain string replace; labeled R-groups are then joined via shared ring-closure digits across a disconnected SMILES. **`isSingleAtom`** on `ChemEnumRGroup` is set when `makeRGroup` finds 0 R-labels and `trySingleAtomCanonical` (RDKit `get_num_atoms(true) === 1` + `remove_hs_in_place()`) returns a canonical atom token. Pipeline is two-stage: `enumerateRaw` returns parseable-but-uncanonical SMILES with **zero RDKit calls**; `executeEnumeration` then canonicalizes the whole column in one batched `Chem:convertNotation` call, which also fixes aromaticity case after a single-atom splice. `enumerate` / `enumerateSample` are sync-RDKit variants for tests. Helpers: `moveStartRLabelToBranch`, `pickFreeRingDigits`, `formatRingDigit`, `substituteRLabelWithRingDigit`, `substituteRLabelWithAtom` |
|
|
282
|
+
| `pt-chem-enum-dialog.ts` | Chem enumeration dialog UI; `polyToolEnumerateChemUI(cell?)` (dialog; cell preload → first core when it has ≥1 R-label, else `grok.shell.info`) and `polyToolEnumerateChemApp` (`DG.View` entry; both share `buildChemEnumPanel` + `bindActionButton`). Card UI 110×104 with 320×260 hover tooltip, three hover-revealed action icons: edit + duplicate (`var(--blue-3)`) + delete (`var(--red-3)`). **Duplicate** reopens the sketcher pre-loaded with the molecule and pushes a NEW card on OK (original untouched). Cores rendered in a single horizontal `virtualView`; R-groups in one horizontal `virtualView` per R# inside a capped-height vertical scroll. Live preview: up to 12 reservoir-sampled molecules via `enumerateSampleRaw` (uncanonical SMILES, `grok.chem.drawMolecule` parses lazily per visible card). `openCoreSketchDialog` accepts when ≥1 R-label is present; `openRGroupSketchDialog` accepts when **(exactly 1 R-label) OR (single atom + target R# set)**. Import wizard (`openImportWizard`) picks Molecule column from any open table, infers R# from column name via `/r[\s_\-:]*(\d+)/i`, dedup checkbox, single-atom rows labeled `R{n} · atom`. Mode tooltip / status messages explain Zip vs Cartesian and the single-atom shortcut |
|
|
283
|
+
| `pt-enumeration-helm.ts` | `doPolyToolEnumerateHelm` engine — Single / Parallel / Matrix / Breadth strategies |
|
|
284
|
+
| `pt-combine-dialog.ts` | `getPTCombineDialog` — Cartesian combine |
|
|
285
|
+
| `pt-placeholders-input.ts` | Grid input for point placeholders |
|
|
286
|
+
| `pt-placeholders-breadth-input.ts` | Grid input for range placeholders |
|
|
287
|
+
| `pt-unrule.ts` / `pt-unrule-dialog.ts` | HELM → harmonized notation reversal |
|
|
288
|
+
| `pt-convert-editor.ts` | `PolyToolConvertFuncEditor` |
|
|
328
289
|
|
|
329
290
|
#### Handlers
|
|
330
291
|
|
|
331
|
-
|
|
332
|
-
**`csv-to-json-monomer-lib-converter.ts`** — `PolyToolCsvLibHandler` — CSV → JSON conversion
|
|
333
|
-
|
|
334
|
-
---
|
|
292
|
+
`monomer-lib-handler.ts` (`PolyToolMonomerLibHandler`), `csv-to-json-monomer-lib-converter.ts` (`PolyToolCsvLibHandler`).
|
|
335
293
|
|
|
336
|
-
### utils
|
|
294
|
+
### `utils/` — Notation Providers & Error Handling
|
|
337
295
|
|
|
338
|
-
|
|
339
|
-
- Custom separator-based notation for cyclized peptides
|
|
340
|
-
- Converts to HELM via `Chain.fromSeparator()`
|
|
296
|
+
`cyclized.ts` (`CyclizedNotationProvider` implements `INotationProvider`), `dimerized.ts` (extends cyclized), `cell-renderer-cyclized.ts` (`CyclizedCellRendererBack` for the cyclized notation), `err-info.ts` (`defaultErrorHandler`).
|
|
341
297
|
|
|
342
|
-
|
|
298
|
+
### `plugins/` — External Plugin Integration
|
|
343
299
|
|
|
344
|
-
|
|
300
|
+
`mermade.ts` — `getExternalAppViewFactories()` loads MerMade synthesis plugin via `grok.functions.call()`.
|
|
345
301
|
|
|
346
|
-
|
|
302
|
+
### `demo/`
|
|
347
303
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
**`mermade.ts`** — `getExternalAppViewFactories()` — Loads MerMade synthesis plugin dynamically via `grok.functions.call()`
|
|
351
|
-
|
|
352
|
-
### demo/
|
|
353
|
-
|
|
354
|
-
**`demo-st-ui.ts`** — Demo functions for all three apps (translator, pattern, structure)
|
|
304
|
+
`demo-st-ui.ts` — demo functions for translator / pattern / structure.
|
|
355
305
|
|
|
356
306
|
---
|
|
357
307
|
|
|
358
308
|
## Tests
|
|
359
309
|
|
|
360
|
-
Test entry: `package-test.ts` → `tests
|
|
310
|
+
Test entry: `package-test.ts` → imports each test file under `src/tests/`. Test framework: `@datagrok-libraries/test`.
|
|
361
311
|
|
|
362
|
-
|
|
|
363
|
-
|
|
364
|
-
| `formats-to-helm.ts` | Formats to HELM / HELM to Formats | Bidirectional format↔HELM conversion |
|
|
312
|
+
| File | Category | What it tests |
|
|
313
|
+
|---|---|---|
|
|
314
|
+
| `formats-to-helm.ts` | Formats to HELM / HELM to Formats | Bidirectional format ↔ HELM conversion |
|
|
365
315
|
| `formats-support.ts` | Formats support | All expected formats available |
|
|
366
|
-
| `helm-to-nucleotides.ts` | HELM to Nucleotides | HELM → nucleotide string |
|
|
316
|
+
| `helm-to-nucleotides.ts` | HELM to Nucleotides | HELM → bare nucleotide string |
|
|
367
317
|
| `files-tests.ts` | files | CSV file-based integration tests |
|
|
368
318
|
| `polytool-chain-from-notation-tests.ts` | PolyTool: Chain | Chain parsing, HELM conversion, rule application |
|
|
369
319
|
| `polytool-chain-parse-notation-tests.ts` | PolyTool: Chain: parseNotation | Index translation, monomer counts |
|
|
370
320
|
| `polytool-convert-tests.ts` | PolyTool: Convert | End-to-end conversion pipeline |
|
|
371
|
-
| `polytool-detectors-custom-notation-test.ts` | PolyTool: detectors | Semantic
|
|
372
|
-
| `polytool-enumerate-tests.ts` | PolyTool: Enumerate | Single/Parallel/Matrix enumeration |
|
|
321
|
+
| `polytool-detectors-custom-notation-test.ts` | PolyTool: detectors | Semantic-type detection |
|
|
322
|
+
| `polytool-enumerate-tests.ts` | PolyTool: Enumerate | Single / Parallel / Matrix enumeration |
|
|
373
323
|
| `polytool-enumerate-breadth-tests.ts` | PolyTool: Enumerate | Breadth range enumeration |
|
|
324
|
+
| `polytool-enumerate-chem-tests.ts` | PolyTool: Enumerate | Chem enumeration |
|
|
374
325
|
| `polytool-unrule-tests.ts` | PolyTool: Unrule | HELM → harmonized notation |
|
|
375
326
|
| `toAtomicLevel-tests.ts` | toAtomicLevel | Synthetic monomer generation via RDKit |
|
|
376
|
-
| `
|
|
377
|
-
| `
|
|
327
|
+
| `oligo-renderer-tests.ts` | OligoRenderer: parser / dictionary / layout / hit testing / drawing smoke | HELM parse, alias resolution, layout invariants, hit-test correctness, smoke drawing |
|
|
328
|
+
| `const.ts` | — | Test data: `formatsToHelm`, `helmToNucleotides` |
|
|
329
|
+
| `utils/` | — | Test helpers (`detect-macromolecule-utils.ts`, `index.ts`) |
|
|
378
330
|
|
|
379
331
|
---
|
|
380
332
|
|
|
@@ -383,25 +335,45 @@ Test entry: `package-test.ts` → `tests/` directory
|
|
|
383
335
|
```
|
|
384
336
|
files/
|
|
385
337
|
├── monomers-sample/
|
|
386
|
-
│ ├── monomer-lib.json
|
|
387
|
-
│ ├── codes-to-symbols.json
|
|
388
|
-
│ ├── formats-to-helm.json
|
|
389
|
-
│ ├── linkers.json
|
|
390
|
-
│ ├── pattern-app-data.json
|
|
338
|
+
│ ├── monomer-lib.json
|
|
339
|
+
│ ├── codes-to-symbols.json
|
|
340
|
+
│ ├── formats-to-helm.json
|
|
341
|
+
│ ├── linkers.json
|
|
342
|
+
│ ├── pattern-app-data.json
|
|
391
343
|
│ └── README.md
|
|
392
344
|
├── polytool-rules/
|
|
393
|
-
│ └── rules_example.json
|
|
345
|
+
│ └── rules_example.json
|
|
394
346
|
├── samples/
|
|
395
|
-
│ ├── HELM.csv
|
|
396
|
-
│ ├── cyclized.csv
|
|
397
|
-
│ ├── cyclized_MSA.csv
|
|
398
|
-
│
|
|
347
|
+
│ ├── HELM.csv
|
|
348
|
+
│ ├── cyclized.csv
|
|
349
|
+
│ ├── cyclized_MSA.csv
|
|
350
|
+
│ ├── bulk-translation-axolabs.csv
|
|
351
|
+
│ └── sirna-demo.csv # 30+ siRNA / ASO duplexes covering 2'-OMe, 2'-F, GalNAc-L3, Chol, LNA/MOE gapmers, fallback cases — generated by prototypes/gen-sirna-demo.mjs
|
|
399
352
|
└── tests/
|
|
400
|
-
├── axolabs1.csv
|
|
401
|
-
├── polytool-reaction-lib.json
|
|
353
|
+
├── axolabs1.csv
|
|
354
|
+
├── polytool-reaction-lib.json
|
|
355
|
+
├── chem_enum_cores.csv
|
|
356
|
+
├── chem_enum_rgroups.csv
|
|
402
357
|
└── README.md
|
|
403
358
|
```
|
|
404
359
|
|
|
360
|
+
> **Note**: the OligoNucleotide subsystem also relies on `packages/Bio/files/monomer-libraries/oligo-conjugates.json` (GalNAc / L3 / Chol / Bio / Toc / Pal / DBCO from PubChem). That file lives in the **Bio** package because it's a global monomer library merged by `MonomerLibFromFilesProvider` — not an ST-internal asset.
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## `prototypes/` — Off-Tree Dev Tooling
|
|
365
|
+
|
|
366
|
+
Helper scripts and a standalone HTML prototype for the OligoNucleotide subsystem. These are **not bundled** in the published package and do not register Datagrok functions.
|
|
367
|
+
|
|
368
|
+
| File | Purpose |
|
|
369
|
+
|---|---|
|
|
370
|
+
| `gen-sirna-demo.mjs` | Generates `files/samples/sirna-demo.csv` — 30+ siRNA / ASO duplexes, all conjugate placements (5'-only, 3'-only, both ends, AS-only, dual-strand) |
|
|
371
|
+
| `gen-oligo-conjugates.mjs` | Fetches molfiles + canonical SMILES from PubChem, writes `packages/Bio/files/monomer-libraries/oligo-conjugates.json` (CHEM-type entries: GalNAc, L3, Chol, Bio, Toc, Pal, DBCO) |
|
|
372
|
+
| `validate-oligo-conjugates.mjs` | Validates the generated `oligo-conjugates.json` against Bio's HELM monomer JSON schema using the same Ajv2020 + ajv-errors config as `MonomerLibFileValidator` |
|
|
373
|
+
| `sirna-renderer-prototype.html` | Standalone HTML/CSS/JS prototype of the duplex cell renderer — reference visual against which the production canvas renderer was tuned |
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
405
377
|
## Key Design Patterns
|
|
406
378
|
|
|
407
379
|
1. **HELM as Pivot Format** — All format conversions go through HELM as intermediate representation
|
|
@@ -412,6 +384,12 @@ files/
|
|
|
412
384
|
6. **Greedy Longest-Match** — Sequence parsing always tries longest codes first
|
|
413
385
|
7. **SVG Composable Blocks** — `TitleBlock`, `StrandsBlock`, `LegendBlock` extend `SVGBlockBase`
|
|
414
386
|
8. **Dialog Singletons** — Strand/terminal editors prevent multiple instances
|
|
387
|
+
9. **HELMCore-canonical aliases** (oligo-renderer) — input HELM may use vendor / Pistoia / legacy symbols (`mR`, `fR`, `sP`); the renderer resolves through alias maps and serializes canonical (`m`, `fl2r`, `sp`) before forwarding to Bio's library-driven pipelines (so monomer lookups always hit)
|
|
388
|
+
10. **Column-version-keyed cache** — the OligoNucleotide cell renderer's per-cell layout cache is keyed by `${colName}@${col.version}::${rowIdx}`, so column edits orphan old entries automatically
|
|
389
|
+
11. **Two-stage chem-enum pipeline** — `enumerateRaw` does pure-string assembly (ring-closure trick + atom splice for single-atom R-groups), produces parseable but uncanonical SMILES with **zero per-row RDKit calls**; `executeEnumeration` then canonicalizes the whole output column in a single batched `Chem:convertNotation` call (`overwrite: true`, `kekulize: false`). This also handles aromaticity case-fixup after a single-atom splice (e.g. uppercase `N` spliced into an aromatic ring). The bulk path is parallelized across Chem workers; per-row sync RDKit (`enumerate` / `enumerateSample`) is reserved for tests
|
|
390
|
+
12. **Single-atom R-group shortcut** (chem-enum) — drawing a bare atom (`N`, `O`, `Cl`) without any `[*:N]` label is accepted as long as RDKit confirms exactly one heavy atom. Such groups bypass ring-closure joining and are spliced into the core's `[*:N]` slot via plain string replace; mixing single-atom and labeled R-groups in the same enumeration is supported per R-number
|
|
391
|
+
|
|
392
|
+
---
|
|
415
393
|
|
|
416
394
|
## Key Data Flow
|
|
417
395
|
|
|
@@ -424,7 +402,7 @@ User Input (sequence string)
|
|
|
424
402
|
|
|
425
403
|
PolyTool:
|
|
426
404
|
Separator notation → parseSeparator() → Chain
|
|
427
|
-
→ Chain.applyRules() → handleLinkRules/handleReactionRules
|
|
405
|
+
→ Chain.applyRules() → handleLinkRules / handleReactionRules
|
|
428
406
|
→ Chain.getHelm() → HELM string
|
|
429
407
|
→ helmToMol() → V3000 molfile (optional)
|
|
430
408
|
|
|
@@ -432,9 +410,52 @@ Pattern:
|
|
|
432
410
|
Raw sequence + PatternConfig
|
|
433
411
|
→ applyPatternToRawSequence() → modified nucleotides
|
|
434
412
|
→ SVGRenderer.renderPattern() → visual output
|
|
413
|
+
|
|
414
|
+
OligoNucleotide cell rendering:
|
|
415
|
+
HELM cell value
|
|
416
|
+
→ parseHelmDuplex() → ParsedDuplex {sense, antisense}
|
|
417
|
+
→ computeLayout(w, h, model) → ChipPos[] with leading-conjugate shifts
|
|
418
|
+
→ drawDuplex() → canvas
|
|
419
|
+
→ onMouseMove → hitTest → showMonomerTooltip
|
|
420
|
+
→ getBioLib() → findMonomerMolfile (canonical alias)
|
|
421
|
+
→ grok.chem.drawMolecule → cached HTMLElement
|
|
422
|
+
|
|
423
|
+
OligoNucleotide structures panel:
|
|
424
|
+
HELM cell value
|
|
425
|
+
→ split chains by '|', renumber each to RNA1{…}, canonicalizeHelm
|
|
426
|
+
→ temp DataFrame[Macromolecule helm column]
|
|
427
|
+
→ DG.SemanticValue.fromTableCell → Bio:toAtomicLevelPanel widget
|
|
428
|
+
→ ui.accordion(lazy panes) per strand
|
|
435
429
|
```
|
|
436
430
|
|
|
431
|
+
---
|
|
432
|
+
|
|
437
433
|
## Scripts
|
|
438
434
|
|
|
439
|
-
- `scripts/build-monomer-lib.py` — Python
|
|
440
|
-
- `link-bio` —
|
|
435
|
+
- `scripts/build-monomer-lib.py` — Python (RDKit) builds monomer-library JSON from source files
|
|
436
|
+
- `link-bio` — bash script to build and link `@datagrok-libraries/bio` locally
|
|
437
|
+
|
|
438
|
+
---
|
|
439
|
+
|
|
440
|
+
## Quick Lookups
|
|
441
|
+
|
|
442
|
+
| Looking for... | Check first |
|
|
443
|
+
|---|---|
|
|
444
|
+
| Function/panel/cell-renderer registration | `src/package.ts` (`PackageFunctions` class) |
|
|
445
|
+
| Context-menu wiring + `Oligo` submenu | `detectors.js` (`autostartContextMenu`) |
|
|
446
|
+
| OligoNucleotide cell renderer | `src/oligo-renderer/cell-renderer.ts` |
|
|
447
|
+
| OligoNucleotide layout / drawing | `src/oligo-renderer/canvas-renderer.ts` |
|
|
448
|
+
| HELM canonicalization (alias → HELMCore) | `src/oligo-renderer/helm-parser.ts` (`canonicalizeHelm`) |
|
|
449
|
+
| Modification colors / aliases | `src/oligo-renderer/types.ts` |
|
|
450
|
+
| Sense/antisense structure panel | `src/oligo-renderer/structures-panel.ts` |
|
|
451
|
+
| Convert HELM → Oligo / combine sense+AS | `src/oligo-renderer/converters.ts` |
|
|
452
|
+
| Translator app | `src/apps/translator/` |
|
|
453
|
+
| Pattern designer app | `src/apps/pattern/` |
|
|
454
|
+
| Structure app | `src/apps/structure/` |
|
|
455
|
+
| PolyTool convert pipeline | `src/polytool/conversion/`, `pt-dialog.ts` |
|
|
456
|
+
| HELM enumeration (with `outputAsOligo`) | `src/polytool/pt-enumerate-seq-dialog.ts` |
|
|
457
|
+
| Chem enumeration (logic) | `src/polytool/pt-chem-enum.ts` (`buildJoinedSmiles` two-path assembly, `trySingleAtomCanonical`, `substituteRLabelWithAtom`) |
|
|
458
|
+
| Chem enumeration (UI) | `src/polytool/pt-chem-enum-dialog.ts` (`buildChemEnumPanel`, sketch dialogs, `openImportWizard`, duplicate/edit/delete card icons) |
|
|
459
|
+
| Demo / sample siRNA data | `files/samples/sirna-demo.csv` |
|
|
460
|
+
| Off-tree dev tooling | `prototypes/` (gen / validate / HTML prototype) |
|
|
461
|
+
| Auto-generated wrappers | `src/package.g.ts`, `src/package-api.ts` |
|