@datagrok/bio 2.15.13 → 2.16.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.
Files changed (78) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/detectors.js +16 -11
  3. package/dist/455.js.map +1 -1
  4. package/dist/980.js +1 -1
  5. package/dist/980.js.map +1 -1
  6. package/dist/package-test.js +6 -6
  7. package/dist/package-test.js.map +1 -1
  8. package/dist/package.js +3 -3
  9. package/dist/package.js.map +1 -1
  10. package/package.json +5 -5
  11. package/src/analysis/sequence-activity-cliffs.ts +3 -4
  12. package/src/analysis/sequence-diversity-viewer.ts +5 -3
  13. package/src/analysis/sequence-similarity-viewer.ts +8 -5
  14. package/src/analysis/sequence-space.ts +3 -2
  15. package/src/calculations/monomerLevelMols.ts +3 -3
  16. package/src/demo/bio01-similarity-diversity.ts +4 -1
  17. package/src/package-test.ts +1 -1
  18. package/src/package-types.ts +35 -2
  19. package/src/package.ts +57 -71
  20. package/src/tests/WebLogo-layout-tests.ts +1 -1
  21. package/src/tests/WebLogo-positions-test.ts +11 -5
  22. package/src/tests/WebLogo-project-tests.ts +1 -1
  23. package/src/tests/activity-cliffs-utils.ts +11 -14
  24. package/src/tests/bio-tests.ts +85 -79
  25. package/src/tests/checkInputColumn-tests.ts +15 -10
  26. package/src/tests/converters-test.ts +12 -5
  27. package/src/tests/detectors-benchmark-tests.ts +5 -2
  28. package/src/tests/detectors-tests.ts +51 -44
  29. package/src/tests/detectors-weak-and-likely-tests.ts +12 -5
  30. package/src/tests/fasta-export-tests.ts +13 -5
  31. package/src/tests/helm-tests.ts +85 -0
  32. package/src/tests/mm-distance-tests.ts +14 -7
  33. package/src/tests/monomer-libraries-tests.ts +1 -1
  34. package/src/tests/msa-tests.ts +33 -24
  35. package/src/tests/renderers-monomer-placer-tests.ts +2 -5
  36. package/src/tests/renderers-test.ts +15 -9
  37. package/src/tests/scoring.ts +9 -6
  38. package/src/tests/seq-handler-get-helm-tests.ts +7 -5
  39. package/src/tests/seq-handler-get-region-tests.ts +9 -3
  40. package/src/tests/seq-handler-splitted-tests.ts +11 -5
  41. package/src/tests/seq-handler-tests.ts +17 -10
  42. package/src/tests/sequence-space-utils.ts +9 -4
  43. package/src/tests/splitters-test.ts +5 -4
  44. package/src/tests/substructure-filters-tests.ts +16 -13
  45. package/src/tests/to-atomic-level-tests.ts +5 -3
  46. package/src/tests/to-atomic-level-ui-tests.ts +4 -1
  47. package/src/tests/utils/detectors-utils.ts +4 -4
  48. package/src/utils/calculate-scores.ts +11 -9
  49. package/src/utils/cell-renderer-custom.ts +27 -17
  50. package/src/utils/cell-renderer.ts +14 -8
  51. package/src/utils/check-input-column.ts +13 -9
  52. package/src/utils/context-menu.ts +4 -4
  53. package/src/utils/convert.ts +21 -14
  54. package/src/utils/get-region-func-editor.ts +8 -5
  55. package/src/utils/get-region.ts +4 -5
  56. package/src/utils/helm-to-molfile/converter/helm.ts +4 -4
  57. package/src/utils/helm-to-molfile/utils.ts +5 -6
  58. package/src/utils/macromolecule-column-widget.ts +6 -7
  59. package/src/utils/monomer-cell-renderer-base.ts +8 -1
  60. package/src/utils/monomer-lib/lib-manager.ts +3 -2
  61. package/src/utils/monomer-lib/monomer-colors.ts +10 -10
  62. package/src/utils/monomer-lib/monomer-lib-base.ts +6 -1
  63. package/src/utils/monomer-lib/monomer-lib.ts +15 -9
  64. package/src/utils/multiple-sequence-alignment-ui.ts +30 -30
  65. package/src/utils/save-as-fasta.ts +19 -12
  66. package/src/utils/seq-helper/seq-handler.ts +859 -0
  67. package/src/utils/seq-helper/seq-helper.ts +11 -21
  68. package/src/utils/sequence-to-mol.ts +7 -8
  69. package/src/utils/split-to-monomers.ts +7 -2
  70. package/src/utils/types.ts +8 -7
  71. package/src/utils/ui-utils.ts +2 -2
  72. package/src/viewers/web-logo-viewer.ts +18 -16
  73. package/src/widgets/bio-substructure-filter.ts +1 -2
  74. package/src/widgets/composition-analysis-widget.ts +6 -6
  75. package/src/widgets/representations.ts +7 -4
  76. package/src/tests/detectors-custom-notation-tests.ts +0 -37
  77. package/src/utils/cyclized.ts +0 -89
  78. package/src/utils/dimerized.ts +0 -10
