@datagrok/sequence-translator 1.6.2 → 1.6.4
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 +9 -0
- package/detectors.js +30 -12
- 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 +1 -1
- package/src/package.ts +23 -18
- package/src/polytool/const.ts +2 -0
- package/src/polytool/conversion/pt-conversion.ts +4 -2
- package/src/polytool/conversion/pt-rules.ts +16 -1
- package/src/polytool/conversion/rule-manager.ts +27 -21
- package/src/polytool/pt-dialog.ts +56 -9
- package/src/polytool/pt-enumerate-seq-dialog.ts +133 -45
- package/src/polytool/pt-placeholders-breadth-input.ts +9 -0
- package/src/polytool/pt-placeholders-input.ts +18 -5
- package/src/polytool/types.ts +1 -0
- package/src/polytool/utils.ts +1 -1
- package/src/tests/polytool-convert-tests.ts +2 -2
- package/src/global.d.ts +0 -13
- package/src/utils/context-menu.ts +0 -53
package/package.json
CHANGED
package/src/package.ts
CHANGED
|
@@ -22,7 +22,6 @@ import {polyToolEnumerateHelmUI} from './polytool/pt-enumerate-seq-dialog';
|
|
|
22
22
|
import {_setPeptideColumn} from './polytool/utils';
|
|
23
23
|
import {PolyToolCsvLibHandler} from './polytool/csv-to-json-monomer-lib-converter';
|
|
24
24
|
import {ITranslationHelper} from './types';
|
|
25
|
-
import {addContextMenuUI} from './utils/context-menu';
|
|
26
25
|
import {PolyToolConvertFuncEditor} from './polytool/pt-convert-editor';
|
|
27
26
|
import {CyclizedNotationProvider} from './utils/cyclized';
|
|
28
27
|
import {getSeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
@@ -50,7 +49,7 @@ async function initSequenceTranslatorInt(): Promise<void> {
|
|
|
50
49
|
|
|
51
50
|
//name: Oligo Toolkit
|
|
52
51
|
//meta.icon: img/icons/toolkit.png
|
|
53
|
-
//meta.browsePath: Oligo
|
|
52
|
+
//meta.browsePath: Peptides | Oligo Toolkit
|
|
54
53
|
//tags: app
|
|
55
54
|
//output: view v
|
|
56
55
|
export async function oligoToolkitApp(): Promise<DG.ViewBase> {
|
|
@@ -65,7 +64,7 @@ export async function oligoToolkitApp(): Promise<DG.ViewBase> {
|
|
|
65
64
|
|
|
66
65
|
//name: Oligo Translator
|
|
67
66
|
//meta.icon: img/icons/translator.png
|
|
68
|
-
//meta.browsePath: Oligo
|
|
67
|
+
//meta.browsePath: Peptides | Oligo Toolkit
|
|
69
68
|
//tags: app
|
|
70
69
|
//output: view v
|
|
71
70
|
export async function oligoTranslatorApp(): Promise<DG.ViewBase> {
|
|
@@ -75,7 +74,7 @@ export async function oligoTranslatorApp(): Promise<DG.ViewBase> {
|
|
|
75
74
|
|
|
76
75
|
//name: Oligo Pattern
|
|
77
76
|
//meta.icon: img/icons/pattern.png
|
|
78
|
-
//meta.browsePath: Oligo
|
|
77
|
+
//meta.browsePath: Peptides | Oligo Toolkit
|
|
79
78
|
//tags: app
|
|
80
79
|
//output: view v
|
|
81
80
|
export async function oligoPatternApp(): Promise<DG.ViewBase> {
|
|
@@ -85,7 +84,7 @@ export async function oligoPatternApp(): Promise<DG.ViewBase> {
|
|
|
85
84
|
|
|
86
85
|
//name: Oligo Structure
|
|
87
86
|
//meta.icon: img/icons/structure.png
|
|
88
|
-
//meta.browsePath: Oligo
|
|
87
|
+
//meta.browsePath: Peptides | Oligo Toolkit
|
|
89
88
|
//tags: app
|
|
90
89
|
//output: view v
|
|
91
90
|
export async function oligoStructureApp(): Promise<DG.ViewBase> {
|
|
@@ -210,7 +209,7 @@ export async function getPolyToolConvertEditor(call: DG.FuncCall): Promise<DG.Co
|
|
|
210
209
|
export async function polyToolConvert2(table: DG.DataFrame,
|
|
211
210
|
seqCol: DG.Column, generateHelm: boolean, chiralityEngine: boolean, rules: string[]
|
|
212
211
|
): Promise<DG.Column<string>> {
|
|
213
|
-
const ptConvertRes = await polyToolConvert(seqCol, generateHelm, chiralityEngine, rules);
|
|
212
|
+
const ptConvertRes = await polyToolConvert(seqCol, generateHelm, false, chiralityEngine, false, rules);
|
|
214
213
|
return ptConvertRes[0];
|
|
215
214
|
}
|
|
216
215
|
|
|
@@ -248,14 +247,6 @@ export async function createMonomerLibraryForPolyTool(file: DG.FileInfo) {
|
|
|
248
247
|
DG.Utils.download(jsonFileName, jsonFileContent);
|
|
249
248
|
}
|
|
250
249
|
|
|
251
|
-
// -- Handle context menu --
|
|
252
|
-
|
|
253
|
-
//name: addContextMenu
|
|
254
|
-
//input: object event
|
|
255
|
-
export function addContextMenu(event: DG.EventData): void {
|
|
256
|
-
addContextMenuUI(event);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
250
|
// //name: PolyTool Converter
|
|
260
251
|
// //meta.icon: img/icons/structure.png
|
|
261
252
|
// //meta.browsePath: PolyTool
|
|
@@ -282,22 +273,36 @@ export function addContextMenu(event: DG.EventData): void {
|
|
|
282
273
|
// }
|
|
283
274
|
// }
|
|
284
275
|
|
|
285
|
-
//name:
|
|
276
|
+
//name: HELM Enumerator
|
|
286
277
|
//meta.icon: img/icons/structure.png
|
|
287
|
-
//meta.browsePath: PolyTool
|
|
278
|
+
//meta.browsePath: Peptides | PolyTool
|
|
288
279
|
//tags: app
|
|
289
280
|
export async function ptEnumeratorHelmApp(): Promise<void> {
|
|
290
281
|
await polyToolEnumerateHelmUI();
|
|
291
282
|
}
|
|
292
283
|
|
|
293
|
-
//name:
|
|
284
|
+
//name: Chem Enumerator
|
|
294
285
|
//meta.icon: img/icons/structure.png
|
|
295
|
-
//meta.browsePath: PolyTool
|
|
286
|
+
//meta.browsePath: Peptides | PolyTool
|
|
296
287
|
//tags: app
|
|
297
288
|
export async function ptEnumeratorChemApp(): Promise<void> {
|
|
298
289
|
polyToolEnumerateChemUI();
|
|
299
290
|
}
|
|
300
291
|
|
|
292
|
+
|
|
293
|
+
//name: Polytool Helm Enumerator dialog
|
|
294
|
+
//input: object cell {nullable: true}
|
|
295
|
+
export async function getPtHelmEnumeratorDialog(cell?: DG.Cell) {
|
|
296
|
+
return polyToolEnumerateHelmUI(cell);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
//name: Polytool Chem Enumerator dialog
|
|
300
|
+
//input: object cell {nullable: true}
|
|
301
|
+
export async function getPtChemEnumeratorDialog(cell?: DG.Cell) {
|
|
302
|
+
return polyToolEnumerateChemUI(cell);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
|
|
301
306
|
//name: applyNotationProviderForHarmonizedSequence
|
|
302
307
|
//input: column col
|
|
303
308
|
//input: string separator
|
package/src/polytool/const.ts
CHANGED
|
@@ -32,6 +32,8 @@ export const PT_WARNING_COLUMN = 'No marcomolecule column chosen!';
|
|
|
32
32
|
|
|
33
33
|
export const PT_UI_GET_HELM = 'Get HELM';
|
|
34
34
|
export const PT_UI_ADD_HELM = 'Add HELM column';
|
|
35
|
+
export const PT_UI_LINEARIZE = 'Linearize';
|
|
36
|
+
export const PT_UI_LINEARIZE_TT = 'Make representation linear if possible';
|
|
35
37
|
export const PT_UI_USE_CHIRALITY = 'Chirality engine';
|
|
36
38
|
export const PT_UI_HIGHLIGHT_MONOMERS = 'Highlight monomers';
|
|
37
39
|
export const PT_UI_DIALOG_CONVERSION = 'Poly Tool Conversion';
|
|
@@ -6,13 +6,15 @@ import {Chain} from './pt-chain';
|
|
|
6
6
|
import {_package} from '../../package';
|
|
7
7
|
|
|
8
8
|
/** The main PolyTool convert engine. Returns list of Helms. Covered with tests. */
|
|
9
|
-
export function doPolyToolConvert(sequences: string[], rules: Rules, helmHelper: IHelmHelper): string[] {
|
|
9
|
+
export function doPolyToolConvert(sequences: string[], rules: Rules, helmHelper: IHelmHelper): [string[], boolean[]] {
|
|
10
10
|
const helms = new Array<string>(sequences.length);
|
|
11
|
+
const isLinear = new Array<boolean>(sequences.length);
|
|
11
12
|
for (let i = 0; i < sequences.length; i++) {
|
|
12
13
|
try {
|
|
13
14
|
if (sequences[i] == null) { helms[i] = ''; } else {
|
|
14
15
|
const chain = Chain.fromSeparator(sequences[i], helmHelper);
|
|
15
16
|
chain.applyRules(rules);
|
|
17
|
+
isLinear[i] = chain.monomersUnderRules.length > 1 || chain.linkagesUnderRules.length > 0 ? false : true;
|
|
16
18
|
helms[i] = chain.getHelm();
|
|
17
19
|
}
|
|
18
20
|
} catch (err: any) {
|
|
@@ -21,5 +23,5 @@ export function doPolyToolConvert(sequences: string[], rules: Rules, helmHelper:
|
|
|
21
23
|
helms[i] = '';
|
|
22
24
|
}
|
|
23
25
|
}
|
|
24
|
-
return helms;
|
|
26
|
+
return [helms, isLinear];
|
|
25
27
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as DG from 'datagrok-api/dg';
|
|
2
2
|
import * as grok from 'datagrok-api/grok';
|
|
3
|
+
import * as ui from 'datagrok-api/ui';
|
|
3
4
|
import {ActiveFiles} from '@datagrok-libraries/utils/src/settings/active-files-base';
|
|
4
5
|
import {RulesManager} from './rule-manager';
|
|
5
6
|
|
|
@@ -93,10 +94,15 @@ export class Rules {
|
|
|
93
94
|
getLinkRulesDf(): DG.DataFrame {
|
|
94
95
|
const length = this.linkRules.length;
|
|
95
96
|
const codeCol = DG.Column.int(NAME_CODE, length);
|
|
97
|
+
codeCol.setTag('friendlyName', 'Code');
|
|
96
98
|
const firstMonomerCol = DG.Column.string(NAME_FIRST_MONOMERS, length);
|
|
99
|
+
firstMonomerCol.setTag('friendlyName', 'First monomers');
|
|
97
100
|
const secondMonomerCol = DG.Column.string(NAME_SECOND_MONOMERS, length);
|
|
101
|
+
secondMonomerCol.setTag('friendlyName', 'Second monomers');
|
|
98
102
|
const firstLinkingGroup = DG.Column.int(NAME_FIRST_LINK, length);
|
|
103
|
+
firstLinkingGroup.setTag('friendlyName', 'First group');
|
|
99
104
|
const secondLinkingGroup = DG.Column.int(NAME_SECOND_LINK, length);
|
|
105
|
+
secondLinkingGroup.setTag('friendlyName', 'Second group');
|
|
100
106
|
|
|
101
107
|
for (let i = 0; i < length; i++) {
|
|
102
108
|
codeCol.set(i, this.linkRules[i].code);
|
|
@@ -106,20 +112,29 @@ export class Rules {
|
|
|
106
112
|
secondLinkingGroup.set(i, this.linkRules[i].secondLinkingGroup);
|
|
107
113
|
}
|
|
108
114
|
|
|
109
|
-
|
|
115
|
+
const res = DG.DataFrame.fromColumns([
|
|
110
116
|
codeCol, firstMonomerCol, secondMonomerCol, firstLinkingGroup, secondLinkingGroup
|
|
111
117
|
]);
|
|
118
|
+
|
|
119
|
+
return res;
|
|
112
120
|
}
|
|
113
121
|
|
|
114
122
|
getSynthesisRulesDf(): DG.DataFrame {
|
|
115
123
|
const length = this.reactionRules.length;
|
|
116
124
|
const codeCol = DG.Column.int(NAME_CODE, length);
|
|
125
|
+
codeCol.setTag('friendlyName', 'Code');
|
|
117
126
|
const firstMonomerCol = DG.Column.string(NAME_FIRST_MONOMERS, length);
|
|
127
|
+
firstMonomerCol.setTag('friendlyName', 'First monomers');
|
|
118
128
|
const secondMonomerCol = DG.Column.string(NAME_SECOND_MONOMERS, length);
|
|
129
|
+
secondMonomerCol.setTag('friendlyName', 'Second monomers');
|
|
119
130
|
const name = DG.Column.string(NAME_REACTION_NAME, length);
|
|
131
|
+
name.setTag('friendlyName', 'Name');
|
|
120
132
|
const firstReactant = DG.Column.string('firstReactant', length);
|
|
133
|
+
firstReactant.setTag('friendlyName', 'First reactant');
|
|
121
134
|
const secondReactant = DG.Column.string('secondReactant', length);
|
|
135
|
+
secondReactant.setTag('friendlyName', 'Second reactant');
|
|
122
136
|
const product = DG.Column.string('product', length);
|
|
137
|
+
product.setTag('friendlyName', 'Product');
|
|
123
138
|
|
|
124
139
|
for (let i = 0; i < length; i++) {
|
|
125
140
|
codeCol.set(i, this.reactionRules[i].code);
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import * as DG from 'datagrok-api/dg';
|
|
2
2
|
import * as grok from 'datagrok-api/grok';
|
|
3
|
+
import * as ui from 'datagrok-api/ui';
|
|
3
4
|
import {getMonomerPairs, getRules, Rules} from './pt-rules';
|
|
4
5
|
import {_package, applyNotationProviderForCyclized} from '../../package';
|
|
5
6
|
import {getHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
|
|
6
7
|
import {doPolyToolConvert} from './pt-conversion';
|
|
7
8
|
import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
|
|
8
9
|
|
|
10
|
+
|
|
11
|
+
const TAB_LINKS = 'Links';
|
|
12
|
+
const TAB_REACTIONS = 'Reactions';
|
|
13
|
+
const TAB_DIMERS = 'Dimers';
|
|
14
|
+
|
|
9
15
|
export class RulesManager {
|
|
10
16
|
rules: Rules;
|
|
11
17
|
linkRuleDataFrame: DG.DataFrame;
|
|
@@ -16,8 +22,6 @@ export class RulesManager {
|
|
|
16
22
|
homoDimerInput: DG.InputBase;
|
|
17
23
|
heteroDimerInput: DG.InputBase;
|
|
18
24
|
|
|
19
|
-
currentTab = '';
|
|
20
|
-
|
|
21
25
|
// every rule set will have its editor instance
|
|
22
26
|
private static instances: Record<string, RulesManager> = {};
|
|
23
27
|
|
|
@@ -92,20 +96,15 @@ export class RulesManager {
|
|
|
92
96
|
grok.shell.info(`Polytool rules at ${this.fileName} was updated`);
|
|
93
97
|
}
|
|
94
98
|
|
|
95
|
-
private createGridDiv(name: string, grid: DG.Grid
|
|
99
|
+
private createGridDiv(name: string, grid: DG.Grid) {
|
|
96
100
|
const header = ui.h1(name, 'polytool-grid-header');
|
|
97
101
|
header.style.marginTop = '10px';
|
|
98
102
|
header.style.marginRight = '10px';
|
|
99
103
|
grid.root.style.height = '100%';
|
|
100
104
|
|
|
101
|
-
buttons.forEach((b) => {
|
|
102
|
-
b.style.marginLeft = '5px';
|
|
103
|
-
b.style.marginRight = '10px';
|
|
104
|
-
});
|
|
105
|
-
|
|
106
105
|
const gridDiv = ui.splitV([
|
|
107
106
|
ui.box(
|
|
108
|
-
|
|
107
|
+
header,
|
|
109
108
|
{style: {maxHeight: '60px'}},
|
|
110
109
|
),
|
|
111
110
|
grid.root,
|
|
@@ -129,10 +128,10 @@ export class RulesManager {
|
|
|
129
128
|
}
|
|
130
129
|
const helmHelper = await getHelmHelper();
|
|
131
130
|
|
|
132
|
-
const helms = doPolyToolConvert(seqs, this.rules, helmHelper);
|
|
131
|
+
const [helms, isLinear] = doPolyToolConvert(seqs, this.rules, helmHelper);
|
|
133
132
|
|
|
134
|
-
const initCol = DG.Column.fromStrings('
|
|
135
|
-
const helmCol = DG.Column.fromStrings('
|
|
133
|
+
const initCol = DG.Column.fromStrings('Monomers', seqs);
|
|
134
|
+
const helmCol = DG.Column.fromStrings('Helm', helms);
|
|
136
135
|
|
|
137
136
|
applyNotationProviderForCyclized(initCol, '-');
|
|
138
137
|
initCol.semType = DG.SEMTYPE.MACROMOLECULE;
|
|
@@ -158,10 +157,10 @@ export class RulesManager {
|
|
|
158
157
|
}
|
|
159
158
|
const helmHelper = await getHelmHelper();
|
|
160
159
|
|
|
161
|
-
const helms = doPolyToolConvert(seqs, this.rules, helmHelper);
|
|
160
|
+
const [helms, isLinear] = doPolyToolConvert(seqs, this.rules, helmHelper);
|
|
162
161
|
|
|
163
|
-
const initCol = DG.Column.fromStrings('
|
|
164
|
-
const helmCol = DG.Column.fromStrings('
|
|
162
|
+
const initCol = DG.Column.fromStrings('Monomers', seqs);
|
|
163
|
+
const helmCol = DG.Column.fromStrings('Helm', helms);
|
|
165
164
|
|
|
166
165
|
initCol.semType = DG.SEMTYPE.MACROMOLECULE;
|
|
167
166
|
applyNotationProviderForCyclized(initCol, '-');
|
|
@@ -177,19 +176,15 @@ export class RulesManager {
|
|
|
177
176
|
async getForm() {
|
|
178
177
|
inputsTabControl: DG.TabControl;
|
|
179
178
|
|
|
180
|
-
const saveLinksButton = ui.bigButton('Save', () => { this.save(); });
|
|
181
|
-
const addLinkButton = ui.button('Add rule', () => { this.linkRuleDataFrame.rows.addNew(); });
|
|
182
179
|
const linksGridDiv = this.createGridDiv('Rules',
|
|
183
|
-
this.linkRuleDataFrame.plot.grid({showAddNewRowIcon: true})
|
|
180
|
+
this.linkRuleDataFrame.plot.grid({showAddNewRowIcon: true}));
|
|
184
181
|
const linkExamples = this.createGridDiv('Examples', await this.getLinkExamplesGrid());
|
|
185
182
|
linksGridDiv.style.width = '50%';
|
|
186
183
|
linkExamples.style.width = '50%';
|
|
187
184
|
const links = ui.divH([linksGridDiv, linkExamples]);
|
|
188
185
|
|
|
189
|
-
const saveReactionsButton = ui.bigButton('Save', () => { this.save(); });
|
|
190
|
-
const addReactionButton = ui.button('Add rule', () => { this.synthRuleDataFrame.rows.addNew(); });
|
|
191
186
|
const reactionsGridDiv = this.createGridDiv('Rules',
|
|
192
|
-
this.synthRuleDataFrame.plot.grid({showAddNewRowIcon: true})
|
|
187
|
+
this.synthRuleDataFrame.plot.grid({showAddNewRowIcon: true}));
|
|
193
188
|
const reactionExamples = this.createGridDiv('Examples', await this.getReactionExamplesGrid());
|
|
194
189
|
reactionsGridDiv.style.width = '50%';
|
|
195
190
|
reactionExamples.style.width = '50%';
|
|
@@ -215,6 +210,17 @@ export class RulesManager {
|
|
|
215
210
|
inputsTabControl.root,
|
|
216
211
|
]);
|
|
217
212
|
|
|
213
|
+
const saveButton = ui.bigButton('Save', () => { this.save(); });
|
|
214
|
+
const addButton = ui.button('Add rule', () => {
|
|
215
|
+
const currentTab = inputsTabControl.currentPane.name;
|
|
216
|
+
if (currentTab == TAB_LINKS)
|
|
217
|
+
this.linkRuleDataFrame.rows.addNew();
|
|
218
|
+
else if (currentTab == TAB_REACTIONS)
|
|
219
|
+
this.synthRuleDataFrame.rows.addNew();
|
|
220
|
+
});
|
|
221
|
+
const topPanel = [saveButton, addButton];
|
|
222
|
+
this.v!.setRibbonPanels([topPanel]);
|
|
223
|
+
|
|
218
224
|
panel.style.height = '100%';
|
|
219
225
|
panel.style.alignItems = 'center';
|
|
220
226
|
|
|
@@ -8,7 +8,7 @@ import {Unsubscribable} from 'rxjs';
|
|
|
8
8
|
import {getHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
|
|
9
9
|
import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
|
|
10
10
|
import {ALPHABET, NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
11
|
-
import {getSeqHelper, ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
11
|
+
import {getSeqHelper, ISeqHelper, ToAtomicLevelRes} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
12
12
|
import {MmcrTemps} from '@datagrok-libraries/bio/src/utils/cell-renderer-consts';
|
|
13
13
|
import {addMonomerHoverLink, buildMonomerHoverLink} from '@datagrok-libraries/bio/src/monomer-works/monomer-hover';
|
|
14
14
|
import {getRdKitModule} from '@datagrok-libraries/bio/src/chem/rdkit-module';
|
|
@@ -23,7 +23,8 @@ import {getEnumerationChem, PT_CHEM_EXAMPLE} from './pt-enumeration-chem';
|
|
|
23
23
|
|
|
24
24
|
import {
|
|
25
25
|
PT_ERROR_DATAFRAME, PT_UI_ADD_HELM, PT_UI_DIALOG_CONVERSION, PT_UI_DIALOG_ENUMERATION,
|
|
26
|
-
PT_UI_GET_HELM,
|
|
26
|
+
PT_UI_GET_HELM, PT_UI_LINEARIZE, PT_UI_LINEARIZE_TT,
|
|
27
|
+
PT_UI_HIGHLIGHT_MONOMERS, PT_UI_RULES_USED, PT_UI_USE_CHIRALITY
|
|
27
28
|
} from './const';
|
|
28
29
|
|
|
29
30
|
import {_package} from '../package';
|
|
@@ -33,12 +34,13 @@ import {MonomerMap} from '@datagrok-libraries/bio/src/monomer-works/types';
|
|
|
33
34
|
import {ISeqMonomer} from '@datagrok-libraries/bio/src/helm/types';
|
|
34
35
|
import wu from 'wu';
|
|
35
36
|
import {PolymerTypes} from '@datagrok-libraries/js-draw-lite/src/types/org';
|
|
36
|
-
import {getMonomersDictFromLib} from '@datagrok-libraries/bio/src/monomer-works/to-atomic-level';
|
|
37
|
+
import {_toAtomicLevel, getMonomersDictFromLib} from '@datagrok-libraries/bio/src/monomer-works/to-atomic-level';
|
|
37
38
|
import {monomerSeqToMolfile} from '@datagrok-libraries/bio/src/monomer-works/to-atomic-level-utils';
|
|
38
39
|
import {LRUCache} from 'lru-cache';
|
|
39
40
|
import {getMonomerHover, ISubstruct, setMonomerHover} from '@datagrok-libraries/chem-meta/src/types';
|
|
40
41
|
import {getMolHighlight} from '@datagrok-libraries/bio/src/monomer-works/seq-to-molfile';
|
|
41
42
|
import {ChemTags} from '@datagrok-libraries/chem-meta/src/consts';
|
|
43
|
+
import {getMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
|
|
42
44
|
|
|
43
45
|
type PolyToolConvertSerialized = {
|
|
44
46
|
generateHelm: boolean;
|
|
@@ -99,6 +101,9 @@ export async function getPolyToolConvertDialog(srcCol?: DG.Column): Promise<DG.D
|
|
|
99
101
|
const generateHelmInput = ui.input.bool(PT_UI_GET_HELM, {value: true});
|
|
100
102
|
ui.tooltip.bind(generateHelmInput.root, PT_UI_ADD_HELM);
|
|
101
103
|
|
|
104
|
+
const linearizeInput = ui.input.bool(PT_UI_LINEARIZE, {value: true});
|
|
105
|
+
ui.tooltip.bind(linearizeInput.root, PT_UI_LINEARIZE_TT);
|
|
106
|
+
|
|
102
107
|
const chiralityEngineInput = ui.input.bool(PT_UI_USE_CHIRALITY, {value: true});
|
|
103
108
|
const highlightMonomersInput = ui.input.bool(PT_UI_HIGHLIGHT_MONOMERS, {value: true});
|
|
104
109
|
let ruleFileList: string[];
|
|
@@ -112,6 +117,7 @@ export async function getPolyToolConvertDialog(srcCol?: DG.Column): Promise<DG.D
|
|
|
112
117
|
const div = ui.divV([
|
|
113
118
|
srcColInput,
|
|
114
119
|
generateHelmInput,
|
|
120
|
+
linearizeInput,
|
|
115
121
|
chiralityEngineInput,
|
|
116
122
|
highlightMonomersInput,
|
|
117
123
|
rulesHeader,
|
|
@@ -121,7 +127,10 @@ export async function getPolyToolConvertDialog(srcCol?: DG.Column): Promise<DG.D
|
|
|
121
127
|
const exec = async (): Promise<void> => {
|
|
122
128
|
try {
|
|
123
129
|
const ruleFileList = await ruleInputs.getActive();
|
|
124
|
-
await polyToolConvert(
|
|
130
|
+
await polyToolConvert(
|
|
131
|
+
srcColInput.value!, generateHelmInput.value!, linearizeInput.value!,
|
|
132
|
+
chiralityEngineInput.value!, highlightMonomersInput.value!, ruleFileList
|
|
133
|
+
);
|
|
125
134
|
} catch (err: any) {
|
|
126
135
|
defaultErrorHandler(err);
|
|
127
136
|
}
|
|
@@ -261,8 +270,8 @@ function dealGroups(col: DG.Column<string>): void {
|
|
|
261
270
|
}
|
|
262
271
|
|
|
263
272
|
/** Returns Helm and molfile columns. */
|
|
264
|
-
export async function polyToolConvert(
|
|
265
|
-
|
|
273
|
+
export async function polyToolConvert(seqCol: DG.Column<string>,
|
|
274
|
+
generateHelm: boolean, linearize: boolean, chiralityEngine: boolean, highlight: boolean, ruleFiles: string[]
|
|
266
275
|
): Promise<[DG.Column, DG.Column]> {
|
|
267
276
|
const pi = DG.TaskBarProgressIndicator.create('PolyTool converting...');
|
|
268
277
|
try {
|
|
@@ -274,7 +283,7 @@ export async function polyToolConvert(
|
|
|
274
283
|
|
|
275
284
|
const table = seqCol.dataFrame;
|
|
276
285
|
const rules = await getRules(ruleFiles);
|
|
277
|
-
const resList = doPolyToolConvert(seqCol.toList(), rules, helmHelper);
|
|
286
|
+
const [resList, isLinear] = doPolyToolConvert(seqCol.toList(), rules, helmHelper);
|
|
278
287
|
|
|
279
288
|
const resHelmColName = getUnusedName(table, `transformed(${seqCol.name})`);
|
|
280
289
|
const resHelmCol = DG.Column.fromType(DG.COLUMN_TYPE.STRING, resHelmColName, resList.length)
|
|
@@ -284,15 +293,53 @@ export async function polyToolConvert(
|
|
|
284
293
|
resHelmCol.setTag(DG.TAGS.CELL_RENDERER, 'helm');
|
|
285
294
|
if (generateHelm && table) table.columns.add(resHelmCol, true);
|
|
286
295
|
|
|
287
|
-
|
|
296
|
+
|
|
288
297
|
const rdKitModule: RDModule = await getRdKitModule();
|
|
289
298
|
const lib = await getOverriddenLibrary(rules);
|
|
290
299
|
const resHelmColTemp = resHelmCol.temp;
|
|
291
300
|
resHelmColTemp[MmcrTemps.overriddenLibrary] = lib;
|
|
292
301
|
resHelmCol.temp = resHelmColTemp;
|
|
302
|
+
|
|
303
|
+
const seqHelper: ISeqHelper = await getSeqHelper();
|
|
293
304
|
const toAtomicLevelRes =
|
|
294
|
-
await seqHelper.helmToAtomicLevel(resHelmCol, chiralityEngine,
|
|
305
|
+
await seqHelper.helmToAtomicLevel(resHelmCol, chiralityEngine, highlight, lib);
|
|
306
|
+
|
|
295
307
|
const resMolCol = toAtomicLevelRes.molCol!;
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
const allLinear = isLinear.filter((l) => l).length;
|
|
311
|
+
if (linearize && allLinear > 0) {
|
|
312
|
+
const lin = new Array<string>(allLinear);
|
|
313
|
+
let counter = 0;
|
|
314
|
+
for (let i = 0; i < isLinear.length; i++) {
|
|
315
|
+
if (isLinear[i]) {
|
|
316
|
+
lin[counter] = resList[i];
|
|
317
|
+
counter++;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const linCol = DG.Column.fromStrings('helm', lin);
|
|
322
|
+
linCol.semType = DG.SEMTYPE.MACROMOLECULE;
|
|
323
|
+
linCol.meta.units = NOTATION.HELM;
|
|
324
|
+
linCol.setTag(DG.TAGS.CELL_RENDERER, 'helm');
|
|
325
|
+
|
|
326
|
+
const monomerLibHelper = await getMonomerLibHelper();
|
|
327
|
+
const systemMonomerLib = monomerLibHelper.getMonomerLib();
|
|
328
|
+
let linear: ToAtomicLevelRes | null = null;
|
|
329
|
+
try {
|
|
330
|
+
linear = await _toAtomicLevel(DG.DataFrame.create(0), linCol, systemMonomerLib, seqHelper, rdKitModule);
|
|
331
|
+
counter = 0;
|
|
332
|
+
for (let i = 0; i < isLinear.length; i++) {
|
|
333
|
+
if (isLinear[i]) {
|
|
334
|
+
resMolCol.set(i, linear!.molCol!.get(counter));
|
|
335
|
+
counter++;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
} catch (e: any) {
|
|
339
|
+
grok.shell.warning('PolyTool was not able to linearize sequences');
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
296
343
|
dealGroups(resMolCol);
|
|
297
344
|
resMolCol.name = getUnusedName(table, `molfile(${seqCol.name})`);
|
|
298
345
|
resMolCol.semType = DG.SEMTYPE.MOLECULE;
|