@datagrok/sequence-translator 1.3.4 → 1.3.9
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 +33 -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/data-manager.ts +4 -1
- package/src/apps/pattern/model/translator.ts +45 -8
- 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 +7 -9
- package/src/apps/pattern/view/components/numeric-label-visibility-controls.ts +4 -5
- 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/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 +106 -17
- 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 -127
|
@@ -3,11 +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 {
|
|
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';
|
|
11
20
|
|
|
12
21
|
const PT_ERROR_DATAFRAME = 'No dataframe with macromolecule columns open';
|
|
13
22
|
const PT_WARNING_COLUMN = 'No marcomolecule column chosen!';
|
|
@@ -24,15 +33,15 @@ export async function getPolyToolConversionDialog(): Promise<DG.Dialog> {
|
|
|
24
33
|
if (!targetColumns)
|
|
25
34
|
throw new Error(PT_ERROR_DATAFRAME);
|
|
26
35
|
|
|
27
|
-
const targetColumnInput = ui.
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
);
|
|
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
|
+
});
|
|
31
40
|
|
|
32
|
-
const generateHelmChoiceInput = ui.
|
|
41
|
+
const generateHelmChoiceInput = ui.input.bool(PT_UI_GET_HELM, {value: true});
|
|
33
42
|
ui.tooltip.bind(generateHelmChoiceInput.root, PT_UI_ADD_HELM);
|
|
34
43
|
|
|
35
|
-
const chiralityEngineInput = ui.
|
|
44
|
+
const chiralityEngineInput = ui.input.bool(PT_UI_USE_CHIRALITY, {value: false});
|
|
36
45
|
const ruleInputs = new RuleInputs(RULES_PATH, RULES_STORAGE_NAME, '.json');
|
|
37
46
|
const rulesHeader = ui.inlineText([PT_UI_RULES_USED]);
|
|
38
47
|
ui.tooltip.bind(rulesHeader, 'Add or specify rules to use');
|
|
@@ -73,42 +82,122 @@ export async function getPolyToolConversionDialog(): Promise<DG.Dialog> {
|
|
|
73
82
|
return dialog;
|
|
74
83
|
}
|
|
75
84
|
|
|
76
|
-
export async function
|
|
77
|
-
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;
|
|
78
90
|
|
|
79
|
-
const
|
|
80
|
-
const screenLibrary = ui.
|
|
91
|
+
const helmInput = helmHelper.createHelmInput('Macromolecule', {value: helmValue});
|
|
92
|
+
const screenLibrary = ui.input.choice('Library to use', {value: null, items: libList});
|
|
81
93
|
|
|
94
|
+
helmInput.input.setAttribute('style', `min-width:250px!important;`);
|
|
82
95
|
screenLibrary.input.setAttribute('style', `min-width:250px!important;`);
|
|
83
96
|
|
|
84
97
|
const div = ui.div([
|
|
85
|
-
helmInput.
|
|
98
|
+
helmInput.root,
|
|
86
99
|
screenLibrary.root
|
|
87
100
|
]);
|
|
88
101
|
|
|
102
|
+
// Displays the molecule from a current cell (monitors changes)
|
|
103
|
+
const cccSubs = grok.events.onCurrentCellChanged.subscribe(() => {
|
|
104
|
+
const cell = grok.shell.tv.dataFrame.currentCell;
|
|
105
|
+
|
|
106
|
+
if (cell.column.semType === DG.SEMTYPE.MACROMOLECULE && cell.column.meta.units === NOTATION.HELM)
|
|
107
|
+
helmInput.stringValue = cell.value;
|
|
108
|
+
});
|
|
109
|
+
|
|
89
110
|
const dialog = ui.dialog(PT_UI_DIALOG_ENUMERATION)
|
|
90
111
|
.add(div)
|
|
91
112
|
.onOK(async () => {
|
|
92
113
|
try {
|
|
93
|
-
const helmString = helmInput.
|
|
94
|
-
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();
|
|
95
118
|
if (helmString === undefined || helmString === '') {
|
|
96
119
|
grok.shell.warning('PolyTool: no molecule was provided');
|
|
97
120
|
} else if (helmSelections === undefined || helmSelections.length < 1) {
|
|
98
121
|
grok.shell.warning('PolyTool: no selection was provided');
|
|
99
122
|
} else {
|
|
100
|
-
const molecules = await
|
|
123
|
+
const molecules = await getEnumerationHelm(helmString, helmSelections, screenLibrary.value!);
|
|
101
124
|
const molCol = DG.Column.fromStrings('Enumerated', molecules);
|
|
102
125
|
const df = DG.DataFrame.fromColumns([molCol]);
|
|
103
126
|
grok.shell.addTableView(df);
|
|
104
127
|
}
|
|
105
128
|
} catch (err: any) {
|
|
106
|
-
|
|
129
|
+
defaultErrorHandler(err);
|
|
107
130
|
} finally {
|
|
108
|
-
|
|
131
|
+
cccSubs.unsubscribe();
|
|
109
132
|
}
|
|
110
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});
|
|
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
|
+
]);
|
|
111
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);
|
|
196
|
+
} finally {
|
|
197
|
+
cccSubs.unsubscribe();
|
|
198
|
+
}
|
|
199
|
+
}).onCancel(() => {
|
|
200
|
+
cccSubs.unsubscribe();
|
|
112
201
|
});
|
|
113
202
|
|
|
114
203
|
return dialog;
|
|
@@ -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
|
+
}
|
package/webpack.config.js
CHANGED
|
@@ -2,9 +2,7 @@ const path = require('path');
|
|
|
2
2
|
const packageName = path.parse(require('./package.json').name).name.toLowerCase().replace(/-/g, '');
|
|
3
3
|
|
|
4
4
|
module.exports = {
|
|
5
|
-
cache: {
|
|
6
|
-
type: 'filesystem',
|
|
7
|
-
},
|
|
5
|
+
cache: {type: 'filesystem'},
|
|
8
6
|
mode: 'development',
|
|
9
7
|
entry: {
|
|
10
8
|
package: ['./src/package.ts'],
|
|
@@ -12,7 +10,7 @@ module.exports = {
|
|
|
12
10
|
filename: 'package-test.js',
|
|
13
11
|
library: {type: 'var', name: `${packageName}_test`},
|
|
14
12
|
import: './src/package-test.ts',
|
|
15
|
-
}
|
|
13
|
+
},
|
|
16
14
|
},
|
|
17
15
|
resolve: {
|
|
18
16
|
extensions: ['.ts', '.tsx', '.wasm', '.mjs', '.js', '.json'],
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import * as ui from 'datagrok-api/ui';
|
|
2
|
-
import * as grok from 'datagrok-api/grok';
|
|
3
|
-
|
|
4
|
-
import {IHelmHelper, getHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
|
|
5
|
-
import {IHelmWebEditor} from '@datagrok-libraries/bio/src/helm/types';
|
|
6
|
-
import '@datagrok-libraries/bio/src/types/helm';
|
|
7
|
-
import '@datagrok-libraries/bio/src/types/jsdraw2';
|
|
8
|
-
import * as org from 'org';
|
|
9
|
-
import $ from 'cash-dom';
|
|
10
|
-
import {Unsubscribable, fromEvent} from 'rxjs';
|
|
11
|
-
import {IMonomerLibFileManager, IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
|
|
12
|
-
|
|
13
|
-
import {Chain} from './pt-conversion';
|
|
14
|
-
|
|
15
|
-
const LIB_PATH = 'System:AppData/Bio/monomer-libraries/';
|
|
16
|
-
const PT_HELM_EXAMPLE = 'PEPTIDE1{[R].[F].[T].[G].[H].[F].[G].[A].[A].[Y].[P].[E].[NH2]}$$$$';
|
|
17
|
-
|
|
18
|
-
export async function getLibrariesList(): Promise<string[]> {
|
|
19
|
-
const monomerLibHelper: IMonomerLibHelper = await grok.functions.call('Bio:getMonomerLibHelper', {});
|
|
20
|
-
const monomerFileManager: IMonomerLibFileManager = await monomerLibHelper.getFileManager();
|
|
21
|
-
return monomerFileManager.getValidLibraryPaths();
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export async function getEnumeration(helmString: string, helmSelections: number[], screenLibrary: string):
|
|
25
|
-
Promise<string[]> {
|
|
26
|
-
const variableMonomers = await getAvaialableMonomers(screenLibrary);
|
|
27
|
-
const chain: Chain = Chain.fromHelm(helmString);
|
|
28
|
-
const size = helmSelections.length*variableMonomers.length;
|
|
29
|
-
const enumerations = new Array<string>(size);
|
|
30
|
-
|
|
31
|
-
for (let i = 0; i < helmSelections.length; i++) {
|
|
32
|
-
for (let j = 0; j < variableMonomers.length; j++)
|
|
33
|
-
enumerations[i*variableMonomers.length + j] = chain.getHelmChanged(helmSelections[i], variableMonomers[j]);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return enumerations;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export class HelmInput {
|
|
40
|
-
webEditorHost: HTMLDivElement | null;
|
|
41
|
-
webEditorApp: org.helm.IWebEditorApp | null;
|
|
42
|
-
helmHelper: IHelmHelper;
|
|
43
|
-
editor: IHelmWebEditor;
|
|
44
|
-
subs: Unsubscribable[];
|
|
45
|
-
|
|
46
|
-
helmString: string = PT_HELM_EXAMPLE;
|
|
47
|
-
helmSelection: number[];
|
|
48
|
-
|
|
49
|
-
constructor(
|
|
50
|
-
helmHelper: IHelmHelper, editor: IHelmWebEditor) {
|
|
51
|
-
this.helmHelper = helmHelper;
|
|
52
|
-
this.editor = editor;
|
|
53
|
-
|
|
54
|
-
this.webEditorHost = null;
|
|
55
|
-
this.webEditorApp = null;
|
|
56
|
-
const subs: Unsubscribable[] = [];
|
|
57
|
-
|
|
58
|
-
subs.push(fromEvent<MouseEvent>(editor.host, 'click').subscribe(() => {
|
|
59
|
-
this.webEditorHost = ui.div();
|
|
60
|
-
//TODO: use not hh, but anything from editor.getHelm(true)
|
|
61
|
-
this.webEditorApp = helmHelper.createWebEditorApp(this.webEditorHost, this.getHelmString());
|
|
62
|
-
const dlg = ui.dialog({showHeader: false, showFooter: true})
|
|
63
|
-
.add(this.webEditorHost!)
|
|
64
|
-
.onOK(() => {
|
|
65
|
-
try {
|
|
66
|
-
const webEditorValue = this.webEditorApp!.canvas.getHelm(true)
|
|
67
|
-
.replace(/<\/span>/g, '').replace(/<span style='background:#bbf;'>/g, '');
|
|
68
|
-
editor.editor.setHelm(webEditorValue);
|
|
69
|
-
this.helmString = webEditorValue;
|
|
70
|
-
this.helmSelection = [];
|
|
71
|
-
|
|
72
|
-
//@ts-ignore
|
|
73
|
-
const selection = this.webEditorApp?.canvas.helm.jsd.m.atoms;
|
|
74
|
-
for (let i = 0; i < selection.length; i++) {
|
|
75
|
-
if (selection[i].selected)
|
|
76
|
-
this.helmSelection.push(i);
|
|
77
|
-
}
|
|
78
|
-
} catch (err: any) {
|
|
79
|
-
//this.logger.error(err);
|
|
80
|
-
} finally {
|
|
81
|
-
$(this.webEditorHost).empty();
|
|
82
|
-
this.webEditorHost = null;
|
|
83
|
-
this.webEditorApp = null;
|
|
84
|
-
}
|
|
85
|
-
})
|
|
86
|
-
.onCancel(() => {
|
|
87
|
-
$(this.webEditorHost).empty();
|
|
88
|
-
this.webEditorHost = null;
|
|
89
|
-
this.webEditorApp = null;
|
|
90
|
-
})
|
|
91
|
-
.show({modal: true, fullScreen: true});
|
|
92
|
-
}));
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
static async init() {
|
|
96
|
-
const helmHelper = await getHelmHelper();
|
|
97
|
-
|
|
98
|
-
const editor = helmHelper.createHelmWebEditor();
|
|
99
|
-
editor.host.style.width = '200px';
|
|
100
|
-
editor.host.style.height = '100px';
|
|
101
|
-
editor.host.style.paddingLeft = '40px';
|
|
102
|
-
editor.editor.setHelm(PT_HELM_EXAMPLE);
|
|
103
|
-
|
|
104
|
-
return new HelmInput(helmHelper, editor);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
getHelmString(): string {
|
|
108
|
-
return this.helmString;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
getHelmSelections() {
|
|
112
|
-
return this.helmSelection;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
getDiv(): HTMLDivElement {
|
|
116
|
-
const title = ui.divText('Macromolecule', {style: {paddingTop: '43px', color: 'var(--grey-4)'}});
|
|
117
|
-
|
|
118
|
-
return ui.divH([title, this.editor.host], {style: {paddingLeft: '48px'}});
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
async function getAvaialableMonomers(screenLibrary: string): Promise<string[]> {
|
|
123
|
-
const monomerLibHelper: IMonomerLibHelper = await grok.functions.call('Bio:getMonomerLibHelper', {});
|
|
124
|
-
const monomerLib = await monomerLibHelper.readLibrary(LIB_PATH, screenLibrary);
|
|
125
|
-
//NOTICE: works with Peptides only
|
|
126
|
-
return monomerLib.getMonomerSymbolsByType('PEPTIDE');
|
|
127
|
-
}
|