@@ -3,11 +3,14 @@ import * as DG from 'datagrok-api/dg';
3
3
  import * as ui from 'datagrok-api/ui';
4
4
 
5
5
  import {getGridCellColTemp, CellRendererBackBase} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
6
- import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
7
6
  import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
8
- import {GridCell} from 'datagrok-api/dg';
7
+ import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
8
+
9
+ import {_package} from '../package';
9
10
 
10
11
  export class MacromoleculeCustomCellRenderer extends DG.GridCellRenderer {
12
+ private readonly seqHelper: ISeqHelper;
13
+
11
14
  get name(): string { return 'sequence'; }
12
15
 
13
16
  get cellType(): string { return 'sequence'; }
@@ -16,18 +19,26 @@ export class MacromoleculeCustomCellRenderer extends DG.GridCellRenderer {
16
19
 
17
20
  get defaultWidth(): number | null { return 230; }
18
21
 
19
- getRendererBack(gridCell: DG.GridCell): CellRendererBackBase<string> {
20
- const [gridCol, tableCol, temp] = getGridCellColTemp<string, any>(gridCell);
21
- const sh = SeqHandler.forColumn(tableCol);
22
- if (sh.notation !== NOTATION.CUSTOM)
23
- throw new Error(`Unexpected notation: '${sh.notation}'.`);
24
- const back = sh.getRendererBack(gridCol, tableCol);
22
+ constructor() {
23
+ super();
24
+ this.seqHelper = _package.seqHelper;
25
+ }
26
+
27
+ getRendererBack(gridCell: DG.GridCell): CellRendererBackBase<string> | null {
28
+ const [gridCol, tableCol, _temp] = getGridCellColTemp<string, any>(gridCell);
29
+ let back: CellRendererBackBase<string> | null = null;
30
+ if (this.seqHelper) {
31
+ const sh = this.seqHelper.getSeqHandler(tableCol);
32
+ if (sh.notation !== NOTATION.CUSTOM)
33
+ throw new Error(`Unexpected notation: '${sh.notation}'.`);
34
+ back = sh.getRendererBack(gridCol, tableCol);
35
+ }
25
36
  return back;
26
37
  }
27
38
 
28
- override onMouseEnter(gridCell: GridCell, e: MouseEvent) {
39
+ override onMouseEnter(gridCell: DG.GridCell, e: MouseEvent) {
29
40
  const back = this.getRendererBack(gridCell);
30
- back.onMouseEnter(gridCell, e);
41
+ back?.onMouseEnter(gridCell, e);
31
42
  }
32
43
 
33
44
  override onMouseLeave(gridCell: DG.GridCell, e: MouseEvent) {
@@ -39,32 +50,31 @@ export class MacromoleculeCustomCellRenderer extends DG.GridCellRenderer {
39
50
 
40
51
  override onMouseMove(gridCell: DG.GridCell, e: MouseEvent) {
41
52
  const back = this.getRendererBack(gridCell);
42
- back.onMouseMove(gridCell, e);
53
+ back?.onMouseMove(gridCell, e);
43
54
  }
44
55
 
45
56
  override onClick(gridCell: DG.GridCell, e: MouseEvent) {
46
57
  const back = this.getRendererBack(gridCell);
47
- back.onClick(gridCell, e);
58
+ back?.onClick(gridCell, e);
48
59
  }
49
60
 
50
61
  override onDoubleClick(gridCell: DG.GridCell, e: MouseEvent) {
51
62
  const back = this.getRendererBack(gridCell);
52
- back.onDoubleClick(gridCell, e);
63
+ back?.onDoubleClick(gridCell, e);
53
64
  }
54
65
 
55
66
  override onKeyDown(gridCell: DG.GridCell, e: KeyboardEvent) {
56
67
  const back = this.getRendererBack(gridCell);
57
- back.onKeyDown(gridCell, e);
68
+ back?.onKeyDown(gridCell, e);
58
69
  }
59
70
 
60
71
  override onKeyPress(gridCell: DG.GridCell, e: KeyboardEvent) {
61
72
  const back = this.getRendererBack(gridCell);
62
- back.onKeyPress(gridCell, e);
73
+ back?.onKeyPress(gridCell, e);
63
74
  }
64
75
 
65
76
  override render(g: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, gridCell: DG.GridCell, cellStyle: DG.GridCellStyle) {
66
77
  const back = this.getRendererBack(gridCell);
67
- back.render(g, x, y, w, h, gridCell, cellStyle);
78
+ back?.render(g, x, y, w, h, gridCell, cellStyle);
68
79
  }
69
80
  }
70
-
@@ -17,21 +17,19 @@ import {
17
17
  TAGS as bioTAGS,
18
18
  ALPHABET,
19
19
  } from '@datagrok-libraries/bio/src/utils/macromolecule';
20
- import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
20
+ import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
21
21
  import {getSplitter} from '@datagrok-libraries/bio/src/utils/macromolecule/utils';
22
- import {IMonomerLib, IMonomerLibBase} from '@datagrok-libraries/bio/src/types';
22
+ import {IMonomerLibBase} from '@datagrok-libraries/bio/src/types';
23
23
  import {GapOriginals} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
24
- import {ISeqMonomer} from '@datagrok-libraries/bio/src/helm/types';
25
24
  import {execMonomerHoverLinks} from '@datagrok-libraries/bio/src/monomer-works/monomer-hover';
26
- import {CellRendererBackBase, getGridCellColTemp} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
25
+ import {getGridCellColTemp} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
27
26
  import {HelmTypes} from '@datagrok-libraries/bio/src/helm/consts';
28
27
  import {MmcrTemps, rendererSettingsChangedState, tempTAGS} from '@datagrok-libraries/bio/src/utils/cell-renderer-consts';
29
- import {getMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
28
+
29
+ import {CellRendererWithMonomerLibBackBase} from './monomer-cell-renderer-base';
30
30
  import * as C from './constants';
31
31
 
32
32
  import {_package} from '../package';
33
- import {CellRendererWithMonomerLibBackBase} from './monomer-cell-renderer-base';
34
- import {timeout} from 'rxjs/operators';
35
33
 
36
34
  type TempType = { [tagName: string]: any };
37
35
 
@@ -60,6 +58,8 @@ type RendererGridCellTemp = {
60
58
  }
61
59
 
62
60
  export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
61
+ private readonly seqHelper: ISeqHelper;
62
+
63
63
  get name(): string { return 'sequence'; }
64
64
 
65
65
  get cellType(): string { return 'sequence'; }
@@ -68,6 +68,11 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
68
68
 
69
69
  get defaultWidth(): number | null { return 230; }
70
70
 
71
+ constructor() {
72
+ super();
73
+ this.seqHelper = _package.seqHelper;
74
+ }
75
+
71
76
  onClick(gridCell: DG.GridCell, _e: MouseEvent): void {
72
77
  const colTemp: TempType = gridCell.cell.column.temp;
73
78
  colTemp[tempTAGS.currentWord] = gridCell.cell.value;
@@ -106,7 +111,7 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
106
111
  getGridCellColTemp<string, MonomerPlacer>(gridCell);
107
112
  if (!tableCol) return;
108
113
  const tableColTemp: TempType = tableCol.temp;
109
- const sh = SeqHandler.forColumn(tableCol);
114
+ const sh = this.seqHelper.getSeqHandler(tableCol);
110
115
 
111
116
  let gapLength = 0;
112
117
  const msaGapLength = 8;
@@ -132,6 +137,7 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
132
137
  };
133
138
  });
134
139
  tableCol.temp[MmcrTemps.rendererSettingsChanged] === rendererSettingsChangedState.true;
140
+ seqColTemp.init().then(() => {});
135
141
  }
136
142
 
137
143
  seqColTemp.render(g, x, y, w, h, gridCell, _cellStyle);
@@ -2,7 +2,9 @@ import * as grok from 'datagrok-api/grok';
2
2
  import * as DG from 'datagrok-api/dg';
3
3
  import * as ui from 'datagrok-api/ui';
4
4
 
5
- import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
5
+ import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
6
+
7
+ import {_package} from '../package';
6
8
 
7
9
  /**
8
10
  * Checks if the column is suitable for the analysis.
@@ -13,9 +15,11 @@ import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
13
15
  * @param {boolean} notify show warning message if the column is not suitable for the analysis
14
16
  * @return {boolean} True if the column is suitable for the analysis.
15
17
  */
16
- export function checkInputColumnUI(col: DG.Column, name: string, allowedNotations: string[] = [],
17
- allowedAlphabets: string[] = [], notify: boolean = true): boolean {
18
- const [res, msg]: [boolean, string] = checkInputColumn(col, name, allowedNotations, allowedAlphabets);
18
+ export function checkInputColumnUI(col: DG.Column, name: string,
19
+ allowedNotations: string[] = [], allowedAlphabets: string[] = [], notify: boolean = true
20
+ ): boolean {
21
+ const seqHelper = _package.seqHelper;
22
+ const [res, msg]: [boolean, string] = checkInputColumn(col, name, seqHelper, allowedNotations, allowedAlphabets);
19
23
  if (notify && !res)
20
24
  grok.shell.warning(msg);
21
25
  return res;
@@ -23,23 +27,23 @@ export function checkInputColumnUI(col: DG.Column, name: string, allowedNotation
23
27
 
24
28
  /**
25
29
  * Checks if the column is suitable for the analysis.
26
- * @param {DG.Column} col macromolecule coulumn.
27
- * @param {string} name column name
30
+ * @param {DG.Column} col macromolecule column.
31
+ * @param {string} name Analysis name
28
32
  * @param {string[]} allowedNotations allowed notations
29
33
  * @param {string[]} allowedAlphabets allowed alphabets
30
34
  * @return {[boolean, string]} [True if the column is suitable for the analysis, warning message].
31
35
  */
32
- export function checkInputColumn(
33
- col: DG.Column, name: string, allowedNotations: string[] = [], allowedAlphabets: string[] = [],
36
+ export function checkInputColumn(col: DG.Column, name: string, seqHelper: ISeqHelper,
37
+ allowedNotations: string[] = [], allowedAlphabets: string[] = [],
34
38
  ): [boolean, string] {
35
39
  let res: boolean = true;
36
40
  let msg: string = '';
37
41
 
38
- const sh = SeqHandler.forColumn(col);
39
42
  if (col.semType !== DG.SEMTYPE.MACROMOLECULE) {
40
43
  grok.shell.warning(name + ' analysis is allowed for Macromolecules semantic type');
41
44
  res = false;
42
45
  } else {
46
+ const sh = seqHelper.getSeqHandler(col);
43
47
  const notation: string = sh.notation;
44
48
  if (allowedNotations.length > 0 &&
45
49
  !allowedNotations.some((n) => notation.toUpperCase() == (n.toUpperCase()))
@@ -2,21 +2,21 @@ import * as grok from 'datagrok-api/grok';
2
2
  import * as DG from 'datagrok-api/dg';
3
3
  import * as ui from 'datagrok-api/ui';
4
4
 
5
- import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
6
5
  import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
6
+ import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
7
7
 
8
8
  import {_package} from '../package';
9
9
 
10
10
 
11
- export function addCopyMenuUI(cell: DG.Cell, menu: DG.Menu): void {
12
- const sh = SeqHandler.forColumn(cell.column);
11
+ export function addCopyMenuUI(cell: DG.Cell, menu: DG.Menu, seqHelper: ISeqHelper): void {
12
+ const sh = seqHelper.getSeqHandler(cell.column);
13
13
  const tgtNotationList: string[] = Object.values(NOTATION).filter((v) => v !== sh.units);
14
14
 
15
15
  menu.group('Copy')
16
16
  .items(tgtNotationList, (tgtNotation) => {
17
17
  const srcCol = cell.column;
18
18
  const srcRowIdx = cell.rowIndex;
19
- const srcSh = SeqHandler.forColumn(srcCol);
19
+ const srcSh = seqHelper.getSeqHandler(srcCol);
20
20
  const separator = tgtNotation === NOTATION.SEPARATOR ? _package.properties.defaultSeparator : undefined;
21
21
  const joiner = srcSh.getJoiner({notation: tgtNotation as NOTATION, separator});
22
22
  const srcSS = srcSh.getSplitted(srcRowIdx);
@@ -6,7 +6,7 @@ import $ from 'cash-dom';
6
6
  import {Subscription} from 'rxjs';
7
7
 
8
8
  import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
9
- import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
9
+ import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
10
10
 
11
11
 
12
12
  let convertDialog: DG.Dialog | null = null;
@@ -15,13 +15,14 @@ let convertDialogSubs: Subscription[] = [];
15
15
  /**
16
16
  * Converts notations of a Macromolecule column
17
17
  *
18
- * @param {DG.column} col Column with 'Macromolecule' semantic type
18
+ * @param {DG.Column<string>} col Column with 'Macromolecule' semantic type
19
+ * @param {ISeqHelper} seqHelper
19
20
  */
20
- export function convert(col?: DG.Column): void {
21
+ export function convert(col: DG.Column<string> | undefined, seqHelper: ISeqHelper): void {
21
22
  let srcCol = col ?? grok.shell.t.columns.bySemType('Macromolecule')!;
22
23
  if (!srcCol)
23
24
  throw new Error('No column with Macromolecule semantic type found');
24
- let converterSh = SeqHandler.forColumn(srcCol);
25
+ let converterSh = seqHelper.getSeqHandler(srcCol);
25
26
  let currentNotation: NOTATION = converterSh.notation;
26
27
  const dialogHeader = ui.divText(
27
28
  'Current notation: ' + currentNotation,
@@ -46,14 +47,16 @@ export function convert(col?: DG.Column): void {
46
47
  }
47
48
 
48
49
  srcCol = newCol;
49
- converterSh = SeqHandler.forColumn(srcCol);
50
+ converterSh = seqHelper.getSeqHandler(srcCol);
50
51
  currentNotation = converterSh.notation;
51
52
  if (currentNotation === NOTATION.HELM)
52
53
  separatorInput.value = '/'; // helm monomers can have - in the name like D-aThr;
53
54
  dialogHeader.textContent = 'Current notation: ' + currentNotation;
54
55
  filteredNotations = notations.filter((e) => e !== currentNotation);
55
- targetNotationInput = ui.input.choice('Convert to', {value: filteredNotations[0], items: filteredNotations,
56
- onValueChanged: toggleSeparator});
56
+ targetNotationInput = ui.input.choice('Convert to', {
57
+ value: filteredNotations[0], items: filteredNotations,
58
+ onValueChanged: toggleSeparator
59
+ });
57
60
  toggleSeparator();
58
61
  convertDialog?.clear();
59
62
  convertDialog?.add(ui.div([
@@ -64,8 +67,10 @@ export function convert(col?: DG.Column): void {
64
67
  ]));
65
68
  };
66
69
 
67
- const targetColumnInput = ui.input.column('Column', {table: grok.shell.t, value: srcCol,
68
- onValueChanged: (value) => toggleColumn(value)});
70
+ const targetColumnInput = ui.input.column('Column', {
71
+ table: grok.shell.t, value: srcCol,
72
+ onValueChanged: (value) => toggleColumn(value)
73
+ });
69
74
 
70
75
  const separatorArray = ['-', '.', '/'];
71
76
  let filteredNotations = notations.filter((e) => e !== currentNotation);
@@ -79,8 +84,10 @@ export function convert(col?: DG.Column): void {
79
84
  else
80
85
  $(separatorInput.root).show();
81
86
  };
82
- let targetNotationInput = ui.input.choice('Convert to', {value: filteredNotations[0], items: filteredNotations,
83
- onValueChanged: toggleSeparator});
87
+ let targetNotationInput = ui.input.choice('Convert to', {
88
+ value: filteredNotations[0], items: filteredNotations,
89
+ onValueChanged: toggleSeparator
90
+ });
84
91
 
85
92
  // set correct visibility on init
86
93
  toggleSeparator();
@@ -101,7 +108,7 @@ export function convert(col?: DG.Column): void {
101
108
  const targetNotation = targetNotationInput.value as NOTATION;
102
109
  const separator: string | undefined = targetNotation === NOTATION.SEPARATOR ? separatorInput.value! : undefined;
103
110
 
104
- await convertDo(srcCol, targetNotation, separator);
111
+ await convertDo(srcCol, seqHelper, targetNotation, separator);
105
112
  })
106
113
  .show({x: 350, y: 100});
107
114
 
@@ -118,8 +125,8 @@ export function convert(col?: DG.Column): void {
118
125
  * @param {NOTATION} targetNotation Target notation
119
126
  * @param {string | null} separator Separator for SEPARATOR notation
120
127
  */
121
- export async function convertDo(srcCol: DG.Column, targetNotation: NOTATION, separator?: string): Promise<DG.Column> {
122
- const converterSh = SeqHandler.forColumn(srcCol);
128
+ export async function convertDo(srcCol: DG.Column, seqHelper: ISeqHelper, targetNotation: NOTATION, separator?: string): Promise<DG.Column> {
129
+ const converterSh = seqHelper.getSeqHandler(srcCol);
123
130
  const newColumn = converterSh.convert(targetNotation, separator);
124
131
  srcCol.dataFrame.columns.add(newColumn);
125
132
 
@@ -3,7 +3,7 @@ import * as ui from 'datagrok-api/ui';
3
3
  import * as DG from 'datagrok-api/dg';
4
4
 
5
5
  import {TAGS as bioTAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
6
- import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
6
+ import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
7
7
 
8
8
  import {_package} from '../package';
9
9
 
@@ -33,12 +33,14 @@ export class GetRegionFuncEditor {
33
33
  }();
34
34
 
35
35
  constructor(
36
- private readonly call: DG.FuncCall
36
+ private readonly call: DG.FuncCall,
37
+ private readonly seqHelper: ISeqHelper,
37
38
  ) {
38
39
  const getDesc = (paramName: string) => this.call.inputParams[paramName].property.description;
39
40
 
40
41
  this.inputs.table = ui.input.table('Table', {value: this.call.inputParams['table'].value ?? grok.shell.tv.dataFrame});
41
42
 
43
+ //@formatter:off
42
44
  const seqColValue = this.call.inputParams['sequence'].value ??
43
45
  this.inputs.table.value!.columns.bySemType(DG.SEMTYPE.MACROMOLECULE);
44
46
  this.inputs.sequence = ui.input.column('Sequence', {table: grok.shell.tv.dataFrame, value: seqColValue,
@@ -52,6 +54,7 @@ export class GetRegionFuncEditor {
52
54
  this.inputs.name = ui.input.string('Column name', {value: this.getDefaultName(),
53
55
  onValueChanged: this.nameInputChanged.bind(this), clearIcon: true});
54
56
  this.inputs.name.onInput.subscribe(() => this.nameInputInput.bind(this)); // To catch clear event
57
+ //@formatter:on
55
58
 
56
59
  // tooltips
57
60
  for (const paramName in this.call.inputParams) {
@@ -65,7 +68,7 @@ export class GetRegionFuncEditor {
65
68
 
66
69
  private sequenceInputChanged(): void {
67
70
  const seqCol = this.inputs.sequence.value;
68
- const sh = seqCol ? SeqHandler.forColumn(seqCol) : null;
71
+ const sh = seqCol ? this.seqHelper.getSeqHandler(seqCol) : null;
69
72
  this.updateRegionItems();
70
73
  this.updateStartEndInputItems();
71
74
  this.updateRegion(true);
@@ -84,7 +87,7 @@ export class GetRegionFuncEditor {
84
87
  this.inputs.start.value = reg?.start;
85
88
  this.inputs.end.value = reg?.end;
86
89
  } else {
87
- const sh = SeqHandler.forColumn(this.inputs.sequence.value!);
90
+ const sh = this.seqHelper.getSeqHandler(this.inputs.sequence.value!);
88
91
  this.inputs.start.value = sh.posList[0];
89
92
  this.inputs.end.value = sh.posList[sh.posList.length - 1];
90
93
  }
@@ -117,7 +120,7 @@ export class GetRegionFuncEditor {
117
120
 
118
121
  private updateStartEndInputItems(): void {
119
122
  const seqCol = this.inputs.sequence.value;
120
- const sh = seqCol ? SeqHandler.forColumn(seqCol) : null;
123
+ const sh = seqCol ? this.seqHelper.getSeqHandler(seqCol) : null;
121
124
 
122
125
  const startSE = (this.inputs.start.input as HTMLSelectElement);
123
126
  const endSE = (this.inputs.end.input as HTMLSelectElement);
@@ -2,11 +2,10 @@ import * as grok from 'datagrok-api/grok';
2
2
  import * as ui from 'datagrok-api/ui';
3
3
  import * as DG from 'datagrok-api/dg';
4
4
 
5
- import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
6
- import {TaskBarProgressIndicator} from 'datagrok-api/dg';
5
+ import {_package} from '../package';
7
6
 
8
7
  export function getRegionUI(col: DG.Column<string>): void {
9
- const sh = SeqHandler.forColumn(col);
8
+ const sh = _package.seqHelper.getSeqHandler(col);
10
9
 
11
10
  const nameInput = ui.input.string('Name', {value: ''});
12
11
  const startPositionInput = ui.input.choice('Start Position', {value: sh.posList[0], items: sh.posList,
@@ -23,7 +22,7 @@ export function getRegionUI(col: DG.Column<string>): void {
23
22
  startPositionInput,
24
23
  endPositionInput,
25
24
  ])).onOK(() => {
26
- const pi = TaskBarProgressIndicator.create('Getting region...');
25
+ const pi = DG.TaskBarProgressIndicator.create('Getting region...');
27
26
  try {
28
27
  const name: string = nameInput.value ?? getDefaultName();
29
28
  const regCol = getRegionDo(col, name, startPositionInput.value, endPositionInput.value);
@@ -39,7 +38,7 @@ export function getRegionUI(col: DG.Column<string>): void {
39
38
  export function getRegionDo(
40
39
  col: DG.Column<string>, startPosName: string | null, endPosName: string | null, name: string | null
41
40
  ): DG.Column<string> {
42
- const sh = SeqHandler.forColumn(col);
41
+ const sh = _package.seqHelper.getSeqHandler(col);
43
42
 
44
43
  let startPosIdx: number | null = null;
45
44
  let endPosIdx: number | null = null;
@@ -21,8 +21,8 @@ export class Helm {
21
21
  * complex polymer scope) */
22
22
  readonly bondData: Bond[][];
23
23
 
24
- private simplePolymers: SimplePolymer[];
25
- private connectionList?: ConnectionList;
24
+ public readonly simplePolymers: SimplePolymer[];
25
+ public readonly connectionList?: ConnectionList;
26
26
 
27
27
  /** Maps global monomer index to r-group ids (starting from 1) participating
28
28
  * in connection */
@@ -74,8 +74,8 @@ export class Helm {
74
74
  });
75
75
  }
76
76
 
77
- private getMonomerIdxShifts(): {[simplePolymerId: string]: number} {
78
- const result: {[simplePolymerId: string]: number} = {};
77
+ private getMonomerIdxShifts(): { [simplePolymerId: string]: number } {
78
+ const result: { [simplePolymerId: string]: number } = {};
79
79
  let shift = 0;
80
80
  this.simplePolymers.forEach((simplePolymer) => {
81
81
  result[simplePolymer.id] = shift;
@@ -6,14 +6,14 @@ import {IMonomerLibBase} from '@datagrok-libraries/bio/src/types';
6
6
 
7
7
  import {SeqHelper} from '../seq-helper';
8
8
 
9
- import {_package, getMonomerLib} from '../../package';
9
+ import {_package} from '../../package';
10
10
 
11
11
  /** Translate HELM column into molfile column and append to the dataframe */
12
12
  export async function getMolColumnFromHelm(
13
13
  df: DG.DataFrame, helmCol: DG.Column<string>, chiralityEngine: boolean = true, monomerLib: IMonomerLibBase
14
14
  ): Promise<DG.Column<string>> {
15
- const seqHelper = await SeqHelper.getInstance();
16
- const converter = seqHelper.getHelmToMolfileConverter(monomerLib);
15
+ const seqHelper: SeqHelper = _package.seqHelper as SeqHelper;
16
+ const converter = await seqHelper.getHelmToMolfileConverter(monomerLib);
17
17
  const molCol = converter.convertToRdKitBeautifiedMolfileColumn(helmCol, chiralityEngine, _package.rdKitModule, monomerLib);
18
18
  molCol.semType = DG.SEMTYPE.MOLECULE;
19
19
  return molCol;
@@ -22,9 +22,8 @@ export async function getMolColumnFromHelm(
22
22
  export async function getSmilesColumnFromHelm(
23
23
  helmCol: DG.Column<string>
24
24
  ): Promise<DG.Column<string>> {
25
- const seqHelper = await SeqHelper.getInstance();
26
- const monomerLib = getMonomerLib();
27
- const converter = seqHelper.getHelmToMolfileConverter(monomerLib);
25
+ const seqHelper: SeqHelper = _package.seqHelper as SeqHelper;
26
+ const converter = await seqHelper.getHelmToMolfileConverter(_package.monomerLib);
28
27
  const smilesCol = converter.convertToSmiles(helmCol);
29
28
  smilesCol.semType = DG.SEMTYPE.MOLECULE;
30
29
  return smilesCol;
@@ -3,7 +3,7 @@ import * as ui from 'datagrok-api/ui';
3
3
  import * as DG from 'datagrok-api/dg';
4
4
 
5
5
  import {TAGS as wlTAGS} from '@datagrok-libraries/bio/src/viewers/web-logo';
6
- import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
6
+ import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
7
7
 
8
8
  import {WebLogoViewer} from '../viewers/web-logo-viewer';
9
9
 
@@ -13,18 +13,17 @@ import {_package} from '../package';
13
13
  export class MacromoleculeColumnWidget extends DG.Widget {
14
14
  private viewed: boolean = false;
15
15
 
16
- private readonly seqCol: DG.Column<string>;
17
-
18
16
  private wlViewer: WebLogoViewer | null = null;
19
17
 
20
- constructor(seqCol: DG.Column<string>) {
18
+ constructor(
19
+ private readonly seqCol: DG.Column<string>,
20
+ private readonly seqHelper: ISeqHelper,
21
+ ) {
21
22
  super(ui.divV([]));
22
-
23
- this.seqCol = seqCol;
24
23
  }
25
24
 
26
25
  async init(): Promise<void> {
27
- const sh = SeqHandler.forColumn(this.seqCol);
26
+ const sh = this.seqHelper.getSeqHandler(this.seqCol);
28
27
  const pkgTooltipWebLogo = _package.properties.tooltipWebLogo;
29
28
  const colTooltipWebLogo = this.seqCol.getTag(wlTAGS.tooltipWebLogo);
30
29
 
@@ -5,13 +5,15 @@ import * as ui from 'datagrok-api/ui';
5
5
  import {getMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
6
6
  import {CellRendererBackBase} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
7
7
  import {IMonomerLibBase} from '@datagrok-libraries/bio/src/types/index';
8
+ import {ISeqHelper, getSeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
8
9
 
9
10
  import {_package} from '../package';
10
11
 
11
12
  export abstract class CellRendererWithMonomerLibBackBase extends CellRendererBackBase<string> {
12
13
  protected monomerLib: IMonomerLibBase | null = null;
14
+ protected seqHelper: ISeqHelper | null = null;
13
15
 
14
- constructor(
16
+ protected constructor(
15
17
  gridCol: DG.GridColumn | null,
16
18
  tableCol: DG.Column<string>,
17
19
  ) {
@@ -26,5 +28,10 @@ export abstract class CellRendererWithMonomerLibBackBase extends CellRendererBac
26
28
  this.gridCol?.grid?.invalidate();
27
29
  }));
28
30
  });
31
+ getSeqHelper().then((seqHelper) => {
32
+ this.seqHelper = seqHelper;
33
+ this.dirty = true;
34
+ this.gridCol?.grid?.invalidate();
35
+ });
29
36
  }
30
37
  }
@@ -35,7 +35,8 @@ export class MonomerLibManager implements IMonomerLibHelper {
35
35
 
36
36
  public get eventManager(): IMonomerLibFileEventManager { return this._eventManager; }
37
37
 
38
- public async awaitLoaded(timeout: number = 5000): Promise<void> {
38
+ public async awaitLoaded(timeout: number = Infinity): Promise<void> {
39
+ timeout = timeout === Infinity ? 1 * 60000 : timeout; // Limit the max lib loaded timeout
39
40
  return await Promise.race([
40
41
  (async () => {
41
42
  const fileManager = await this.getFileManager();
@@ -273,7 +274,7 @@ export class MonomerLibManager implements IMonomerLibHelper {
273
274
  /** Changes userLibSettings set only HELMCoreLibrary.json, polytool-lib.json */
274
275
  async loadMonomerLibForTests(): Promise<void> {
275
276
  await setUserLibSettings(LIB_SETTINGS_FOR_TESTS);
276
- await this.awaitLoaded();
277
+ await this.awaitLoaded(10000);
277
278
  await this.loadMonomerLib(true); // load default libraries
278
279
  }
279
280
 
@@ -8,20 +8,20 @@ import {HelmType} from '@datagrok-libraries/bio/src/helm/types';
8
8
  export const naturalMonomerColors = {
9
9
  [HelmTypes.BASE]: {
10
10
  // Chromatogram palette // HELMWebEditor monomerColors
11
- A: "green", // "#A0A0FF",
12
- G: "black", // "#FF7070",
13
- T: "red", // "#A0FFA0",
14
- C: "blue", // "#FF8C4B",
15
- U: "red", // "#FF8080"
11
+ A: "#20E040", // "#A0A0FF",
12
+ G: "#040404", // "#FF7070",
13
+ T: "#FF8080", // "#A0FFA0",
14
+ C: "#2060FF", // "#FF8C4B",
15
+ U: "#FF8080", // "#FF8080"
16
16
  },
17
17
 
18
18
  [HelmTypes.NUCLEOTIDE]: {
19
19
  // Chromatogram palette // HELMWebEditor monomerColors
20
- A: "green", // "#A0A0FF",
21
- G: "black", // "#FF7070",
22
- T: "red", // "#A0FFA0",
23
- C: "blue", // "#FF8C4B",
24
- U: "red", // "#FF8080"
20
+ A: "#20E040", // "#A0A0FF",
21
+ G: "#040404", // "#FF7070",
22
+ T: "#FF8080", // "#A0FFA0",
23
+ C: "#2060FF", // "#FF8C4B",
24
+ U: "#FF8080", // "#FF8080"
25
25
  },
26
26
 
27
27
  [HelmTypes.LINKER]: {
@@ -42,11 +42,16 @@ export class MonomerLibBase implements IMonomerLibBase {
42
42
 
43
43
  constructor(
44
44
  protected _monomers: MonomerLibDataType,
45
+ public readonly source: string,
45
46
  ) {
46
47
  this._isEmpty = !this._monomers || Object.keys(this._monomers).length === 0 ||
47
48
  Object.entries(this._monomers).every(([_, ptMonomers]) => Object.keys(ptMonomers).length === 0);
48
49
  }
49
50
 
51
+ getMonomerSymbolsByType(polymerType: PolymerType): string[] {
52
+ return Object.keys(this._monomers[polymerType]);
53
+ }
54
+
50
55
  /** Creates missing {@link Monomer} */
51
56
  addMissingMonomer(polymerType: PolymerType, monomerSymbol: string): Monomer {
52
57
  let mSet = this._monomers[polymerType];
@@ -212,7 +217,7 @@ export class MonomerLibBase implements IMonomerLibBase {
212
217
  if (rgbM)
213
218
  return [parseInt(rgbM[1]), parseInt(rgbM[2]), parseInt(rgbM[3])];
214
219
 
215
- const n = DG.Color.fromHtml(colors.textcolor!);
220
+ const n = DG.Color.fromHtml(html);
216
221
  return [DG.Color.r(n), DG.Color.g(n), DG.Color.b(n)];
217
222
  };
218
223