@datagrok/sequence-translator 1.3.15 → 1.4.1
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 +7 -1
- package/dist/package-test.js.map +1 -1
- package/dist/package.js +1 -1
- package/dist/package.js.map +1 -1
- package/package.json +3 -3
- package/src/apps/common/view/components/colored-input/colored-text-input.ts +1 -1
- package/src/apps/common/view/components/colored-input/style.css +2 -3
- package/src/apps/pattern/view/components/right-section.ts +6 -3
- package/src/apps/structure/view/ui.ts +9 -6
- package/src/apps/translator/view/style.css +0 -4
- package/src/apps/translator/view/ui.ts +10 -7
- package/src/demo/demo-st-ui.ts +1 -1
- package/src/polytool/pt-conversion.ts +1 -3
- package/src/polytool/pt-convert-editor.ts +8 -8
- package/src/polytool/pt-dialog.ts +1 -3
- package/src/polytool/pt-enumeration-chem.ts +6 -10
- package/src/polytool/pt-enumeration-helm-dialog.ts +5 -5
- package/src/polytool/pt-placeholders-input.ts +1 -1
- package/src/tests/polytool-enumerate-tests.ts +12 -12
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datagrok/sequence-translator",
|
|
3
3
|
"friendlyName": "Sequence Translator",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.4.1",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Alexey Choposky",
|
|
7
7
|
"email": "achopovsky@datagrok.ai"
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
}
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@datagrok-libraries/bio": "^5.42.
|
|
25
|
+
"@datagrok-libraries/bio": "^5.42.15",
|
|
26
26
|
"@datagrok-libraries/chem-meta": "^1.2.5",
|
|
27
27
|
"@datagrok-libraries/tutorials": "^1.4.0",
|
|
28
28
|
"@datagrok-libraries/utils": "^4.3.0",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@datagrok-libraries/helm-web-editor": "^1.1.11",
|
|
43
43
|
"@datagrok-libraries/js-draw-lite": "^0.0.8",
|
|
44
|
-
"@datagrok/bio": "^2.15.
|
|
44
|
+
"@datagrok/bio": "^2.15.1",
|
|
45
45
|
"@datagrok/helm": "^2.5.0",
|
|
46
46
|
"@datagrok/chem": "^1.12.0",
|
|
47
47
|
"@types/jquery": "^3.5.14",
|
|
@@ -19,7 +19,7 @@ export class ColoredTextInput {
|
|
|
19
19
|
/** Resize, no scrolls */
|
|
20
20
|
resizeable: boolean = true
|
|
21
21
|
) {
|
|
22
|
-
$(this.root).addClass('colored-text-input');
|
|
22
|
+
$(this.root).addClass('st-colored-text-input');
|
|
23
23
|
if (resizeable) {
|
|
24
24
|
// make input field automatically resizeable
|
|
25
25
|
this.textInputBase.onChanged.subscribe(
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
.colored-text-input > textarea {
|
|
1
|
+
.st-colored-text-input > textarea {
|
|
2
2
|
width: 100%;
|
|
3
3
|
-webkit-text-fill-color: transparent;
|
|
4
4
|
background-color: transparent;
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
height: 22px; /* Fine tuned value to avoid "jumping" of the textarea upon autoresize */
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
.colored-text-input > div {
|
|
11
|
+
.st-colored-text-input > div {
|
|
12
12
|
/* The values here are fine tuned to those of the ui.input textarea in order
|
|
13
13
|
* to achieve precise overlap */
|
|
14
14
|
overflow: auto;
|
|
@@ -25,5 +25,4 @@
|
|
|
25
25
|
color: transparent;
|
|
26
26
|
white-space: pre-wrap;
|
|
27
27
|
word-wrap: break-word;
|
|
28
|
-
padding-left: 35px;
|
|
29
28
|
}
|
|
@@ -96,10 +96,10 @@ export class PatternAppRightSection {
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
const message = ui.divV([
|
|
99
|
-
ui.divText(`Author: ${author}`),
|
|
100
99
|
ui.divText(`Pattern Name: ${patternName}`),
|
|
101
|
-
ui.divText(`
|
|
102
|
-
ui.divText(`
|
|
100
|
+
ui.divText(`Author: ${author}`),
|
|
101
|
+
ui.divText(`Created: ${getInfoTimestamp(new Date(createDate))}`),
|
|
102
|
+
ui.divText(`Modified: ${getInfoTimestamp(new Date(modifyDate))}`),
|
|
103
103
|
]);
|
|
104
104
|
grok.shell.info(message);
|
|
105
105
|
}
|
|
@@ -195,3 +195,6 @@ class OverwritePatternDialog {
|
|
|
195
195
|
}
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
+
function getInfoTimestamp(date: Date): string {
|
|
199
|
+
return date.toLocaleString().split(':').slice(0, -1).join(':');
|
|
200
|
+
}
|
|
@@ -33,7 +33,15 @@ class StructureAppLayout {
|
|
|
33
33
|
this.onInvalidInput = new rxjs.Subject<string>();
|
|
34
34
|
this.inputBase = Object.fromEntries(
|
|
35
35
|
STRANDS.map(
|
|
36
|
-
(key) =>
|
|
36
|
+
(key) => {
|
|
37
|
+
const input = ui.input.textArea(key.toUpperCase(), {value: '', onValueChanged: () => {
|
|
38
|
+
this.onInput.next();
|
|
39
|
+
// WARNING: this fine tuning is necessary to fix layout within ui.form
|
|
40
|
+
// js-api version ^1.21
|
|
41
|
+
$(input.root.getElementsByTagName('div')).css('padding-left', '38px');
|
|
42
|
+
}});
|
|
43
|
+
return [key, input];
|
|
44
|
+
}
|
|
37
45
|
)
|
|
38
46
|
);
|
|
39
47
|
this.useChiralInput = ui.input.bool('Use chiral', {value: true});
|
|
@@ -165,11 +173,6 @@ class StructureAppLayout {
|
|
|
165
173
|
}
|
|
166
174
|
|
|
167
175
|
private getMolfile(ss: StrandData, as: StrandData, as2: StrandData): string {
|
|
168
|
-
// if (ss.strand === '' && (as.strand !== '' || as2.strand !== '')) {
|
|
169
|
-
// this.onInvalidInput.next();
|
|
170
|
-
// return '';
|
|
171
|
-
// }
|
|
172
|
-
|
|
173
176
|
return getLinkedMolfile(ss, as, as2, this.useChiralInput.value!, this.th);
|
|
174
177
|
}
|
|
175
178
|
|
|
@@ -10,8 +10,6 @@ import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
|
10
10
|
|
|
11
11
|
import {DEFAULT_FORMATS} from '../../common/model/const';
|
|
12
12
|
import {download} from '../../common/model/helpers';
|
|
13
|
-
import {FormatDetector} from '../../common/model/parsing-validation/format-detector';
|
|
14
|
-
import {SequenceValidator} from '../../common/model/parsing-validation/sequence-validator';
|
|
15
13
|
import {ColoredTextInput} from '../../common/view/components/colored-input/colored-text-input';
|
|
16
14
|
import {highlightInvalidSubsequence} from '../../common/view/components/colored-input/input-painters';
|
|
17
15
|
import {MoleculeImage} from '../../common/view/components/molecule-img';
|
|
@@ -20,11 +18,11 @@ import {IsolatedAppUIBase} from '../../common/view/isolated-app-ui';
|
|
|
20
18
|
import {MonomerLibViewer} from '../../common/view/monomer-lib-viewer';
|
|
21
19
|
import {SequenceToMolfileConverter} from '../../structure/model/sequence-to-molfile';
|
|
22
20
|
import {convert, getSupportedTargetFormats, getTranslatedSequences} from '../model/conversion-utils';
|
|
23
|
-
import {FormatConverter} from '../model/format-converter';
|
|
24
21
|
import {ITranslationHelper} from '../../../types';
|
|
25
22
|
|
|
26
23
|
import {NUCLEOTIDES_FORMAT, SEQUENCE_COPIED_MSG, SEQ_TOOLTIP_MSG} from './const';
|
|
27
24
|
import './style.css';
|
|
25
|
+
import $ from 'cash-dom';
|
|
28
26
|
import {_package} from '../../../package';
|
|
29
27
|
|
|
30
28
|
const enum REQUIRED_COLUMN_LABEL {
|
|
@@ -55,7 +53,12 @@ class TranslatorAppLayout {
|
|
|
55
53
|
await this.updateMolImg();
|
|
56
54
|
}
|
|
57
55
|
});
|
|
58
|
-
|
|
56
|
+
|
|
57
|
+
$(this.formatChoiceInput.root.getElementsByTagName('select')[0]).css('width', '20%');
|
|
58
|
+
|
|
59
|
+
this.sequenceInputBase = ui.input.textArea(
|
|
60
|
+
'', {value: DEFAULT_AXOLABS_INPUT, onValueChanged: () => { this.onInput.next(); }}
|
|
61
|
+
);
|
|
59
62
|
|
|
60
63
|
this.init();
|
|
61
64
|
|
|
@@ -457,9 +460,9 @@ class ColumnInputsManager {
|
|
|
457
460
|
this.selectColumnIfTableNotNull(selectedTable, selectedColumnName, columnLabel);
|
|
458
461
|
|
|
459
462
|
const input = ui.input.choice(`${columnLabel}`, {
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
+
value: selectedColumnName, items: columnNames,
|
|
464
|
+
onValueChanged: (value) => this.selectColumnIfTableNotNull(selectedTable, value, columnLabel)
|
|
465
|
+
}
|
|
463
466
|
);
|
|
464
467
|
|
|
465
468
|
return input;
|
package/src/demo/demo-st-ui.ts
CHANGED
|
@@ -24,7 +24,7 @@ export async function demoOligoStructureUI() {
|
|
|
24
24
|
await tryCatch(async () => {
|
|
25
25
|
async function setInputValue(idx: number, sequence: string): Promise<void> {
|
|
26
26
|
await delay(500);
|
|
27
|
-
const textInputs: NodeListOf<HTMLTextAreaElement> = document.querySelectorAll('.colored-text-input > textarea');
|
|
27
|
+
const textInputs: NodeListOf<HTMLTextAreaElement> = document.querySelectorAll('.st-colored-text-input > textarea');
|
|
28
28
|
const textarea = textInputs[idx];
|
|
29
29
|
textarea.value = sequence;
|
|
30
30
|
const event = new Event('input');
|
|
@@ -269,9 +269,7 @@ export class Chain {
|
|
|
269
269
|
export function doPolyToolConvert(sequences: string[], rules: Rules): string[] {
|
|
270
270
|
const helms = new Array<string>(sequences.length);
|
|
271
271
|
for (let i = 0; i < sequences.length; i++) {
|
|
272
|
-
if (sequences[i] === undefined)
|
|
273
|
-
helms[i] = '';
|
|
274
|
-
else {
|
|
272
|
+
if (sequences[i] === undefined) { helms[i] = ''; } else {
|
|
275
273
|
const chain = Chain.fromNotation(sequences[i], rules);
|
|
276
274
|
helms[i] = chain.getHelm();
|
|
277
275
|
}
|
|
@@ -74,14 +74,14 @@ export class PolyToolConvertFuncEditor {
|
|
|
74
74
|
|
|
75
75
|
public async showDialog(): Promise<DG.Column<string>> {
|
|
76
76
|
const formDiv = ui.div([
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
77
|
+
this.inputs.table,
|
|
78
|
+
this.inputs.seqCol,
|
|
79
|
+
this.inputs.generateHelm,
|
|
80
|
+
this.inputs.chiralityEngine,
|
|
81
|
+
this.inputs.rules.header,
|
|
82
|
+
this.inputs.rules.form,
|
|
83
|
+
],
|
|
84
|
+
{style: {minWidth: '320px'}});
|
|
85
85
|
|
|
86
86
|
return new Promise((resolve, reject) => {
|
|
87
87
|
ui.dialog({title: PT_UI_DIALOG_CONVERSION})
|
|
@@ -3,7 +3,6 @@ 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 $ from 'cash-dom';
|
|
7
6
|
import {Unsubscribable} from 'rxjs';
|
|
8
7
|
|
|
9
8
|
import {getHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
|
|
@@ -110,7 +109,6 @@ async function getPolyToolEnumerationChemDialog(cell?: DG.Cell): Promise<DG.Dial
|
|
|
110
109
|
for (const sub of subs) sub.unsubscribe();
|
|
111
110
|
};
|
|
112
111
|
try {
|
|
113
|
-
|
|
114
112
|
const [libList, helmHelper] = await Promise.all([
|
|
115
113
|
getLibrariesList(), getHelmHelper()]);
|
|
116
114
|
|
|
@@ -209,7 +207,7 @@ export async function polyToolConvert(
|
|
|
209
207
|
|
|
210
208
|
const resHelmColName = getUnusedName(table, `transformed(${seqCol.name})`);
|
|
211
209
|
const resHelmCol = DG.Column.fromType(DG.COLUMN_TYPE.STRING, resHelmColName, resList.length)
|
|
212
|
-
.init((rowIdx: number) => { return resList[rowIdx];});
|
|
210
|
+
.init((rowIdx: number) => { return resList[rowIdx]; });
|
|
213
211
|
resHelmCol.semType = DG.SEMTYPE.MACROMOLECULE;
|
|
214
212
|
resHelmCol.meta.units = NOTATION.HELM;
|
|
215
213
|
resHelmCol.setTag(DG.TAGS.CELL_RENDERER, 'helm');
|
|
@@ -60,12 +60,11 @@ M END`;
|
|
|
60
60
|
|
|
61
61
|
export async function getEnumerationChem(molString: string, screenLibrary: string):
|
|
62
62
|
Promise<string[]> {
|
|
63
|
-
|
|
64
63
|
const variableMonomers = await getAvailableMonomers(screenLibrary);
|
|
65
64
|
const variableMols = await getAvailableMonomerMols(screenLibrary);
|
|
66
65
|
const enumerations = new Array<string>(variableMonomers.length);
|
|
67
66
|
|
|
68
|
-
|
|
67
|
+
const rdkitModule: RDModule = await grok.functions.call('Chem:getRdKitModule');
|
|
69
68
|
const molScaffold: RDMol = rdkitModule.get_mol(molString);
|
|
70
69
|
const smiScaffold = molScaffold.get_smiles();
|
|
71
70
|
molScaffold.delete();
|
|
@@ -73,7 +72,6 @@ export async function getEnumerationChem(molString: string, screenLibrary: strin
|
|
|
73
72
|
const smilesSubsts = new Array<string>(variableMonomers.length);
|
|
74
73
|
|
|
75
74
|
for (let i = 0; i < variableMonomers.length; i++) {
|
|
76
|
-
|
|
77
75
|
const name = variableMonomers[i];
|
|
78
76
|
const molBlock = variableMols[name];
|
|
79
77
|
const molSubst: RDMol = rdkitModule.get_mol(molBlock);
|
|
@@ -87,18 +85,16 @@ export async function getEnumerationChem(molString: string, screenLibrary: strin
|
|
|
87
85
|
//TODO: use RDKit linking function when exposed
|
|
88
86
|
const smiResRaw = `${smiScaffold}.${smilesSubsts[i]}`.replaceAll('[1*]C', 'C([1*])').replaceAll('[1*]c', 'c([1*])').replaceAll('[1*]O', 'O([1*])').replaceAll('[1*]N', 'N([1*])');
|
|
89
87
|
const smiRes = `${smiResRaw}`.replaceAll('([1*])', '9').replaceAll('[1*]', '9');
|
|
90
|
-
molRes = rdkitModule.get_mol(smiRes, JSON.stringify({mappedDummiesAreRGroups: true}))
|
|
91
|
-
|
|
88
|
+
molRes = rdkitModule.get_mol(smiRes, JSON.stringify({mappedDummiesAreRGroups: true}));
|
|
89
|
+
const molV3 = molRes.get_v3Kmolblock();
|
|
92
90
|
enumerations[i] = molV3;
|
|
93
|
-
}
|
|
94
|
-
catch(err:any) {
|
|
91
|
+
} catch (err:any) {
|
|
95
92
|
enumerations[i] = '';
|
|
96
|
-
}
|
|
97
|
-
finally {
|
|
93
|
+
} finally {
|
|
98
94
|
molRes?.delete();
|
|
99
95
|
}
|
|
100
96
|
}
|
|
101
|
-
|
|
97
|
+
|
|
102
98
|
|
|
103
99
|
return enumerations;
|
|
104
100
|
}
|
|
@@ -82,9 +82,9 @@ export async function polyToolEnumerateHelmUI(cell?: DG.Cell): Promise<void> {
|
|
|
82
82
|
if (isFirstShow) {
|
|
83
83
|
const dialogInputList = dialog.inputs;
|
|
84
84
|
const dialogRootCash = $(dialog.root);
|
|
85
|
-
const contentMaxHeight = maxHeight
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
const contentMaxHeight = maxHeight -
|
|
86
|
+
dialogRootCash.find('div.d4-dialog-header').get(0)!.offsetHeight -
|
|
87
|
+
dialogRootCash.find('div.d4-dialog-footer').get(0)!.offsetHeight;
|
|
88
88
|
|
|
89
89
|
// dialog.inputs2.macromolecule.root.style.backgroundColor = '#CCFFCC';
|
|
90
90
|
|
|
@@ -259,9 +259,9 @@ async function getPolyToolEnumerateDialog(
|
|
|
259
259
|
let rowIdx = posList.indexOf(clickedAtomContIdxStr);
|
|
260
260
|
if (rowIdx === -1) {
|
|
261
261
|
rowIdx = posList.findIndex((v) => isNaN(v));
|
|
262
|
-
if (rowIdx === -1)
|
|
262
|
+
if (rowIdx === -1)
|
|
263
263
|
rowIdx = phDf.rows.addNew([clickedAtomContIdxStr, '']).idx;
|
|
264
|
-
|
|
264
|
+
|
|
265
265
|
phDf.set('Position', rowIdx, clickedAtomContIdxStr);
|
|
266
266
|
// const tgtCell = inputs.placeholders.grid.cell('Monomers', rowIdx);
|
|
267
267
|
}
|
|
@@ -107,7 +107,7 @@ export function getPlaceholdersFromText(src: string): PolyToolPlaceholders {
|
|
|
107
107
|
const lineM = /^\s*(?<pos>\d+)\s*:\s*(?<monomers>.+)$/.exec(line);
|
|
108
108
|
if (lineM) {
|
|
109
109
|
const pos: number = parseInt(lineM.groups!['pos']) - 1;
|
|
110
|
-
const monomerList: string[] = lineM.groups!['monomers'].split(',').map(m => m.trim());
|
|
110
|
+
const monomerList: string[] = lineM.groups!['monomers'].split(',').map((m) => m.trim());
|
|
111
111
|
if (!(pos in res)) res[pos] = [];
|
|
112
112
|
res[pos].push(...monomerList);
|
|
113
113
|
}
|
|
@@ -86,18 +86,18 @@ category('PolyTool: Enumerate', () => {
|
|
|
86
86
|
}
|
|
87
87
|
},
|
|
88
88
|
tgt: [
|
|
89
|
-
[
|
|
90
|
-
[
|
|
91
|
-
[
|
|
92
|
-
[
|
|
93
|
-
[
|
|
94
|
-
[
|
|
95
|
-
[
|
|
96
|
-
[
|
|
97
|
-
[
|
|
98
|
-
[
|
|
99
|
-
[
|
|
100
|
-
[
|
|
89
|
+
['PEPTIDE1{[Ac(1)].D.W.G.K.L.Y.[C(1)].G.[NH2]}$$$$V2.0', '-F2D-P5K-[Tic]7Y'],
|
|
90
|
+
['PEPTIDE1{[Ac(1)].D.W.G.K.L.T.[C(1)].G.[NH2]}$$$$V2.0', '-F2D-P5K-[Tic]7T'],
|
|
91
|
+
['PEPTIDE1{[Ac(1)].D.W.G.P.L.Y.[C(1)].G.[NH2]}$$$$V2.0', '-F2D-P5P-[Tic]7Y'],
|
|
92
|
+
['PEPTIDE1{[Ac(1)].D.W.G.P.L.T.[C(1)].G.[NH2]}$$$$V2.0', '-F2D-P5P-[Tic]7T'],
|
|
93
|
+
['PEPTIDE1{[Ac(1)].D.W.G.[F4COO].L.Y.[C(1)].G.[NH2]}$$$$V2.0', '-F2D-P5[F4COO]-[Tic]7Y'],
|
|
94
|
+
['PEPTIDE1{[Ac(1)].D.W.G.[F4COO].L.T.[C(1)].G.[NH2]}$$$$V2.0', '-F2D-P5[F4COO]-[Tic]7T'],
|
|
95
|
+
['PEPTIDE1{[Ac(1)].L.W.G.K.L.Y.[C(1)].G.[NH2]}$$$$V2.0', '-F2L-P5K-[Tic]7Y'],
|
|
96
|
+
['PEPTIDE1{[Ac(1)].L.W.G.K.L.T.[C(1)].G.[NH2]}$$$$V2.0', '-F2L-P5K-[Tic]7T'],
|
|
97
|
+
['PEPTIDE1{[Ac(1)].L.W.G.P.L.Y.[C(1)].G.[NH2]}$$$$V2.0', '-F2L-P5P-[Tic]7Y'],
|
|
98
|
+
['PEPTIDE1{[Ac(1)].L.W.G.P.L.T.[C(1)].G.[NH2]}$$$$V2.0', '-F2L-P5P-[Tic]7T'],
|
|
99
|
+
['PEPTIDE1{[Ac(1)].L.W.G.[F4COO].L.Y.[C(1)].G.[NH2]}$$$$V2.0', '-F2L-P5[F4COO]-[Tic]7Y'],
|
|
100
|
+
['PEPTIDE1{[Ac(1)].L.W.G.[F4COO].L.T.[C(1)].G.[NH2]}$$$$V2.0', '-F2L-P5[F4COO]-[Tic]7T'],
|
|
101
101
|
],
|
|
102
102
|
}
|
|
103
103
|
};
|