@datagrok/bio 2.15.13 → 2.16.2

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 (80) hide show
  1. package/CHANGELOG.md +25 -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 +14 -14
  11. package/src/analysis/sequence-activity-cliffs.ts +9 -8
  12. package/src/analysis/sequence-diversity-viewer.ts +6 -4
  13. package/src/analysis/sequence-similarity-viewer.ts +9 -6
  14. package/src/analysis/sequence-space.ts +3 -2
  15. package/src/calculations/monomerLevelMols.ts +4 -5
  16. package/src/demo/bio01-similarity-diversity.ts +4 -1
  17. package/src/package-test.ts +1 -1
  18. package/src/package-types.ts +34 -2
  19. package/src/package.ts +60 -76
  20. package/src/substructure-search/substructure-search.ts +15 -9
  21. package/src/tests/WebLogo-layout-tests.ts +1 -1
  22. package/src/tests/WebLogo-positions-test.ts +11 -5
  23. package/src/tests/WebLogo-project-tests.ts +1 -1
  24. package/src/tests/activity-cliffs-utils.ts +11 -14
  25. package/src/tests/bio-tests.ts +85 -79
  26. package/src/tests/checkInputColumn-tests.ts +15 -10
  27. package/src/tests/converters-test.ts +12 -5
  28. package/src/tests/detectors-benchmark-tests.ts +5 -2
  29. package/src/tests/detectors-tests.ts +51 -44
  30. package/src/tests/detectors-weak-and-likely-tests.ts +12 -5
  31. package/src/tests/fasta-export-tests.ts +13 -5
  32. package/src/tests/helm-tests.ts +85 -0
  33. package/src/tests/mm-distance-tests.ts +14 -7
  34. package/src/tests/monomer-libraries-tests.ts +1 -1
  35. package/src/tests/msa-tests.ts +33 -24
  36. package/src/tests/renderers-monomer-placer-tests.ts +2 -5
  37. package/src/tests/renderers-test.ts +15 -9
  38. package/src/tests/scoring.ts +9 -6
  39. package/src/tests/seq-handler-get-helm-tests.ts +7 -5
  40. package/src/tests/seq-handler-get-region-tests.ts +9 -3
  41. package/src/tests/seq-handler-splitted-tests.ts +11 -5
  42. package/src/tests/seq-handler-tests.ts +17 -10
  43. package/src/tests/sequence-space-utils.ts +9 -4
  44. package/src/tests/splitters-test.ts +5 -4
  45. package/src/tests/substructure-filters-tests.ts +22 -23
  46. package/src/tests/to-atomic-level-tests.ts +5 -3
  47. package/src/tests/to-atomic-level-ui-tests.ts +4 -1
  48. package/src/tests/utils/detectors-utils.ts +4 -4
  49. package/src/utils/calculate-scores.ts +11 -9
  50. package/src/utils/cell-renderer-custom.ts +27 -17
  51. package/src/utils/cell-renderer.ts +14 -8
  52. package/src/utils/check-input-column.ts +13 -9
  53. package/src/utils/context-menu.ts +4 -4
  54. package/src/utils/convert.ts +21 -14
  55. package/src/utils/get-region-func-editor.ts +8 -5
  56. package/src/utils/get-region.ts +4 -5
  57. package/src/utils/helm-to-molfile/converter/helm.ts +4 -4
  58. package/src/utils/helm-to-molfile/utils.ts +5 -6
  59. package/src/utils/macromolecule-column-widget.ts +6 -7
  60. package/src/utils/monomer-cell-renderer-base.ts +8 -1
  61. package/src/utils/monomer-lib/lib-manager.ts +3 -2
  62. package/src/utils/monomer-lib/monomer-colors.ts +10 -10
  63. package/src/utils/monomer-lib/monomer-lib-base.ts +6 -1
  64. package/src/utils/monomer-lib/monomer-lib.ts +15 -9
  65. package/src/utils/multiple-sequence-alignment-ui.ts +30 -30
  66. package/src/utils/save-as-fasta.ts +19 -12
  67. package/src/utils/seq-helper/seq-handler.ts +836 -0
  68. package/src/utils/seq-helper/seq-helper.ts +43 -19
  69. package/src/utils/sequence-to-mol.ts +7 -8
  70. package/src/utils/split-to-monomers.ts +7 -2
  71. package/src/utils/types.ts +8 -7
  72. package/src/utils/ui-utils.ts +2 -2
  73. package/src/viewers/web-logo-viewer.ts +18 -16
  74. package/src/widgets/bio-substructure-filter-helm.ts +5 -2
  75. package/src/widgets/bio-substructure-filter.ts +14 -24
  76. package/src/widgets/composition-analysis-widget.ts +6 -6
  77. package/src/widgets/representations.ts +7 -4
  78. package/src/tests/detectors-custom-notation-tests.ts +0 -37
  79. package/src/utils/cyclized.ts +0 -89
  80. package/src/utils/dimerized.ts +0 -10
