@datagrok/sequence-translator 1.4.7 → 1.4.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/.eslintrc.json +1 -1
- package/CHANGELOG.md +25 -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 +9 -9
- package/src/apps/common/model/oligo-toolkit-package.ts +13 -7
- package/src/package.ts +8 -7
- package/src/polytool/const.ts +1 -0
- package/src/polytool/{pt-conversion.ts → conversion/pt-chain.ts} +37 -241
- package/src/polytool/conversion/pt-conversion.ts +27 -0
- package/src/polytool/conversion/pt-misc.ts +183 -0
- package/src/polytool/pt-dialog.ts +135 -6
- package/src/polytool/{pt-enumeration-helm-dialog.ts → pt-enumerate-seq-dialog.ts} +241 -112
- package/src/polytool/pt-enumeration-helm.ts +2 -2
- package/src/polytool/pt-placeholders-breadth-input.ts +80 -39
- package/src/polytool/pt-placeholders-input.ts +96 -35
- package/src/polytool/pt-unrule.ts +1 -1
- package/src/polytool/types.ts +5 -1
- package/src/tests/polytool-chain-from-notation-tests.ts +3 -4
- package/src/tests/polytool-chain-parse-notation-tests.ts +2 -1
- package/src/tests/polytool-convert-tests.ts +2 -1
- package/src/tests/toAtomicLevel-tests.ts +1 -2
- package/src/utils/cell-renderer-cyclized.ts +37 -0
- package/src/utils/context-menu.ts +1 -1
- package/src/utils/cyclized.ts +23 -26
|
@@ -4,8 +4,9 @@ import * as DG from 'datagrok-api/dg';
|
|
|
4
4
|
|
|
5
5
|
import $ from 'cash-dom';
|
|
6
6
|
import wu from 'wu';
|
|
7
|
-
import {
|
|
8
|
-
|
|
7
|
+
import {Unsubscribable} from 'rxjs';
|
|
8
|
+
|
|
9
|
+
import {GetMonomerResType, HelmAtom, MonomerNumberingTypes} from '@datagrok-libraries/helm-web-editor/src/types/org-helm';
|
|
9
10
|
import {getHelmHelper, HelmInputBase, IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
|
|
10
11
|
import {getMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
|
|
11
12
|
import {HelmType, PolymerType} from '@datagrok-libraries/bio/src/helm/types';
|
|
@@ -14,6 +15,8 @@ import {getSeqHelper, ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-he
|
|
|
14
15
|
import '@datagrok-libraries/bio/src/types/input';
|
|
15
16
|
import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
|
|
16
17
|
import {InputColumnBase} from '@datagrok-libraries/bio/src/types/input';
|
|
18
|
+
import {SeqValueBase} from '@datagrok-libraries/bio/src/utils/macromolecule/seq-handler';
|
|
19
|
+
import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
17
20
|
|
|
18
21
|
import {PolyToolEnumeratorParams, PolyToolEnumeratorType, PolyToolEnumeratorTypes} from './types';
|
|
19
22
|
import {getLibrariesList} from './utils';
|
|
@@ -21,11 +24,18 @@ import {doPolyToolEnumerateHelm, PT_HELM_EXAMPLE} from './pt-enumeration-helm';
|
|
|
21
24
|
import {PolyToolPlaceholdersInput} from './pt-placeholders-input';
|
|
22
25
|
import {defaultErrorHandler} from '../utils/err-info';
|
|
23
26
|
import {PolyToolPlaceholdersBreadthInput} from './pt-placeholders-breadth-input';
|
|
24
|
-
import {PT_UI_DIALOG_ENUMERATION} from './const';
|
|
27
|
+
import {PT_UI_DIALOG_ENUMERATION, PT_UI_GET_HELM, PT_UI_HIGHLIGHT_MONOMERS, PT_UI_RULES_USED, PT_UI_USE_CHIRALITY} from './const';
|
|
25
28
|
import {PolyToolDataRole, PolyToolTags} from '../consts';
|
|
26
|
-
import {
|
|
29
|
+
import {RuleInputs, RULES_PATH, RULES_STORAGE_NAME} from './pt-rules';
|
|
30
|
+
import {Chain} from './conversion/pt-chain';
|
|
31
|
+
import {polyToolConvert} from './pt-dialog';
|
|
27
32
|
|
|
28
33
|
import {_package, applyNotationProviderForCyclized} from '../package';
|
|
34
|
+
import {getUnusedColName} from '@datagrok-libraries/bio/src/monomer-works/utils';
|
|
35
|
+
import {buildMonomerHoverLink} from '@datagrok-libraries/bio/src/monomer-works/monomer-hover';
|
|
36
|
+
import {MmcrTemps} from '@datagrok-libraries/bio/src/utils/cell-renderer-consts';
|
|
37
|
+
import {getRdKitModule} from '@datagrok-libraries/bio/src/chem/rdkit-module';
|
|
38
|
+
import {PolymerTypes} from '@datagrok-libraries/bio/src/helm/consts';
|
|
29
39
|
|
|
30
40
|
type PolyToolEnumerateInputs = {
|
|
31
41
|
macromolecule: HelmInputBase;
|
|
@@ -35,7 +45,10 @@ type PolyToolEnumerateInputs = {
|
|
|
35
45
|
trivialNameCol: InputColumnBase,
|
|
36
46
|
keepOriginal: DG.InputBase<boolean>;
|
|
37
47
|
toAtomicLevel: DG.InputBase<boolean>;
|
|
38
|
-
|
|
48
|
+
generateHelm: DG.InputBase<boolean>;
|
|
49
|
+
chiralityEngine: DG.InputBase<boolean>;
|
|
50
|
+
highlightMonomers: DG.InputBase<boolean>;
|
|
51
|
+
rules: { header: HTMLElement, form: HTMLDivElement },
|
|
39
52
|
};
|
|
40
53
|
|
|
41
54
|
type PolyToolEnumerateHelmSerialized = {
|
|
@@ -46,7 +59,10 @@ type PolyToolEnumerateHelmSerialized = {
|
|
|
46
59
|
trivialNameCol: string;
|
|
47
60
|
keepOriginal: boolean;
|
|
48
61
|
toAtomicLevel: boolean;
|
|
49
|
-
|
|
62
|
+
generateHelm: boolean;
|
|
63
|
+
chiralityEngine: boolean;
|
|
64
|
+
highlightMonomers: boolean;
|
|
65
|
+
rules: string[],
|
|
50
66
|
};
|
|
51
67
|
|
|
52
68
|
export async function polyToolEnumerateHelmUI(cell?: DG.Cell): Promise<void> {
|
|
@@ -72,26 +88,24 @@ export async function polyToolEnumerateHelmUI(cell?: DG.Cell): Promise<void> {
|
|
|
72
88
|
.filter((el) => el instanceof HTMLElement)
|
|
73
89
|
.map((el) => (el as HTMLElement).offsetHeight).reduce((sum, h) => sum + h, 0);
|
|
74
90
|
const remainFitHeight = contentHeight - otherInputsHeight - 38;
|
|
75
|
-
|
|
91
|
+
for (const idx of wu.count(0).take(dialogContentEl.children.length)) {
|
|
76
92
|
if (idx in fitInputs) {
|
|
93
|
+
const el = dialogContentEl.children[idx] as HTMLElement;
|
|
77
94
|
const inputFitHeight = remainFitHeight * fitInputs[idx] / fitInputsSumHeight;
|
|
78
|
-
|
|
95
|
+
el.style.height = `${inputFitHeight}px`;
|
|
79
96
|
}
|
|
80
|
-
}
|
|
97
|
+
}
|
|
81
98
|
};
|
|
82
99
|
dialog = await getPolyToolEnumerateDialog(cell, resizeInputs);
|
|
83
100
|
|
|
84
101
|
let isFirstShow = true;
|
|
85
102
|
ui.onSizeChanged(dialog.root).subscribe(() => {
|
|
86
103
|
if (isFirstShow) {
|
|
87
|
-
const dialogInputList = dialog.inputs;
|
|
88
104
|
const dialogRootCash = $(dialog.root);
|
|
89
105
|
const contentMaxHeight = maxHeight -
|
|
90
106
|
dialogRootCash.find('div.d4-dialog-header').get(0)!.offsetHeight -
|
|
91
107
|
dialogRootCash.find('div.d4-dialog-footer').get(0)!.offsetHeight;
|
|
92
108
|
|
|
93
|
-
// dialog.inputs2.macromolecule.root.style.backgroundColor = '#CCFFCC';
|
|
94
|
-
|
|
95
109
|
const dialogWidth = maxWidth * 0.7;
|
|
96
110
|
const dialogHeight = maxHeight * 0.7;
|
|
97
111
|
|
|
@@ -113,7 +127,7 @@ export async function polyToolEnumerateHelmUI(cell?: DG.Cell): Promise<void> {
|
|
|
113
127
|
_package.logger.debug('PolyToolEnumerateHelmUI: dialog after show');
|
|
114
128
|
} catch (err: any) {
|
|
115
129
|
const [errMsg, errStack] = errInfo(err);
|
|
116
|
-
grok.shell.warning('To run PolyTool Enumeration, sketch the macromolecule and select monomers to vary');
|
|
130
|
+
//grok.shell.warning('To run PolyTool Enumeration, sketch the macromolecule and select monomers to vary');
|
|
117
131
|
_package.logger.error(errMsg, undefined, errStack);
|
|
118
132
|
}
|
|
119
133
|
}
|
|
@@ -129,18 +143,56 @@ async function getPolyToolEnumerateDialog(
|
|
|
129
143
|
inputs.placeholders.detach();
|
|
130
144
|
};
|
|
131
145
|
try {
|
|
132
|
-
const
|
|
146
|
+
const libHelper = await getMonomerLibHelper();
|
|
147
|
+
const monomerLib = libHelper.getMonomerLib();
|
|
133
148
|
const seqHelper = await getSeqHelper();
|
|
134
149
|
const emptyDf: DG.DataFrame = DG.DataFrame.fromColumns([]);
|
|
135
150
|
|
|
136
151
|
const [libList, helmHelper] = await Promise.all([getLibrariesList(), getHelmHelper()]);
|
|
152
|
+
const monomerLibFuncs = helmHelper.buildMonomersFuncsFromLib(monomerLib);
|
|
153
|
+
|
|
154
|
+
const getValue = (cell?: DG.Cell): [SeqValueBase, PolyToolDataRole] => {
|
|
155
|
+
let resSeqValue: SeqValueBase;
|
|
156
|
+
let resDataRole: PolyToolDataRole;
|
|
157
|
+
if (cell && cell.rowIndex >= 0 && cell?.column.semType == DG.SEMTYPE.MACROMOLECULE) {
|
|
158
|
+
const sh = seqHelper.getSeqHandler(cell.column);
|
|
159
|
+
resSeqValue = sh.getValue(cell.rowIndex);
|
|
160
|
+
resDataRole = (resSeqValue.tags[PolyToolTags.dataRole] as PolyToolDataRole.template) ?? PolyToolDataRole.macromolecule;
|
|
161
|
+
} else {
|
|
162
|
+
const seqCol = DG.Column.fromList(DG.COLUMN_TYPE.STRING, 'seq', [PT_HELM_EXAMPLE]);
|
|
163
|
+
seqCol.meta.units = NOTATION.HELM;
|
|
164
|
+
const sh = seqHelper.getSeqHandler(seqCol);
|
|
165
|
+
resSeqValue = sh.getValue(0);
|
|
166
|
+
resDataRole = PolyToolDataRole.macromolecule;
|
|
167
|
+
}
|
|
168
|
+
return [resSeqValue, resDataRole];
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
let [seqValue, dataRole]: [SeqValueBase, PolyToolDataRole] = getValue(cell);
|
|
137
172
|
|
|
138
173
|
let srcId: { value: string, colName: string } | null = null;
|
|
174
|
+
let ruleFileList: string[];
|
|
175
|
+
let ruleInputs: RuleInputs;
|
|
139
176
|
const trivialNameSampleDiv = ui.divText('', {style: {marginLeft: '8px', marginTop: '2px'}});
|
|
140
177
|
const warningsTextDiv = ui.divText('', {style: {color: 'red'}});
|
|
141
178
|
inputs = {
|
|
142
179
|
macromolecule: helmHelper.createHelmInput(
|
|
143
|
-
'Macromolecule', {
|
|
180
|
+
'Macromolecule', {
|
|
181
|
+
editable: false,
|
|
182
|
+
editorOptions: {
|
|
183
|
+
drawOptions: {
|
|
184
|
+
monomerNumbering: MonomerNumberingTypes.continuous,
|
|
185
|
+
getMonomer: (a: HelmAtom | HelmType, name?: string): GetMonomerResType => {
|
|
186
|
+
const aa: HelmAtom = a as HelmAtom;
|
|
187
|
+
if (aa.T === 'ATOM') {
|
|
188
|
+
const canonicalSymbol = seqValue.getSplitted().getCanonical(aa.bio!.continuousId - 1);
|
|
189
|
+
return monomerLibFuncs.getMonomer(aa.bio!.type, canonicalSymbol);
|
|
190
|
+
} else
|
|
191
|
+
return monomerLibFuncs.getMonomer(a, name);
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
}
|
|
195
|
+
}),
|
|
144
196
|
placeholders: await PolyToolPlaceholdersInput.create(
|
|
145
197
|
'Placeholders', {
|
|
146
198
|
showAddNewRowIcon: true,
|
|
@@ -163,9 +215,19 @@ async function getPolyToolEnumerateDialog(
|
|
|
163
215
|
keepOriginal: ui.input.bool(
|
|
164
216
|
'Keep original', {value: false}),
|
|
165
217
|
toAtomicLevel: ui.input.bool(
|
|
166
|
-
'To atomic level', {
|
|
167
|
-
|
|
168
|
-
|
|
218
|
+
'To atomic level', {
|
|
219
|
+
value: false,
|
|
220
|
+
onValueChanged: (value, input) => { updateViewRules(); }
|
|
221
|
+
}),
|
|
222
|
+
generateHelm: ui.input.bool(PT_UI_GET_HELM, {value: true}),
|
|
223
|
+
chiralityEngine: ui.input.bool(PT_UI_USE_CHIRALITY, {value: false}),
|
|
224
|
+
highlightMonomers: ui.input.bool(PT_UI_HIGHLIGHT_MONOMERS, {value: false}),
|
|
225
|
+
rules: {
|
|
226
|
+
header: ui.inlineText([PT_UI_RULES_USED]),
|
|
227
|
+
form: await (ruleInputs = new RuleInputs(RULES_PATH, RULES_STORAGE_NAME, '.json', {
|
|
228
|
+
onValueChanged: (value: string[]) => { ruleFileList = value; }
|
|
229
|
+
})).getForm()
|
|
230
|
+
},
|
|
169
231
|
trivialNameCol: ui.input.column2(
|
|
170
232
|
'Trivial name', {
|
|
171
233
|
table: cell?.dataFrame,
|
|
@@ -186,28 +248,33 @@ async function getPolyToolEnumerateDialog(
|
|
|
186
248
|
}),
|
|
187
249
|
};
|
|
188
250
|
|
|
189
|
-
inputs.toHarmonizedSequence.root.style.display = 'none';
|
|
190
251
|
inputs.trivialNameCol.addOptions(trivialNameSampleDiv);
|
|
191
252
|
|
|
192
253
|
let placeholdersValidity: string | null = null;
|
|
193
254
|
inputs.placeholders.addValidator((value: string): string | null => {
|
|
194
255
|
const errors: string[] = [];
|
|
195
256
|
try {
|
|
257
|
+
if (dataRole !== PolyToolDataRole.macromolecule)
|
|
258
|
+
return null;
|
|
259
|
+
|
|
196
260
|
const missedMonomerList: { polymerType: PolymerType, symbol: string }[] = [];
|
|
197
261
|
for (const ph of inputs.placeholders.placeholdersValue) {
|
|
198
262
|
const pos = ph.position;
|
|
263
|
+
if (pos == null)
|
|
264
|
+
continue;
|
|
199
265
|
if (pos >= inputs.macromolecule.molValue.atoms.length) {
|
|
200
266
|
errors.push(`There is no monomer at position ${pos + 1}.`);
|
|
201
267
|
continue;
|
|
202
268
|
}
|
|
203
269
|
const a = inputs.macromolecule.molValue.atoms[pos];
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
270
|
+
if (a) {
|
|
271
|
+
const helmType: HelmType = a.biotype()!;
|
|
272
|
+
const polymerType = helmTypeToPolymerType(helmType);
|
|
273
|
+
for (const symbol of ph.monomers) {
|
|
274
|
+
const substituteMonomer = monomerLib.getMonomer(polymerType, symbol)!;
|
|
275
|
+
if (!substituteMonomer || !substituteMonomer.lib)
|
|
276
|
+
missedMonomerList.push({polymerType, symbol});
|
|
277
|
+
}
|
|
211
278
|
}
|
|
212
279
|
}
|
|
213
280
|
|
|
@@ -231,6 +298,57 @@ async function getPolyToolEnumerateDialog(
|
|
|
231
298
|
return placeholdersValidity;
|
|
232
299
|
});
|
|
233
300
|
|
|
301
|
+
// inputs.placeholdersBreadth.addValidator((value: string): string | null => {
|
|
302
|
+
// const errors: string[] = [];
|
|
303
|
+
// try {
|
|
304
|
+
// if (dataRole !== PolyToolDataRole.macromolecule)
|
|
305
|
+
// return null;
|
|
306
|
+
//
|
|
307
|
+
// const missedMonomerList: { polymerType: PolymerType, symbol: string }[] = [];
|
|
308
|
+
// for (const ph of inputs.placeholdersBreadth.placeholdersBreadthValue) {
|
|
309
|
+
// const posErrors = [];
|
|
310
|
+
// if (ph.start == null || ph.end == null)
|
|
311
|
+
// continue;
|
|
312
|
+
// if (ph.start < 0)
|
|
313
|
+
// posErrors.push(`There is no monomer at start position ${ph.start + 1}.`);
|
|
314
|
+
// if (ph.start >= inputs.macromolecule.molValue.atoms.length)
|
|
315
|
+
// posErrors.push(`There is no monomer at start position ${ph.start + 1}.`);
|
|
316
|
+
// if (ph.end < 0)
|
|
317
|
+
// posErrors.push(`There is no monomer at end position ${ph.end + 1}.`);
|
|
318
|
+
// if (ph.end >= inputs.macromolecule.molValue.atoms.length)
|
|
319
|
+
// posErrors.push(`There is no monomer at end position ${ph.end + 1}.`);
|
|
320
|
+
// errors.push(...posErrors);
|
|
321
|
+
// if (posErrors.length > 0)
|
|
322
|
+
// continue;
|
|
323
|
+
//
|
|
324
|
+
// const polymerType = PolymerTypes.PEPTIDE;
|
|
325
|
+
// for (const symbol of ph.monomers) {
|
|
326
|
+
// const substituteMonomer = monomerLib.getMonomer(null, symbol)!;
|
|
327
|
+
// if (!substituteMonomer || !substituteMonomer.lib)
|
|
328
|
+
// missedMonomerList.push({polymerType, symbol});
|
|
329
|
+
// }
|
|
330
|
+
//
|
|
331
|
+
// const byType: { [polymerType: string]: string[] } = {};
|
|
332
|
+
// for (const sm of missedMonomerList) {
|
|
333
|
+
// let byTypeList = byType[sm.polymerType];
|
|
334
|
+
// if (!byTypeList) byTypeList = byType[sm.polymerType] = [];
|
|
335
|
+
// byTypeList.push(sm.symbol);
|
|
336
|
+
// }
|
|
337
|
+
// const byTypeStr: string = Object.entries(byType)
|
|
338
|
+
// .map(([polymerType, symbolList]) => `${polymerType}: ${symbolList.join(', ')}`)
|
|
339
|
+
// .join('\n');
|
|
340
|
+
// if (Object.keys(byTypeStr).length > 0)
|
|
341
|
+
// errors.push(`Placeholders contain missed monomers: ${byTypeStr}`);
|
|
342
|
+
// placeholdersValidity = errors.length > 0 ? errors.join('\n') : null;
|
|
343
|
+
// }
|
|
344
|
+
// } catch (err: any) {
|
|
345
|
+
// const [errMsg, errStack] = defaultErrorHandler(err, false);
|
|
346
|
+
// placeholdersValidity = errMsg;
|
|
347
|
+
// }
|
|
348
|
+
// setTimeout(() => { updateWarnings(); }, 0);
|
|
349
|
+
// return placeholdersValidity;
|
|
350
|
+
// });
|
|
351
|
+
|
|
234
352
|
subs.push(inputs.macromolecule.onMouseMove.subscribe((e: MouseEvent) => {
|
|
235
353
|
try {
|
|
236
354
|
_package.logger.debug(`${logPrefix}, placeholdersInput.onMouseMove()`);
|
|
@@ -265,39 +383,19 @@ async function getPolyToolEnumerateDialog(
|
|
|
265
383
|
const clickedAtom = helmHelper.getHoveredAtom(argsX, argsY, mol, inputs.macromolecule.root.clientHeight);
|
|
266
384
|
if (clickedAtom) {
|
|
267
385
|
const clickedAtomContIdx = clickedAtom._parent.atoms.indexOf(clickedAtom);
|
|
268
|
-
const clickedAtomContIdxStr = (clickedAtomContIdx + 1)
|
|
269
|
-
|
|
270
|
-
const phDf = inputs.placeholders.grid.dataFrame;
|
|
271
|
-
const posList = phDf.columns.byName('Position').toList();
|
|
272
|
-
let rowIdx = posList.indexOf(clickedAtomContIdxStr);
|
|
273
|
-
if (rowIdx === -1) {
|
|
274
|
-
rowIdx = posList.findIndex((v) => isNaN(v));
|
|
275
|
-
if (rowIdx === -1)
|
|
276
|
-
rowIdx = phDf.rows.addNew([clickedAtomContIdxStr, '']).idx;
|
|
277
|
-
|
|
278
|
-
phDf.set('Position', rowIdx, clickedAtomContIdxStr);
|
|
279
|
-
// const tgtCell = inputs.placeholders.grid.cell('Monomers', rowIdx);
|
|
280
|
-
}
|
|
281
|
-
phDf.currentCell = phDf.cell(rowIdx, 'Monomers');
|
|
282
|
-
//const gridRowIdx = inputs.placeholders.grid.tableRowToGrid(rowIdx);
|
|
283
|
-
//const monomersGCell = inputs.placeholders.grid.cell('Monomers', gridRowIdx);
|
|
284
|
-
const k = 42;
|
|
386
|
+
const clickedAtomContIdxStr = String(clickedAtomContIdx + 1);
|
|
387
|
+
inputs.placeholders.addPosition(clickedAtomContIdx);
|
|
285
388
|
}
|
|
286
389
|
} catch (err: any) {
|
|
287
390
|
defaultErrorHandler(err);
|
|
288
391
|
}
|
|
289
392
|
}));
|
|
290
|
-
subs.push(inputs.placeholders.
|
|
291
|
-
updateMolView();
|
|
292
|
-
}));
|
|
293
|
-
subs.push(fromEvent<KeyboardEvent>(inputs.placeholders.grid.root, 'keydown')
|
|
294
|
-
.subscribe((e: KeyboardEvent) => {
|
|
295
|
-
if (e.key === 'Enter') e.stopPropagation();
|
|
296
|
-
}));
|
|
393
|
+
subs.push(inputs.placeholders.onChanged.subscribe(() => { updateViewMol(); }));
|
|
297
394
|
|
|
298
395
|
// TODO: suspect
|
|
299
396
|
subs.push(ui.onSizeChanged(inputs.placeholders.root).subscribe(() => {
|
|
300
|
-
if (resizeInputs)
|
|
397
|
+
if (resizeInputs)
|
|
398
|
+
resizeInputs();
|
|
301
399
|
}));
|
|
302
400
|
|
|
303
401
|
// Displays the molecule from a current cell (monitors changes)
|
|
@@ -305,14 +403,15 @@ async function getPolyToolEnumerateDialog(
|
|
|
305
403
|
const cell = grok.shell.tv.dataFrame.currentCell;
|
|
306
404
|
if (cell.column.semType !== DG.SEMTYPE.MACROMOLECULE) return;
|
|
307
405
|
|
|
308
|
-
|
|
406
|
+
[seqValue, dataRole] = getValue();
|
|
407
|
+
fillForCurrentCell(seqValue, dataRole, cell);
|
|
309
408
|
}));
|
|
310
409
|
|
|
311
410
|
inputs.macromolecule.root.style.setProperty('min-width', '250px', 'important');
|
|
312
411
|
// inputs.macromolecule.root.style.setProperty('max-height', '300px', 'important');
|
|
313
412
|
|
|
314
|
-
const
|
|
315
|
-
|
|
413
|
+
const updateViewMol = () => {
|
|
414
|
+
const phPosSet = new Set<number>(inputs.placeholders.placeholdersValue.map((ph) => ph.position));
|
|
316
415
|
const mol = inputs.macromolecule.molValue;
|
|
317
416
|
for (let aI = 0; aI < mol.atoms.length; aI++) {
|
|
318
417
|
const a = mol.atoms[aI];
|
|
@@ -321,6 +420,22 @@ async function getPolyToolEnumerateDialog(
|
|
|
321
420
|
inputs.macromolecule.redraw();
|
|
322
421
|
};
|
|
323
422
|
|
|
423
|
+
const updateViewRules = () => {
|
|
424
|
+
if (inputs.toAtomicLevel.value && dataRole === PolyToolDataRole.template) {
|
|
425
|
+
inputs.generateHelm.root.style.removeProperty('display');
|
|
426
|
+
inputs.chiralityEngine.root.style.removeProperty('display');
|
|
427
|
+
inputs.highlightMonomers.root.style.removeProperty('display');
|
|
428
|
+
inputs.rules.header.style.removeProperty('display');
|
|
429
|
+
inputs.rules.form.style.removeProperty('display');
|
|
430
|
+
} else {
|
|
431
|
+
inputs.generateHelm.root.style.display = inputs.chiralityEngine.root.style.display =
|
|
432
|
+
inputs.highlightMonomers.root.style.display = 'none';
|
|
433
|
+
inputs.rules.header.style.display = inputs.rules.form.style.display = 'none';
|
|
434
|
+
}
|
|
435
|
+
if (resizeInputs)
|
|
436
|
+
resizeInputs();
|
|
437
|
+
};
|
|
438
|
+
|
|
324
439
|
const updateWarnings = () => {
|
|
325
440
|
const warnings = placeholdersValidity;
|
|
326
441
|
// const iw = inputs.warnings;
|
|
@@ -344,15 +459,6 @@ async function getPolyToolEnumerateDialog(
|
|
|
344
459
|
};
|
|
345
460
|
|
|
346
461
|
const fillTrivialNameList = (table?: DG.DataFrame) => {
|
|
347
|
-
// const colList: DG.Column[] = [];
|
|
348
|
-
// const colCount: number = cell.dataFrame.columns.length;
|
|
349
|
-
//
|
|
350
|
-
// // TODO: by semType?
|
|
351
|
-
// for (let colI: number = 0; colI < colCount; ++colI) {
|
|
352
|
-
// const col = cell.dataFrame.columns.byIndex(colI);
|
|
353
|
-
// if (col.type === DG.COLUMN_TYPE.STRING) colList.push(col);
|
|
354
|
-
// }
|
|
355
|
-
|
|
356
462
|
if (table) {
|
|
357
463
|
inputs.trivialNameCol.setColumnInputTable(table);
|
|
358
464
|
inputs.trivialNameCol.root.style.removeProperty('display');
|
|
@@ -360,36 +466,18 @@ async function getPolyToolEnumerateDialog(
|
|
|
360
466
|
inputs.trivialNameCol.setColumnInputTable(emptyDf);
|
|
361
467
|
inputs.trivialNameCol.root.style.setProperty('display', 'none');
|
|
362
468
|
}
|
|
363
|
-
if (resizeInputs)
|
|
469
|
+
if (resizeInputs)
|
|
470
|
+
resizeInputs();
|
|
364
471
|
};
|
|
365
472
|
|
|
366
|
-
const fillForCurrentCell =
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
let table: DG.DataFrame | undefined = undefined;
|
|
370
|
-
if (cell && cell.rowIndex >= 0 && cell?.column.semType == DG.SEMTYPE.MACROMOLECULE) {
|
|
371
|
-
const sh = _package.seqHelper.getSeqHandler(cell.column);
|
|
372
|
-
const mValue = await sh.getValue(cell.rowIndex);
|
|
373
|
-
helmValue = mValue.value;
|
|
374
|
-
table = cell.dataFrame;
|
|
375
|
-
resDataRole = (mValue.tags[PolyToolTags.dataRole] as PolyToolDataRole.template) ?? PolyToolDataRole.macromolecule;
|
|
376
|
-
} else {
|
|
377
|
-
helmValue = PT_HELM_EXAMPLE;
|
|
378
|
-
resDataRole = PolyToolDataRole.macromolecule;
|
|
379
|
-
}
|
|
380
|
-
inputs.macromolecule.stringValue = helmValue;
|
|
381
|
-
|
|
382
|
-
if (resDataRole === PolyToolDataRole.template) {
|
|
383
|
-
inputs.toAtomicLevel.root.style.display = 'none';
|
|
384
|
-
} else {
|
|
385
|
-
inputs.toAtomicLevel.root.style.removeProperty('display');
|
|
386
|
-
}
|
|
387
|
-
|
|
473
|
+
const fillForCurrentCell = (mmValue: SeqValueBase, dataRole: PolyToolDataRole, cell?: DG.Cell): void => {
|
|
474
|
+
inputs.macromolecule.value = mmValue;
|
|
475
|
+
const table: DG.DataFrame | undefined = cell?.dataFrame;
|
|
388
476
|
fillTrivialNameList(table);
|
|
389
|
-
return resDataRole;
|
|
390
477
|
};
|
|
391
478
|
|
|
392
|
-
|
|
479
|
+
fillForCurrentCell(seqValue, dataRole, cell);
|
|
480
|
+
updateViewRules();
|
|
393
481
|
|
|
394
482
|
const exec = async (): Promise<void> => {
|
|
395
483
|
try {
|
|
@@ -415,9 +503,15 @@ async function getPolyToolEnumerateDialog(
|
|
|
415
503
|
breadthPlaceholders: inputs.placeholdersBreadth.placeholdersBreadthValue,
|
|
416
504
|
keepOriginal: inputs.keepOriginal.value,
|
|
417
505
|
};
|
|
418
|
-
const toAtomicLevelV = inputs.toAtomicLevel.value
|
|
419
|
-
const enumeratorResDf = await
|
|
420
|
-
toAtomicLevelV
|
|
506
|
+
const toAtomicLevelV: boolean = inputs.toAtomicLevel.value;
|
|
507
|
+
const enumeratorResDf = await polyToolEnumerateSeq(srcHelm, dataRole, srcId, params,
|
|
508
|
+
toAtomicLevelV ? {
|
|
509
|
+
generateHelm: inputs.generateHelm.value,
|
|
510
|
+
chiralityEngine: inputs.chiralityEngine.value,
|
|
511
|
+
highlightMonomers: inputs.highlightMonomers.value,
|
|
512
|
+
rules: await ruleInputs.getActive()
|
|
513
|
+
} : false,
|
|
514
|
+
helmHelper);
|
|
421
515
|
grok.shell.addTableView(enumeratorResDf);
|
|
422
516
|
}
|
|
423
517
|
} catch (err: any) {
|
|
@@ -426,12 +520,27 @@ async function getPolyToolEnumerateDialog(
|
|
|
426
520
|
};
|
|
427
521
|
|
|
428
522
|
const dialog = ui.dialog({title: PT_UI_DIALOG_ENUMERATION, showFooter: true})
|
|
429
|
-
.add(inputs.macromolecule)
|
|
430
|
-
.add(
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
523
|
+
.add(inputs.macromolecule.root)
|
|
524
|
+
.add(ui.divH([
|
|
525
|
+
ui.divV([
|
|
526
|
+
inputs.placeholders.root,
|
|
527
|
+
inputs.enumeratorType.root,],
|
|
528
|
+
{style: {width: '50%'}}
|
|
529
|
+
),
|
|
530
|
+
ui.divV([
|
|
531
|
+
inputs.placeholdersBreadth.root],
|
|
532
|
+
{style: {width: '50%'}}),],
|
|
533
|
+
{style: {width: '100%'}}))
|
|
534
|
+
.add(ui.divH([
|
|
535
|
+
ui.divV([
|
|
536
|
+
inputs.trivialNameCol.root,
|
|
537
|
+
inputs.keepOriginal.root],
|
|
538
|
+
{style: {width: '50%'}}),
|
|
539
|
+
ui.divV([
|
|
540
|
+
ui.divH([inputs.toAtomicLevel.root, inputs.generateHelm.root]),
|
|
541
|
+
ui.divH([inputs.chiralityEngine.root, inputs.highlightMonomers.root]),
|
|
542
|
+
inputs.rules.header, inputs.rules.form],
|
|
543
|
+
{style: {width: '50%'}}),],
|
|
435
544
|
{style: {width: '100%'}}))
|
|
436
545
|
.add(warningsTextDiv)
|
|
437
546
|
// .addButton('Enumerate', () => {
|
|
@@ -452,18 +561,24 @@ async function getPolyToolEnumerateDialog(
|
|
|
452
561
|
trivialNameCol: inputs.trivialNameCol.stringValue,
|
|
453
562
|
keepOriginal: inputs.keepOriginal.value,
|
|
454
563
|
toAtomicLevel: inputs.toAtomicLevel.value,
|
|
455
|
-
|
|
564
|
+
generateHelm: inputs.generateHelm.value,
|
|
565
|
+
chiralityEngine: inputs.chiralityEngine.value,
|
|
566
|
+
highlightMonomers: inputs.highlightMonomers.value,
|
|
567
|
+
rules: ruleFileList,
|
|
456
568
|
};
|
|
457
569
|
},
|
|
458
570
|
/* applyInput */ (x: PolyToolEnumerateHelmSerialized): void => {
|
|
459
571
|
inputs.macromolecule.stringValue = x.macromolecule;
|
|
460
572
|
inputs.placeholders.stringValue = x.placeholders;
|
|
461
|
-
inputs.enumeratorType.value = x.enumeratorType;
|
|
573
|
+
inputs.enumeratorType.value = x.enumeratorType ?? PolyToolEnumeratorTypes.Single;
|
|
462
574
|
inputs.placeholdersBreadth.stringValue = x.placeholdersBreadth;
|
|
463
575
|
inputs.trivialNameCol.stringValue = x.trivialNameCol;
|
|
464
|
-
inputs.keepOriginal.value = x.keepOriginal;
|
|
465
|
-
inputs.toAtomicLevel.value = x.toAtomicLevel;
|
|
466
|
-
inputs.
|
|
576
|
+
inputs.keepOriginal.value = x.keepOriginal ?? false;
|
|
577
|
+
inputs.toAtomicLevel.value = x.toAtomicLevel ?? true;
|
|
578
|
+
inputs.generateHelm.value = x.generateHelm ?? true;
|
|
579
|
+
inputs.chiralityEngine.value = x.chiralityEngine ?? false;
|
|
580
|
+
inputs.highlightMonomers.value = x.highlightMonomers ?? false;
|
|
581
|
+
ruleInputs.setActive(x.rules);
|
|
467
582
|
});
|
|
468
583
|
return dialog;
|
|
469
584
|
} catch (err: any) {
|
|
@@ -476,13 +591,17 @@ async function getPolyToolEnumerateDialog(
|
|
|
476
591
|
* @param {DG.SemanticValue} srcValue Source value to enumerate, either of data role
|
|
477
592
|
* {@link PolyToolDataRole.template} or {@link PolyToolDataRole.macromolecule}
|
|
478
593
|
* */
|
|
479
|
-
async function
|
|
594
|
+
async function polyToolEnumerateSeq(
|
|
480
595
|
srcHelm: string, dataRole: PolyToolDataRole, srcId: { value: string, colName: string } | null,
|
|
481
|
-
params: PolyToolEnumeratorParams,
|
|
596
|
+
params: PolyToolEnumeratorParams,
|
|
597
|
+
toAtomicLevel: { generateHelm: boolean, chiralityEngine: boolean, highlightMonomers: boolean, rules: string[] } | false,
|
|
598
|
+
helmHelper: IHelmHelper
|
|
482
599
|
): Promise<DG.DataFrame> {
|
|
483
600
|
const pi = DG.TaskBarProgressIndicator.create('PolyTool enumerating...');
|
|
484
601
|
try {
|
|
485
|
-
await
|
|
602
|
+
const libHelper = await getMonomerLibHelper();
|
|
603
|
+
const rdKitModule = await getRdKitModule();
|
|
604
|
+
const monomerLib = libHelper.getMonomerLib(); // TODO: Get monomer lib from src SeqValueBase
|
|
486
605
|
|
|
487
606
|
const resList = doPolyToolEnumerateHelm(srcHelm, srcId?.value ?? '', params);
|
|
488
607
|
let enumCol: DG.Column<string>;
|
|
@@ -500,9 +619,9 @@ async function polyToolEnumerateHelm(
|
|
|
500
619
|
templateList[rowIdx] = chain.getNotation();
|
|
501
620
|
}
|
|
502
621
|
enumCol = DG.Column.fromList(DG.COLUMN_TYPE.STRING, 'Enumerated', templateList);
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
622
|
+
enumCol.semType = DG.SEMTYPE.MACROMOLECULE;
|
|
623
|
+
enumCol.setTag(PolyToolTags.dataRole, PolyToolDataRole.template);
|
|
624
|
+
applyNotationProviderForCyclized(enumCol, '-');
|
|
506
625
|
break;
|
|
507
626
|
}
|
|
508
627
|
}
|
|
@@ -512,10 +631,20 @@ async function polyToolEnumerateHelm(
|
|
|
512
631
|
applyNotationProviderForCyclized(enumCol, '-');
|
|
513
632
|
}
|
|
514
633
|
|
|
515
|
-
if (toAtomicLevel
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
634
|
+
if (toAtomicLevel) {
|
|
635
|
+
let resHelmCol: DG.Column<string>;
|
|
636
|
+
if (dataRole === PolyToolDataRole.macromolecule) {
|
|
637
|
+
resHelmCol = enumCol;
|
|
638
|
+
const talRes = await helmHelper.seqHelper.helmToAtomicLevel(resHelmCol,
|
|
639
|
+
toAtomicLevel.chiralityEngine, toAtomicLevel.highlightMonomers);
|
|
640
|
+
enumeratorResDf.columns.add(talRes.molCol!, false);
|
|
641
|
+
const resMolCol = talRes.molCol!;
|
|
642
|
+
buildMonomerHoverLink(resHelmCol, resMolCol, monomerLib, helmHelper.seqHelper, rdKitModule);
|
|
643
|
+
} else if (dataRole === PolyToolDataRole.template) {
|
|
644
|
+
const talRes = await polyToolConvert(enumCol,
|
|
645
|
+
toAtomicLevel.generateHelm, toAtomicLevel.chiralityEngine, toAtomicLevel.rules);
|
|
646
|
+
resHelmCol = talRes[0];
|
|
647
|
+
}
|
|
519
648
|
}
|
|
520
649
|
|
|
521
650
|
if (srcId) {
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
} from '@datagrok-libraries/bio/src/helm/types';
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
import {Chain} from './pt-
|
|
12
|
+
import {Chain, PtBio} from './conversion/pt-chain';
|
|
13
13
|
import {getAvailableMonomers} from './utils';
|
|
14
14
|
import {PolyToolEnumeratorParams, PolyToolEnumeratorTypes, PolyToolPlaceholder, PolyToolBreadthPlaceholder} from './types';
|
|
15
15
|
|
|
@@ -76,7 +76,7 @@ function getPtEnumeratorBreadth(m: HelmMol, placeholdersBreadth: PolyToolBreadth
|
|
|
76
76
|
export function doPolyToolEnumerateHelm(
|
|
77
77
|
helm: string, id: string, params: PolyToolEnumeratorParams
|
|
78
78
|
): [ /* helm */ string, /* id */ string][] {
|
|
79
|
-
const molHandler = new JSDraw2.MolHandler<HelmType, IHelmEditorOptions>();
|
|
79
|
+
const molHandler = new JSDraw2.MolHandler<HelmType, PtBio, IHelmEditorOptions>();
|
|
80
80
|
const plugin = new org.helm.webeditor.Plugin(molHandler);
|
|
81
81
|
org.helm.webeditor.IO.parseHelm(plugin, helm, new JSDraw2.Point(0, 0), undefined);
|
|
82
82
|
const m = molHandler.m;
|