@datagrok/sequence-translator 0.0.12 → 1.0.0
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/README.md +19 -11
- package/dist/package-test.js +192 -135
- package/dist/package.js +195 -122
- package/package.json +7 -6
- package/src/defineAxolabsPattern.ts +58 -55
- package/src/package-test.ts +1 -1
- package/src/package.ts +28 -17
- package/src/structures-works/from-monomers.ts +20 -12
- package/src/structures-works/save-sense-antisense.ts +5 -2
- package/src/structures-works/sequence-codes-tools.ts +128 -45
- package/src/tests/smiles-tests.ts +31 -27
- package/{test-SequenceTranslator-c2bbc2b235db-afc0e1c5.html → test-SequenceTranslator-089b6516ed77-d62c21a9.html} +2 -2
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datagrok/sequence-translator",
|
|
3
3
|
"friendlyName": "Sequence Translator",
|
|
4
|
-
"version": "0.0
|
|
5
|
-
"description": "",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"description": "SequenceTranslator is a [package](https://datagrok.ai/help/develop/develop#packages) for the [Datagrok](https://datagrok.ai) platform, used to translate [oligonucleotide](https://en.wikipedia.org/wiki/Oligonucleotide) sequences between [different representations](https://github.com/datagrok-ai/public/tree/master/packages/SequenceTranslator#sequence-representations).",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "https://github.com/datagrok-ai/public.git",
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@datagrok-libraries/utils": "^0.1.0",
|
|
13
13
|
"@types/react": "latest",
|
|
14
|
-
"datagrok-api": "^
|
|
14
|
+
"datagrok-api": "^1.1.7",
|
|
15
15
|
"datagrok-tools": "^4.1.2",
|
|
16
|
-
"npm": "^
|
|
16
|
+
"npm": "^8.11.0",
|
|
17
17
|
"save-svg-as-png": "^1.4.17",
|
|
18
18
|
"ts-loader": "latest",
|
|
19
19
|
"typescript": "latest",
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"jest": "^27.0.0",
|
|
49
49
|
"@types/jest": "^27.0.0",
|
|
50
50
|
"ts-jest": "^27.0.0",
|
|
51
|
-
"puppeteer": "
|
|
52
|
-
}
|
|
51
|
+
"puppeteer": "^13.7.0"
|
|
52
|
+
},
|
|
53
|
+
"category": "Bioinformatics"
|
|
53
54
|
}
|
|
@@ -114,7 +114,7 @@ export function defineAxolabsPattern() {
|
|
|
114
114
|
asPtoLinkages = asPtoLinkages.concat(Array(maximalAsLength - asBases.length).fill(fullyPto));
|
|
115
115
|
asBases = asBases.concat(Array(maximalAsLength - asBases.length).fill(sequenceBase));
|
|
116
116
|
let nucleotideCounter = 0;
|
|
117
|
-
for (let i = 0; i < asLength.value
|
|
117
|
+
for (let i = 0; i < asLength.value!; i++) {
|
|
118
118
|
asPtoLinkages[i] = ui.boolInput('', asPtoLinkages[i].value, () => {
|
|
119
119
|
updateSvgScheme();
|
|
120
120
|
updateOutputExamples();
|
|
@@ -157,7 +157,7 @@ export function defineAxolabsPattern() {
|
|
|
157
157
|
ssPtoLinkages = ssPtoLinkages.concat(Array(maximalSsLength - ssBases.length).fill(fullyPto));
|
|
158
158
|
ssBases = ssBases.concat(Array(maximalSsLength - ssBases.length).fill(sequenceBase));
|
|
159
159
|
let nucleotideCounter = 0;
|
|
160
|
-
for (let i = 0; i < ssLength.value
|
|
160
|
+
for (let i = 0; i < ssLength.value!; i++) {
|
|
161
161
|
ssPtoLinkages[i] = ui.boolInput('', ssPtoLinkages[i].value, () => {
|
|
162
162
|
updateSvgScheme();
|
|
163
163
|
updateOutputExamples();
|
|
@@ -196,11 +196,11 @@ export function defineAxolabsPattern() {
|
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
function updateUiForNewSequenceLength() {
|
|
199
|
-
if (ssLength.value < maximalValidSequenceLength && asLength.value < maximalValidSequenceLength) {
|
|
200
|
-
if (ssLength.value > maximalSsLength)
|
|
201
|
-
maximalSsLength = ssLength.value
|
|
202
|
-
if (asLength.value > maximalAsLength)
|
|
203
|
-
maximalAsLength = asLength.value
|
|
199
|
+
if (ssLength.value! < maximalValidSequenceLength && asLength.value! < maximalValidSequenceLength) {
|
|
200
|
+
if (ssLength.value! > maximalSsLength)
|
|
201
|
+
maximalSsLength = ssLength.value!;
|
|
202
|
+
if (asLength.value! > maximalAsLength)
|
|
203
|
+
maximalAsLength = asLength.value!;
|
|
204
204
|
updateSsModification();
|
|
205
205
|
updateAsModification();
|
|
206
206
|
updateSvgScheme();
|
|
@@ -236,17 +236,17 @@ export function defineAxolabsPattern() {
|
|
|
236
236
|
}
|
|
237
237
|
|
|
238
238
|
function updateInputExamples() {
|
|
239
|
-
ssInputExample.value = generateExample(ssLength.value
|
|
239
|
+
ssInputExample.value = generateExample(ssLength.value!, sequenceBase.value!);
|
|
240
240
|
if (createAsStrand.value)
|
|
241
|
-
asInputExample.value = generateExample(asLength.value
|
|
241
|
+
asInputExample.value = generateExample(asLength.value!, sequenceBase.value!);
|
|
242
242
|
}
|
|
243
243
|
|
|
244
244
|
function updateOutputExamples() {
|
|
245
245
|
ssOutputExample.value = translateSequence(
|
|
246
|
-
ssInputExample.value, ssBases, ssPtoLinkages, ssFiveModification, ssThreeModification, firstSsPto.value);
|
|
246
|
+
ssInputExample.value, ssBases, ssPtoLinkages, ssFiveModification, ssThreeModification, firstSsPto.value!);
|
|
247
247
|
if (createAsStrand.value) {
|
|
248
248
|
asOutputExample.value = translateSequence(
|
|
249
|
-
asInputExample.value, asBases, asPtoLinkages, asFiveModification, asThreeModification, firstAsPto.value);
|
|
249
|
+
asInputExample.value, asBases, asPtoLinkages, asFiveModification, asThreeModification, firstAsPto.value!);
|
|
250
250
|
}
|
|
251
251
|
}
|
|
252
252
|
|
|
@@ -256,11 +256,11 @@ export function defineAxolabsPattern() {
|
|
|
256
256
|
ui.span([
|
|
257
257
|
drawAxolabsPattern(
|
|
258
258
|
getShortName(saveAs.value),
|
|
259
|
-
createAsStrand.value
|
|
260
|
-
ssBases.slice(0, ssLength.value).map((e) => e.value),
|
|
261
|
-
asBases.slice(0, asLength.value).map((e) => e.value),
|
|
262
|
-
[firstSsPto.value].concat(ssPtoLinkages.slice(0, ssLength.value).map((e) => e.value)),
|
|
263
|
-
[firstAsPto.value].concat(asPtoLinkages.slice(0, asLength.value).map((e) => e.value)),
|
|
259
|
+
createAsStrand.value!,
|
|
260
|
+
ssBases.slice(0, ssLength.value!).map((e) => e.value),
|
|
261
|
+
asBases.slice(0, asLength.value!).map((e) => e.value),
|
|
262
|
+
[firstSsPto.value!].concat(ssPtoLinkages.slice(0, ssLength.value!).map((e) => e.value)),
|
|
263
|
+
[firstAsPto.value!].concat(asPtoLinkages.slice(0, asLength.value!).map((e) => e.value)),
|
|
264
264
|
ssThreeModification.value,
|
|
265
265
|
ssFiveModification.value,
|
|
266
266
|
asThreeModification.value,
|
|
@@ -329,7 +329,7 @@ export function defineAxolabsPattern() {
|
|
|
329
329
|
}
|
|
330
330
|
|
|
331
331
|
function checkWhetherAllValuesInColumnHaveTheSameLength(colName: string): boolean {
|
|
332
|
-
const col = tables.value
|
|
332
|
+
const col = tables.value!.columns.byName(colName);
|
|
333
333
|
let allLengthsAreTheSame = true;
|
|
334
334
|
for (let i = 1; i < col.length; i++) {
|
|
335
335
|
if (col.get(i - 1).length != col.get(i).length) {
|
|
@@ -344,10 +344,10 @@ export function defineAxolabsPattern() {
|
|
|
344
344
|
.add(ui.divText('The sequence length should match the number of Raw sequences in the input file'))
|
|
345
345
|
.add(ui.divText('\'ADD COLUMN\' to see sequences lengths'))
|
|
346
346
|
.addButton('ADD COLUMN', () => {
|
|
347
|
-
tables.value
|
|
348
|
-
grok.shell.info('Column with lengths added to \'' + tables.value
|
|
347
|
+
tables.value!.columns.addNewInt('Sequences lengths in ' + colName).init((j: number) => col.get(j).length);
|
|
348
|
+
grok.shell.info('Column with lengths added to \'' + tables.value!.name + '\'');
|
|
349
349
|
dialog.close();
|
|
350
|
-
grok.shell.v = grok.shell.getTableView(tables.value
|
|
350
|
+
grok.shell.v = grok.shell.getTableView(tables.value!.name);
|
|
351
351
|
})
|
|
352
352
|
.show();
|
|
353
353
|
}
|
|
@@ -368,10 +368,10 @@ export function defineAxolabsPattern() {
|
|
|
368
368
|
userStorageKey,
|
|
369
369
|
saveAs.stringValue,
|
|
370
370
|
JSON.stringify({
|
|
371
|
-
'ssBases': ssBases.slice(0, ssLength.value).map((e) => e.value),
|
|
372
|
-
'asBases': asBases.slice(0, asLength.value).map((e) => e.value),
|
|
373
|
-
'ssPtoLinkages': [firstSsPto.value].concat(ssPtoLinkages.slice(0, ssLength.value).map((e) => e.value)),
|
|
374
|
-
'asPtoLinkages': [firstAsPto.value].concat(asPtoLinkages.slice(0, asLength.value).map((e) => e.value)),
|
|
371
|
+
'ssBases': ssBases.slice(0, ssLength.value!).map((e) => e.value),
|
|
372
|
+
'asBases': asBases.slice(0, asLength.value!).map((e) => e.value),
|
|
373
|
+
'ssPtoLinkages': [firstSsPto.value].concat(ssPtoLinkages.slice(0, ssLength.value!).map((e) => e.value)),
|
|
374
|
+
'asPtoLinkages': [firstAsPto.value].concat(asPtoLinkages.slice(0, asLength.value!).map((e) => e.value)),
|
|
375
375
|
'ssThreeModification': ssThreeModification.value,
|
|
376
376
|
'ssFiveModification': ssFiveModification.value,
|
|
377
377
|
'asThreeModification': asThreeModification.value,
|
|
@@ -506,24 +506,24 @@ export function defineAxolabsPattern() {
|
|
|
506
506
|
|
|
507
507
|
function validateSsColumn(colName: string) {
|
|
508
508
|
const allLengthsAreTheSame: boolean = checkWhetherAllValuesInColumnHaveTheSameLength(colName);
|
|
509
|
-
const firstSequence = tables.value
|
|
509
|
+
const firstSequence = tables.value!.columns.byName(colName).get(0);
|
|
510
510
|
if (allLengthsAreTheSame && firstSequence.length != ssLength.value)
|
|
511
|
-
ssLength.value = tables.value
|
|
511
|
+
ssLength.value = tables.value!.columns.byName(colName).get(0).length;
|
|
512
512
|
ssInputExample.value = firstSequence;
|
|
513
513
|
}
|
|
514
514
|
|
|
515
515
|
function validateAsColumn(colName: string) {
|
|
516
516
|
const allLengthsAreTheSame: boolean = checkWhetherAllValuesInColumnHaveTheSameLength(colName);
|
|
517
|
-
const firstSequence = tables.value
|
|
517
|
+
const firstSequence = tables.value!.columns.byName(colName).get(0);
|
|
518
518
|
if (allLengthsAreTheSame && firstSequence.length != asLength.value)
|
|
519
|
-
asLength.value = tables.value
|
|
519
|
+
asLength.value = tables.value!.columns.byName(colName).get(0).length;
|
|
520
520
|
asLengthDiv.innerHTML = '';
|
|
521
521
|
asLengthDiv.append(asLength.root);
|
|
522
522
|
asInputExample.value = firstSequence;
|
|
523
523
|
}
|
|
524
524
|
|
|
525
525
|
function validateIdsColumn(colName: string) {
|
|
526
|
-
const col = tables.value
|
|
526
|
+
const col = tables.value!.columns.byName(colName);
|
|
527
527
|
if (col.type != DG.TYPE.INT)
|
|
528
528
|
grok.shell.error('Column should contain integers only');
|
|
529
529
|
else if (col.categories.length < col.length) {
|
|
@@ -531,32 +531,35 @@ export function defineAxolabsPattern() {
|
|
|
531
531
|
ui.dialog('Non-unique IDs')
|
|
532
532
|
.add(ui.divText('Press \'OK\' to select rows with non-unique values'))
|
|
533
533
|
.onOK(() => {
|
|
534
|
-
const selection = tables.value
|
|
534
|
+
const selection = tables.value!.selection;
|
|
535
535
|
selection.init((i: number) => duplicates.indexOf(col.get(i)) > -1);
|
|
536
|
-
grok.shell.v = grok.shell.getTableView(tables.value
|
|
537
|
-
grok.shell.info('Rows are selected in table \'' + tables.value
|
|
536
|
+
grok.shell.v = grok.shell.getTableView(tables.value!.name);
|
|
537
|
+
grok.shell.info('Rows are selected in table \'' + tables.value!.name + '\'');
|
|
538
538
|
})
|
|
539
539
|
.show();
|
|
540
540
|
}
|
|
541
541
|
}
|
|
542
542
|
|
|
543
543
|
const tables = ui.tableInput('Tables', grok.shell.tables[0], grok.shell.tables, (t: DG.DataFrame) => {
|
|
544
|
-
inputSsColumn =
|
|
544
|
+
const inputSsColumn =
|
|
545
|
+
ui.choiceInput('SS Column', '', t.columns.names(), (colName: string) => validateSsColumn(colName));
|
|
545
546
|
inputSsColumnDiv.innerHTML = '';
|
|
546
547
|
inputSsColumnDiv.append(inputSsColumn.root);
|
|
547
|
-
inputAsColumn =
|
|
548
|
+
const inputAsColumn =
|
|
549
|
+
ui.choiceInput('AS Column', '', t.columns.names(), (colName: string) => validateAsColumn(colName));
|
|
548
550
|
inputAsColumnDiv.innerHTML = '';
|
|
549
551
|
inputAsColumnDiv.append(inputAsColumn.root);
|
|
550
|
-
inputIdColumn =
|
|
552
|
+
const inputIdColumn =
|
|
553
|
+
ui.choiceInput('ID Column', '', t.columns.names(), (colName: string) => validateIdsColumn(colName));
|
|
551
554
|
inputIdColumnDiv.innerHTML = '';
|
|
552
555
|
inputIdColumnDiv.append(inputIdColumn.root);
|
|
553
556
|
});
|
|
554
557
|
|
|
555
|
-
|
|
558
|
+
const inputSsColumn = ui.choiceInput('SS Column', '', []);
|
|
556
559
|
inputSsColumnDiv.append(inputSsColumn.root);
|
|
557
|
-
|
|
560
|
+
const inputAsColumn = ui.choiceInput('AS Column', '', []);
|
|
558
561
|
inputAsColumnDiv.append(inputAsColumn.root);
|
|
559
|
-
|
|
562
|
+
const inputIdColumn = ui.choiceInput('ID Column', '', []);
|
|
560
563
|
inputIdColumnDiv.append(inputIdColumn.root);
|
|
561
564
|
|
|
562
565
|
updatePatternsList();
|
|
@@ -573,8 +576,8 @@ export function defineAxolabsPattern() {
|
|
|
573
576
|
updateOutputExamples();
|
|
574
577
|
});
|
|
575
578
|
|
|
576
|
-
const firstSsPto = ui.boolInput('First SS PTO', fullyPto.value
|
|
577
|
-
const firstAsPto = ui.boolInput('First AS PTO', fullyPto.value
|
|
579
|
+
const firstSsPto = ui.boolInput('First SS PTO', fullyPto.value!, () => updateSvgScheme());
|
|
580
|
+
const firstAsPto = ui.boolInput('First AS PTO', fullyPto.value!, () => updateSvgScheme());
|
|
578
581
|
firstAsPtoDiv.append(firstAsPto.root);
|
|
579
582
|
|
|
580
583
|
const createAsStrand = ui.boolInput('Create AS Strand', true, (v: boolean) => {
|
|
@@ -643,34 +646,34 @@ export function defineAxolabsPattern() {
|
|
|
643
646
|
dialog
|
|
644
647
|
.add(ui.divText('Length of sequences in columns doesn\'t match entered length. Update length value?'))
|
|
645
648
|
.addButton('YES', () => {
|
|
646
|
-
ssLength.value = tables.value
|
|
647
|
-
asLength.value = tables.value
|
|
649
|
+
ssLength.value = tables.value!.columns.byName(inputSsColumn.value!).getString(0).length;
|
|
650
|
+
asLength.value = tables.value!.columns.byName(inputAsColumn.value!).getString(0).length;
|
|
648
651
|
dialog.close();
|
|
649
652
|
})
|
|
650
653
|
.show();
|
|
651
654
|
} else {
|
|
652
655
|
if (inputIdColumn.value != null)
|
|
653
|
-
addColumnWithIds(tables.value
|
|
656
|
+
addColumnWithIds(tables.value!.name, inputIdColumn.value, getShortName(saveAs.value));
|
|
654
657
|
addColumnWithTranslatedSequences(
|
|
655
|
-
tables.value
|
|
656
|
-
ssFiveModification, ssThreeModification, firstSsPto.value);
|
|
658
|
+
tables.value!.name, inputSsColumn.value, ssBases, ssPtoLinkages,
|
|
659
|
+
ssFiveModification, ssThreeModification, firstSsPto.value!);
|
|
657
660
|
if (createAsStrand.value) {
|
|
658
661
|
addColumnWithTranslatedSequences(
|
|
659
|
-
tables.value
|
|
660
|
-
asFiveModification, asThreeModification, firstAsPto.value);
|
|
662
|
+
tables.value!.name, inputAsColumn.value!, asBases, asPtoLinkages,
|
|
663
|
+
asFiveModification, asThreeModification, firstAsPto.value!);
|
|
661
664
|
}
|
|
662
|
-
grok.shell.v = grok.shell.getTableView(tables.value
|
|
665
|
+
grok.shell.v = grok.shell.getTableView(tables.value!.name);
|
|
663
666
|
grok.shell.info(((createAsStrand.value) ? 'Columns were' : 'Column was') +
|
|
664
|
-
' added to table \'' + tables.value
|
|
667
|
+
' added to table \'' + tables.value!.name + '\'');
|
|
665
668
|
}
|
|
666
669
|
});
|
|
667
670
|
|
|
668
|
-
const ssInputExample = ui.textInput('Sense Strand', generateExample(ssLength.value
|
|
671
|
+
const ssInputExample = ui.textInput('Sense Strand', generateExample(ssLength.value!, sequenceBase.value!), () => {
|
|
669
672
|
ssOutputExample.value = translateSequence(ssInputExample.value, ssBases, ssPtoLinkages,
|
|
670
|
-
ssFiveModification, ssThreeModification, firstSsPto.value);
|
|
673
|
+
ssFiveModification, ssThreeModification, firstSsPto.value!);
|
|
671
674
|
});
|
|
672
675
|
const ssOutputExample = ui.textInput(' ', translateSequence(
|
|
673
|
-
ssInputExample.value, ssBases, ssPtoLinkages, ssThreeModification, ssFiveModification, firstSsPto.value));
|
|
676
|
+
ssInputExample.value, ssBases, ssPtoLinkages, ssThreeModification, ssFiveModification, firstSsPto.value!));
|
|
674
677
|
(ssInputExample.input as HTMLElement).style.resize = 'none';
|
|
675
678
|
(ssInputExample.input as HTMLElement).style.minWidth = exampleMinWidth;
|
|
676
679
|
(ssOutputExample.input as HTMLElement).style.resize = 'none';
|
|
@@ -686,12 +689,12 @@ export function defineAxolabsPattern() {
|
|
|
686
689
|
], 'ui-input-options'),
|
|
687
690
|
);
|
|
688
691
|
|
|
689
|
-
const asInputExample = ui.textInput('Antisense Strand', generateExample(asLength.value
|
|
692
|
+
const asInputExample = ui.textInput('Antisense Strand', generateExample(asLength.value!, sequenceBase.value!), () => {
|
|
690
693
|
asOutputExample.value = translateSequence(
|
|
691
|
-
asInputExample.value, asBases, asPtoLinkages, asFiveModification, asThreeModification, firstSsPto.value);
|
|
694
|
+
asInputExample.value, asBases, asPtoLinkages, asFiveModification, asThreeModification, firstSsPto.value!);
|
|
692
695
|
});
|
|
693
696
|
const asOutputExample = ui.textInput(' ', translateSequence(
|
|
694
|
-
asInputExample.value, asBases, asPtoLinkages, asFiveModification, asThreeModification, firstSsPto.value));
|
|
697
|
+
asInputExample.value, asBases, asPtoLinkages, asFiveModification, asThreeModification, firstSsPto.value!));
|
|
695
698
|
(asInputExample.input as HTMLElement).style.resize = 'none';
|
|
696
699
|
(asInputExample.input as HTMLElement).style.minWidth = exampleMinWidth;
|
|
697
700
|
(asOutputExample.input as HTMLElement).style.resize = 'none';
|
package/src/package-test.ts
CHANGED
package/src/package.ts
CHANGED
|
@@ -7,7 +7,8 @@ import $ from 'cash-dom';
|
|
|
7
7
|
import {defineAxolabsPattern} from './defineAxolabsPattern';
|
|
8
8
|
import {saveSenseAntiSense} from './structures-works/save-sense-antisense';
|
|
9
9
|
import {sequenceToSmiles, sequenceToMolV3000} from './structures-works/from-monomers';
|
|
10
|
-
import {convertSequence, undefinedInputSequence, isValidSequence} from
|
|
10
|
+
import {convertSequence, undefinedInputSequence, isValidSequence, getFormat} from
|
|
11
|
+
'./structures-works/sequence-codes-tools';
|
|
11
12
|
import {map, COL_NAMES, MODIFICATIONS} from './structures-works/map';
|
|
12
13
|
import {SALTS_CSV} from './salts';
|
|
13
14
|
import {USERS_CSV} from './users';
|
|
@@ -29,14 +30,17 @@ export function sequenceTranslator(): void {
|
|
|
29
30
|
windows.showToolbox = false;
|
|
30
31
|
windows.showHelp = false;
|
|
31
32
|
|
|
32
|
-
function updateTableAndMolecule(sequence: string): void {
|
|
33
|
+
function updateTableAndMolecule(sequence: string, inputFormat: string, isSet: boolean): void {
|
|
33
34
|
moleculeSvgDiv.innerHTML = '';
|
|
34
35
|
outputTableDiv.innerHTML = '';
|
|
35
36
|
const pi = DG.TaskBarProgressIndicator.create('Rendering table and molecule...');
|
|
36
37
|
let errorsExist = false;
|
|
37
38
|
try {
|
|
38
39
|
sequence = sequence.replace(/\s/g, '');
|
|
39
|
-
const output = isValidSequence(sequence);
|
|
40
|
+
const output = isValidSequence(sequence, null);
|
|
41
|
+
if (isSet)
|
|
42
|
+
output.synthesizer = [inputFormat];
|
|
43
|
+
inputFormatChoiceInput.value = output.synthesizer![0];
|
|
40
44
|
const outputSequenceObj = convertSequence(sequence, output);
|
|
41
45
|
const tableRows = [];
|
|
42
46
|
|
|
@@ -88,13 +92,13 @@ export function sequenceTranslator(): void {
|
|
|
88
92
|
[item.key, item.value], ['Code', 'Sequence']).root,
|
|
89
93
|
]),
|
|
90
94
|
);
|
|
91
|
-
semTypeOfInputSequence.textContent = 'Detected input type: ' + outputSequenceObj.type;
|
|
92
95
|
|
|
93
96
|
if (outputSequenceObj.type != undefinedInputSequence && outputSequenceObj.Error != undefinedInputSequence) {
|
|
94
97
|
const canvas = ui.canvas(300, 170);
|
|
95
98
|
canvas.addEventListener('click', () => {
|
|
96
99
|
const canv = ui.canvas($(window).width(), $(window).height());
|
|
97
|
-
const mol = sequenceToMolV3000(inputSequenceField.value.replace(/\s/g, ''), false, true
|
|
100
|
+
const mol = sequenceToMolV3000(inputSequenceField.value.replace(/\s/g, ''), false, true,
|
|
101
|
+
output.synthesizer![0]);
|
|
98
102
|
// @ts-ignore
|
|
99
103
|
OCL.StructureView.drawMolecule(canv, OCL.Molecule.fromMolfile(mol), {suppressChiralText: true});
|
|
100
104
|
ui.dialog('Molecule: ' + inputSequenceField.value)
|
|
@@ -103,7 +107,8 @@ export function sequenceTranslator(): void {
|
|
|
103
107
|
});
|
|
104
108
|
$(canvas).on('mouseover', () => $(canvas).css('cursor', 'zoom-in'));
|
|
105
109
|
$(canvas).on('mouseout', () => $(canvas).css('cursor', 'default'));
|
|
106
|
-
const mol = sequenceToMolV3000(inputSequenceField.value.replace(/\s/g, ''), false, true
|
|
110
|
+
const mol = sequenceToMolV3000(inputSequenceField.value.replace(/\s/g, ''), false, true,
|
|
111
|
+
output.synthesizer![0]);
|
|
107
112
|
// @ts-ignore
|
|
108
113
|
OCL.StructureView.drawMolecule(canvas, OCL.Molecule.fromMolfile(mol), {suppressChiralText: true});
|
|
109
114
|
moleculeSvgDiv.append(canvas);
|
|
@@ -114,10 +119,14 @@ export function sequenceTranslator(): void {
|
|
|
114
119
|
}
|
|
115
120
|
}
|
|
116
121
|
|
|
117
|
-
const
|
|
122
|
+
const inputFormatChoiceInput = ui.choiceInput(
|
|
123
|
+
'Input format: ', 'Janssen GCRS Codes', Object.keys(map), (format: string) => {
|
|
124
|
+
updateTableAndMolecule(inputSequenceField.value.replace(/\s/g, ''), format, true);
|
|
125
|
+
});
|
|
118
126
|
const moleculeSvgDiv = ui.block([]);
|
|
119
127
|
const outputTableDiv = ui.div([]);
|
|
120
|
-
const inputSequenceField = ui.textInput('', defaultInput, (sequence: string) => updateTableAndMolecule(sequence
|
|
128
|
+
const inputSequenceField = ui.textInput('', defaultInput, (sequence: string) => updateTableAndMolecule(sequence,
|
|
129
|
+
inputFormatChoiceInput.value!, false));
|
|
121
130
|
|
|
122
131
|
const asoDf = DG.DataFrame.fromObjects([
|
|
123
132
|
{'Name': '2\'MOE-5Me-rU', 'BioSpring': '5', 'Janssen GCRS': 'moeT'},
|
|
@@ -156,12 +165,11 @@ export function sequenceTranslator(): void {
|
|
|
156
165
|
);
|
|
157
166
|
|
|
158
167
|
const overhangModificationsGrid = DG.Viewer.grid(
|
|
159
|
-
DG.DataFrame.
|
|
160
|
-
|
|
161
|
-
{'Name': '(GalNAc-2-JNJ)'},
|
|
168
|
+
DG.DataFrame.fromColumns([
|
|
169
|
+
DG.Column.fromStrings('Name', Object.keys(MODIFICATIONS)),
|
|
162
170
|
])!, {showRowHeader: false, showCellTooltip: false},
|
|
163
171
|
);
|
|
164
|
-
updateTableAndMolecule(defaultInput);
|
|
172
|
+
updateTableAndMolecule(defaultInput, inputFormatChoiceInput.value!, true);
|
|
165
173
|
|
|
166
174
|
const appMainDescription = ui.info([
|
|
167
175
|
ui.divText('How to convert one sequence:', {style: {'font-weight': 'bolder'}}),
|
|
@@ -193,7 +201,7 @@ export function sequenceTranslator(): void {
|
|
|
193
201
|
inputSequenceField.root,
|
|
194
202
|
], 'input-base'),
|
|
195
203
|
], 'inputSequence'),
|
|
196
|
-
|
|
204
|
+
ui.div([inputFormatChoiceInput], {style: {padding: '5px 0'}}),
|
|
197
205
|
ui.block([
|
|
198
206
|
ui.h1('Output'),
|
|
199
207
|
outputTableDiv,
|
|
@@ -218,14 +226,16 @@ export function sequenceTranslator(): void {
|
|
|
218
226
|
|
|
219
227
|
const topPanel = [
|
|
220
228
|
ui.iconFA('download', () => {
|
|
221
|
-
const result = sequenceToMolV3000(inputSequenceField.value.replace(/\s/g, '')
|
|
229
|
+
const result = sequenceToMolV3000(inputSequenceField.value.replace(/\s/g, ''), false, false,
|
|
230
|
+
inputFormatChoiceInput.value!);
|
|
222
231
|
const element = document.createElement('a');
|
|
223
232
|
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(result));
|
|
224
233
|
element.setAttribute('download', inputSequenceField.value.replace(/\s/g, '') + '.mol');
|
|
225
234
|
element.click();
|
|
226
235
|
}, 'Save .mol file'),
|
|
227
236
|
ui.iconFA('copy', () => {
|
|
228
|
-
navigator.clipboard.writeText(
|
|
237
|
+
navigator.clipboard.writeText(
|
|
238
|
+
sequenceToSmiles(inputSequenceField.value.replace(/\s/g, ''), false, inputFormatChoiceInput.value!))
|
|
229
239
|
.then(() => grok.shell.info(sequenceWasCopied));
|
|
230
240
|
}, 'Copy SMILES'),
|
|
231
241
|
switchInput.root,
|
|
@@ -248,9 +258,10 @@ async function saveTableAsSdFile(table: DG.DataFrame) {
|
|
|
248
258
|
const typeColumn = table.col(COL_NAMES.TYPE)!;
|
|
249
259
|
let result = '';
|
|
250
260
|
for (let i = 0; i < table.rowCount; i++) {
|
|
261
|
+
const format = getFormat(structureColumn.get(i));
|
|
251
262
|
result += (typeColumn.get(i) == 'SS') ?
|
|
252
|
-
sequenceToMolV3000(structureColumn.get(i), false, true) + '\n' + `> <Sequence>\nSense Strand\n\n` :
|
|
253
|
-
sequenceToMolV3000(structureColumn.get(i), true, true) + '\n' + `> <Sequence>\nAnti Sense\n\n`;
|
|
263
|
+
sequenceToMolV3000(structureColumn.get(i), false, true, format!) + '\n' + `> <Sequence>\nSense Strand\n\n` :
|
|
264
|
+
sequenceToMolV3000(structureColumn.get(i), true, true, format!) + '\n' + `> <Sequence>\nAnti Sense\n\n`;
|
|
254
265
|
for (const col of table.columns) {
|
|
255
266
|
if (col.name != COL_NAMES.SEQUENCE)
|
|
256
267
|
result += `> <${col.name}>\n${col.get(i)}\n\n`;
|
|
@@ -2,8 +2,9 @@ import {map, stadardPhosphateLinkSmiles, SYNTHESIZERS, TECHNOLOGIES, MODIFICATIO
|
|
|
2
2
|
import {isValidSequence} from './sequence-codes-tools';
|
|
3
3
|
import {getNucleotidesMol} from './mol-transformations';
|
|
4
4
|
|
|
5
|
-
export function sequenceToMolV3000(sequence: string, inverted: boolean = false, oclRender: boolean = false
|
|
6
|
-
|
|
5
|
+
export function sequenceToMolV3000(sequence: string, inverted: boolean = false, oclRender: boolean = false,
|
|
6
|
+
format: string): string {
|
|
7
|
+
const obj = getObjectWithCodesAndSmiles(sequence, format);
|
|
7
8
|
let codes = sortByStringLengthInDescendingOrder(Object.keys(obj));
|
|
8
9
|
let i = 0;
|
|
9
10
|
const smilesCodes:string[] = [];
|
|
@@ -38,8 +39,8 @@ export function sequenceToMolV3000(sequence: string, inverted: boolean = false,
|
|
|
38
39
|
return getNucleotidesMol(smilesCodes, oclRender);
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
export function sequenceToSmiles(sequence: string, inverted: boolean = false): string {
|
|
42
|
-
const obj = getObjectWithCodesAndSmiles(sequence);
|
|
42
|
+
export function sequenceToSmiles(sequence: string, inverted: boolean = false, format: string): string {
|
|
43
|
+
const obj = getObjectWithCodesAndSmiles(sequence, format);
|
|
43
44
|
let codes = sortByStringLengthInDescendingOrder(Object.keys(obj));
|
|
44
45
|
let i = 0;
|
|
45
46
|
let smiles = '';
|
|
@@ -82,19 +83,26 @@ export function sequenceToSmiles(sequence: string, inverted: boolean = false): s
|
|
|
82
83
|
smiles.slice(0, smiles.length - stadardPhosphateLinkSmiles.length + 1);
|
|
83
84
|
}
|
|
84
85
|
|
|
85
|
-
function getObjectWithCodesAndSmiles(sequence: string) {
|
|
86
|
+
function getObjectWithCodesAndSmiles(sequence: string, format: string) {
|
|
86
87
|
const obj: { [code: string]: string } = {};
|
|
87
|
-
|
|
88
|
-
for (const
|
|
89
|
-
for (const
|
|
90
|
-
|
|
88
|
+
if (format == null) {
|
|
89
|
+
for (const synthesizer of Object.keys(map)) {
|
|
90
|
+
for (const technology of Object.keys(map[synthesizer])) {
|
|
91
|
+
for (const code of Object.keys(map[synthesizer][technology]))
|
|
92
|
+
obj[code] = map[synthesizer][technology][code].SMILES;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
} else {
|
|
96
|
+
for (const technology of Object.keys(map[format])) {
|
|
97
|
+
for (const code of Object.keys(map[format][technology]))
|
|
98
|
+
obj[code] = map[format][technology][code].SMILES;
|
|
91
99
|
}
|
|
92
100
|
}
|
|
93
101
|
// TODO: create object based from synthesizer type to avoid key(codes) duplicates
|
|
94
|
-
const output = isValidSequence(sequence);
|
|
95
|
-
if (output.synthesizer
|
|
102
|
+
const output = isValidSequence(sequence, format);
|
|
103
|
+
if (output.synthesizer!.includes(SYNTHESIZERS.MERMADE_12))
|
|
96
104
|
obj['g'] = map[SYNTHESIZERS.MERMADE_12][TECHNOLOGIES.SI_RNA]['g'].SMILES;
|
|
97
|
-
else if (output.synthesizer
|
|
105
|
+
else if (output.synthesizer!.includes(SYNTHESIZERS.AXOLABS))
|
|
98
106
|
obj['g'] = map[SYNTHESIZERS.AXOLABS][TECHNOLOGIES.SI_RNA]['g'].SMILES;
|
|
99
107
|
return obj;
|
|
100
108
|
}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import * as ui from 'datagrok-api/ui';
|
|
2
2
|
import {sequenceToMolV3000} from '../structures-works/from-monomers';
|
|
3
3
|
import {linkV3000} from '../structures-works/mol-transformations';
|
|
4
|
+
import {getFormat} from '../structures-works/sequence-codes-tools';
|
|
4
5
|
|
|
5
6
|
export function saveSdf(as: string, ss: string, oneEntity: boolean, fit3dx: boolean) {
|
|
6
|
-
const
|
|
7
|
-
const
|
|
7
|
+
const formatAs = getFormat(as);
|
|
8
|
+
const formatSs = getFormat(ss);
|
|
9
|
+
const molSS = sequenceToMolV3000(ss, false, false, formatSs!);
|
|
10
|
+
const molAS = sequenceToMolV3000(as, true, false, formatAs!);
|
|
8
11
|
let result: string;
|
|
9
12
|
if (oneEntity)
|
|
10
13
|
result = linkV3000([molSS, molAS], true, !fit3dx) + '\n\n$$$$\n';
|