@datagrok/sequence-translator 1.0.16 → 1.0.17
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/detectors.js +0 -28
- package/dist/package-test.js +3830 -3738
- package/dist/package.js +3826 -3734
- package/package.json +3 -1
- package/setup-unlink-clean.sh +21 -0
- package/src/autostart/calculations.ts +2 -2
- package/src/autostart/registration.ts +102 -37
- package/src/{axolabs/define-pattern.ts → axolabs-tab/axolabs-tab.ts} +2 -2
- package/src/axolabs-tab/define-pattern.ts +874 -0
- package/src/{axolabs → axolabs-tab}/draw-svg.ts +1 -1
- package/src/{axolabs → axolabs-tab}/helpers.ts +2 -2
- package/src/{autostart → hardcode-to-be-eliminated}/ICDs.ts +0 -0
- package/src/{autostart → hardcode-to-be-eliminated}/IDPs.ts +0 -0
- package/src/{structures-works → hardcode-to-be-eliminated}/const.ts +0 -0
- package/src/{axolabs → hardcode-to-be-eliminated}/constants.ts +0 -0
- package/src/{structures-works → hardcode-to-be-eliminated}/converters.ts +1 -1
- package/src/{structures-works → hardcode-to-be-eliminated}/map.ts +2 -2
- package/src/{autostart → hardcode-to-be-eliminated}/salts.ts +0 -0
- package/src/{autostart → hardcode-to-be-eliminated}/sources.ts +0 -0
- package/src/{autostart → hardcode-to-be-eliminated}/users.ts +0 -0
- package/src/{main/main-view.ts → main-tab/main-tab.ts} +27 -79
- package/src/package.ts +40 -23
- package/src/sdf-tab/sdf-tab.ts +163 -0
- package/src/{structures-works → sdf-tab}/sequence-codes-tools.ts +8 -5
- package/src/tests/smiles-tests.ts +2 -2
- package/src/utils/const.ts +0 -0
- package/src/{helpers.ts → utils/helpers.ts} +3 -3
- package/src/utils/sdf-add-columns.ts +3 -3
- package/src/utils/sdf-save-table.ts +4 -4
- package/src/utils/structures-works/draw-molecule.ts +84 -0
- package/src/{structures-works → utils/structures-works}/from-monomers.ts +15 -16
- package/src/{structures-works → utils/structures-works}/mol-transformations.ts +34 -52
- package/{test-SequenceTranslator-6288c2fbe346-cce4ac1d.html → test-SequenceTranslator-6288c2fbe346-695b7b55.html} +10 -10
- package/src/structures-works/save-sense-antisense.ts +0 -91
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datagrok/sequence-translator",
|
|
3
3
|
"friendlyName": "Sequence Translator",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.17",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Alexey Choposky",
|
|
7
7
|
"email": "achopovsky@datagrok.ai"
|
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
"@datagrok-libraries/utils": "^1.17.2",
|
|
17
17
|
"@types/react": "^18.0.15",
|
|
18
18
|
"@datagrok-libraries/bio": "^5.11.1",
|
|
19
|
+
"@deck.gl/core": "8.8.12",
|
|
20
|
+
"@luma.gl/core": "8.5.17",
|
|
19
21
|
"datagrok-api": "^1.8.2",
|
|
20
22
|
"datagrok-tools": "^4.1.2",
|
|
21
23
|
"npm": "^8.11.0",
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
package_dir=$(pwd)
|
|
3
|
+
|
|
4
|
+
GREEN='\e[0;32m'
|
|
5
|
+
NO_COLOR='\e[0m'
|
|
6
|
+
|
|
7
|
+
dirs=(
|
|
8
|
+
"../../js-api/"
|
|
9
|
+
"../../libraries/utils/"
|
|
10
|
+
"../../libraries/bio/"
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
npm uninstall --location=global datagrok-api @datagrok-libraries/utils @datagrok-libraries/ml @datagrok-libraries/bio
|
|
14
|
+
|
|
15
|
+
for dir in ${dirs[@]}; do
|
|
16
|
+
cd $package_dir
|
|
17
|
+
cd $dir
|
|
18
|
+
echo -e $GREEN Removing node_modules and dist in $(pwd) $NO_COLOR
|
|
19
|
+
rm -rf node_modules dist
|
|
20
|
+
# rm package-lock.json
|
|
21
|
+
done
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as DG from 'datagrok-api/dg';
|
|
2
2
|
|
|
3
|
-
import {sortByStringLengthInDescendingOrder} from '../helpers';
|
|
4
|
-
import {MODIFICATIONS} from '../
|
|
3
|
+
import {sortByStringLengthInDescendingOrder} from '../utils/helpers';
|
|
4
|
+
import {MODIFICATIONS} from '../hardcode-to-be-eliminated/map';
|
|
5
5
|
|
|
6
6
|
export function saltMass(
|
|
7
7
|
saltNames: string[], saltsMolWeightList: number[], equivalentsCol: DG.Column, i: number, saltCol: DG.Column
|
|
@@ -4,24 +4,31 @@ import * as DG from 'datagrok-api/dg';
|
|
|
4
4
|
import {
|
|
5
5
|
siRnaBioSpringToGcrs, siRnaAxolabsToGcrs, gcrsToNucleotides, asoGapmersBioSpringToGcrs, gcrsToMermade12,
|
|
6
6
|
siRnaNucleotidesToGcrs
|
|
7
|
-
} from '../
|
|
8
|
-
import {weightsObj, SYNTHESIZERS} from '../
|
|
7
|
+
} from '../hardcode-to-be-eliminated/converters';
|
|
8
|
+
import {weightsObj, SYNTHESIZERS} from '../hardcode-to-be-eliminated/map';
|
|
9
9
|
import {SEQUENCE_TYPES, COL_NAMES, GENERATED_COL_NAMES} from './constants';
|
|
10
10
|
import {saltMass, saltMolWeigth, molecularWeight, batchMolWeight} from './calculations';
|
|
11
|
-
import {isValidSequence} from '../
|
|
12
|
-
import {sequenceToMolV3000} from '../structures-works/from-monomers';
|
|
13
|
-
import {linkStrandsV3000} from '../structures-works/mol-transformations';
|
|
14
|
-
import {stringify, download, removeEmptyRows, differenceOfTwoArrays} from '../helpers';
|
|
11
|
+
import {isValidSequence} from '../sdf-tab/sequence-codes-tools';
|
|
12
|
+
import {sequenceToMolV3000} from '../utils/structures-works/from-monomers';
|
|
13
|
+
import {linkStrandsV3000} from '../utils/structures-works/mol-transformations';
|
|
14
|
+
import {stringify, download, removeEmptyRows, differenceOfTwoArrays} from '../utils/helpers';
|
|
15
15
|
|
|
16
|
-
import {SALTS_CSV} from '
|
|
17
|
-
import {USERS_CSV} from '
|
|
18
|
-
import {ICDS} from '
|
|
19
|
-
import {SOURCES} from '
|
|
20
|
-
import {IDPS} from '
|
|
16
|
+
import {SALTS_CSV} from '../hardcode-to-be-eliminated/salts';
|
|
17
|
+
import {USERS_CSV} from '../hardcode-to-be-eliminated/users';
|
|
18
|
+
import {ICDS} from '../hardcode-to-be-eliminated/ICDs';
|
|
19
|
+
import {SOURCES} from '../hardcode-to-be-eliminated/sources';
|
|
20
|
+
import {IDPS} from '../hardcode-to-be-eliminated/IDPs';
|
|
21
21
|
|
|
22
22
|
import {sdfAddColumns} from '../utils/sdf-add-columns';
|
|
23
23
|
import {sdfSaveTable} from '../utils/sdf-save-table';
|
|
24
24
|
|
|
25
|
+
const enum PREFIXES {
|
|
26
|
+
AS = 'AS',
|
|
27
|
+
SS = 'SS',
|
|
28
|
+
AS1 = 'AS1',
|
|
29
|
+
AS2 = 'AS2'
|
|
30
|
+
}
|
|
31
|
+
|
|
25
32
|
const enum SEQ_TYPE {
|
|
26
33
|
AS = 'AS',
|
|
27
34
|
SS = 'SS',
|
|
@@ -29,20 +36,38 @@ const enum SEQ_TYPE {
|
|
|
29
36
|
DIMER = 'Dimer',
|
|
30
37
|
}
|
|
31
38
|
|
|
32
|
-
/** Computable
|
|
33
|
-
const enum
|
|
39
|
+
/** Computable categories of sequence types */
|
|
40
|
+
const enum SEQ_TYPE_CATEGORY {
|
|
34
41
|
AS_OR_SS,
|
|
35
42
|
DUPLEX,
|
|
36
43
|
DIMER,
|
|
37
44
|
}
|
|
38
45
|
|
|
39
|
-
/**
|
|
40
|
-
const
|
|
41
|
-
|
|
46
|
+
/** Map between types and their categories inferrable from 'Sequence' column */
|
|
47
|
+
const typeCategoryMap = {
|
|
48
|
+
[SEQ_TYPE.AS]: SEQ_TYPE_CATEGORY.AS_OR_SS,
|
|
49
|
+
[SEQ_TYPE.SS]: SEQ_TYPE_CATEGORY.AS_OR_SS,
|
|
50
|
+
[SEQ_TYPE.DIMER]: SEQ_TYPE_CATEGORY.DIMER,
|
|
51
|
+
[SEQ_TYPE.DUPLEX]: SEQ_TYPE_CATEGORY.DUPLEX,
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/** Style used for cells in 'Type' column */
|
|
55
|
+
const typeColCellStyle = {
|
|
56
|
+
'display': 'flex',
|
|
57
|
+
'justify-content': 'center',
|
|
58
|
+
'align-items': 'center',
|
|
59
|
+
'text-color': 'var(--grey-5)', // --grey-6 does not match other cells
|
|
42
60
|
'width': '100%',
|
|
43
61
|
'height': '100%',
|
|
44
62
|
};
|
|
45
63
|
|
|
64
|
+
const pinkBackground = {
|
|
65
|
+
'background-color': '#ff8080',
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/** Style used for a cell with invalid value */
|
|
69
|
+
const typeColErrorStyle = Object.assign({}, pinkBackground, typeColCellStyle);
|
|
70
|
+
|
|
46
71
|
export function sdfHandleErrorUI(msgPrefix: string, df: DG.DataFrame, rowI: number, err: any) {
|
|
47
72
|
const errStr: string = err.toString();
|
|
48
73
|
const errMsg: string = msgPrefix + `row #${rowI + 1}, name: '${df.get('Chemistry Name', rowI)}', ` +
|
|
@@ -50,34 +75,61 @@ export function sdfHandleErrorUI(msgPrefix: string, df: DG.DataFrame, rowI: numb
|
|
|
50
75
|
grok.shell.warning(errMsg);
|
|
51
76
|
}
|
|
52
77
|
|
|
53
|
-
|
|
54
|
-
function getActualTypeClass(actualType: string):
|
|
55
|
-
if (
|
|
56
|
-
return
|
|
57
|
-
else if (actualType === SEQ_TYPE.DIMER)
|
|
58
|
-
return SEQ_TYPE_CLASS.DIMER;
|
|
59
|
-
else if (actualType === SEQ_TYPE.DUPLEX)
|
|
60
|
-
return SEQ_TYPE_CLASS.DUPLEX;
|
|
78
|
+
/** Determine the category of the value specified in 'Types' column */
|
|
79
|
+
function getActualTypeClass(actualType: string): SEQ_TYPE_CATEGORY {
|
|
80
|
+
if (Object.keys(typeCategoryMap).includes(actualType))
|
|
81
|
+
return typeCategoryMap[actualType as SEQ_TYPE];
|
|
61
82
|
else
|
|
62
83
|
throw new Error('Some types in \'Types\' column are invalid ');
|
|
63
84
|
}
|
|
64
85
|
|
|
65
|
-
function
|
|
86
|
+
function isASorSS(splittedLines: string[][]): boolean {
|
|
87
|
+
return splittedLines.length === 1 && splittedLines[0].length === 1;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Check whether the number of lines and prefixes in the 'Sequence' string
|
|
91
|
+
* are valid */
|
|
92
|
+
function verifyPrefixes(splittedLines: string[][], allowedPrefixes: Set<PREFIXES>, allowedLength: number): boolean {
|
|
93
|
+
const lengthCriterion = splittedLines.length === allowedLength;
|
|
94
|
+
let prefixCriterion = true;
|
|
95
|
+
for (const line of splittedLines) {
|
|
96
|
+
const prefix = line[0];
|
|
97
|
+
prefixCriterion &&= (allowedPrefixes.has(prefix as PREFIXES));
|
|
98
|
+
}
|
|
99
|
+
return lengthCriterion && prefixCriterion;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function isDuplex(splittedLines: string[][]): boolean {
|
|
103
|
+
const allowedPrefixes = new Set([PREFIXES.SS, PREFIXES.AS]);
|
|
104
|
+
return verifyPrefixes(splittedLines, allowedPrefixes, 2);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function isDimer(splittedLines: string[][]): boolean {
|
|
108
|
+
const allowedPrefixes = new Set([PREFIXES.SS, PREFIXES.AS1, PREFIXES.AS2]);
|
|
109
|
+
return verifyPrefixes(splittedLines, allowedPrefixes, 3);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function inferTypeClassFromSequence(seq: string): SEQ_TYPE_CATEGORY {
|
|
66
113
|
const lines = seq.split('\n');
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
114
|
+
const splittedLines = [];
|
|
115
|
+
for (const line of lines)
|
|
116
|
+
splittedLines.push(line.split(' '));
|
|
117
|
+
if (isASorSS(splittedLines))
|
|
118
|
+
return SEQ_TYPE_CATEGORY.AS_OR_SS;
|
|
119
|
+
else if (isDuplex(splittedLines))
|
|
120
|
+
return SEQ_TYPE_CATEGORY.DUPLEX;
|
|
121
|
+
else if (isDimer(splittedLines))
|
|
122
|
+
return SEQ_TYPE_CATEGORY.DIMER;
|
|
73
123
|
else
|
|
74
|
-
throw new Error('
|
|
75
|
-
//todo: throw in the case of wrong formatting
|
|
124
|
+
throw new Error('Some cells in \'Sequence\' column have wrong formatting');
|
|
76
125
|
}
|
|
77
126
|
|
|
78
127
|
/** Compare type specified in 'Type' column to that computed from 'Sequence' column */
|
|
79
128
|
function validateType(actualType: string, seq: string): boolean {
|
|
80
|
-
|
|
129
|
+
if (actualType === '' && seq === '')
|
|
130
|
+
return true;
|
|
131
|
+
else
|
|
132
|
+
return getActualTypeClass(actualType) === inferTypeClassFromSequence(seq);
|
|
81
133
|
}
|
|
82
134
|
|
|
83
135
|
function oligoSdFileGrid(view: DG.TableView): void {
|
|
@@ -90,8 +142,21 @@ function oligoSdFileGrid(view: DG.TableView): void {
|
|
|
90
142
|
const seqCol = df.getCol(seqColName);
|
|
91
143
|
grid.onCellPrepare((gridCell: DG.GridCell) => {
|
|
92
144
|
if (gridCell.isTableCell && gridCell.gridColumn.column!.name === typeColName) {
|
|
93
|
-
|
|
94
|
-
|
|
145
|
+
let isValidType = false;
|
|
146
|
+
let formattingError = false;
|
|
147
|
+
try {
|
|
148
|
+
isValidType = validateType(gridCell.cell.value, seqCol.get(gridCell.tableRow!.idx));
|
|
149
|
+
} catch {
|
|
150
|
+
formattingError = true;
|
|
151
|
+
}
|
|
152
|
+
const el = ui.div(
|
|
153
|
+
gridCell.cell.value, isValidType ? {style: typeColCellStyle} : {style: typeColErrorStyle}
|
|
154
|
+
);
|
|
155
|
+
gridCell.style.element = el;
|
|
156
|
+
const msg = formattingError ? 'Sequence pattern or Type value has wrong formatting' :
|
|
157
|
+
'Input in Type column doesn\'t match the Sequence pattern';
|
|
158
|
+
if (!isValidType)
|
|
159
|
+
ui.tooltip.bind(el, msg);
|
|
95
160
|
}
|
|
96
161
|
});
|
|
97
162
|
}
|
|
@@ -126,7 +191,7 @@ export function autostartOligoSdFileSubscription() {
|
|
|
126
191
|
});
|
|
127
192
|
}); // /^[fmpsACGU]{6,}$/
|
|
128
193
|
} else if (DG.Detector.sampleCategories(seqCol,
|
|
129
|
-
|
|
194
|
+
(s) => /(\(invabasic\)|\(GalNAc-2-JNJ\)|f|m|ps|A|C|G|U){6,}$/.test(s)) ||
|
|
130
195
|
DG.Detector.sampleCategories(seqCol, (s) => /^(?=.*moe)(?=.*5mC)(?=.*ps){6,}/.test(s))) {
|
|
131
196
|
menu.item('Convert GCRS to raw', () => {
|
|
132
197
|
grid.table.columns.addNewString(seqCol.name + ' to raw').init((i: number) => {
|
|
@@ -6,7 +6,7 @@ import * as svg from 'save-svg-as-png';
|
|
|
6
6
|
import $ from 'cash-dom';
|
|
7
7
|
|
|
8
8
|
import {drawAxolabsPattern} from './draw-svg';
|
|
9
|
-
import {AXOLABS_MAP} from '
|
|
9
|
+
import {AXOLABS_MAP} from '../hardcode-to-be-eliminated/constants';
|
|
10
10
|
import {isOverhang} from './helpers';
|
|
11
11
|
|
|
12
12
|
const baseChoices: string[] = Object.keys(AXOLABS_MAP);
|
|
@@ -114,7 +114,7 @@ function addColumnWithTranslatedSequences(
|
|
|
114
114
|
});
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
export function
|
|
117
|
+
export function getAxolabsTab() {
|
|
118
118
|
const enumerateModifications = [defaultBase];
|
|
119
119
|
let maximalSsLength = defaultSequenceLength;
|
|
120
120
|
let maximalAsLength = defaultSequenceLength;
|