@datagrok/bio 2.11.28 → 2.11.30

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 (58) hide show
  1. package/CHANGELOG.md +12 -1
  2. package/dist/23.js +2 -0
  3. package/dist/23.js.map +1 -0
  4. package/dist/282.js +2 -0
  5. package/dist/282.js.map +1 -0
  6. package/dist/36.js +2 -0
  7. package/dist/36.js.map +1 -0
  8. package/dist/40.js +2 -0
  9. package/dist/40.js.map +1 -0
  10. package/dist/413.js +2 -0
  11. package/dist/413.js.map +1 -0
  12. package/dist/42.js +1 -1
  13. package/dist/42.js.map +1 -1
  14. package/dist/427.js +2 -0
  15. package/dist/427.js.map +1 -0
  16. package/dist/65.js +2 -0
  17. package/dist/65.js.map +1 -0
  18. package/dist/709.js +3 -0
  19. package/dist/709.js.map +1 -0
  20. package/dist/package-test.js +1 -1
  21. package/dist/package-test.js.map +1 -1
  22. package/dist/package.js +1 -1
  23. package/dist/package.js.map +1 -1
  24. package/files/tests/to-atomic-level-msa-fasta-input.csv +10 -0
  25. package/files/tests/to-atomic-level-msa-fasta-output.csv +2178 -0
  26. package/package.json +9 -9
  27. package/src/package.ts +12 -10
  28. package/src/tests/msa-tests.ts +2 -2
  29. package/src/tests/pepsea-tests.ts +1 -1
  30. package/src/tests/renderers-test.ts +16 -16
  31. package/src/tests/splitters-test.ts +7 -12
  32. package/src/tests/substructure-filters-tests.ts +277 -55
  33. package/src/tests/to-atomic-level-tests.ts +32 -22
  34. package/src/tests/utils/sequences-generators.ts +6 -3
  35. package/src/tests/utils.ts +6 -6
  36. package/src/utils/cell-renderer.ts +2 -0
  37. package/src/utils/docker.ts +36 -0
  38. package/src/viewers/vd-regions-viewer.ts +4 -0
  39. package/src/viewers/web-logo-viewer.ts +4 -0
  40. package/src/widgets/bio-substructure-filter-helm.ts +168 -0
  41. package/src/widgets/bio-substructure-filter-types.ts +131 -0
  42. package/src/widgets/bio-substructure-filter.ts +215 -175
  43. package/src/widgets/composition-analysis-widget.ts +1 -1
  44. package/dist/100.js +0 -2
  45. package/dist/100.js.map +0 -1
  46. package/dist/118.js +0 -2
  47. package/dist/118.js.map +0 -1
  48. package/dist/361.js +0 -2
  49. package/dist/361.js.map +0 -1
  50. package/dist/471.js +0 -2
  51. package/dist/471.js.map +0 -1
  52. package/dist/649.js +0 -2
  53. package/dist/649.js.map +0 -1
  54. package/dist/664.js +0 -2
  55. package/dist/664.js.map +0 -1
  56. package/dist/886.js +0 -3
  57. package/dist/886.js.map +0 -1
  58. /package/dist/{886.js.LICENSE.txt → 709.js.LICENSE.txt} +0 -0
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "name": "Leonid Stolbov",
6
6
  "email": "lstolbov@datagrok.ai"
7
7
  },
8
- "version": "2.11.28",
8
+ "version": "2.11.30",
9
9
  "description": "Bioinformatics support (import/export of sequences, conversion, visualization, analysis). [See more](https://github.com/datagrok-ai/public/blob/master/packages/Bio/README.md) for details.",
10
10
  "repository": {
11
11
  "type": "git",
@@ -34,15 +34,15 @@
34
34
  ],
35
35
  "dependencies": {
36
36
  "@biowasm/aioli": "^3.1.0",
37
- "@datagrok-libraries/bio": "^5.39.21",
37
+ "@datagrok-libraries/bio": "^5.39.24",
38
38
  "@datagrok-libraries/chem-meta": "^1.2.1",
39
- "@datagrok-libraries/ml": "^6.4.1",
39
+ "@datagrok-libraries/ml": "^6.4.7",
40
40
  "@datagrok-libraries/tutorials": "^1.3.11",
41
- "@datagrok-libraries/utils": "^4.1.36",
41
+ "@datagrok-libraries/utils": "^4.1.43",
42
42
  "@datagrok-libraries/math": "^1.0.7",
43
43
  "cash-dom": "^8.0.0",
44
44
  "css-loader": "^6.7.3",
45
- "datagrok-api": "^1.16.0",
45
+ "datagrok-api": "^1.17.13",
46
46
  "dayjs": "^1.11.4",
47
47
  "fastest-levenshtein": "^1.0.16",
48
48
  "openchemlib": "6.0.1",
@@ -65,8 +65,8 @@
65
65
  "webpack": "^5.76.3",
66
66
  "webpack-bundle-analyzer": "latest",
67
67
  "webpack-cli": "^4.9.1",
68
- "@datagrok/chem": "^1.8.8",
69
- "@datagrok/helm": "^2.1.24",
68
+ "@datagrok/chem": "^1.8.11",
69
+ "@datagrok/helm": "^2.1.27",
70
70
  "@datagrok/dendrogram": "^1.2.22"
71
71
  },
