@datagrok/sequence-translator 1.3.5 → 1.3.10
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 +37 -0
- package/detectors.js +32 -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 +10 -6
- package/src/apps/common/view/components/colored-input/style.css +3 -2
- package/src/apps/pattern/model/const.ts +8 -5
- package/src/apps/pattern/model/data-manager.ts +44 -16
- package/src/apps/pattern/model/event-bus.ts +2 -0
- package/src/apps/pattern/model/translator.ts +45 -8
- package/src/apps/pattern/model/types.ts +8 -6
- package/src/apps/pattern/view/components/bulk-convert/column-input.ts +4 -10
- package/src/apps/pattern/view/components/bulk-convert/table-input.ts +5 -8
- package/src/apps/pattern/view/components/edit-block-controls.ts +6 -15
- package/src/apps/pattern/view/components/load-block-controls.ts +11 -10
- package/src/apps/pattern/view/components/numeric-label-visibility-controls.ts +4 -5
- package/src/apps/pattern/view/components/right-section.ts +50 -1
- package/src/apps/pattern/view/components/strand-editor/header-controls.ts +2 -2
- package/src/apps/pattern/view/components/strand-editor/strand-controls.ts +2 -2
- package/src/apps/pattern/view/components/terminal-modification-editor.ts +1 -1
- package/src/apps/pattern/view/components/translation-examples-block.ts +1 -1
- package/src/apps/pattern/view/ui.ts +1 -1
- package/src/apps/structure/view/ui.ts +5 -5
- package/src/apps/translator/view/ui.ts +15 -27
- package/src/package.ts +52 -11
- package/src/plugins/mermade.ts +1 -1
- package/src/polytool/pt-conversion.ts +2 -2
- package/src/polytool/pt-dialog.ts +99 -18
- package/src/polytool/pt-enumeration-chem.ts +105 -0
- package/src/polytool/pt-enumeration-helm.ts +22 -0
- package/src/polytool/pt-ui.ts +25 -0
- package/src/polytool/utils.ts +34 -3
- package/src/utils/context-menu.ts +57 -0
- package/src/utils/err-info.ts +13 -0
- package/webpack.config.js +2 -4
- package/src/polytool/pt-enumeration.ts +0 -141
|
@@ -47,13 +47,12 @@ class TranslatorAppLayout {
|
|
|
47
47
|
this.moleculeImgDiv.style.marginTop = '12px';
|
|
48
48
|
|
|
49
49
|
this.outputTableDiv = ui.div([]);
|
|
50
|
-
this.formatChoiceInput = ui.
|
|
50
|
+
this.formatChoiceInput = ui.input.choice('', {value: DEFAULT_FORMATS.HELM, items: this.inputFormats, onValueChanged: async () => {
|
|
51
51
|
this.format = this.formatChoiceInput.value;
|
|
52
52
|
this.updateTable();
|
|
53
53
|
await this.updateMolImg();
|
|
54
|
-
});
|
|
55
|
-
this.sequenceInputBase = ui.
|
|
56
|
-
() => { this.onInput.next(); });
|
|
54
|
+
}});
|
|
55
|
+
this.sequenceInputBase = ui.input.textArea('', {value: DEFAULT_AXOLABS_INPUT, onValueChanged: () => { this.onInput.next(); }});
|
|
57
56
|
|
|
58
57
|
this.init();
|
|
59
58
|
|
|
@@ -100,18 +99,12 @@ class TranslatorAppLayout {
|
|
|
100
99
|
|
|
101
100
|
const tableControlsManager = new TableControlsManager(this.eventBus);
|
|
102
101
|
const tableControls = tableControlsManager.createUIComponents();
|
|
103
|
-
const inputFormats = ui.
|
|
104
|
-
|
|
105
|
-
DEFAULT_FORMATS.AXOLABS,
|
|
106
|
-
this.inputFormats,
|
|
107
|
-
(value: string) => this.eventBus.selectInputFormat(value)
|
|
102
|
+
const inputFormats = ui.input.choice('Input format', {value: DEFAULT_FORMATS.AXOLABS,
|
|
103
|
+
items: this.inputFormats, onValueChanged: (input) => this.eventBus.selectInputFormat(input.value)}
|
|
108
104
|
);
|
|
109
105
|
|
|
110
|
-
const outputFormats = ui.
|
|
111
|
-
|
|
112
|
-
NUCLEOTIDES_FORMAT,
|
|
113
|
-
getSupportedTargetFormats(this.th),
|
|
114
|
-
(value: string) => this.eventBus.selectOutputFormat(value)
|
|
106
|
+
const outputFormats = ui.input.choice('Output format', {value: NUCLEOTIDES_FORMAT,
|
|
107
|
+
items: getSupportedTargetFormats(this.th), onValueChanged: (input) => this.eventBus.selectOutputFormat(input.value)}
|
|
115
108
|
);
|
|
116
109
|
const convertBulkButton = this.createConvertBulkButton();
|
|
117
110
|
|
|
@@ -169,7 +162,7 @@ class TranslatorAppLayout {
|
|
|
169
162
|
if (outputFormat === NUCLEOTIDES_FORMAT || outputFormat === DEFAULT_FORMATS.HELM) {
|
|
170
163
|
translatedColumn.semType = DG.SEMTYPE.MACROMOLECULE;
|
|
171
164
|
const units = outputFormat == NUCLEOTIDES_FORMAT ? NOTATION.FASTA : NOTATION.HELM;
|
|
172
|
-
translatedColumn.
|
|
165
|
+
translatedColumn.meta.units = units;
|
|
173
166
|
const seqHandler = SeqHandler.forColumn(translatedColumn as DG.Column<string>);
|
|
174
167
|
const setUnits = outputFormat == NUCLEOTIDES_FORMAT ? SeqHandler.setUnitsToFastaColumn :
|
|
175
168
|
SeqHandler.setUnitsToHelmColumn;
|
|
@@ -381,16 +374,13 @@ class TableInputManager {
|
|
|
381
374
|
private createTableInput(): DG.InputBase<DG.DataFrame | null> {
|
|
382
375
|
const currentlySelectedTable = this.eventBus.getSelectedTable();
|
|
383
376
|
|
|
384
|
-
const tableInput = ui.
|
|
385
|
-
|
|
386
|
-
currentlySelectedTable,
|
|
387
|
-
this.availableTables,
|
|
388
|
-
(table: DG.DataFrame) => {
|
|
377
|
+
const tableInput = ui.input.table('Table', {value: currentlySelectedTable!, items: this.availableTables,
|
|
378
|
+
onValueChanged: (input) => {
|
|
389
379
|
// WARNING: non-null check necessary to prevent resetting columns to
|
|
390
380
|
// null upon handling onTableAdded
|
|
391
|
-
if (
|
|
392
|
-
this.eventBus.selectTable(
|
|
393
|
-
});
|
|
381
|
+
if (input.value !== null)
|
|
382
|
+
this.eventBus.selectTable(input.value);
|
|
383
|
+
}});
|
|
394
384
|
return tableInput;
|
|
395
385
|
}
|
|
396
386
|
|
|
@@ -459,10 +449,8 @@ class ColumnInputsManager {
|
|
|
459
449
|
const selectedColumnName = matchingColumnName ? matchingColumnName : columnNames[0];
|
|
460
450
|
this.selectColumnIfTableNotNull(selectedTable, selectedColumnName, columnLabel);
|
|
461
451
|
|
|
462
|
-
const input = ui.
|
|
463
|
-
|
|
464
|
-
selectedColumnName, columnNames,
|
|
465
|
-
(colName: string) => this.selectColumnIfTableNotNull(selectedTable, colName, columnLabel)
|
|
452
|
+
const input = ui.input.choice(`${columnLabel}`, {value: selectedColumnName, items: columnNames,
|
|
453
|
+
onValueChanged: (input) => this.selectColumnIfTableNotNull(selectedTable, input.value, columnLabel)}
|
|
466
454
|
);
|
|
467
455
|
|
|
468
456
|
return input;
|
package/src/package.ts
CHANGED
|
@@ -16,10 +16,12 @@ import {demoOligoPatternUI, demoOligoStructureUI, demoOligoTranslatorUI} from '.
|
|
|
16
16
|
import {getExternalAppViewFactories} from './plugins/mermade';
|
|
17
17
|
|
|
18
18
|
//polytool specific
|
|
19
|
-
import {getPolyToolConversionDialog
|
|
19
|
+
import {getPolyToolConversionDialog} from './polytool/pt-dialog';
|
|
20
20
|
import {_setPeptideColumn} from './polytool/utils';
|
|
21
21
|
import {PolyToolCsvLibHandler} from './polytool/csv-to-json-monomer-lib-converter';
|
|
22
22
|
import {ITranslationHelper} from './types';
|
|
23
|
+
import {polyToolEnumerateHelmUI, polyToolEnumerateChemUI} from './polytool/pt-ui';
|
|
24
|
+
import {addContextMenuUI} from './utils/context-menu';
|
|
23
25
|
|
|
24
26
|
export const _package: OligoToolkitPackage = new OligoToolkitPackage();
|
|
25
27
|
|
|
@@ -163,19 +165,20 @@ export async function polyToolConvert(): Promise<void> {
|
|
|
163
165
|
}
|
|
164
166
|
}
|
|
165
167
|
|
|
166
|
-
//top-menu: Bio | Convert | PolyTool-Enumerate
|
|
167
|
-
//name:
|
|
168
|
+
//top-menu: Bio | Convert | PolyTool-Enumerate HELM
|
|
169
|
+
//name: polyToolEnumerateHelm
|
|
168
170
|
//description: Perform cyclization of polymers
|
|
169
|
-
export async function
|
|
170
|
-
|
|
171
|
-
try {
|
|
172
|
-
dialog = await getPolyToolEnumerationDialog();
|
|
173
|
-
dialog.show();
|
|
174
|
-
} catch (err: any) {
|
|
175
|
-
grok.shell.warning('To run PolyTool Enumeration, sketch the macromolecule and select monomers to vary');
|
|
176
|
-
}
|
|
171
|
+
export async function polyToolEnumerateHelm(): Promise<void> {
|
|
172
|
+
polyToolEnumerateHelmUI();
|
|
177
173
|
}
|
|
178
174
|
|
|
175
|
+
// //top-menu: Bio | Convert | PolyTool-Enumerate Chem
|
|
176
|
+
// //name: polyToolEnumerateChem
|
|
177
|
+
// //description: Perform cyclization of polymers
|
|
178
|
+
// export async function polyToolEnumerateChem(): Promise<void> {
|
|
179
|
+
// polyToolEnumerateChemUI();
|
|
180
|
+
// }
|
|
181
|
+
|
|
179
182
|
//name: polyToolColumnChoice
|
|
180
183
|
//input: dataframe df [Input data table]
|
|
181
184
|
//input: column macroMolecule
|
|
@@ -194,3 +197,41 @@ export async function createMonomerLibraryForPolyTool(file: DG.FileInfo) {
|
|
|
194
197
|
const jsonFileContent = JSON.stringify(libObject, null, 2);
|
|
195
198
|
DG.Utils.download(jsonFileName, jsonFileContent);
|
|
196
199
|
}
|
|
200
|
+
|
|
201
|
+
// -- Handle context menu --
|
|
202
|
+
|
|
203
|
+
//name: addContextMenu
|
|
204
|
+
//input: object event
|
|
205
|
+
export function addContextMenu(event: DG.EventData): void {
|
|
206
|
+
addContextMenuUI(event);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// //name: PolyTool Converter
|
|
210
|
+
// //meta.icon: img/icons/structure.png
|
|
211
|
+
// //meta.browsePath: PolyTool
|
|
212
|
+
// //tags: app
|
|
213
|
+
// //output: view v
|
|
214
|
+
// export async function ptConverterApp(): Promise<DG.ViewBase> {
|
|
215
|
+
// const view = await getSpecifiedAppView(APP_NAME.STRUCTURE);
|
|
216
|
+
// return view;
|
|
217
|
+
// }
|
|
218
|
+
|
|
219
|
+
// //name: PolyTool Enumerator Helm
|
|
220
|
+
// //meta.icon: img/icons/structure.png
|
|
221
|
+
// //meta.browsePath: PolyTool
|
|
222
|
+
// //tags: app
|
|
223
|
+
// //output: view v
|
|
224
|
+
// export async function ptEnumeratorHelmApp(): Promise<DG.ViewBase> {
|
|
225
|
+
// const view = await getSpecifiedAppView(APP_NAME.STRUCTURE);
|
|
226
|
+
// return view;
|
|
227
|
+
// }
|
|
228
|
+
|
|
229
|
+
// //name: PolyTool Enumerator Chem
|
|
230
|
+
// //meta.icon: img/icons/structure.png
|
|
231
|
+
// //meta.browsePath: PolyTool
|
|
232
|
+
// //tags: app
|
|
233
|
+
// //output: view v
|
|
234
|
+
// export async function ptEnumeratorChemApp(): Promise<DG.ViewBase> {
|
|
235
|
+
// const view = await getSpecifiedAppView(APP_NAME.STRUCTURE);
|
|
236
|
+
// return view;
|
|
237
|
+
// }
|
package/src/plugins/mermade.ts
CHANGED
|
@@ -41,7 +41,7 @@ export async function getExternalAppViewFactories(
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
function getMerMadeParameters(th: ITranslationHelper): { [name: string]: any } {
|
|
44
|
-
const base = ui.
|
|
44
|
+
const base = ui.input.textArea('', {value: ''});
|
|
45
45
|
const input = new ColoredTextInput(base, th.highlightInvalidSubsequence);
|
|
46
46
|
|
|
47
47
|
return {
|
|
@@ -10,7 +10,7 @@ export const RULES_DIMER = '(#2)';
|
|
|
10
10
|
export const RULES_HETERODIMER = '($2)';
|
|
11
11
|
|
|
12
12
|
function addCommonTags(col: DG.Column): void {
|
|
13
|
-
col.
|
|
13
|
+
col.semType = DG.SEMTYPE.MACROMOLECULE;
|
|
14
14
|
col.setTag('aligned', ALIGNMENT.SEQ);
|
|
15
15
|
col.setTag('alphabet', ALPHABET.PT);
|
|
16
16
|
}
|
|
@@ -290,7 +290,7 @@ export async function addTransformedColumn(
|
|
|
290
290
|
const targetHelmCol = DG.Column.fromList('string', helmColName, targetList);
|
|
291
291
|
|
|
292
292
|
addCommonTags(targetHelmCol);
|
|
293
|
-
targetHelmCol.
|
|
293
|
+
targetHelmCol.meta.units = NOTATION.HELM;
|
|
294
294
|
|
|
295
295
|
if (addHelm) {
|
|
296
296
|
targetHelmCol.setTag('cell.renderer', 'helm');
|
|
@@ -3,12 +3,20 @@ import * as grok from 'datagrok-api/grok';
|
|
|
3
3
|
import * as ui from 'datagrok-api/ui';
|
|
4
4
|
import * as DG from 'datagrok-api/dg';
|
|
5
5
|
|
|
6
|
+
import wu from 'wu';
|
|
7
|
+
|
|
8
|
+
import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
|
|
9
|
+
import {getHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
|
|
10
|
+
import {HelmAtom} from '@datagrok-libraries/bio/src/helm/types';
|
|
11
|
+
|
|
6
12
|
import {RuleInputs, RULES_PATH, RULES_STORAGE_NAME} from './pt-rules';
|
|
7
13
|
import {addTransformedColumn} from './pt-conversion';
|
|
8
14
|
|
|
9
15
|
import {handleError} from './utils';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
16
|
+
import {defaultErrorHandler} from '../utils/err-info';
|
|
17
|
+
import {getLibrariesList} from './utils';
|
|
18
|
+
import {getEnumerationHelm, PT_HELM_EXAMPLE} from './pt-enumeration-helm';
|
|
19
|
+
import {getEnumerationChem, PT_CHEM_EXAMPLE} from './pt-enumeration-chem';
|
|
12
20
|
|
|
13
21
|
const PT_ERROR_DATAFRAME = 'No dataframe with macromolecule columns open';
|
|
14
22
|
const PT_WARNING_COLUMN = 'No marcomolecule column chosen!';
|
|
@@ -25,15 +33,15 @@ export async function getPolyToolConversionDialog(): Promise<DG.Dialog> {
|
|
|
25
33
|
if (!targetColumns)
|
|
26
34
|
throw new Error(PT_ERROR_DATAFRAME);
|
|
27
35
|
|
|
28
|
-
const targetColumnInput = ui.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
);
|
|
36
|
+
const targetColumnInput = ui.input.column('Column', {
|
|
37
|
+
table: grok.shell.t, value: targetColumns[0],
|
|
38
|
+
filter: (col: DG.Column) => col.semType === DG.SEMTYPE.MACROMOLECULE
|
|
39
|
+
});
|
|
32
40
|
|
|
33
|
-
const generateHelmChoiceInput = ui.
|
|
41
|
+
const generateHelmChoiceInput = ui.input.bool(PT_UI_GET_HELM, {value: true});
|
|
34
42
|
ui.tooltip.bind(generateHelmChoiceInput.root, PT_UI_ADD_HELM);
|
|
35
43
|
|
|
36
|
-
const chiralityEngineInput = ui.
|
|
44
|
+
const chiralityEngineInput = ui.input.bool(PT_UI_USE_CHIRALITY, {value: false});
|
|
37
45
|
const ruleInputs = new RuleInputs(RULES_PATH, RULES_STORAGE_NAME, '.json');
|
|
38
46
|
const rulesHeader = ui.inlineText([PT_UI_RULES_USED]);
|
|
39
47
|
ui.tooltip.bind(rulesHeader, 'Add or specify rules to use');
|
|
@@ -74,44 +82,117 @@ export async function getPolyToolConversionDialog(): Promise<DG.Dialog> {
|
|
|
74
82
|
return dialog;
|
|
75
83
|
}
|
|
76
84
|
|
|
77
|
-
export async function
|
|
78
|
-
const
|
|
85
|
+
export async function getPolyToolEnumerationHelmDialog(cell?: DG.Cell): Promise<DG.Dialog> {
|
|
86
|
+
const [libList, helmHelper] = await Promise.all([
|
|
87
|
+
getLibrariesList(), getHelmHelper()]);
|
|
88
|
+
|
|
89
|
+
const helmValue = cell ? cell.value : PT_HELM_EXAMPLE;
|
|
79
90
|
|
|
80
|
-
const
|
|
81
|
-
const screenLibrary = ui.
|
|
91
|
+
const helmInput = helmHelper.createHelmInput('Macromolecule', {value: helmValue});
|
|
92
|
+
const screenLibrary = ui.input.choice('Library to use', {value: null, items: libList});
|
|
82
93
|
|
|
94
|
+
helmInput.input.setAttribute('style', `min-width:250px!important;`);
|
|
83
95
|
screenLibrary.input.setAttribute('style', `min-width:250px!important;`);
|
|
84
96
|
|
|
85
97
|
const div = ui.div([
|
|
86
|
-
helmInput.
|
|
98
|
+
helmInput.root,
|
|
87
99
|
screenLibrary.root
|
|
88
100
|
]);
|
|
89
101
|
|
|
102
|
+
// Displays the molecule from a current cell (monitors changes)
|
|
90
103
|
const cccSubs = grok.events.onCurrentCellChanged.subscribe(() => {
|
|
91
104
|
const cell = grok.shell.tv.dataFrame.currentCell;
|
|
92
105
|
|
|
93
|
-
if (cell.column.semType === DG.SEMTYPE.MACROMOLECULE && cell.column.
|
|
94
|
-
helmInput.
|
|
106
|
+
if (cell.column.semType === DG.SEMTYPE.MACROMOLECULE && cell.column.meta.units === NOTATION.HELM)
|
|
107
|
+
helmInput.stringValue = cell.value;
|
|
95
108
|
});
|
|
96
109
|
|
|
97
110
|
const dialog = ui.dialog(PT_UI_DIALOG_ENUMERATION)
|
|
98
111
|
.add(div)
|
|
99
112
|
.onOK(async () => {
|
|
100
113
|
try {
|
|
101
|
-
const helmString = helmInput.
|
|
102
|
-
const helmSelections = helmInput.
|
|
114
|
+
const helmString = helmInput.stringValue;
|
|
115
|
+
const helmSelections: number[] = wu.enumerate<HelmAtom>(helmInput.value.atoms)
|
|
116
|
+
.filter(([a, aI]) => a.highlighted)
|
|
117
|
+
.map(([a, aI]) => aI).toArray();
|
|
103
118
|
if (helmString === undefined || helmString === '') {
|
|
104
119
|
grok.shell.warning('PolyTool: no molecule was provided');
|
|
105
120
|
} else if (helmSelections === undefined || helmSelections.length < 1) {
|
|
106
121
|
grok.shell.warning('PolyTool: no selection was provided');
|
|
107
122
|
} else {
|
|
108
|
-
const molecules = await
|
|
123
|
+
const molecules = await getEnumerationHelm(helmString, helmSelections, screenLibrary.value!);
|
|
109
124
|
const molCol = DG.Column.fromStrings('Enumerated', molecules);
|
|
110
125
|
const df = DG.DataFrame.fromColumns([molCol]);
|
|
111
126
|
grok.shell.addTableView(df);
|
|
112
127
|
}
|
|
113
128
|
} catch (err: any) {
|
|
129
|
+
defaultErrorHandler(err);
|
|
130
|
+
} finally {
|
|
131
|
+
cccSubs.unsubscribe();
|
|
132
|
+
}
|
|
133
|
+
}).onCancel(() => {
|
|
134
|
+
cccSubs.unsubscribe();
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
return dialog;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export async function getPolyToolEnumerationChemDialog(cell?: DG.Cell): Promise<DG.Dialog> {
|
|
141
|
+
const [libList, helmHelper] = await Promise.all([
|
|
142
|
+
getLibrariesList(), getHelmHelper()]);
|
|
143
|
+
|
|
144
|
+
let molValue = PT_CHEM_EXAMPLE;//cell ? cell.value : PT_CHEM_EXAMPLE;
|
|
145
|
+
const molInput = new DG.chem.Sketcher(DG.chem.SKETCHER_MODE.EXTERNAL);
|
|
146
|
+
molInput.syncCurrentObject = false;
|
|
147
|
+
// sketcher.setMolFile(col.tags[ALIGN_BY_SCAFFOLD_TAG]);
|
|
148
|
+
molInput.onChanged.subscribe((_: any) => {
|
|
149
|
+
molValue = molInput.getMolFile();
|
|
150
|
+
// col.tags[ALIGN_BY_SCAFFOLD_TAG] = molFile;
|
|
151
|
+
// col.temp[ALIGN_BY_SCAFFOLD_TAG] = molFile;
|
|
152
|
+
// col.dataFrame?.fireValuesChanged();
|
|
153
|
+
});
|
|
154
|
+
molInput.root.classList.add('ui-input-editor');
|
|
155
|
+
molInput.root.style.marginTop = '3px';
|
|
156
|
+
molInput.setMolFile(molValue);
|
|
157
|
+
|
|
158
|
+
//const helmInput = helmHelper.createHelmInput('Macromolecule', {value: helmValue});
|
|
159
|
+
const screenLibrary = ui.input.choice('Library to use', {value: null, items: libList});
|
|
114
160
|
|
|
161
|
+
molInput.root.setAttribute('style', `min-width:250px!important;`);
|
|
162
|
+
molInput.root.setAttribute('style', `max-width:250px!important;`);
|
|
163
|
+
screenLibrary.input.setAttribute('style', `min-width:250px!important;`);
|
|
164
|
+
|
|
165
|
+
const div = ui.div([
|
|
166
|
+
molInput.root,
|
|
167
|
+
screenLibrary.root
|
|
168
|
+
]);
|
|
169
|
+
|
|
170
|
+
const cccSubs = grok.events.onCurrentCellChanged.subscribe(() => {
|
|
171
|
+
const cell = grok.shell.tv.dataFrame.currentCell;
|
|
172
|
+
|
|
173
|
+
if (cell.column.semType === DG.SEMTYPE.MOLECULE)
|
|
174
|
+
molInput.setValue(cell.value);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
// Displays the molecule from a current cell (monitors changes)
|
|
178
|
+
const dialog = ui.dialog(PT_UI_DIALOG_ENUMERATION)
|
|
179
|
+
.add(div)
|
|
180
|
+
.onOK(async () => {
|
|
181
|
+
try {
|
|
182
|
+
const molString = molInput.getMolFile();
|
|
183
|
+
|
|
184
|
+
if (molString === undefined || molString === '') {
|
|
185
|
+
grok.shell.warning('PolyTool: no molecule was provided');
|
|
186
|
+
} else if (!molString.includes('R#')) {
|
|
187
|
+
grok.shell.warning('PolyTool: no R group was provided');
|
|
188
|
+
} else {
|
|
189
|
+
const molecules = await getEnumerationChem(molString, screenLibrary.value!);
|
|
190
|
+
const molCol = DG.Column.fromStrings('Enumerated', molecules);
|
|
191
|
+
const df = DG.DataFrame.fromColumns([molCol]);
|
|
192
|
+
grok.shell.addTableView(df);
|
|
193
|
+
}
|
|
194
|
+
} catch (err: any) {
|
|
195
|
+
defaultErrorHandler(err);
|
|
115
196
|
} finally {
|
|
116
197
|
cccSubs.unsubscribe();
|
|
117
198
|
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import * as ui from 'datagrok-api/ui';
|
|
2
|
+
import * as grok from 'datagrok-api/grok';
|
|
3
|
+
import * as DG from 'datagrok-api/dg';
|
|
4
|
+
|
|
5
|
+
import {getAvailableMonomers, getAvailableMonomerMols} from './utils';
|
|
6
|
+
import {RDModule, RDMol} from '@datagrok-libraries/chem-meta/src/rdkit-api';
|
|
7
|
+
|
|
8
|
+
export const PT_CHEM_EXAMPLE = `
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
22 24 0 0 0 0 0 0 0 0999 V2000
|
|
12
|
+
0.3128 -0.7509 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
13
|
+
0.3128 0.0740 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
14
|
+
-0.4054 -1.1623 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
15
|
+
-1.1081 -0.7509 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
16
|
+
-0.4054 0.4877 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
|
|
17
|
+
-1.1081 0.0740 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
18
|
+
-1.8175 -1.1623 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
19
|
+
1.0222 0.4877 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
20
|
+
-1.8175 0.4877 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
21
|
+
-2.5292 -0.7509 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
22
|
+
1.0222 1.3127 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
23
|
+
1.7227 1.7263 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
24
|
+
-0.4054 -1.9896 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
|
|
25
|
+
-2.5292 0.0740 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
26
|
+
2.4544 1.3127 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
27
|
+
1.7406 0.0740 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
28
|
+
1.0222 -1.1623 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
|
|
29
|
+
2.4544 0.4877 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
|
|
30
|
+
-1.8175 -1.9896 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
|
|
31
|
+
-3.2453 0.4877 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
|
|
32
|
+
3.1670 1.7285 0.0000 R# 0 0 0 0 0 0 0 0 0 0 0 0
|
|
33
|
+
1.7149 2.5513 0.0000 R# 0 0 0 0 0 0 0 0 0 0 0 0
|
|
34
|
+
2 1 2 0 0 0 0
|
|
35
|
+
3 1 1 0 0 0 0
|
|
36
|
+
4 3 1 0 0 0 0
|
|
37
|
+
5 2 1 0 0 0 0
|
|
38
|
+
6 5 1 0 0 0 0
|
|
39
|
+
7 4 1 0 0 0 0
|
|
40
|
+
8 2 1 0 0 0 0
|
|
41
|
+
9 6 1 0 0 0 0
|
|
42
|
+
10 7 2 0 0 0 0
|
|
43
|
+
11 8 2 0 0 0 0
|
|
44
|
+
12 11 1 0 0 0 0
|
|
45
|
+
13 3 2 0 0 0 0
|
|
46
|
+
14 9 2 0 0 0 0
|
|
47
|
+
15 18 1 0 0 0 0
|
|
48
|
+
16 8 1 0 0 0 0
|
|
49
|
+
17 1 1 0 0 0 0
|
|
50
|
+
18 16 2 0 0 0 0
|
|
51
|
+
19 7 1 0 0 0 0
|
|
52
|
+
20 14 1 0 0 0 0
|
|
53
|
+
6 4 2 0 0 0 0
|
|
54
|
+
15 12 2 0 0 0 0
|
|
55
|
+
14 10 1 0 0 0 0
|
|
56
|
+
15 21 1 0 0 0 0
|
|
57
|
+
12 22 1 0 0 0 0
|
|
58
|
+
M RGP 2 21 1 22 2
|
|
59
|
+
M END`;
|
|
60
|
+
|
|
61
|
+
export async function getEnumerationChem(molString: string, screenLibrary: string):
|
|
62
|
+
Promise<string[]> {
|
|
63
|
+
const variableMonomers = await getAvailableMonomers(screenLibrary);
|
|
64
|
+
const variableMols = await getAvailableMonomerMols(screenLibrary);
|
|
65
|
+
|
|
66
|
+
const idx = molString.indexOf('M RGP');
|
|
67
|
+
const rCount = parseInt(molString.slice(idx + 6, idx + 9)); //extracting from molfile positions
|
|
68
|
+
const size = 1 * variableMonomers.length;
|
|
69
|
+
const enumerations = new Array<string>(size);
|
|
70
|
+
|
|
71
|
+
const rdkitModule: RDModule = await grok.functions.call('Chem:getRdKitModule');
|
|
72
|
+
const molScaffold: RDMol = rdkitModule.get_mol(molString);
|
|
73
|
+
const smiScaffold = molScaffold.get_smiles();
|
|
74
|
+
molScaffold.delete();
|
|
75
|
+
|
|
76
|
+
const smilesSubsts = new Array<string>(variableMonomers.length);
|
|
77
|
+
|
|
78
|
+
for (let i = 0; i < variableMonomers.length; i++) {
|
|
79
|
+
|
|
80
|
+
const name = variableMonomers[i];
|
|
81
|
+
const molBlock = variableMols[name];
|
|
82
|
+
const molSubst: RDMol = rdkitModule.get_mol(molBlock);
|
|
83
|
+
smilesSubsts[i] = molSubst.get_smiles();
|
|
84
|
+
molSubst.delete();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
//TODO: get for all R groups
|
|
88
|
+
for (let i = 0; i < 1; i++) {
|
|
89
|
+
for (let j = 0; j < variableMonomers.length; j++) {
|
|
90
|
+
try {
|
|
91
|
+
const smiResRaw = `${smiScaffold}.${smilesSubsts[j]}`.replaceAll('[1*]C', 'C([1*])').replaceAll('[1*]c', 'c([1*])').replaceAll('[1*]O', 'O([1*])').replaceAll('[1*]N', 'N([1*])');
|
|
92
|
+
const smiRes = `${smiResRaw}`.replaceAll('([1*])', '9').replaceAll('[1*]', '9');
|
|
93
|
+
const molRes: RDMol = rdkitModule.get_mol(smiRes);
|
|
94
|
+
|
|
95
|
+
enumerations[i * variableMonomers.length + j] = molRes.get_v3Kmolblock();
|
|
96
|
+
molRes.delete();
|
|
97
|
+
}
|
|
98
|
+
catch(err:any) {
|
|
99
|
+
enumerations[i * variableMonomers.length + j] = '';
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return enumerations;
|
|
105
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as ui from 'datagrok-api/ui';
|
|
2
|
+
import * as grok from 'datagrok-api/grok';
|
|
3
|
+
import * as DG from 'datagrok-api/dg';
|
|
4
|
+
import {Chain} from './pt-conversion';
|
|
5
|
+
import {getAvailableMonomers} from './utils'
|
|
6
|
+
|
|
7
|
+
export const PT_HELM_EXAMPLE = 'PEPTIDE1{[R].[F].[T].[G].[H].[F].[G].[A].[A].[Y].[P].[E].[NH2]}$$$$';
|
|
8
|
+
|
|
9
|
+
export async function getEnumerationHelm(helmString: string, helmSelections: number[], screenLibrary: string):
|
|
10
|
+
Promise<string[]> {
|
|
11
|
+
const variableMonomers = await getAvailableMonomers(screenLibrary);
|
|
12
|
+
const chain: Chain = Chain.fromHelm(helmString);
|
|
13
|
+
const size = helmSelections.length * variableMonomers.length;
|
|
14
|
+
const enumerations = new Array<string>(size);
|
|
15
|
+
|
|
16
|
+
for (let i = 0; i < helmSelections.length; i++) {
|
|
17
|
+
for (let j = 0; j < variableMonomers.length; j++)
|
|
18
|
+
enumerations[i * variableMonomers.length + j] = chain.getHelmChanged(helmSelections[i], variableMonomers[j]);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return enumerations;
|
|
22
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as grok from 'datagrok-api/grok';
|
|
2
|
+
import * as DG from 'datagrok-api/dg';
|
|
3
|
+
import * as ui from 'datagrok-api/ui';
|
|
4
|
+
|
|
5
|
+
import {getPolyToolEnumerationHelmDialog, getPolyToolEnumerationChemDialog} from './pt-dialog';
|
|
6
|
+
|
|
7
|
+
export function polyToolEnumerateHelmUI(cell?: DG.Cell): void {
|
|
8
|
+
getPolyToolEnumerationHelmDialog(cell)
|
|
9
|
+
.then((dialog) => {
|
|
10
|
+
dialog.show({resizable: true});
|
|
11
|
+
})
|
|
12
|
+
.catch((_err: any) => {
|
|
13
|
+
grok.shell.warning('To run PolyTool Enumeration, sketch the macromolecule and select monomers to vary');
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function polyToolEnumerateChemUI(cell?: DG.Cell): void {
|
|
18
|
+
getPolyToolEnumerationChemDialog(cell)
|
|
19
|
+
.then((dialog) => {
|
|
20
|
+
dialog.show({resizable: true});
|
|
21
|
+
})
|
|
22
|
+
.catch((_err: any) => {
|
|
23
|
+
grok.shell.warning('To run PolyTool Enumeration, sketch the molecule and specify the R group to vary');
|
|
24
|
+
});
|
|
25
|
+
}
|
package/src/polytool/utils.ts
CHANGED
|
@@ -2,19 +2,27 @@
|
|
|
2
2
|
import * as grok from 'datagrok-api/grok';
|
|
3
3
|
import * as ui from 'datagrok-api/ui';
|
|
4
4
|
import * as DG from 'datagrok-api/dg';
|
|
5
|
-
import {_package} from '../package';
|
|
6
5
|
|
|
6
|
+
import {_package} from '../package';
|
|
7
7
|
import {ALPHABET, ALIGNMENT, NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
8
|
+
import {OrgType} from '@datagrok-libraries/bio/src/helm/types';
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
IMonomerLibFileManager, IMonomerLibHelper
|
|
12
|
+
} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
|
|
13
|
+
|
|
14
|
+
declare const org: OrgType;
|
|
15
|
+
const LIB_PATH = 'System:AppData/Bio/monomer-libraries/';
|
|
8
16
|
|
|
9
17
|
export function _setPeptideColumn(col: DG.Column): void {
|
|
10
18
|
addCommonTags(col);
|
|
11
|
-
col.
|
|
19
|
+
col.meta.units = NOTATION.SEPARATOR;
|
|
12
20
|
col.setTag('separator', '-');
|
|
13
21
|
// col.setTag('cell.renderer', 'sequence');
|
|
14
22
|
}
|
|
15
23
|
|
|
16
24
|
function addCommonTags(col: DG.Column<any>) {
|
|
17
|
-
col.
|
|
25
|
+
col.semType = DG.SEMTYPE.MACROMOLECULE;
|
|
18
26
|
col.setTag('aligned', ALIGNMENT.SEQ);
|
|
19
27
|
col.setTag('alphabet', ALPHABET.PT);
|
|
20
28
|
}
|
|
@@ -25,3 +33,26 @@ export function handleError(err: any): void {
|
|
|
25
33
|
grok.shell.error(errMsg);
|
|
26
34
|
_package.logger.error(err.message, undefined, stack);
|
|
27
35
|
}
|
|
36
|
+
|
|
37
|
+
export async function getAvailableMonomers(screenLibrary: string): Promise<string[]> {
|
|
38
|
+
const monomerLibHelper: IMonomerLibHelper = await grok.functions.call('Bio:getMonomerLibHelper', {});
|
|
39
|
+
const monomerLib = await monomerLibHelper.readLibrary(LIB_PATH, screenLibrary);
|
|
40
|
+
//NOTICE: works with Peptides only
|
|
41
|
+
return monomerLib.getMonomerSymbolsByType('PEPTIDE');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export async function getAvailableMonomerMols(screenLibrary: string): Promise<{[monomerSymbol: string]: string}> {
|
|
45
|
+
const monomerLibHelper: IMonomerLibHelper = await grok.functions.call('Bio:getMonomerLibHelper', {});
|
|
46
|
+
const monomerLib = await monomerLibHelper.readLibrary(LIB_PATH, screenLibrary);
|
|
47
|
+
const monomers = monomerLib.getMonomerSymbolsByType('PEPTIDE');
|
|
48
|
+
const mols = new Array<string>(monomers.length);
|
|
49
|
+
|
|
50
|
+
//NOTICE: works with Peptides only
|
|
51
|
+
return monomerLib.getMonomerMolsByPolymerType('PEPTIDE')!;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export async function getLibrariesList(): Promise<string[]> {
|
|
55
|
+
const monomerLibHelper: IMonomerLibHelper = await grok.functions.call('Bio:getMonomerLibHelper', {});
|
|
56
|
+
const monomerFileManager: IMonomerLibFileManager = await monomerLibHelper.getFileManager();
|
|
57
|
+
return monomerFileManager.getValidLibraryPaths();
|
|
58
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import * as grok from 'datagrok-api/grok';
|
|
2
|
+
import * as DG from 'datagrok-api/dg';
|
|
3
|
+
import * as ui from 'datagrok-api/ui';
|
|
4
|
+
|
|
5
|
+
import {defaultErrorHandler} from './err-info';
|
|
6
|
+
import {_package, addContextMenu} from '../package';
|
|
7
|
+
import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
|
|
8
|
+
import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
9
|
+
import {polyToolEnumerateHelmUI} from '../polytool/pt-ui';
|
|
10
|
+
|
|
11
|
+
export type SequenceTranslatorWindowType = Window & {
|
|
12
|
+
$sequenceTranslator?: {
|
|
13
|
+
contextMenuError?: any
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
declare const window: SequenceTranslatorWindowType;
|
|
17
|
+
|
|
18
|
+
export function addContextMenuUI(event: DG.EventData): void {
|
|
19
|
+
try {
|
|
20
|
+
const item = event.args.item;
|
|
21
|
+
if (item) {
|
|
22
|
+
const menu: DG.Menu = event.args.menu;
|
|
23
|
+
if (item instanceof DG.GridCell || item.constructor.name == 'GridCell') {
|
|
24
|
+
const gridCell: DG.GridCell = item;
|
|
25
|
+
if (addContextMenuForCell(gridCell, menu))
|
|
26
|
+
event.preventDefault();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
} catch (err: any) {
|
|
30
|
+
defaultErrorHandler(err);
|
|
31
|
+
if (!window.$sequenceTranslator) window.$sequenceTranslator = {};
|
|
32
|
+
window.$sequenceTranslator.contextMenuError = err;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function addContextMenuForCell(gridCell: DG.GridCell, menu: DG.Menu): boolean {
|
|
37
|
+
const logPrefix: string = `ST: addContextMenuForCell()`;
|
|
38
|
+
_package.logger.debug(`${logPrefix}, start`);
|
|
39
|
+
|
|
40
|
+
const polyToolEnumerate = () => {
|
|
41
|
+
polyToolEnumerateHelmUI(gridCell.cell);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
if (gridCell && gridCell.tableColumn) {
|
|
45
|
+
switch (gridCell.tableColumn.semType) {
|
|
46
|
+
case DG.SEMTYPE.MACROMOLECULE: {
|
|
47
|
+
const sh = SeqHandler.forColumn(gridCell.tableColumn);
|
|
48
|
+
if (sh.notation === NOTATION.HELM) {
|
|
49
|
+
menu
|
|
50
|
+
.item('PolyTool-Enumerate', polyToolEnumerate);
|
|
51
|
+
true;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as grok from 'datagrok-api/grok';
|
|
2
|
+
import * as ui from 'datagrok-api/ui';
|
|
3
|
+
import * as DG from 'datagrok-api/dg';
|
|
4
|
+
|
|
5
|
+
import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
|
|
6
|
+
|
|
7
|
+
import {_package} from '../package';
|
|
8
|
+
|
|
9
|
+
export function defaultErrorHandler(err: any): void {
|
|
10
|
+
const [errMsg, errStack] = errInfo(err);
|
|
11
|
+
_package.logger.error(errMsg, undefined, errStack);
|
|
12
|
+
grok.shell.error(errMsg);
|
|
13
|
+
}
|