@datagrok/sequence-translator 1.2.4 → 1.2.5

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@datagrok/sequence-translator",
3
3
  "friendlyName": "Sequence Translator",
4
- "version": "1.2.4",
4
+ "version": "1.2.5",
5
5
  "author": {
6
6
  "name": "Alexey Choposky",
7
7
  "email": "achopovsky@datagrok.ai"
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 (inputStrandColumn[s].value === '')
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 = tables.value!.getCol(colName);
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
- tables.value!.columns.addNewInt('Sequences lengths in ' + colName).init((j: number) => col.get(j).length);
230
- grok.shell.info('Column with lengths added to \'' + tables.value!.name + '\'');
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(tables.value!.name);
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 = tables.value!.getCol(colName).get(0);
370
+ const firstSequence = tableInput.value!.getCol(colName).get(0);
371
371
  if (allLengthsAreTheSame && firstSequence.length !== strandLengthInput[strand].value)
372
- strandLengthInput[strand].value = tables.value!.getCol(colName).get(0).length;
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 = tables.value!.getCol(colName);
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 = tables.value!.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(tables.value!.name);
388
- grok.shell.info('Rows are selected in table \'' + tables.value!.name + '\'');
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
- // todo: rename to strandColumnInput
448
- const inputStrandColumn = Object.fromEntries(STRANDS.map((strand) => {
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
- const tables = ui.tableInput('Tables', grok.shell.tables[0], grok.shell.tables, (t: DG.DataFrame) => {
553
- STRANDS.forEach((strand) => {
554
- inputStrandColumn[strand] = ui.choiceInput(`${strand} column`, '', t.columns.names(), (colName: string) => {
555
- validateStrandColumn(colName, strand);
556
- strandVar[strand] = colName;
557
- });
558
- inputStrandColumnDiv[strand].innerHTML = '';
559
- inputStrandColumnDiv[strand].append(inputStrandColumn[strand].root);
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
- // todo: unify with inputStrandColumn
563
- const inputIdColumn = ui.choiceInput('ID column', '', t.columns.names(), (colName: string) => {
564
- validateIdsColumn(colName);
565
- idVar = colName;
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
- inputIdColumnDiv.innerHTML = '';
568
- inputIdColumnDiv.append(inputIdColumn.root);
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
- inputStrandColumnDiv[AS].hidden = !v;
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 = tables.value!.getCol(inputStrandColumn[s].value!).getString(0).length;
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(tables.value!.name, idVar, getShortName(saveAs.value));
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
- tables.value!.name, strandVar[strand], baseInputsObject[strand], ptoLinkages[strand],
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(tables.value!.name);
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 \'' + tables.value!.name + '\'');
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
- tables.root,
667
- inputStrandColumnDiv[SS],
668
- inputStrandColumnDiv[AS],
669
- inputIdColumnDiv,
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
- tables.root,
712
- inputStrandColumn[SS],
713
- inputStrandColumn[AS],
722
+ tableInput.root,
723
+ strandColumnInput[SS],
724
+ strandColumnInput[AS],
714
725
  inputIdColumn.root,
715
726
  ui.buttonsInput([
716
727
  convertSequenceButton,