72
72
  "scripts": {
@@ -74,12 +74,12 @@
74
74
  "link-bio": "npm link @datagrok-libraries/bio",
75
75
  "link-ml": "npm link @datagrok-libraries/ml",
76
76
  "link-utils": "npm link @datagrok-libraries/utils",
77
- "link-all": "npm link @datagrok-libraries/chem-meta datagrok-api @datagrok-libraries/utils @datagrok-libraries/ml @datagrok-libraries/bio @datagrok-libraries/tutorials",
77
+ "link-all": "npm link @datagrok-libraries/chem-meta datagrok-api @datagrok-libraries/utils @datagrok-libraries/math @datagrok-libraries/ml @datagrok-libraries/bio @datagrok-libraries/tutorials",
78
78
  "debug-sequences1": "webpack && grok publish",
79
79
  "release-sequences1": "webpack && grok publish --release",
80
80
  "build-sequences1": "webpack",
81
81
  "build": "webpack",
82
- "build-all": "npm --prefix ./../../libraries/chem-meta run build && npm --prefix ./../../js-api run build && npm --prefix ./../../libraries/utils run build && npm --prefix ./../../libraries/ml run build && npm --prefix ./../../libraries/bio run build && npm --prefix ./../../libraries/tutorials run build && npm run build",
82
+ "build-all": "npm --prefix ./../../libraries/chem-meta run build && npm --prefix ./../../js-api run build && npm --prefix ./../../libraries/utils run build && npm --prefix ./../../libraries/math run build && npm --prefix ./../../libraries/ml run build && npm --prefix ./../../libraries/bio run build && npm --prefix ./../../libraries/tutorials run build && npm run build",
83
83
  "debug-sequences1-local": "webpack && grok publish local",
84
84
  "release-sequences1-local": "webpack && grok publish local --release",
85
85
  "debug-sequences1-dev": "webpack && grok publish dev",
package/src/package.ts CHANGED
@@ -71,11 +71,13 @@ import {detectMacromoleculeProbeDo} from './utils/detect-macromolecule-probe';
71
71
  import {ActivityCliffsEditor} from '@datagrok-libraries/ml/src/functionEditors/activity-cliffs-function-editor';
72
72
  import BitArray from '@datagrok-libraries/utils/src/bit-array';
73
73
  import {BYPASS_LARGE_DATA_WARNING} from '@datagrok-libraries/ml/src/functionEditors/consts';
74
- import {getEmbeddingColsNames, multiColReduceDimensionality} from
75
- '@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/reduce-dimensionality';
74
+ import {
75
+ getEmbeddingColsNames, multiColReduceDimensionality
76
+ } from '@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/reduce-dimensionality';
76
77
  import {DimReductionMethods} from '@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/types';
77
- import {ITSNEOptions, IUMAPOptions} from
78
- '@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/multi-column-dim-reducer';
78
+ import {
79
+ ITSNEOptions, IUMAPOptions
80
+ } from '@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/multi-column-dim-reducer';
79
81
 
80
82
  export const _package = new BioPackage();
81
83
 
@@ -483,7 +485,7 @@ export async function activityCliffs(table: DG.DataFrame, molecules: DG.Column<s
483
485
  //input: double gapOpen = 1 {caption: Gap open penalty; default: 1; optional: true}
484
486
  //input: double gapExtend = 0.6 {caption: Gap extension penalty; default: 0.6; optional: true}
485
487
  // eslint-disable-next-line max-len
486
- //input: string fingerprintType = Morgan {caption: Fingerprint type; choices: ['Morgan', 'RDKit', 'Pattern']; default: Morgan; optional: true}
488
+ //input: string fingerprintType = Morgan {caption: Fingerprint type; choices: ['Morgan', 'RDKit', 'Pattern', 'AtomPair', 'MACCS', 'TopologicalTorsion']; default: Morgan; optional: true}
487
489
  //output: object result
488
490
  export async function macromoleculePreprocessingFunction(
489
491
  col: DG.Column, metric: MmDistanceFunctionsNames, gapOpen: number = 1, gapExtend: number = 0.6,
@@ -557,13 +559,13 @@ export async function sequenceSpaceTopMenu(table: DG.DataFrame, molecules: DG.Co
557
559
  //top-menu: Bio | Convert | To Atomic Level...
558
560
  //name: To Atomic Level
559
561
  //description: Converts sequences to molblocks
560
- //input: dataframe df [Input data table]
561
- //input: column macroMolecule {semType: Macromolecule}
562
- //input: bool nonlinear=false { description: Slower mode for cycling/branching HELM structures }
563
- export async function toAtomicLevel(df: DG.DataFrame, macroMolecule: DG.Column, nonlinear: boolean): Promise<void> {
562
+ //input: dataframe table [Input data table]
563
+ //input: column macroMolecule {caption: Sequence; semType: Macromolecule}
564
+ //input: bool nonlinear =false {description: Slower mode for cycling/branching HELM structures}
565
+ export async function toAtomicLevel(table: DG.DataFrame, seqCol: DG.Column, nonlinear: boolean): Promise<void> {
564
566
  const pi = DG.TaskBarProgressIndicator.create('Converting to atomic level ...');
565
567
  try {
566
- await sequenceToMolfile(df, macroMolecule, nonlinear);
568
+ await sequenceToMolfile(table, seqCol, nonlinear);
567
569
  } finally {
568
570
  pi.close();
569
571
  }
@@ -81,12 +81,12 @@ MWRSWYCKHPMWRSWYCKHPMWRSWYCKHPMWRSWYCKHPMWRSWYCKHPMWRSWYCKHPMWRSWYCKHPMWRSWYCKHP
81
81
  test('isCorrectHelm', async () => {
82
82
  await awaitContainerStart();
83
83
  await _testMSAOnColumn(helmFromCsv, helmToCsv, NOTATION.HELM, NOTATION.SEPARATOR, undefined, 'mafft');
84
- });
84
+ }, {timeout: 60000});
85
85
 
86
86
  test('isCorrectHelmLong', async () => {
87
87
  await awaitContainerStart();
88
88
  await _testMSAOnColumn(longHelmFromCsv, longHelmToCsv, NOTATION.HELM, NOTATION.SEPARATOR, undefined, 'mafft');
89
- });
89
+ }, {timeout: 60000});
90
90
 
91
91
  test('isCorrectSeparator', async () => {
92
92
  await _testMSAOnColumn(
@@ -20,5 +20,5 @@ category('PepSeA', () => {
20
20
  const alignedTestCol = table.getCol('MSA');
21
21
  for (let i = 0; i < alignedCol!.length; ++i)
22
22
  expect(alignedCol!.get(i) == alignedTestCol.get(i), true);
23
- });
23
+ }, {timeout: 60000});
24
24
  });
@@ -4,14 +4,15 @@ import * as DG from 'datagrok-api/dg';
4
4
  import $ from 'cash-dom';
5
5
 
6
6
  import {category, expect, test, awaitCheck, delay} from '@datagrok-libraries/utils/src/test';
7
+ import {ALIGNMENT, ALPHABET, NOTATION, TAGS as bioTAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
8
+ import {UnitsHandler} from '@datagrok-libraries/bio/src/utils/units-handler';
7
9
 
8
10
  import {importFasta} from '../package';
9
11
  import {convertDo} from '../utils/convert';
10
- import * as C from '../utils/constants';
11
12
  import {generateLongSequence, generateManySequences, performanceTest} from './utils/sequences-generators';
12
- import {ALIGNMENT, ALPHABET, NOTATION, TAGS as bioTAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
13
- import {UnitsHandler} from '@datagrok-libraries/bio/src/utils/units-handler';
14
13
  import {multipleSequenceAlignmentUI} from '../utils/multiple-sequence-alignment-ui';
14
+ import {awaitGrid} from './utils';
15
+ import * as C from '../utils/constants';
15
16
 
16
17
  category('renderers', () => {
17
18
  test('long sequence performance ', async () => {
@@ -62,8 +63,8 @@ category('renderers', () => {
62
63
  // call to calculate 'cell.renderer' tag
63
64
  await grok.data.detectSemanticTypes(df);
64
65
 
65
- await awaitCheck(() => { return tv.grid.dataFrame != df; },
66
- 'View grid has wrong data frame', 100);
66
+ await awaitGrid(tv.grid);
67
+ expect(tv.grid.dataFrame.id, df.id);
67
68
 
68
69
  const resCellRenderer = seqCol.getTag(DG.TAGS.CELL_RENDERER);
69
70
  expect(resCellRenderer, 'sequence');
@@ -82,8 +83,8 @@ category('renderers', () => {
82
83
  // call to calculate 'cell.renderer' tag
83
84
  await grok.data.detectSemanticTypes(df);
84
85
 
85
- await awaitCheck(() => { return tv.grid.dataFrame != df; },
86
- 'View grid has wrong data frame', 100);
86
+ await awaitGrid(tv.grid);
87
+ expect(tv.grid.dataFrame.id, df.id);
87
88
 
88
89
  const resCellRenderer = seqCol.getTag(DG.TAGS.CELL_RENDERER);
89
90
  expect(resCellRenderer, 'sequence');
@@ -104,8 +105,8 @@ category('renderers', () => {
104
105
  // call to calculate 'cell.renderer' tag
105
106
  await grok.data.detectSemanticTypes(df);
106
107
 
107
- await awaitCheck(() => { return tv.grid.dataFrame != df; },
108
- 'View grid has wrong data frame', 100);
108
+ await awaitGrid(tv.grid);
109
+ expect(tv.grid.dataFrame.id, df.id);
109
110
 
110
111
  const resCellRenderer = seqDiffCol.getTag(DG.TAGS.CELL_RENDERER);
111
112
  expect(resCellRenderer, C.SEM_TYPES.MACROMOLECULE_DIFFERENCE);
@@ -125,8 +126,8 @@ category('renderers', () => {
125
126
  await grok.data.detectSemanticTypes(df);
126
127
 
127
128
  console.log('Bio: tests/renderers/afterMsa, table view');
128
- await awaitCheck(() => { return tv.grid.dataFrame != df; },
129
- 'View grid has wrong data frame', 100);
129
+ await awaitGrid(tv.grid);
130
+ expect(tv.grid.dataFrame.id, df.id);
130
131
 
131
132
  console.log('Bio: tests/renderers/afterMsa, src before test ' +
132
133
  `semType="${srcSeqCol!.semType}", units="${srcSeqCol!.getTag(DG.TAGS.UNITS)}", ` +
@@ -138,9 +139,8 @@ category('renderers', () => {
138
139
  expect(srcSeqCol.getTag(DG.TAGS.CELL_RENDERER), 'sequence');
139
140
 
140
141
  const msaSeqCol = await multipleSequenceAlignmentUI({col: srcSeqCol});
141
- tv.grid.invalidate();
142
- await awaitCheck(() => { return tv.grid.dataFrame != df; },
143
- 'View grid has wrong data frame', 100);
142
+ await awaitGrid(tv.grid);
143
+ expect(tv.grid.dataFrame.id, df.id);
144
144
 
145
145
  expect(msaSeqCol.semType, DG.SEMTYPE.MACROMOLECULE);
146
146
  expect(msaSeqCol.getTag(DG.TAGS.UNITS), NOTATION.FASTA);
@@ -166,8 +166,8 @@ category('renderers', () => {
166
166
  await grok.data.detectSemanticTypes(df);
167
167
 
168
168
  const tgtCol: DG.Column = await convertDo(srcCol, NOTATION.SEPARATOR, '/');
169
- await awaitCheck(() => { return tv.grid.dataFrame != df; },
170
- 'View grid has wrong data frame', 100);
169
+ await awaitGrid(tv.grid);
170
+ expect(tv.grid.dataFrame.id, df.id);
171
171
 
172
172
  const resCellRenderer = tgtCol.getTag(DG.TAGS.CELL_RENDERER);
173
173
  expect(resCellRenderer, 'sequence');
@@ -3,25 +3,20 @@ import * as ui from 'datagrok-api/ui';
3
3
  import * as DG from 'datagrok-api/dg';
4
4
 
5
5
  import {
6
- after,
7
- before,
8
- category,
9
- test,
10
- expect,
11
- expectArray,
12
- delay,
13
- awaitCheck
6
+ after, before, category, test, expect, expectArray, delay, awaitCheck
14
7
  } from '@datagrok-libraries/utils/src/test';
15
- import * as C from '../utils/constants';
16
- import {_package, getHelmMonomers} from '../package';
17
8
  import {
18
9
  TAGS as bioTAGS,
19
10
  splitterAsFasta,
20
11
  splitterAsHelm,
21
12
  NOTATION
22
13
  } from '@datagrok-libraries/bio/src/utils/macromolecule';
14
+
23
15
  import {splitToMonomersUI} from '../utils/split-to-monomers';
16
+ import {awaitGrid} from './utils';
17
+ import * as C from '../utils/constants';
24
18
 
19
+ import {getHelmMonomers} from '../package';
25
20
 
26
21
  category('splitters', async () => {
27
22
  before(async () => {
@@ -107,8 +102,8 @@ category('splitters', async () => {
107
102
 
108
103
  // TODO: Check cell.renderer for columns of monomers
109
104
  const tv: DG.TableView = grok.shell.addTableView(newDf);
110
- await awaitCheck(() => { return tv.grid.dataFrame != df; },
111
- 'View grid has wrong data frame', 100);
105
+ await awaitGrid(tv.grid);
106
+ expect(tv.grid.dataFrame.id, df.id);
112
107
  });
113
108
 
114
109
  test('getHelmMonomers', async () => {
@@ -1,14 +1,19 @@
1
- import * as DG from 'datagrok-api/dg';
2
1
  import * as grok from 'datagrok-api/grok';
2
+ import * as ui from 'datagrok-api/ui';
3
+ import * as DG from 'datagrok-api/dg';
3
4
 
4
- import {after, before, category, test, expect, delay, testEvent} from '@datagrok-libraries/utils/src/test';
5
+ import {after, before, category, test, expect, delay, testEvent, awaitCheck} from '@datagrok-libraries/utils/src/test';
5
6
  import {getMonomerLibHelper, IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
6
7
  import {
7
8
  LibSettings, getUserLibSettings, setUserLibSettings, setUserLibSettingsForTests
8
9
  } from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
9
10
 
10
11
  import {awaitGrid, readDataframe} from './utils';
11
- import {BioSubstructureFilter, HelmFilter, SeparatorFilter} from '../widgets/bio-substructure-filter';
12
+ import {
13
+ BioSubstructureFilter, FastaBioFilter, SeparatorBioFilter, SeparatorFilterProps
14
+ } from '../widgets/bio-substructure-filter';
15
+ import {BioFilterProps} from '../widgets/bio-substructure-filter-types';
16
+ import {HelmBioFilter} from '../widgets/bio-substructure-filter-helm';
12
17
 
13
18
  import {_package} from '../package-test';
14
19
 
@@ -34,17 +39,29 @@ category('substructureFilters', async () => {
34
39
  });
35
40
 
36
41
  test('fasta', async () => {
37
- const fasta = await readDataframe('tests/filter_FASTA.csv');
42
+ const df = await readDataframe('tests/filter_FASTA.csv');
43
+ await grok.data.detectSemanticTypes(df);
44
+
45
+ const fSubStr: string = 'MD';
46
+ const fTrueCount: number = 3;
47
+
38
48
  const filter = new BioSubstructureFilter();
39
- await grok.data.detectSemanticTypes(fasta);
40
- filter.attach(fasta);
41
- filter.bioFilter!.substructure = 'MD';
42
- await delay(100);
43
- expect(filter.dataFrame!.filter.trueCount, 3);
44
- expect(filter.dataFrame!.filter.get(0), true);
45
- expect(filter.dataFrame!.filter.get(3), true);
46
- expect(filter.dataFrame!.filter.get(8), true);
47
- expect(filter.dataFrame!.filter.get(1), false);
49
+ filter.attach(df);
50
+ await filter.awaitRendered();
51
+ try {
52
+ expect(!!filter.bioFilter, true);
53
+ expect(filter.bioFilter!.type, 'FastaBioFilter');
54
+ const bf = filter.bioFilter as FastaBioFilter;
55
+
56
+ await testEvent(df.onRowsFiltered, () => {}, () => {
57
+ bf.props = new BioFilterProps(fSubStr);
58
+ }, 5000, 'testEvent onRowsFiltered');
59
+ expect(filter.dataFrame!.filter.trueCount, fTrueCount);
60
+ expect(filter.dataFrame?.filter.toBinaryString(), '10010000100000');
61
+ } finally {
62
+ filter.detach();
63
+ }
64
+ await filter.awaitRendered();
48
65
  });
49
66
 
50
67
  test('separator', async () => {
@@ -52,49 +69,254 @@ category('substructureFilters', async () => {
52
69
  const filter = new BioSubstructureFilter();
53
70
  await grok.data.detectSemanticTypes(msa);
54
71
  filter.attach(msa);
55
- filter.bioFilter!.substructure = 'meI';
56
- await delay(100);
57
- expect(filter.dataFrame!.filter.trueCount, 7);
58
- expect(filter.dataFrame!.filter.get(2), false);
59
- filter.bioFilter!.substructure = '/meI';
60
- await delay(100);
61
- expect(filter.dataFrame!.filter.trueCount, 0);
62
- filter.bioFilter!.substructure = 'meI-hHis';
63
- (filter.bioFilter! as SeparatorFilter).separatorInput.value = '-';
64
- await delay(100);
65
- expect(filter.dataFrame!.filter.trueCount, 7);
66
- expect(filter.dataFrame!.filter.get(2), false);
72
+ await filter.awaitRendered();
73
+ try {
74
+ expect(!!filter.bioFilter, true);
75
+ expect(filter.bioFilter!.type, 'SeparatorBioFilter');
76
+ const bf = filter.bioFilter as SeparatorBioFilter;
77
+
78
+ await testEvent(msa.onRowsFiltered, () => {}, () => {
79
+ bf.props = new SeparatorFilterProps('meI');
80
+ }, 5000, 'testEvent onRowsFiltered');
81
+ expect(filter.dataFrame!.filter.trueCount, 7);
82
+ expect(filter.dataFrame!.filter.get(2), false);
83
+
84
+ await testEvent(msa.onRowsFiltered, () => {}, () => {
85
+ bf.props = new SeparatorFilterProps('/meI');
86
+ }, 5000, 'testEvent onRowsFiltered');
87
+ expect(filter.dataFrame!.filter.trueCount, 0);
88
+
89
+ await testEvent(msa.onRowsFiltered, () => {}, () => {
90
+ bf.props = new SeparatorFilterProps('meI-hHis', '-');
91
+ }, 5000, 'testEvent onRowsFiltered');
92
+ expect(filter.dataFrame!.filter.trueCount, 7);
93
+ expect(filter.dataFrame!.filter.get(2), false);
94
+ } finally {
95
+ filter.detach();
96
+ }
97
+ await filter.awaitRendered();
67
98
  });
68
99
 
69
- test('helm', async () => {
70
- const helm = await readDataframe('tests/filter_HELM.csv');
71
- const helmTableView = grok.shell.addTableView(helm);
100
+ // test('helm', async () => {
101
+ // const df = await readDataframe('tests/filter_HELM.csv');
102
+ // await grok.data.detectSemanticTypes(df);
103
+ // const view = grok.shell.addTableView(df);
104
+ //
105
+ // // // Helm filter calls waitForElementInDom
106
+ // // const fg = view.getFiltersGroup({createDefaultFilters: false});
107
+ // // _package.logger.debug('Bio tests: substructureFilters/helm, filter attaching.');
108
+ // // const filter = new BioSubstructureFilter();
109
+ // // filter.attach(df);
110
+ // // _package.logger.debug('Bio tests: substructureFilters/helm, filter attached.');
111
+ // // const fg = await df.plot.fromType(DG.VIEWER.FILTERS, {
112
+ // // filters: [
113
+ // // {type: 'Bio:bioSubstructureFilter', column: 'HELM string'}]
114
+ // // }) as DG.FilterGroup;
115
+ // // const fg2 = view.getFiltersGroup({createDefaultFilters: false});
116
+ // const fg = view.getFiltersGroup();
117
+ // await awaitCheck(() => fg.filters.length == 1, 'Filter panel has not been created', 3000);
118
+ // await awaitGrid(view.grid);
119
+ // const filter = fg.filters[0] as BioSubstructureFilter;
120
+ // // TODO: Check filter type
121
+ //
122
+ // _package.logger.debug('Bio tests: substructureFilters/helm, filter 1 changing.');
123
+ // const bf = filter.bioFilter as HelmBioFilter;
124
+ // await delay(1000); // to draw grid and filters
125
+ // await bf.awaitRendered();
126
+ //
127
+ // _package.logger.debug('Bio tests: substructureFilters/helm, filter 1 change awaiting.');
128
+ // await testEvent(df.onRowsFiltered, () => {}, () => {
129
+ // bf.props = new BioFilterProps('PEPTIDE1{C}$$$$V2.0');
130
+ // }, 20000);
131
+ // _package.logger.debug('Bio tests: substructureFilters/helm, filter 1 changed.');
132
+ // expect(filter.dataFrame!.filter.trueCount, 2);
133
+ // expect(filter.dataFrame!.filter.get(0), true);
134
+ // expect(filter.dataFrame!.filter.get(3), true);
135
+ //
136
+ // _package.logger.debug('Bio tests: substructureFilters/helm, filter 2 changing.');
137
+ // await testEvent(df.onRowsFiltered, () => {}, () => {
138
+ // bf.props = new BioFilterProps('PEPTIDE1{A.C}$$$$V2.0');
139
+ // }, 20000);
140
+ // await awaitGrid(view.grid);
141
+ // _package.logger.debug('Bio tests: substructureFilters/helm, filter 2 changed.');
142
+ // expect(filter.dataFrame!.filter.trueCount, 1);
143
+ // expect(filter.dataFrame!.filter.get(3), true);
144
+ // }, {timeout: 30000});
145
+
146
+ test('helm-dialog', async () => {
147
+ const logPrefix = 'Bio tests: substructureFilters/helm-dialog';
148
+ const df = await readDataframe('tests/filter_HELM.csv');
149
+ await grok.data.detectSemanticTypes(df);
150
+ const view = grok.shell.addTableView(df);
151
+
152
+ _package.logger.debug(`${logPrefix}, filter attaching.`);
72
153
  const filter = new BioSubstructureFilter();
73
- await grok.data.detectSemanticTypes(helm);
74
-
75
- _package.logger.debug('Bio/substructureFilters/helm, filter attaching.');
76
- filter.attach(helm);
77
- _package.logger.debug('Bio/substructureFilters/helm, filter attached.');
78
-
79
- _package.logger.debug('Bio/substructureFilters/helm, filter 1 changing.');
80
- (filter.bioFilter! as HelmFilter).helmSubstructure = 'PEPTIDE1{C}$$$$V2.0';
81
-
82
- _package.logger.debug('Bio/substructureFilters/helm, filter 1 change awaiting.');
83
- await testEvent(helm.onRowsFiltered, () => {},
84
- () => { filter.bioFilter!.onChanged.next(); }, 20000);
85
- _package.logger.debug('Bio/substructureFilters/helm, filter 1 changed.');
86
- expect(filter.dataFrame!.filter.trueCount, 2);
87
- expect(filter.dataFrame!.filter.get(0), true);
88
- expect(filter.dataFrame!.filter.get(3), true);
89
-
90
- _package.logger.debug('Bio/substructureFilters/helm, filter 2 changing.');
91
- (filter.bioFilter! as HelmFilter).helmSubstructure = 'PEPTIDE1{A.C}$$$$V2.0';
92
- _package.logger.debug('Bio/substructureFilters/helm, filter 2 change awaiting.');
93
- await testEvent(helm.onRowsFiltered, () => {},
94
- () => { filter.bioFilter!.onChanged.next(); }, 20000);
95
- await awaitGrid(helmTableView.grid);
96
- _package.logger.debug('Bio/substructureFilters/helm, filter 2 changed.');
97
- expect(filter.dataFrame!.filter.trueCount, 1);
98
- expect(filter.dataFrame!.filter.get(3), true);
99
- }, {timeout: 30000});
154
+ filter.attach(df);
155
+ const dlg = ui.dialog('Test filters').add(filter.root).show(); // to waitForElementInDom
156
+ await filter.awaitRendered();
157
+ try {
158
+ const bf = filter.bioFilter as HelmBioFilter;
159
+ expect(filter.bioFilter !== null, true, 'bioFilter is not created');
160
+
161
+ // filter 1
162
+ _package.logger.debug(`${logPrefix}, filter 1 change awaiting...`);
163
+ await testEvent(df.onRowsFiltered, () => {}, () => {
164
+ bf.props = new BioFilterProps('PEPTIDE1{A.C}$$$$V2.0');
165
+ }, 20000);
166
+ _package.logger.debug(`${logPrefix}, filter 1 changed.`);
167
+ expect(filter.dataFrame!.filter.trueCount, 1);
168
+ expect(filter.dataFrame!.filter.toBinaryString(), '0001');
169
+
170
+ // filter 2
171
+ _package.logger.debug(`${logPrefix}, filter 2 change awaiting...`);
172
+ await testEvent(df.onRowsFiltered, () => {}, () => {
173
+ bf.props = new BioFilterProps('PEPTIDE1{C}$$$$V2.0');
174
+ }, 20000);
175
+ await awaitGrid(view.grid);
176
+ _package.logger.debug(`${logPrefix}, filter 2 changed.`);
177
+ expect(filter.dataFrame!.filter.trueCount, 2);
178
+ expect(filter.dataFrame!.filter.toBinaryString(), '1001');
179
+ } finally {
180
+ dlg.close();
181
+ }
182
+ await filter.awaitRendered();
183
+ });
184
+
185
+ // Generates unhandled exception accessing isFiltering before bioFilter created
186
+ test('helm-view', async () => {
187
+ const logPrefix = 'Bio tests: substructureFilters/helm-view';
188
+ const df = await readDataframe('tests/filter_HELM.csv');
189
+ const col = df.getCol('HELM string');
190
+ await grok.data.detectSemanticTypes(df);
191
+ const view = grok.shell.addTableView(df);
192
+
193
+ const fg = view.getFiltersGroup();
194
+
195
+ // await awaitCheck(() => fg.filters.length == 1, 'await filters.length == 1', 1000);
196
+ // const filter = fg.filters.filter((f) => f.columnName == col.name)[0] as BioSubstructureFilter;
197
+ await awaitGrid(view.grid);
198
+ });
199
+
200
+ test('sync-fasta', async () => {
201
+ const df = await _package.files.readCsv('tests/filter_FASTA.csv');
202
+ await grok.data.detectSemanticTypes(df);
203
+
204
+ const fSubStr: string = 'MD';
205
+ const fTrueCount: number = 3;
206
+
207
+ const f1 = await createFilter('fasta', df);
208
+ const f2 = await createFilter('fasta', df);
209
+ await Promise.all([f1.awaitRendered(), f2.awaitRendered()]);
210
+ try {
211
+ expect(!!f1.bioFilter, true);
212
+ expect(!!f2.bioFilter, true);
213
+ expect(f1.bioFilter!.type, 'FastaBioFilter');
214
+ expect(f2.bioFilter!.type, 'FastaBioFilter');
215
+ const bf1 = f1.bioFilter as FastaBioFilter;
216
+ const bf2 = f2.bioFilter as FastaBioFilter;
217
+
218
+ await testEvent(df.onRowsFiltered, () => {}, () => {
219
+ bf1.props = new BioFilterProps(fSubStr);
220
+ }, 10000, 'await onRowsFiltered');
221
+ expect(df.filter.trueCount, fTrueCount);
222
+
223
+ await f1.awaitRendered();
224
+ expect(bf2.props.substructure, fSubStr);
225
+ } finally {
226
+ f1.detach();
227
+ f2.detach();
228
+ }
229
+ await Promise.all([f1.awaitRendered(), f2.awaitRendered()]);
230
+ });
231
+
232
+ // MSA filter has the second input field for separator
233
+ test('sync-msa', async () => {
234
+ const df = await _package.files.readCsv('tests/filter_MSA.csv');
235
+ await grok.data.detectSemanticTypes(df);
236
+
237
+ const fSubStr: string = 'hHis-Aca';
238
+ const fSepStr: string = '-';
239
+ const fTrueCount: number = 8;
240
+
241
+ const f1 = await createFilter('MSA', df);
242
+ const f2 = await createFilter('MSA', df);
243
+ await Promise.all([f1.awaitRendered(), f2.awaitRendered()]);
244
+ try {
245
+ expect(!!f1.bioFilter, true);
246
+ expect(!!f2.bioFilter, true);
247
+ expect(f1.bioFilter!.type, 'SeparatorBioFilter');
248
+ expect(f2.bioFilter!.type, 'SeparatorBioFilter');
249
+ const bf1 = f1.bioFilter as SeparatorBioFilter;
250
+ const bf2 = f2.bioFilter as SeparatorBioFilter;
251
+
252
+ await testEvent(df.onRowsFiltered, () => {}, () => {
253
+ bf1.props = new SeparatorFilterProps(fSubStr, fSepStr);
254
+ }, 10000, 'await onRowsFiltered');
255
+ expect(df.filter.trueCount, fTrueCount);
256
+
257
+ expect(bf2.props.substructure, fSubStr);
258
+ expect(bf2.props.separator, fSepStr);
259
+ } finally {
260
+ f1.detach();
261
+ f2.detach();
262
+ }
263
+ await Promise.all([f1.awaitRendered(), f2.awaitRendered()]);
264
+ });
265
+
266
+ test('sync-helm', async () => {
267
+ const df = await _package.files.readCsv('tests/filter_HELM.csv');
268
+ await grok.data.detectSemanticTypes(df);
269
+ const view = grok.shell.addTableView(df);
270
+
271
+ const fSubStr: string = 'PEPTIDE1{A.C}$$$$V2.0';
272
+ const fTrueCount: number = 1;
273
+
274
+ const f1 = await createFilter('HELM string', df);
275
+ const f2 = await createFilter('HELM string', df);
276
+ const dlg = ui.dialog('Test filters').add(f1.root).add(f2.root).show(); // to waitForElementInDom
277
+ await Promise.all([f1.awaitRendered(), f2.awaitRendered()]);
278
+ try {
279
+ expect(!!f1.bioFilter, true);
280
+ expect(!!f2.bioFilter, true);
281
+ expect(f1.bioFilter!.type, 'HelmBioFilter');
282
+ expect(f2.bioFilter!.type, 'HelmBioFilter');
283
+ const bf1 = f1.bioFilter as HelmBioFilter;
284
+ const bf2 = f2.bioFilter as HelmBioFilter;
285
+
286
+ await testEvent(df.onRowsFiltered, () => {}, () => {
287
+ bf1.props = new BioFilterProps(fSubStr);
288
+ }, 60000, 'await onRowsFiltered'); // wait to load monomers
289
+ await awaitGrid(view.grid);
290
+ //debugger;
291
+
292
+ _package.logger.debug('Bio tests: substructureFilters/sync-helm, before changed event');
293
+ await delay(f1.debounceTime * 2);
294
+ _package.logger.debug('Bio tests: substructureFilters/sync-helm, after changed event');
295
+ expect(df.filter.trueCount, fTrueCount);
296
+
297
+ await f1.awaitRendered();
298
+ expect(bf2.props.substructure, fSubStr);
299
+ } finally {
300
+ f1.detach();
301
+ f2.detach();
302
+ dlg.close();
303
+ }
304
+ await Promise.all([f1.awaitRendered(), f2.awaitRendered()]);
305
+ await awaitGrid(view.grid);
306
+ });
100
307
  });
308
+
309
+ async function createFilter(colName: string, df: DG.DataFrame): Promise<BioSubstructureFilter> {
310
+ if (!df.columns.names().includes(colName)) {
311
+ throw new Error(`The column '${colName}' not found. ` +
312
+ `Available in data frame are ${JSON.stringify(df.columns.names())}`);
313
+ }
314
+
315
+ const filter = new BioSubstructureFilter();
316
+ filter.attach(df);
317
+ filter.applyState({columnName: colName});
318
+ filter.column = df.col(colName);
319
+ filter.columnName = colName;
320
+ //filter.tableName = df.name;
321
+ return filter;
322
+ };