@datagrok/sequence-translator 1.2.4 → 1.2.6
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 -0
- package/dist/package-test.js.map +1 -1
- package/dist/package.js +1 -1
- package/dist/package.js.map +1 -1
- package/package.json +1 -1
- package/src/model/structure-app/mol-transformations.ts +2 -2
- package/src/model/structure-app/sequence-to-molfile.ts +1 -1
- package/src/package.ts +4 -0
- package/src/view/apps/oligo-pattern.ts +67 -56
package/package.json
CHANGED
|
@@ -18,7 +18,7 @@ export function getNucleotidesMol(codes: string[]) {
|
|
|
18
18
|
export function linkStrandsV3000(
|
|
19
19
|
strands: { senseStrands: string[], antiStrands: string[] }, useChirality: boolean = true
|
|
20
20
|
): string {
|
|
21
|
-
let macroMolBlock = '\
|
|
21
|
+
let macroMolBlock = '\n Datagrok macromolecule handler\n\n';
|
|
22
22
|
macroMolBlock += ' 0 0 0 0 0 0 999 V3000\n';
|
|
23
23
|
macroMolBlock += 'M V30 BEGIN CTAB\n';
|
|
24
24
|
let atomBlock = '';
|
|
@@ -189,7 +189,7 @@ export function linkStrandsV3000(
|
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
export function linkV3000(molBlocks: string[], useChirality: boolean = true): string {
|
|
192
|
-
let macroMolBlock = '\
|
|
192
|
+
let macroMolBlock = '\n Datagrok macromolecule handler\n\n';
|
|
193
193
|
macroMolBlock += ' 0 0 0 0 0 0 999 V3000\n';
|
|
194
194
|
macroMolBlock += 'M V30 BEGIN CTAB\n';
|
|
195
195
|
let atomBlock = '';
|
|
@@ -219,7 +219,7 @@ export class SequenceToMolfileConverter {
|
|
|
219
219
|
|
|
220
220
|
|
|
221
221
|
private linkV3000(molBlocks: string[], useChirality: boolean = true): string {
|
|
222
|
-
let macroMolBlock = '\
|
|
222
|
+
let macroMolBlock = '\n Datagrok macromolecule handler\n\n';
|
|
223
223
|
macroMolBlock += ' 0 0 0 0 0 0 999 V3000\n';
|
|
224
224
|
macroMolBlock += 'M V30 BEGIN CTAB\n';
|
|
225
225
|
let atomBlock = '';
|
package/src/package.ts
CHANGED
|
@@ -51,6 +51,7 @@ async function buildLayout(appName: string): Promise<void> {
|
|
|
51
51
|
|
|
52
52
|
//name: Oligo Toolkit
|
|
53
53
|
//meta.icon: img/icons/toolkit.png
|
|
54
|
+
//meta.browsePath: Oligo
|
|
54
55
|
//tags: app
|
|
55
56
|
export async function oligoToolkitApp(): Promise<void> {
|
|
56
57
|
await initSequenceTranslatorLibData();
|
|
@@ -63,6 +64,7 @@ export async function oligoToolkitApp(): Promise<void> {
|
|
|
63
64
|
|
|
64
65
|
//name: Oligo Translator
|
|
65
66
|
//meta.icon: img/icons/translator.png
|
|
67
|
+
//meta.browsePath: Oligo
|
|
66
68
|
//tags: app
|
|
67
69
|
export async function oligoTranslatorApp(): Promise<void> {
|
|
68
70
|
await buildLayout(APP.TRANSLATOR);
|
|
@@ -70,6 +72,7 @@ export async function oligoTranslatorApp(): Promise<void> {
|
|
|
70
72
|
|
|
71
73
|
//name: Oligo Pattern
|
|
72
74
|
//meta.icon: img/icons/pattern.png
|
|
75
|
+
//meta.browsePath: Oligo
|
|
73
76
|
//tags: app
|
|
74
77
|
export async function oligoPatternApp(): Promise<void> {
|
|
75
78
|
await buildLayout(APP.PATTERN);
|
|
@@ -77,6 +80,7 @@ export async function oligoPatternApp(): Promise<void> {
|
|
|
77
80
|
|
|
78
81
|
//name: Oligo Structure
|
|
79
82
|
//meta.icon: img/icons/structure.png
|
|
83
|
+
//meta.browsePath: Oligo
|
|
80
84
|
//tags: app
|
|
81
85
|
export async function oligoStructureApp(): Promise<void> {
|
|
82
86
|
await buildLayout(APP.STRUCTRE);
|
|
@@ -107,7 +107,7 @@ export class PatternLayoutHandler {
|
|
|
107
107
|
|
|
108
108
|
function updateInputExamples() {
|
|
109
109
|
STRANDS.forEach((s) => {
|
|
110
|
-
if (
|
|
110
|
+
if (strandColumnInput[s].value === '')
|
|
111
111
|
inputExample[s].value = generateExample(strandLengthInput[s].value!, sequenceBase.value!);
|
|
112
112
|
});
|
|
113
113
|
}
|
|
@@ -211,7 +211,7 @@ export class PatternLayoutHandler {
|
|
|
211
211
|
}
|
|
212
212
|
|
|
213
213
|
function allColumnValuesOfEqualLength(colName: string): boolean {
|
|
214
|
-
const col =
|
|
214
|
+
const col = tableInput.value!.getCol(colName);
|
|
215
215
|
let allLengthsAreTheSame = true;
|
|
216
216
|
for (let i = 1; i < col.length; i++) {
|
|
217
217
|
if (col.get(i - 1).length !== col.get(i).length && col.get(i).length !== 0) {
|
|
@@ -226,14 +226,14 @@ export class PatternLayoutHandler {
|
|
|
226
226
|
.add(ui.divText('The sequence length should match the number of Raw sequences in the input file'))
|
|
227
227
|
.add(ui.divText('\'ADD COLUMN\' to see sequences lengths'))
|
|
228
228
|
.addButton('ADD COLUMN', () => {
|
|
229
|
-
|
|
230
|
-
grok.shell.info('Column with lengths added to \'' +
|
|
229
|
+
tableInput.value!.columns.addNewInt('Sequences lengths in ' + colName).init((j: number) => col.get(j).length);
|
|
230
|
+
grok.shell.info('Column with lengths added to \'' + tableInput.value!.name + '\'');
|
|
231
231
|
dialog.close();
|
|
232
|
-
grok.shell.v = grok.shell.getTableView(
|
|
232
|
+
grok.shell.v = grok.shell.getTableView(tableInput.value!.name);
|
|
233
233
|
})
|
|
234
234
|
.show();
|
|
235
235
|
}
|
|
236
|
-
if (col.get(0) !== strandLengthInput[SS].value) {
|
|
236
|
+
if (col.get(0).length !== strandLengthInput[SS].value) {
|
|
237
237
|
const d = ui.dialog('Length was updated by value to from imported file');
|
|
238
238
|
d.add(ui.divText('Latest modifications may not take effect during translation'))
|
|
239
239
|
.onOK(() => grok.shell.info('Lengths changed')).show();
|
|
@@ -367,25 +367,26 @@ export class PatternLayoutHandler {
|
|
|
367
367
|
|
|
368
368
|
function validateStrandColumn(colName: string, strand: string): void {
|
|
369
369
|
const allLengthsAreTheSame: boolean = allColumnValuesOfEqualLength(colName);
|
|
370
|
-
const firstSequence =
|
|
370
|
+
const firstSequence = tableInput.value!.getCol(colName).get(0);
|
|
371
371
|
if (allLengthsAreTheSame && firstSequence.length !== strandLengthInput[strand].value)
|
|
372
|
-
strandLengthInput[strand].value =
|
|
372
|
+
strandLengthInput[strand].value = tableInput.value!.getCol(colName).get(0).length;
|
|
373
373
|
inputExample[strand].value = firstSequence;
|
|
374
374
|
}
|
|
375
375
|
|
|
376
376
|
function validateIdsColumn(colName: string) {
|
|
377
|
-
const col =
|
|
377
|
+
const col = tableInput.value!.getCol(colName);
|
|
378
378
|
if (col.type !== DG.TYPE.INT)
|
|
379
379
|
grok.shell.error('Column should contain integers only');
|
|
380
|
+
//@ts-ignore
|
|
380
381
|
else if (col.categories.filter((e) => e !== '').length < col.toList().filter((e) => e !== '').length) {
|
|
381
382
|
const duplicates = findDuplicates(col.getRawData());
|
|
382
383
|
ui.dialog('Non-unique IDs')
|
|
383
384
|
.add(ui.divText('Press \'OK\' to select rows with non-unique values'))
|
|
384
385
|
.onOK(() => {
|
|
385
|
-
const selection =
|
|
386
|
+
const selection = tableInput.value!.selection;
|
|
386
387
|
selection.init((i: number) => duplicates.indexOf(col.get(i)) > -1);
|
|
387
|
-
grok.shell.v = grok.shell.getTableView(
|
|
388
|
-
grok.shell.info('Rows are selected in table \'' +
|
|
388
|
+
grok.shell.v = grok.shell.getTableView(tableInput.value!.name);
|
|
389
|
+
grok.shell.info('Rows are selected in table \'' + tableInput.value!.name + '\'');
|
|
389
390
|
})
|
|
390
391
|
.show();
|
|
391
392
|
}
|
|
@@ -435,23 +436,16 @@ export class PatternLayoutHandler {
|
|
|
435
436
|
return [strand, input];
|
|
436
437
|
}));
|
|
437
438
|
const strandVar = Object.fromEntries(STRANDS.map((strand) => [strand, '']));
|
|
438
|
-
// todo: rename to strandColumnInputDiv
|
|
439
|
-
const inputStrandColumnDiv = Object.fromEntries(STRANDS.map(
|
|
440
|
-
(strand) => [strand, ui.div([])]
|
|
441
|
-
));
|
|
442
439
|
const inputExample = Object.fromEntries(STRANDS.map(
|
|
443
440
|
(strand) => [strand, ui.textInput(
|
|
444
441
|
``, generateExample(strandLengthInput[strand].value!, sequenceBase.value!))
|
|
445
442
|
]));
|
|
446
443
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
const input: StringInput = ui.choiceInput(`${STRAND_NAME[strand]} column`, '', [], (colName: string) => {
|
|
444
|
+
const strandColumnInput = Object.fromEntries(STRANDS.map((strand) => {
|
|
445
|
+
const input = ui.choiceInput(`${STRAND_NAME[strand]} column`, '', [], (colName: string) => {
|
|
450
446
|
validateStrandColumn(colName, strand);
|
|
451
447
|
strandVar[strand] = colName;
|
|
452
448
|
});
|
|
453
|
-
inputStrandColumnDiv[strand].append(input.root);
|
|
454
|
-
//input.addPostfix(``);
|
|
455
449
|
return [strand, input];
|
|
456
450
|
}));
|
|
457
451
|
|
|
@@ -464,8 +458,6 @@ export class PatternLayoutHandler {
|
|
|
464
458
|
input.captionLabel.style.maxWidth = '100px';
|
|
465
459
|
input.captionLabel.style.minWidth = '40px';
|
|
466
460
|
input.captionLabel.style.width = 'auto';
|
|
467
|
-
|
|
468
|
-
|
|
469
461
|
|
|
470
462
|
return [strand, input];
|
|
471
463
|
}));
|
|
@@ -508,9 +500,7 @@ export class PatternLayoutHandler {
|
|
|
508
500
|
STRANDS.forEach((s) => {
|
|
509
501
|
|
|
510
502
|
inputExample[s].input.style.resize = 'none';
|
|
511
|
-
//inputExample[s].input.style.minWidth = EXAMPLE_MIN_WIDTH;
|
|
512
503
|
outputExample[s].input.style.resize = 'none';
|
|
513
|
-
//outputExample[s].input.styl
|
|
514
504
|
inputExample[s].input.style.minWidth = 'none';
|
|
515
505
|
inputExample[s].input.style.flexGrow = '1';
|
|
516
506
|
outputExample[s].input.style.minWidth = 'none';
|
|
@@ -527,7 +517,7 @@ export class PatternLayoutHandler {
|
|
|
527
517
|
);
|
|
528
518
|
})
|
|
529
519
|
|
|
530
|
-
const inputIdColumnDiv = ui.div([]);
|
|
520
|
+
// const inputIdColumnDiv = ui.div([]);
|
|
531
521
|
const svgDiv = ui.div([]);
|
|
532
522
|
const asExampleDiv = ui.div([], 'ui-form ui-form-wide');
|
|
533
523
|
const loadPatternDiv = ui.div([]);
|
|
@@ -549,25 +539,45 @@ export class PatternLayoutHandler {
|
|
|
549
539
|
|
|
550
540
|
const asLengthDiv = ui.div([strandLengthInput[AS].root]);
|
|
551
541
|
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
542
|
+
function getTableInput(tableList: DG.DataFrame[]): DG.InputBase {
|
|
543
|
+
const tableInput = ui.tableInput('Tables', tableList[0], tableList, () => {
|
|
544
|
+
const table = tableInput.value;
|
|
545
|
+
if (table === null) {
|
|
546
|
+
console.warn('Table is null');
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
const tableName = table!.name;
|
|
550
|
+
if (!grok.shell.tableNames.includes(tableName)) {
|
|
551
|
+
const view = grok.shell.v;
|
|
552
|
+
grok.shell.addTableView(table!);
|
|
553
|
+
grok.shell.v = view;
|
|
554
|
+
}
|
|
555
|
+
const columnNames = table.columns.names();
|
|
556
|
+
|
|
557
|
+
STRANDS.forEach((strand) => {
|
|
558
|
+
const defaultColumn = columnNames[0];
|
|
559
|
+
validateStrandColumn(defaultColumn, strand);
|
|
560
|
+
strandVar[strand] = defaultColumn;
|
|
561
|
+
const input = ui.choiceInput(`${STRAND_NAME[strand]} column`, defaultColumn, columnNames, (colName: string) => {
|
|
562
|
+
validateStrandColumn(colName, strand);
|
|
563
|
+
strandVar[strand] = colName;
|
|
564
|
+
console.log(`clicked ${strand} var:`, strandVar[strand]);
|
|
565
|
+
});
|
|
566
|
+
$(strandColumnInput[strand].root).replaceWith(input.root);
|
|
567
|
+
})
|
|
561
568
|
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
569
|
+
idVar = columnNames[0];
|
|
570
|
+
// todo: unify with inputStrandColumn
|
|
571
|
+
const idInput = ui.choiceInput('ID column', columnNames[0], columnNames, (colName: string) => {
|
|
572
|
+
validateIdsColumn(colName);
|
|
573
|
+
idVar = colName;
|
|
574
|
+
});
|
|
575
|
+
$(inputIdColumn.root).replaceWith(idInput.root);
|
|
566
576
|
});
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
});
|
|
577
|
+
return tableInput;
|
|
578
|
+
}
|
|
570
579
|
|
|
580
|
+
const tableInput = getTableInput([]);
|
|
571
581
|
|
|
572
582
|
// todo: unify with strandVar
|
|
573
583
|
let idVar = '';
|
|
@@ -575,13 +585,13 @@ export class PatternLayoutHandler {
|
|
|
575
585
|
validateIdsColumn(colName);
|
|
576
586
|
idVar = colName;
|
|
577
587
|
});
|
|
578
|
-
inputIdColumnDiv.append(inputIdColumn.root);
|
|
588
|
+
// inputIdColumnDiv.append(inputIdColumn.root);
|
|
579
589
|
|
|
580
590
|
updatePatternsList();
|
|
581
591
|
|
|
582
592
|
const createAsStrand = ui.boolInput('Anti sense strand', true, (v: boolean) => {
|
|
583
593
|
modificationSection[AS].hidden = !v;
|
|
584
|
-
|
|
594
|
+
strandColumnInput[AS].root.hidden = !v;
|
|
585
595
|
asLengthDiv.hidden = !v;
|
|
586
596
|
asModificationDiv.hidden = !v;
|
|
587
597
|
asExampleDiv.hidden = !v;
|
|
@@ -618,6 +628,7 @@ export class PatternLayoutHandler {
|
|
|
618
628
|
|
|
619
629
|
const convertSequenceButton = ui.bigButton('Convert', () => {
|
|
620
630
|
const condition = [true, createAsStrand.value];
|
|
631
|
+
console.log(`strand vars:`, Object.values(strandVar));
|
|
621
632
|
if (STRANDS.some((s, i) => condition[i] && strandVar[s] === ''))
|
|
622
633
|
grok.shell.info('Please select table and columns on which to apply pattern');
|
|
623
634
|
else if (STRANDS.some((s) => strandLengthInput[s].value !== inputExample[s].value.length)) {
|
|
@@ -627,24 +638,24 @@ export class PatternLayoutHandler {
|
|
|
627
638
|
.add(ui.divText('Length of sequences in columns doesn\'t match entered length. Update length value?'))
|
|
628
639
|
.addButton('YES', () => {
|
|
629
640
|
STRANDS.forEach((s) => {
|
|
630
|
-
strandLengthInput[s].value =
|
|
641
|
+
strandLengthInput[s].value = tableInput.value!.getCol(strandColumnInput[s].value!).getString(0).length;
|
|
631
642
|
})
|
|
632
643
|
dialog.close();
|
|
633
644
|
})
|
|
634
645
|
.show();
|
|
635
646
|
} else {
|
|
636
647
|
if (idVar !== '')
|
|
637
|
-
addColumnWithIds(
|
|
648
|
+
addColumnWithIds(tableInput.value!.name, idVar, getShortName(saveAs.value));
|
|
638
649
|
const condition = [true, createAsStrand.value];
|
|
639
650
|
STRANDS.forEach((strand, i) => {
|
|
640
651
|
if (condition[i])
|
|
641
652
|
addColumnWithTranslatedSequences(
|
|
642
|
-
|
|
653
|
+
tableInput.value!.name, strandVar[strand], baseInputsObject[strand], ptoLinkages[strand],
|
|
643
654
|
terminalModification[strand][FIVE_PRIME], terminalModification[strand][THREE_PRIME], firstPto[strand].value!);
|
|
644
655
|
})
|
|
645
|
-
grok.shell.v = grok.shell.getTableView(
|
|
656
|
+
grok.shell.v = grok.shell.getTableView(tableInput.value!.name);
|
|
646
657
|
grok.shell.info(((createAsStrand.value) ? 'Columns were' : 'Column was') +
|
|
647
|
-
' added to table \'' +
|
|
658
|
+
' added to table \'' + tableInput.value!.name + '\'');
|
|
648
659
|
updateOutputExamples();
|
|
649
660
|
}
|
|
650
661
|
});
|
|
@@ -663,10 +674,10 @@ export class PatternLayoutHandler {
|
|
|
663
674
|
|
|
664
675
|
const inputsSection = ui.block50([
|
|
665
676
|
ui.h1('Convert options'),
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
677
|
+
tableInput.root,
|
|
678
|
+
strandColumnInput[SS].root,
|
|
679
|
+
strandColumnInput[AS].root,
|
|
680
|
+
inputIdColumn.root,
|
|
670
681
|
ui.buttonsInput([
|
|
671
682
|
convertSequenceButton,
|
|
672
683
|
]),
|
|
@@ -708,9 +719,9 @@ export class PatternLayoutHandler {
|
|
|
708
719
|
loadPatternDiv,
|
|
709
720
|
saveAs.root,
|
|
710
721
|
ui.h1('Convert'),
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
722
|
+
tableInput.root,
|
|
723
|
+
strandColumnInput[SS],
|
|
724
|
+
strandColumnInput[AS],
|
|
714
725
|
inputIdColumn.root,
|
|
715
726
|
ui.buttonsInput([
|
|
716
727
|
convertSequenceButton,
|