@@ -1,13 +1,13 @@
1
1
  import * as DG from 'datagrok-api/dg';
2
2
  import * as grok from 'datagrok-api/grok';
3
+
3
4
  import {expect} from '@datagrok-libraries/utils/src/test';
4
- import {sequenceSpaceTopMenu} from '../package';
5
5
  import {MmDistanceFunctionsNames} from '@datagrok-libraries/ml/src/macromolecule-distance-functions';
6
6
  import {BYPASS_LARGE_DATA_WARNING} from '@datagrok-libraries/ml/src/functionEditors/consts';
7
7
  import {DimReductionMethods} from '@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/types';
8
8
 
9
9
  export async function _testSequenceSpaceReturnsResult(
10
- df: DG.DataFrame, algorithm: DimReductionMethods, colName: string,
10
+ df: DG.DataFrame, algorithm: DimReductionMethods, colName: string
11
11
  ) {
12
12
  // await grok.data.detectSemanticTypes(df);
13
13
  const col: DG.Column = df.getCol(colName);
@@ -18,7 +18,12 @@ export async function _testSequenceSpaceReturnsResult(
18
18
  const preprocessingFunc = DG.Func.find({package: 'Bio', name: 'macromoleculePreprocessingFunction'})[0];
19
19
  if (!preprocessingFunc)
20
20
  throw new Error('Preprocessing function not found');
21
- const sp = await sequenceSpaceTopMenu(df, df.col(colName)!, algorithm, MmDistanceFunctionsNames.LEVENSHTEIN, true,
22
- preprocessingFunc, {[BYPASS_LARGE_DATA_WARNING]: true});
21
+ const sp = await grok.functions.call('Bio:sequenceSpaceTopMenu', {
22
+ table: df, molecules: df.col(colName)!,
23
+ methodName: algorithm, similarityMetric: MmDistanceFunctionsNames.LEVENSHTEIN,
24
+ plotEmbeddings: true, preprocessingFunction: preprocessingFunc, options: {[BYPASS_LARGE_DATA_WARNING]: true}
25
+ });
26
+ // const sp = await sequenceSpaceTopMenu(df, df.col(colName)!, algorithm, MmDistanceFunctionsNames.LEVENSHTEIN, true,
27
+ // preprocessingFunc, {[BYPASS_LARGE_DATA_WARNING]: true});
23
28
  expect(sp != null, true);
24
29
  }
@@ -11,13 +11,12 @@ import {ISeqSplitted} from '@datagrok-libraries/bio/src/utils/macromolecule/type
11
11
  import {IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
12
12
  import {UserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/types';
13
13
  import {getMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
14
+ import {ISeqHelper, getSeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
14
15
 
15
16
  import {splitToMonomersUI} from '../utils/split-to-monomers';
16
17
  import {awaitGrid} from './utils';
17
18
  import * as C from '../utils/constants';
18
- import {getHelmMonomers} from '../package';
19
19
 
20
- import {_package} from '../package-test';
21
20
  import {getUserLibSettings, setUserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
22
21
 
23
22
  category('splitters', async () => {
@@ -89,10 +88,12 @@ category('splitters', async () => {
89
88
  });
90
89
 
91
90
  category('splitters', () => {
91
+ let seqHelper: ISeqHelper;
92
92
  let monomerLibHelper: IMonomerLibHelper;
93
93
  let userLibSettings: UserLibSettings;
94
94
 
95
95
  before(async () => {
96
+ seqHelper = await getSeqHelper();
96
97
  monomerLibHelper = await getMonomerLibHelper();
97
98
  userLibSettings = await getUserLibSettings();
98
99
 
@@ -113,7 +114,7 @@ category('splitters', () => {
113
114
  seqCol.semType = semType;
114
115
  seqCol.setTag(bioTAGS.aligned, C.MSA);
115
116
 
116
- const newDf = await splitToMonomersUI(df, seqCol);
117
+ const newDf: DG.DataFrame = await grok.functions.call('Bio:splitToMonomersTopMenu', {table: df, sequence: seqCol});
117
118
  expect(newDf.columns.names().includes('17'), true);
118
119
  // call to calculate 'cell.renderer' tag
119
120
  await grok.data.detectSemanticTypes(newDf);
@@ -134,7 +135,7 @@ PEPTIDE1{hHis.Aca.Cys_SEt}$$$,5.72388
134
135
  const expectedMonomerList = ['hHis', 'Aca', 'Cys_SEt', 'N', 'T'];
135
136
 
136
137
  const helmCol: DG.Column = df.getCol('HELM');
137
- const res = getHelmMonomers(helmCol);
138
+ const res = await grok.functions.call('Bio:getHelmMonomers', {sequence: helmCol}) as string[];
138
139
 
139
140
  const missed = expectedMonomerList.filter((m) => !res.includes(m));
140
141
  const unexpected = res.filter((m) => !expectedMonomerList.includes(m));
@@ -11,7 +11,7 @@ import {
11
11
  getUserLibSettings, setUserLibSettings
12
12
  } from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
13
13
  import {UserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/types';
14
- import {getHelmHelper, IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
14
+ import {getSeqHelper, ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
15
15
 
16
16
  import {awaitGrid, readDataframe} from './utils';
17
17
 
@@ -23,15 +23,14 @@ import {HelmBioFilter} from '../widgets/bio-substructure-filter-helm';
23
23
 
24
24
  import {_package} from '../package-test';
25
25
 
26
-
27
26
  category('bio-substructure-filters', async () => {
28
- let helmHelper: IHelmHelper;
27
+ let seqHelper: ISeqHelper;
29
28
  let monomerLibHelper: IMonomerLibHelper;
30
29
  /** Backup actual user's monomer libraries settings */
31
30
  let userLibSettings: UserLibSettings;
32
31
 
33
32
  before(async () => {
34
- helmHelper = await getHelmHelper(); // init Helm package
33
+ seqHelper = await getSeqHelper();
35
34
  monomerLibHelper = await getMonomerLibHelper();
36
35
  userLibSettings = await getUserLibSettings();
37
36
 
@@ -52,7 +51,7 @@ category('bio-substructure-filters', async () => {
52
51
  const fSubStr: string = 'MD';
53
52
  const fTrueCount: number = 3;
54
53
 
55
- const filter = new BioSubstructureFilter();
54
+ const filter = new BioSubstructureFilter(seqHelper, _package.logger);
56
55
  filter.attach(df);
57
56
  await filter.awaitRendered();
58
57
  try {
@@ -73,7 +72,7 @@ category('bio-substructure-filters', async () => {
73
72
 
74
73
  test('separator', async () => {
75
74
  const msa = await readDataframe('tests/filter_MSA.csv');
76
- const filter = new BioSubstructureFilter();
75
+ const filter = new BioSubstructureFilter(seqHelper, _package.logger);
77
76
  await grok.data.detectSemanticTypes(msa);
78
77
  filter.attach(msa);
79
78
  await filter.awaitRendered();
@@ -112,7 +111,7 @@ category('bio-substructure-filters', async () => {
112
111
  // // // Helm filter calls waitForElementInDom
113
112
  // // const fg = view.getFiltersGroup({createDefaultFilters: false});
114
113
  // // _package.logger.debug('Bio tests: substructureFilters/helm, filter attaching.');
115
- // // const filter = new BioSubstructureFilter();
114
+ // // const filter = await createBioSubstructureFilter();
116
115
  // // filter.attach(df);
117
116
  // // _package.logger.debug('Bio tests: substructureFilters/helm, filter attached.');
118
117
  // // const fg = await df.plot.fromType(DG.VIEWER.FILTERS, {
@@ -157,7 +156,7 @@ category('bio-substructure-filters', async () => {
157
156
  const view = grok.shell.addTableView(df);
158
157
 
159
158
  _package.logger.debug(`${logPrefix}, filter attaching.`);
160
- const filter = new BioSubstructureFilter();
159
+ const filter = new BioSubstructureFilter(seqHelper, _package.logger);
161
160
  filter.attach(df);
162
161
  const dlg = ui.dialog('Test filters').add(filter.root).show(); // to waitForElementInDom
163
162
  await filter.awaitRendered();
@@ -337,7 +336,6 @@ category('bio-substructure-filters', async () => {
337
336
  const fSeq2SubStr: string = 'GCATT';
338
337
  const fSeq2Trues: number[] = df.getCol('trueSeq2').toList();
339
338
 
340
- //const seq2Filter = new BioSubstructureFilter();
341
339
  const filterList: any[] = [
342
340
  {type: 'Bio:bioSubstructureFilter', columnName: fSeq1ColName},
343
341
  {type: 'Bio:bioSubstructureFilter', columnName: fSeq2ColName},
@@ -451,19 +449,20 @@ category('bio-substructure-filters', async () => {
451
449
  await delay(100);
452
450
  await awaitGrid(view.grid);
453
451
  });
452
+
453
+ async function createFilter(colName: string, df: DG.DataFrame): Promise<BioSubstructureFilter> {
454
+ if (!df.columns.names().includes(colName)) {
455
+ throw new Error(`The column '${colName}' not found. ` +
456
+ `Available in data frame are ${JSON.stringify(df.columns.names())}`);
457
+ }
458
+
459
+ const filter = new BioSubstructureFilter(seqHelper, _package.logger);
460
+ filter.attach(df);
461
+ filter.applyState({columnName: colName});
462
+ filter.column = df.col(colName);
463
+ filter.columnName = colName;
464
+ //filter.tableName = df.name;
465
+ return filter;
466
+ };
454
467
  });
455
468
 
456
- async function createFilter(colName: string, df: DG.DataFrame): Promise<BioSubstructureFilter> {
457
- if (!df.columns.names().includes(colName)) {
458
- throw new Error(`The column '${colName}' not found. ` +
459
- `Available in data frame are ${JSON.stringify(df.columns.names())}`);
460
- }
461
-
462
- const filter = new BioSubstructureFilter();
463
- filter.attach(df);
464
- filter.applyState({columnName: colName});
465
- filter.column = df.col(colName);
466
- filter.columnName = colName;
467
- //filter.tableName = df.name;
468
- return filter;
469
- };
@@ -15,7 +15,7 @@ import {
15
15
  getUserLibSettings, setUserLibSettings
16
16
  } from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
17
17
  import {UserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/types';
18
- import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
18
+ import {getSeqHelper, ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
19
19
  import {getRdKitModule} from '@datagrok-libraries/bio/src/chem/rdkit-module';
20
20
 
21
21
  import {_package} from '../package-test';
@@ -60,11 +60,13 @@ category('toAtomicLevel', async () => {
60
60
  /** Backup actual user's monomer libraries settings */
61
61
  let userLibSettings: UserLibSettings;
62
62
 
63
+ let seqHelper: ISeqHelper;
63
64
  let monomerLib: IMonomerLib;
64
65
  let rdKitModule: RDModule;
65
66
 
66
67
  before(async () => {
67
68
  rdKitModule = await getRdKitModule();
69
+ seqHelper = await getSeqHelper();
68
70
  monomerLibHelper = await getMonomerLibHelper();
69
71
  userLibSettings = await getUserLibSettings();
70
72
  // Clear settings to test default
@@ -214,7 +216,7 @@ PEPTIDE1{Lys_Boc.hHis.Aca.Cys_SEt.T.dK.Thr_PO3H2.Aca.Tyr_PO3H2.Thr_PO3H2.Aca.Tyr
214
216
  seqCol.semType = DG.SEMTYPE.MACROMOLECULE;
215
217
  seqCol.meta.units = NOTATION.FASTA;
216
218
  seqCol.setTag(bioTAGS.alphabet, ALPHABET.PT);
217
- const sh = SeqHandler.forColumn(seqCol);
219
+ const sh = seqHelper.getSeqHandler(seqCol);
218
220
  const resCol = (await _testToAtomicLevel(srcDf, 'seq', monomerLibHelper))!;
219
221
  expect(polishMolfile(resCol.get(0)), polishMolfile(tgtMol));
220
222
  });
@@ -223,7 +225,7 @@ PEPTIDE1{Lys_Boc.hHis.Aca.Cys_SEt.T.dK.Thr_PO3H2.Aca.Tyr_PO3H2.Thr_PO3H2.Aca.Tyr
223
225
  df: DG.DataFrame, seqColName: string = 'seq', monomerLibHelper: IMonomerLibHelper
224
226
  ): Promise<DG.Column | null> {
225
227
  const seqCol: DG.Column<string> = df.getCol(seqColName);
226
- const res = await _toAtomicLevel(df, seqCol, monomerLib, rdKitModule);
228
+ const res = await _toAtomicLevel(df, seqCol, monomerLib, seqHelper, rdKitModule);
227
229
  if (res.warnings.length > 0)
228
230
  _package.logger.warning(`_toAtomicLevel() warnings ${res.warnings.join('\n')}`);
229
231
  return res.molCol;
@@ -11,6 +11,7 @@ import {UserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/types';
11
11
  import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
12
12
  import {getRdKitModule} from '@datagrok-libraries/bio/src/chem/rdkit-module';
13
13
  import {RDModule} from '@datagrok-libraries/chem-meta/src/rdkit-api';
14
+ import {ISeqHelper, getSeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
14
15
 
15
16
  type TestDataTargetType = { atomCount: number, bondCount: number };
16
17
  type TestDataType = {
@@ -22,10 +23,12 @@ category('toAtomicLevel-ui', () => {
22
23
 
23
24
  let monomerLibHelper: IMonomerLibHelper;
24
25
  let userLibSettings: UserLibSettings;
26
+ let seqHelper: ISeqHelper;
25
27
  let monomerLib: IMonomerLib;
26
28
  let rdKitModule: RDModule;
27
29
 
28
30
  before(async () => {
31
+ seqHelper = await getSeqHelper();
29
32
  rdKitModule = await getRdKitModule();
30
33
  monomerLibHelper = await getMonomerLibHelper();
31
34
  userLibSettings = await getUserLibSettings();
@@ -95,7 +98,7 @@ category('toAtomicLevel-ui', () => {
95
98
  async function _testToAtomicLevelFunc(
96
99
  seqCol: DG.Column<string>, nonlinear: boolean, tgt: TestDataTargetType,
97
100
  ): Promise<void> {
98
- const res = (await sequenceToMolfile(seqCol.dataFrame, seqCol, nonlinear, false, monomerLib, rdKitModule))!;
101
+ const res = (await sequenceToMolfile(seqCol.dataFrame, seqCol, nonlinear, false, monomerLib, seqHelper, rdKitModule))!;
99
102
  expect(res.molCol!.semType, DG.SEMTYPE.MOLECULE);
100
103
  const resMolStr = res.molCol!.get(0)!;
101
104
  const resRdMol = rdKitModule.get_mol(resMolStr);
@@ -3,7 +3,7 @@ import * as grok from 'datagrok-api/grok';
3
3
 
4
4
  import {ALIGNMENT, NOTATION, TAGS as bioTAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
5
5
  import {expect} from '@datagrok-libraries/utils/src/test';
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
  export type DetectorTestData = { [testName: string]: { csv: string, neg?: string[], pos?: { [colName: string]: PosCol } } };
9
9
 
@@ -35,8 +35,8 @@ export async function _testNeg(readDf: DfReaderFunc, colName: string) {
35
35
  }
36
36
 
37
37
  export async function _testPos(
38
- readDf: DfReaderFunc, colName: string, units: string, aligned: string | null,
39
- alphabet: string | null, alphabetSize: number, alphabetIsMultichar?: boolean,
38
+ readDf: DfReaderFunc, colName: string, seqHelper: ISeqHelper,
39
+ units: string, aligned: string | null, alphabet: string | null, alphabetSize: number, alphabetIsMultichar?: boolean,
40
40
  separator: string | null = null,
41
41
  ) {
42
42
  const df: DG.DataFrame = await readDf();
@@ -53,7 +53,7 @@ export async function _testPos(
53
53
  if (separator)
54
54
  expect(col.getTag(bioTAGS.separator), separator);
55
55
 
56
- const sh = SeqHandler.forColumn(col);
56
+ const sh = seqHelper.getSeqHandler(col);
57
57
  expect(sh.getAlphabetSize(), alphabetSize);
58
58
  expect(sh.getAlphabetIsMultichar(), alphabetIsMultichar);
59
59
  if (!sh.isHelm()) {
@@ -1,13 +1,15 @@
1
1
  import * as DG from 'datagrok-api/dg';
2
- import { calculateScores, SCORE } from '@datagrok-libraries/bio/src/utils/macromolecule/scoring';
2
+
3
+ import {calculateScores, SCORE} from '@datagrok-libraries/bio/src/utils/macromolecule/scoring';
4
+ import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
3
5
 
4
6
  export async function calculateScoresWithEmptyValues(
5
- table: DG.DataFrame, macromolecule: DG.Column, reference: string, scoring: SCORE
7
+ table: DG.DataFrame, macromolecule: DG.Column, reference: string, scoring: SCORE, seqHelper: ISeqHelper,
6
8
  ): Promise<DG.Column<number>> {
7
- const scores = await calculateScores(table, macromolecule, reference, scoring);
8
- for (let i = 0; i < scores.length; i++) {
9
- if (macromolecule.isNone(i))
10
- scores.set(i, null, false);
11
- }
12
- return scores;
13
- }
9
+ const scores = await calculateScores(table, macromolecule, reference, scoring, seqHelper);
10
+ for (let i = 0; i < scores.length; i++) {
11
+ if (macromolecule.isNone(i))
12
+ scores.set(i, null, false);
13
+ }
14
+ return scores;
15
+ }
@@ -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