@datagrok/sequence-translator 1.0.12 → 1.0.14
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/dist/package-test.js +70739 -1417
- package/dist/package.js +70546 -4914
- package/package.json +6 -4
- package/scripts/build-monomer-lib.py +140 -0
- package/setup-unlink-clean.cmd +14 -0
- package/setup.cmd +14 -11
- package/setup.sh +37 -0
- package/src/__jest__/remote.test.ts +11 -3
- package/src/{ICDs.ts → autostart/ICDs.ts} +0 -0
- package/src/{IDPs.ts → autostart/IDPs.ts} +0 -0
- package/src/autostart/calculations.ts +37 -0
- package/src/autostart/constants.ts +49 -0
- package/src/autostart/registration.ts +101 -122
- package/src/{salts.ts → autostart/salts.ts} +0 -0
- package/src/{sources.ts → autostart/sources.ts} +0 -0
- package/src/{users.ts → autostart/users.ts} +0 -0
- package/src/axolabs/constants.ts +10 -10
- package/src/axolabs/define-pattern.ts +13 -12
- package/src/axolabs/draw-svg.ts +140 -201
- package/src/axolabs/helpers.ts +94 -0
- package/src/helpers.ts +28 -0
- package/src/main/main-view.ts +85 -87
- package/src/package.ts +25 -8
- package/src/structures-works/const.ts +18 -0
- package/src/structures-works/converters.ts +3 -3
- package/src/structures-works/from-monomers.ts +185 -32
- package/src/structures-works/map.ts +20 -35
- package/src/structures-works/mol-transformations.ts +295 -582
- package/src/structures-works/save-sense-antisense.ts +35 -11
- package/src/structures-works/sequence-codes-tools.ts +9 -13
- package/{test-SequenceTranslator-49ff04f38f57-128d0678.html → test-SequenceTranslator-e8c06047b7e7-eb4db608.html} +10 -7
|
@@ -3,90 +3,64 @@ import * as ui from 'datagrok-api/ui';
|
|
|
3
3
|
import * as DG from 'datagrok-api/dg';
|
|
4
4
|
import {siRnaBioSpringToGcrs, siRnaAxolabsToGcrs, gcrsToNucleotides, asoGapmersBioSpringToGcrs, gcrsToMermade12,
|
|
5
5
|
siRnaNucleotidesToGcrs} from '../structures-works/converters';
|
|
6
|
-
import {
|
|
6
|
+
import {weightsObj, SYNTHESIZERS} from '../structures-works/map';
|
|
7
|
+
import {SEQUENCE_TYPES, COL_NAMES, GENERATED_COL_NAMES, CELL_STRUCTURE} from './constants';
|
|
8
|
+
import {saltMass, saltMolWeigth, molecularWeight, batchMolWeight} from './calculations';
|
|
7
9
|
import {isValidSequence} from '../structures-works/sequence-codes-tools';
|
|
8
10
|
import {sequenceToMolV3000} from '../structures-works/from-monomers';
|
|
9
|
-
import {
|
|
11
|
+
import {linkStrandsV3000} from '../structures-works/mol-transformations';
|
|
12
|
+
import {stringify, download, removeEmptyRows, differenceOfTwoArrays} from '../helpers';
|
|
10
13
|
|
|
11
|
-
import {SALTS_CSV} from '
|
|
12
|
-
import {USERS_CSV} from '
|
|
13
|
-
import {ICDS} from '
|
|
14
|
-
import {SOURCES} from '
|
|
15
|
-
import {IDPS} from '
|
|
14
|
+
import {SALTS_CSV} from './salts';
|
|
15
|
+
import {USERS_CSV} from './users';
|
|
16
|
+
import {ICDS} from './ICDs';
|
|
17
|
+
import {SOURCES} from './sources';
|
|
18
|
+
import {IDPS} from './IDPs';
|
|
16
19
|
|
|
17
20
|
|
|
18
|
-
function
|
|
19
|
-
|
|
21
|
+
function parseStrandsFromDuplexCell(s: string): {SS: string, AS: string} {
|
|
22
|
+
const arr = s
|
|
23
|
+
.slice(CELL_STRUCTURE.DUPLEX.BEFORE_SS.length)
|
|
24
|
+
.split(CELL_STRUCTURE.DUPLEX.BEFORE_AS);
|
|
25
|
+
return {SS: arr[0], AS: arr[1]};
|
|
20
26
|
}
|
|
21
27
|
|
|
22
|
-
function
|
|
23
|
-
|
|
28
|
+
function parseStrandsFromTriplexOrDimerCell(s: string): {SS: string, AS1: string, AS2: string} {
|
|
29
|
+
const arr1 = s
|
|
30
|
+
.slice(CELL_STRUCTURE.TRIPLEX_OR_DIMER.BEFORE_SS.length)
|
|
31
|
+
.split(CELL_STRUCTURE.TRIPLEX_OR_DIMER.BEFORE_AS1);
|
|
32
|
+
const arr2 = arr1[1]
|
|
33
|
+
.split(CELL_STRUCTURE.TRIPLEX_OR_DIMER.BEFORE_AS2);
|
|
34
|
+
return {SS: arr1[0], AS1: arr2[0], AS2: arr2[1]};
|
|
24
35
|
}
|
|
25
36
|
|
|
26
|
-
function
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
saltRowIndex == -1 || molWeightCol.get(saltRowIndex) == DG.FLOAT_NULL || equivalentsCol.get(i) == DG.INT_NULL) ?
|
|
31
|
-
DG.FLOAT_NULL :
|
|
32
|
-
molWeightCol.get(saltRowIndex) * equivalentsCol.get(i);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function saltMolWeigth(saltNamesList: string[], saltCol: DG.Column, molWeightCol: DG.Column, i: number) {
|
|
36
|
-
const saltRowIndex = saltNamesList.indexOf(saltCol.get(i));
|
|
37
|
-
return (saltRowIndex == -1) ? DG.FLOAT_NULL : molWeightCol.get(saltRowIndex);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function batchMolWeight(compoundMolWeightCol: DG.Column, saltMassCol: DG.Column, i: number) {
|
|
41
|
-
return (compoundMolWeightCol.getString(i) == '' || saltMassCol.getString(i) == '') ?
|
|
42
|
-
DG.FLOAT_NULL :
|
|
43
|
-
compoundMolWeightCol.get(i) + saltMassCol.get(i);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function molecularWeight(sequence: string, weightsObj: {[index: string]: number}): number {
|
|
47
|
-
const codes = sortByStringLengthInDescendingOrder(Object.keys(weightsObj)).concat(Object.keys(MODIFICATIONS));
|
|
48
|
-
let weight = 0;
|
|
49
|
-
let i = 0;
|
|
50
|
-
while (i < sequence.length) {
|
|
51
|
-
const matchedCode = codes.find((s) => s == sequence.slice(i, i + s.length))!;
|
|
52
|
-
weight += weightsObj[sequence.slice(i, i + matchedCode.length)];
|
|
53
|
-
i += matchedCode.length;
|
|
37
|
+
async function saveTableAsSdFile(table: DG.DataFrame) {
|
|
38
|
+
if (GENERATED_COL_NAMES.some((colName) => !table.columns.contains(colName))) {
|
|
39
|
+
const absentColNames = differenceOfTwoArrays(GENERATED_COL_NAMES, table.columns.names()).join(`', '`);
|
|
40
|
+
grok.shell.warning(`File saved without columns '${absentColNames}'`);
|
|
54
41
|
}
|
|
55
|
-
return weight - 61.97;
|
|
56
|
-
}
|
|
57
42
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
43
|
+
const sequenceCol = table.getCol(COL_NAMES.SEQUENCE);
|
|
44
|
+
const typeCol = table.getCol(COL_NAMES.TYPE);
|
|
61
45
|
|
|
62
|
-
async function saveTableAsSdFile(table: DG.DataFrame) {
|
|
63
|
-
if (!table.columns.contains('Compound Name')) {
|
|
64
|
-
grok.shell.warning(
|
|
65
|
-
'File saved without columns \'' +
|
|
66
|
-
[COL_NAMES.COMPOUND_NAME, COL_NAMES.COMPOUND_COMMENTS, COL_NAMES.CPD_MW,
|
|
67
|
-
COL_NAMES.SALT_MASS, COL_NAMES.BATCH_MW].join('\', \''),
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
const structureColumn = table.getCol(COL_NAMES.SEQUENCE);
|
|
71
|
-
const typeColumn = table.getCol(COL_NAMES.TYPE);
|
|
72
46
|
let result = '';
|
|
73
47
|
for (let i = 0; i < table.rowCount; i++) {
|
|
74
|
-
const format =
|
|
75
|
-
if (
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
result +=
|
|
48
|
+
const format = SYNTHESIZERS.GCRS; //getFormat(sequenceCol.get(i))!;
|
|
49
|
+
if (typeCol.get(i) == SEQUENCE_TYPES.SENSE_STRAND)
|
|
50
|
+
result += `${sequenceToMolV3000(sequenceCol.get(i), false, true, format)}\n> <Sequence>\nSense Strand\n\n`;
|
|
51
|
+
else if (typeCol.get(i) == SEQUENCE_TYPES.ANTISENSE_STRAND)
|
|
52
|
+
result += `${sequenceToMolV3000(sequenceCol.get(i), true, true, format)}\n> <Sequence>\nAnti Sense\n\n`;
|
|
53
|
+
else if (typeCol.get(i) == SEQUENCE_TYPES.DUPLEX) {
|
|
54
|
+
const obj = parseStrandsFromDuplexCell(sequenceCol.get(i));
|
|
55
|
+
const as = `${sequenceToMolV3000(obj.AS, true, true, format)}\n> <Sequence>\nAnti Sense\n\n`;
|
|
56
|
+
const ss = `${sequenceToMolV3000(obj.SS, false, true, format)}\n> <Sequence>\nSense Strand\n\n`;
|
|
57
|
+
result += `${linkStrandsV3000({senseStrands: [ss], antiStrands: [as]}, true)}\n\n`;
|
|
58
|
+
} else if ([SEQUENCE_TYPES.TRIPLEX, SEQUENCE_TYPES.DIMER].includes(typeCol.get(i))) {
|
|
59
|
+
const obj = parseStrandsFromTriplexOrDimerCell(sequenceCol.get(i));
|
|
60
|
+
const as1 = `${sequenceToMolV3000(obj.AS1, true, true, format)}\n> <Sequence>\nAnti Sense\n\n`;
|
|
61
|
+
const as2 = `${sequenceToMolV3000(obj.AS2, true, true, format)}\n> <Sequence>\nAnti Sense\n\n`;
|
|
62
|
+
const ss = `${sequenceToMolV3000(obj.SS, false, true, format)}\n> <Sequence>\nSense Strand\n\n`;
|
|
63
|
+
result += `${linkStrandsV3000({senseStrands: [ss], antiStrands: [as1, as2]}, true)}\n\n`;
|
|
90
64
|
}
|
|
91
65
|
|
|
92
66
|
for (const col of table.columns) {
|
|
@@ -95,17 +69,16 @@ async function saveTableAsSdFile(table: DG.DataFrame) {
|
|
|
95
69
|
}
|
|
96
70
|
result += '$$$$\n';
|
|
97
71
|
}
|
|
98
|
-
|
|
99
|
-
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(result));
|
|
100
|
-
element.setAttribute('download', table.name + '.sdf');
|
|
101
|
-
element.click();
|
|
72
|
+
download(`${table.name}.sdf`, encodeURIComponent(result));
|
|
102
73
|
}
|
|
103
74
|
|
|
104
75
|
export function autostartOligoSdFileSubscription() {
|
|
105
76
|
grok.events.onViewAdded.subscribe((v: any) => {
|
|
106
|
-
if (v.type ==
|
|
77
|
+
if (v.type == DG.VIEW_TYPE.TABLE_VIEW) {
|
|
107
78
|
if (v.dataFrame.columns.contains(COL_NAMES.TYPE))
|
|
108
79
|
oligoSdFile(v.dataFrame);
|
|
80
|
+
|
|
81
|
+
// Should be removed after fixing bug https://github.com/datagrok-ai/public/issues/808
|
|
109
82
|
grok.events.onContextMenu.subscribe((args) => {
|
|
110
83
|
const seqCol = args.args.context.table.currentCol; // /^[fsACGUacgu]{6,}$/
|
|
111
84
|
if (DG.Detector.sampleCategories(seqCol,
|
|
@@ -166,56 +139,56 @@ export function oligoSdFile(table: DG.DataFrame) {
|
|
|
166
139
|
const sequenceCol = table.getCol(COL_NAMES.SEQUENCE);
|
|
167
140
|
const saltCol = table.getCol(COL_NAMES.SALT);
|
|
168
141
|
const equivalentsCol = table.getCol(COL_NAMES.EQUIVALENTS);
|
|
169
|
-
const
|
|
142
|
+
const typeCol = table.getCol(COL_NAMES.TYPE);
|
|
170
143
|
const chemistryNameCol = table.getCol(COL_NAMES.CHEMISTRY_NAME);
|
|
171
144
|
|
|
172
145
|
const molWeightCol = saltsDf.getCol('MOLWEIGHT');
|
|
173
146
|
const saltNamesList = saltsDf.getCol('DISPLAY').toList();
|
|
174
147
|
|
|
148
|
+
let newDf: DG.DataFrame;
|
|
149
|
+
let addColumnsPressed = false;
|
|
150
|
+
|
|
175
151
|
function addColumns(t: DG.DataFrame) {
|
|
176
|
-
if (t.columns.contains(
|
|
152
|
+
if (GENERATED_COL_NAMES.some((colName) => t.columns.contains(colName)))
|
|
177
153
|
return grok.shell.error('Columns already exist');
|
|
178
154
|
|
|
179
|
-
|
|
180
|
-
if (sequenceCol.get(i) == '')
|
|
181
|
-
t.rows.removeAt(i, 1, false);
|
|
182
|
-
}
|
|
155
|
+
t = removeEmptyRows(t, sequenceCol);
|
|
183
156
|
|
|
184
157
|
t.columns.addNewString(COL_NAMES.COMPOUND_NAME).init((i: number) => {
|
|
185
|
-
return (
|
|
158
|
+
return ([SEQUENCE_TYPES.DUPLEX, SEQUENCE_TYPES.DIMER, SEQUENCE_TYPES.TRIPLEX].includes(typeCol.get(i))) ?
|
|
159
|
+
chemistryNameCol.get(i) :
|
|
160
|
+
sequenceCol.get(i);
|
|
186
161
|
});
|
|
187
162
|
|
|
188
163
|
t.columns.addNewString(COL_NAMES.COMPOUND_COMMENTS).init((i: number) => {
|
|
189
|
-
if (
|
|
190
|
-
|
|
191
|
-
|
|
164
|
+
if ([SEQUENCE_TYPES.SENSE_STRAND, SEQUENCE_TYPES.ANTISENSE_STRAND].includes(typeCol.get(i)))
|
|
165
|
+
return sequenceCol.get(i);
|
|
166
|
+
else if (typeCol.get(i) == SEQUENCE_TYPES.DUPLEX) {
|
|
167
|
+
const obj = parseStrandsFromDuplexCell(sequenceCol.get(i));
|
|
168
|
+
return `${chemistryNameCol.get(i)}; duplex of SS: ${obj.SS} and AS: ${obj.AS}`;
|
|
169
|
+
} else if ([SEQUENCE_TYPES.DIMER, SEQUENCE_TYPES.TRIPLEX].includes(typeCol.get(i))) {
|
|
170
|
+
const obj = parseStrandsFromTriplexOrDimerCell(sequenceCol.get(i));
|
|
171
|
+
return `${chemistryNameCol.get(i)}; duplex of SS: ${obj.SS} and AS1: ${obj.AS1} and AS2: ${obj.AS2}`;
|
|
192
172
|
}
|
|
193
|
-
return sequenceCol.get(i);
|
|
194
173
|
});
|
|
195
174
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
isValidSequence(arr[1], null).indexOfFirstNotValidChar == -1
|
|
212
|
-
) ?
|
|
213
|
-
molecularWeight(arr[0], weightsObj) + molecularWeight(arr[1], weightsObj) :
|
|
175
|
+
t.columns.addNewFloat(COL_NAMES.COMPOUND_MOL_WEIGHT).init((i: number) => {
|
|
176
|
+
if ([SEQUENCE_TYPES.SENSE_STRAND, SEQUENCE_TYPES.ANTISENSE_STRAND].includes(typeCol.get(i))) {
|
|
177
|
+
return (isValidSequence(sequenceCol.get(i), null).indexOfFirstNotValidChar == -1) ?
|
|
178
|
+
molecularWeight(sequenceCol.get(i), weightsObj) :
|
|
179
|
+
DG.FLOAT_NULL;
|
|
180
|
+
} else if (typeCol.get(i) == SEQUENCE_TYPES.DUPLEX) {
|
|
181
|
+
const obj = parseStrandsFromDuplexCell(sequenceCol.get(i));
|
|
182
|
+
return (Object.values(obj).every((seq) => isValidSequence(seq, null).indexOfFirstNotValidChar == -1)) ?
|
|
183
|
+
molecularWeight(obj.SS, weightsObj) + molecularWeight(obj.AS, weightsObj) :
|
|
184
|
+
DG.FLOAT_NULL;
|
|
185
|
+
} else if ([SEQUENCE_TYPES.DIMER, SEQUENCE_TYPES.TRIPLEX].includes(typeCol.get(i))) {
|
|
186
|
+
const obj = parseStrandsFromTriplexOrDimerCell(sequenceCol.get(i));
|
|
187
|
+
return (Object.values(obj).every((seq) => isValidSequence(seq, null).indexOfFirstNotValidChar == -1)) ?
|
|
188
|
+
molecularWeight(obj.SS, weightsObj) + molecularWeight(obj.AS1, weightsObj) +
|
|
189
|
+
molecularWeight(obj.AS2, weightsObj) :
|
|
214
190
|
DG.FLOAT_NULL;
|
|
215
191
|
}
|
|
216
|
-
return (isValidSequence(sequenceCol.get(i), null).indexOfFirstNotValidChar == -1) ?
|
|
217
|
-
molecularWeight(sequenceCol.get(i), weightsObj) :
|
|
218
|
-
DG.FLOAT_NULL;
|
|
219
192
|
});
|
|
220
193
|
|
|
221
194
|
t.columns.addNewFloat(COL_NAMES.SALT_MASS).init((i: number) =>
|
|
@@ -224,15 +197,24 @@ export function oligoSdFile(table: DG.DataFrame) {
|
|
|
224
197
|
t.columns.addNewFloat(COL_NAMES.SALT_MOL_WEIGHT).init((i: number) =>
|
|
225
198
|
saltMolWeigth(saltNamesList, saltCol, molWeightCol, i));
|
|
226
199
|
|
|
227
|
-
t.
|
|
228
|
-
|
|
200
|
+
const compoundMolWeightCol = t.getCol(COL_NAMES.COMPOUND_MOL_WEIGHT);
|
|
201
|
+
const saltMassCol = t.getCol(COL_NAMES.SALT_MASS);
|
|
202
|
+
t.columns.addNewFloat(COL_NAMES.BATCH_MOL_WEIGHT).init((i: number) =>
|
|
203
|
+
batchMolWeight(compoundMolWeightCol, saltMassCol, i));
|
|
229
204
|
|
|
205
|
+
grok.shell.getTableView(table.name).grid.columns.setOrder(Object.values(COL_NAMES));
|
|
230
206
|
addColumnsPressed = true;
|
|
231
207
|
return newDf = t;
|
|
232
208
|
}
|
|
233
209
|
|
|
234
|
-
|
|
235
|
-
|
|
210
|
+
function updateCalculatedColumns(t: DG.DataFrame, i: number): void {
|
|
211
|
+
const smValue = saltMass(saltNamesList, molWeightCol, equivalentsCol, i, saltCol);
|
|
212
|
+
t.getCol(COL_NAMES.SALT_MASS).set(i, smValue, false);
|
|
213
|
+
const smwValue = saltMolWeigth(saltNamesList, saltCol, molWeightCol, i);
|
|
214
|
+
t.getCol(COL_NAMES.SALT_MOL_WEIGHT).set(i, smwValue, false);
|
|
215
|
+
const bmw = batchMolWeight(t.getCol(COL_NAMES.COMPOUND_MOL_WEIGHT), t.getCol(COL_NAMES.SALT_MASS), i);
|
|
216
|
+
t.getCol(COL_NAMES.BATCH_MOL_WEIGHT).set(i, bmw, false);
|
|
217
|
+
}
|
|
236
218
|
|
|
237
219
|
const d = ui.div([
|
|
238
220
|
ui.icons.edit(() => {
|
|
@@ -240,18 +222,15 @@ export function oligoSdFile(table: DG.DataFrame) {
|
|
|
240
222
|
if (table.getCol(COL_NAMES.IDP).type != DG.COLUMN_TYPE.STRING)
|
|
241
223
|
table.changeColumnType(COL_NAMES.IDP, DG.COLUMN_TYPE.STRING);
|
|
242
224
|
d.append(
|
|
243
|
-
ui.
|
|
244
|
-
addColumns(table)
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
COL_NAMES.SALT_MASS, COL_NAMES.BATCH_MW].join('\', \''), '',
|
|
248
|
-
),
|
|
249
|
-
ui.button('Save SD file', () => saveTableAsSdFile(addColumnsPressed ? newDf : table)),
|
|
225
|
+
ui.divH([
|
|
226
|
+
ui.icons.add(() => addColumns(table), `Add columns: '${GENERATED_COL_NAMES.join(`', '`)}'`),
|
|
227
|
+
ui.icons.save(() => saveTableAsSdFile(addColumnsPressed ? newDf : table), 'Save SD file'),
|
|
228
|
+
]),
|
|
250
229
|
);
|
|
251
230
|
|
|
252
231
|
const view = grok.shell.getTableView(table.name);
|
|
253
|
-
|
|
254
|
-
view.dataFrame.getCol(COL_NAMES.TYPE).setTag(DG.TAGS.CHOICES,
|
|
232
|
+
view.grid.setOptions({rowHeight: 45});
|
|
233
|
+
view.dataFrame.getCol(COL_NAMES.TYPE).setTag(DG.TAGS.CHOICES, stringify(Object.values(SEQUENCE_TYPES)));
|
|
255
234
|
view.dataFrame.getCol(COL_NAMES.OWNER).setTag(DG.TAGS.CHOICES, stringify(usersDf.columns.byIndex(0).toList()));
|
|
256
235
|
view.dataFrame.getCol(COL_NAMES.SALT).setTag(DG.TAGS.CHOICES, stringify(saltsDf.columns.byIndex(0).toList()));
|
|
257
236
|
view.dataFrame.getCol(COL_NAMES.SOURCE).setTag(DG.TAGS.CHOICES, stringify(sourcesDf.columns.byIndex(0).toList()));
|
|
@@ -281,8 +260,8 @@ export function oligoSdFile(table: DG.DataFrame) {
|
|
|
281
260
|
t.getCol(COL_NAMES.SALT_MASS).set(i, smValue, false);
|
|
282
261
|
const smwValue = saltMolWeigth(saltNamesList, saltCol, molWeightCol, i);
|
|
283
262
|
t.getCol(COL_NAMES.SALT_MOL_WEIGHT).set(i, smwValue, false);
|
|
284
|
-
const bmw = batchMolWeight(t.getCol(COL_NAMES.
|
|
285
|
-
t.getCol(COL_NAMES.
|
|
263
|
+
const bmw = batchMolWeight(t.getCol(COL_NAMES.COMPOUND_MOL_WEIGHT), t.getCol(COL_NAMES.SALT_MASS), i);
|
|
264
|
+
t.getCol(COL_NAMES.BATCH_MOL_WEIGHT).set(i, bmw, false);
|
|
286
265
|
}
|
|
287
266
|
}),
|
|
288
267
|
]);
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/src/axolabs/constants.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
const
|
|
2
|
-
const
|
|
3
|
-
export const
|
|
1
|
+
const RNA_COLOR = 'rgb(255,230,153)';
|
|
2
|
+
const INVABASIC_COLOR = 'rgb(203,119,211)';
|
|
3
|
+
export const AXOLABS_MAP:
|
|
4
4
|
{[index: string]: {fullName: string, symbols: [string, string, string, string], color: string}} =
|
|
5
5
|
{
|
|
6
6
|
'RNA': {
|
|
7
7
|
fullName: 'RNA nucleotides',
|
|
8
8
|
symbols: ['A', 'C', 'G', 'U'],
|
|
9
|
-
color:
|
|
9
|
+
color: RNA_COLOR,
|
|
10
10
|
},
|
|
11
11
|
'DNA': {
|
|
12
12
|
fullName: 'DNA nucleotides',
|
|
@@ -46,22 +46,22 @@ export const axolabsMap:
|
|
|
46
46
|
'A': {
|
|
47
47
|
fullName: 'Adenine',
|
|
48
48
|
symbols: ['a', 'a', 'a', 'a'],
|
|
49
|
-
color:
|
|
49
|
+
color: RNA_COLOR,
|
|
50
50
|
},
|
|
51
51
|
'C': {
|
|
52
52
|
fullName: 'Cytosine',
|
|
53
53
|
symbols: ['c', 'c', 'c', 'c'],
|
|
54
|
-
color:
|
|
54
|
+
color: RNA_COLOR,
|
|
55
55
|
},
|
|
56
56
|
'G': {
|
|
57
57
|
fullName: 'Guanine',
|
|
58
58
|
symbols: ['g', 'g', 'g', 'g'],
|
|
59
|
-
color:
|
|
59
|
+
color: RNA_COLOR,
|
|
60
60
|
},
|
|
61
61
|
'U': {
|
|
62
62
|
fullName: 'Uracil',
|
|
63
63
|
symbols: ['u', 'u', 'u', 'u'],
|
|
64
|
-
color:
|
|
64
|
+
color: RNA_COLOR,
|
|
65
65
|
},
|
|
66
66
|
'X-New': {
|
|
67
67
|
fullName: '',
|
|
@@ -81,7 +81,7 @@ export const axolabsMap:
|
|
|
81
81
|
'InvAbasic': {
|
|
82
82
|
fullName: 'Inverted abasic capped',
|
|
83
83
|
symbols: ['(invabasic)', '(invabasic)', '(invabasic)', '(invabasic)'],
|
|
84
|
-
color:
|
|
84
|
+
color: INVABASIC_COLOR,
|
|
85
85
|
},
|
|
86
86
|
"5\"-vinylps": {
|
|
87
87
|
fullName: '5\'-vinylphosphonate-2\'-OMe-uridine',
|
|
@@ -91,7 +91,7 @@ export const axolabsMap:
|
|
|
91
91
|
'InvAbasic(o)': {
|
|
92
92
|
fullName: 'Inverted abasic capped (overhang)',
|
|
93
93
|
symbols: ['(invabasic)', '(invabasic)', '(invabasic)', '(invabasic)'],
|
|
94
|
-
color:
|
|
94
|
+
color: INVABASIC_COLOR,
|
|
95
95
|
},
|
|
96
96
|
"2\"-OMe-U(o)": {
|
|
97
97
|
fullName: 'Nucleotide Uridine with 2\'O-Methyl protection (overhang)',
|
|
@@ -6,9 +6,10 @@ 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 {
|
|
9
|
+
import {AXOLABS_MAP} from './constants';
|
|
10
|
+
import {isOverhang} from './helpers';
|
|
10
11
|
|
|
11
|
-
const baseChoices: string[] = Object.keys(
|
|
12
|
+
const baseChoices: string[] = Object.keys(AXOLABS_MAP);
|
|
12
13
|
const defaultBase: string = baseChoices[0];
|
|
13
14
|
const defaultPto: boolean = true;
|
|
14
15
|
const defaultSequenceLength: number = 23;
|
|
@@ -17,7 +18,7 @@ const userStorageKey: string = 'SequenceTranslator';
|
|
|
17
18
|
const exampleMinWidth: string = '400px';
|
|
18
19
|
|
|
19
20
|
function generateExample(sequenceLength: number, sequenceBasis: string): string {
|
|
20
|
-
const uniqueSymbols =
|
|
21
|
+
const uniqueSymbols = AXOLABS_MAP[sequenceBasis].symbols.join('');
|
|
21
22
|
return uniqueSymbols.repeat(Math.floor(sequenceLength / 4)) + uniqueSymbols.slice(0, sequenceLength % 4);
|
|
22
23
|
}
|
|
23
24
|
|
|
@@ -64,12 +65,12 @@ function translateSequence(
|
|
|
64
65
|
let i: number = -1;
|
|
65
66
|
let mainSequence = sequence.replace(/[AUGC]/g, function(x: string) {
|
|
66
67
|
i++;
|
|
67
|
-
const indexOfSymbol =
|
|
68
|
-
let symbol =
|
|
69
|
-
if (bases[i].value
|
|
70
|
-
if (i < sequence.length / 2 && bases[i + 1].value
|
|
68
|
+
const indexOfSymbol = AXOLABS_MAP['RNA']['symbols'].indexOf(x);
|
|
69
|
+
let symbol = AXOLABS_MAP[bases[i].value]['symbols'][indexOfSymbol];
|
|
70
|
+
if (isOverhang(bases[i].value)) {
|
|
71
|
+
if (i < sequence.length / 2 && !isOverhang(bases[i + 1].value))
|
|
71
72
|
symbol = symbol + x + 'f';
|
|
72
|
-
else if (i > sequence.length / 2 && bases[i - 1].value
|
|
73
|
+
else if (i > sequence.length / 2 && !isOverhang(bases[i - 1].value))
|
|
73
74
|
symbol = x + 'f' + symbol;
|
|
74
75
|
}
|
|
75
76
|
return (ptoLinkages[i].value) ? symbol + 's' : symbol;
|
|
@@ -150,12 +151,12 @@ export function defineAxolabsPattern() {
|
|
|
150
151
|
updateSvgScheme();
|
|
151
152
|
updateOutputExamples();
|
|
152
153
|
});
|
|
153
|
-
if (asBases[i].value
|
|
154
|
+
if (!isOverhang(asBases[i].value))
|
|
154
155
|
nucleotideCounter++;
|
|
155
156
|
|
|
156
157
|
asModificationItems.append(
|
|
157
158
|
ui.divH([
|
|
158
|
-
ui.div([ui.label(asBases[i].value
|
|
159
|
+
ui.div([ui.label(isOverhang(asBases[i].value) ? '' : String(nucleotideCounter))],
|
|
159
160
|
{style: {width: '20px'}})!,
|
|
160
161
|
ui.block75([asBases[i]])!,
|
|
161
162
|
ui.div([asPtoLinkages[i]])!,
|
|
@@ -196,12 +197,12 @@ export function defineAxolabsPattern() {
|
|
|
196
197
|
updateSvgScheme();
|
|
197
198
|
updateOutputExamples();
|
|
198
199
|
});
|
|
199
|
-
if (ssBases[i].value
|
|
200
|
+
if (!isOverhang(ssBases[i].value))
|
|
200
201
|
nucleotideCounter++;
|
|
201
202
|
|
|
202
203
|
ssModificationItems.append(
|
|
203
204
|
ui.divH([
|
|
204
|
-
ui.div([ui.label(ssBases[i].value
|
|
205
|
+
ui.div([ui.label(isOverhang(ssBases[i].value) ? '' : String(nucleotideCounter))],
|
|
205
206
|
{style: {width: '20px'}})!,
|
|
206
207
|
ui.block75([ssBases[i]])!,
|
|
207
208
|
ui.div([ssPtoLinkages[i]])!,
|