@datagrok/peptides 1.17.0 → 1.17.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 (55) hide show
  1. package/.eslintrc.json +17 -6
  2. package/CHANGELOG.md +4 -0
  3. package/dist/214.js +2 -0
  4. package/dist/436.js +2 -2
  5. package/dist/802.js +2 -0
  6. package/dist/package-test.js +2 -3
  7. package/dist/package.js +2 -3
  8. package/package.json +14 -14
  9. package/src/demo/fasta.ts +8 -2
  10. package/src/model.ts +783 -532
  11. package/src/package-test.ts +1 -3
  12. package/src/package.ts +15 -28
  13. package/src/tests/benchmarks.ts +31 -11
  14. package/src/tests/core.ts +11 -6
  15. package/src/tests/misc.ts +6 -6
  16. package/src/tests/model.ts +79 -44
  17. package/src/tests/table-view.ts +48 -38
  18. package/src/tests/utils.ts +0 -76
  19. package/src/tests/viewers.ts +30 -12
  20. package/src/tests/widgets.ts +30 -11
  21. package/src/utils/algorithms.ts +115 -38
  22. package/src/utils/cell-renderer.ts +181 -72
  23. package/src/utils/constants.ts +33 -7
  24. package/src/utils/misc.ts +244 -10
  25. package/src/utils/parallel-mutation-cliffs.ts +18 -15
  26. package/src/utils/statistics.ts +70 -15
  27. package/src/utils/tooltips.ts +42 -17
  28. package/src/utils/types.ts +29 -26
  29. package/src/utils/worker-creator.ts +5 -0
  30. package/src/viewers/logo-summary.ts +591 -130
  31. package/src/viewers/sar-viewer.ts +893 -239
  32. package/src/widgets/distribution.ts +305 -64
  33. package/src/widgets/manual-alignment.ts +18 -11
  34. package/src/widgets/mutation-cliffs.ts +44 -18
  35. package/src/widgets/peptides.ts +86 -91
  36. package/src/widgets/selection.ts +56 -22
  37. package/src/widgets/settings.ts +94 -44
  38. package/src/workers/mutation-cliffs-worker.ts +3 -16
  39. package/dist/209.js +0 -2
  40. package/dist/361.js +0 -2
  41. package/dist/381.js +0 -2
  42. package/dist/770.js +0 -2
  43. package/dist/831.js +0 -2
  44. package/dist/868.js +0 -2
  45. package/dist/931.js +0 -3
  46. package/dist/931.js.LICENSE.txt +0 -51
  47. package/dist/932.js +0 -2
  48. package/dist/package-test.js.LICENSE.txt +0 -51
  49. package/dist/package.js.LICENSE.txt +0 -51
  50. package/src/tests/peptide-space-test.ts +0 -48
  51. package/src/tests/test-data.ts +0 -649
  52. package/src/utils/molecular-measure.ts +0 -174
  53. package/src/utils/peptide-similarity-space.ts +0 -216
  54. package/src/viewers/peptide-space-viewer.ts +0 -150
  55. package/src/workers/dimensionality-reducer.ts +0 -25
@@ -1,14 +1,16 @@
1
1
  import * as DG from 'datagrok-api/dg';
2
2
 
3
- import {category, test, before, expect, delay, after} from '@datagrok-libraries/utils/src/test';
3
+ import {after, awaitCheck, before, category, delay, expect, test} from '@datagrok-libraries/utils/src/test';
4
4
  import {_package} from '../package-test';
5
- import {CLUSTER_TYPE, PeptidesModel} from '../model';
5
+ import {PeptidesModel, VIEWER_TYPE} from '../model';
6
6
  import {startAnalysis} from '../widgets/peptides';
7
- import {scaleActivity} from '../utils/misc';
7
+ import {initSelection, scaleActivity} from '../utils/misc';
8
8
  import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
9
9
  import {COLUMNS_NAMES, SCALING_METHODS} from '../utils/constants';
10
10
  import {TEST_COLUMN_NAMES} from './utils';
11
11
  import {showMonomerTooltip} from '../utils/tooltips';
12
+ import {CLUSTER_TYPE, LogoSummaryTable} from '../viewers/logo-summary';
13
+ import {MonomerPosition} from '../viewers/sar-viewer';
12
14
 
13
15
  category('Table view', () => {
14
16
  let df: DG.DataFrame;
@@ -49,7 +51,7 @@ category('Table view', () => {
49
51
 
50
52
  test('Visible columns', async () => {
51
53
  const gridCols = model.analysisView.grid.columns;
52
- const posCols = model.positionColumns.toArray().map((col) => col.name);
54
+ const posCols = model.positionColumns!.map((col) => col.name);
53
55
  for (let colIdx = 1; colIdx < gridCols.length; colIdx++) {
54
56
  const col = gridCols.byIndex(colIdx)!;
55
57
  const tableColName = col.column!.name;
@@ -63,100 +65,108 @@ category('Table view', () => {
63
65
  test('Mutation Cliffs selection', async () => {
64
66
  const selection = model.df.selection;
65
67
 
66
- for (const [position, selectedMonomers] of Object.entries(model.mutationCliffsSelection))
68
+ const mpViewer = model.findViewer(VIEWER_TYPE.MONOMER_POSITION) as MonomerPosition;
69
+ await awaitCheck(() => mpViewer.mutationCliffs !== null, 'mutation cliffs haven\'t been generated', 2000);
70
+
71
+ for (const [position, selectedMonomers] of Object.entries(mpViewer.mutationCliffsSelection))
67
72
  expect(selectedMonomers.length, 0, `Selection is not empty for position ${position} after initialization`);
68
73
 
69
74
  // Select first monomer-position pair
70
- model.modifyMutationCliffsSelection(firstPair);
71
- expect(model.mutationCliffsSelection[firstPair.positionOrClusterType].includes(firstPair.monomerOrCluster), true,
75
+ mpViewer.modifyMutationCliffsSelection(firstPair);
76
+ expect(mpViewer.mutationCliffsSelection[firstPair.positionOrClusterType].includes(firstPair.monomerOrCluster), true,
72
77
  `Monomer ${firstPair.monomerOrCluster} is not selected at position ${firstPair.positionOrClusterType}`);
73
78
  expect(selection.trueCount, firstPair.mcCount, `Selection count is not equal to ${firstPair.mcCount} ` +
74
79
  `for monomer ${firstPair.monomerOrCluster} at position ${firstPair.positionOrClusterType}`);
75
80
 
76
81
  // Select second monomer-position pair
77
- model.modifyMutationCliffsSelection(secondPair, {shiftPressed: true, ctrlPressed: false});
78
- expect(model.mutationCliffsSelection[secondPair.positionOrClusterType].includes(secondPair.monomerOrCluster), true,
79
- `Monomer ${secondPair.monomerOrCluster} is not selected at position ${secondPair.positionOrClusterType}`);
82
+ mpViewer.modifyMutationCliffsSelection(secondPair, {shiftPressed: true, ctrlPressed: false});
83
+ expect(mpViewer.mutationCliffsSelection[secondPair.positionOrClusterType].includes(secondPair.monomerOrCluster),
84
+ true, `Monomer ${secondPair.monomerOrCluster} is not selected at position ${secondPair.positionOrClusterType}`);
80
85
  expect(selection.trueCount, secondPair.mcCount + firstPair.mcCount, `Selection count is not equal ` +
81
86
  `to ${secondPair.mcCount + firstPair.mcCount} for monomer ${secondPair.monomerOrCluster} at ` +
82
87
  `position ${secondPair.positionOrClusterType}`);
83
88
 
84
89
  // Deselect second monomer-position pair
85
- model.modifyMutationCliffsSelection(secondPair, {shiftPressed: true, ctrlPressed: true});
86
- expect(model.mutationCliffsSelection[secondPair.positionOrClusterType].includes(secondPair.monomerOrCluster), false,
87
- `Monomer ${secondPair.monomerOrCluster} is still selected at position ${secondPair.positionOrClusterType} after deselection`);
90
+ mpViewer.modifyMutationCliffsSelection(secondPair, {shiftPressed: true, ctrlPressed: true});
91
+ expect(mpViewer.mutationCliffsSelection[secondPair.positionOrClusterType].includes(secondPair.monomerOrCluster),
92
+ false, `Monomer ${secondPair.monomerOrCluster} is still selected at position ` +
93
+ `${secondPair.positionOrClusterType} after deselection`);
88
94
  expect(selection.trueCount, firstPair.mcCount, `Selection count is not equal to ${firstPair.mcCount} ` +
89
95
  `for monomer ${firstPair.monomerOrCluster} at position ${firstPair.positionOrClusterType}`);
90
96
 
91
97
  // Clear monomer-position selection
92
- model.initMutationCliffsSelection();
93
- for (const [position, selectedMonomers] of Object.entries(model.mutationCliffsSelection)) {
98
+ mpViewer.mutationCliffsSelection = initSelection(mpViewer.positionColumns);
99
+ for (const [position, selectedMonomers] of Object.entries(mpViewer.mutationCliffsSelection)) {
94
100
  expect(selectedMonomers.length, 0, `Selection is not empty for position ${position} after clearing ` +
95
101
  `monomer-position selection`);
96
102
  }
97
103
  expect(selection.trueCount, 0, `Selection count is not equal to 0 after clearing monomer-position selection`);
98
104
 
105
+ const lstViewer = model.findViewer(VIEWER_TYPE.LOGO_SUMMARY_TABLE) as LogoSummaryTable | null;
106
+ expect(lstViewer !== null, true, `Couldn't find Logo Summary Table viewer`);
99
107
  // Select first cluster
100
- model.modifyClusterSelection(firstCluster);
101
- expect(model.clusterSelection[firstCluster.positionOrClusterType].includes(firstCluster.monomerOrCluster), true,
102
- `Cluster ${firstCluster.monomerOrCluster} is not selected`);
108
+ lstViewer!.modifyClusterSelection(firstCluster);
109
+ expect(lstViewer!.clusterSelection[firstCluster.positionOrClusterType].includes(firstCluster.monomerOrCluster),
110
+ true, `Cluster ${firstCluster.monomerOrCluster} is not selected`);
103
111
  expect(selection.trueCount, firstCluster.count, `Selection count is not equal to ${firstCluster.count} for ` +
104
112
  `cluster ${firstCluster.monomerOrCluster}`);
105
113
 
106
114
  // Select second cluster
107
- model.modifyClusterSelection(secondCluster, {shiftPressed: true, ctrlPressed: false});
108
- expect(model.clusterSelection[secondCluster.positionOrClusterType].includes(secondCluster.monomerOrCluster), true,
109
- `Cluster ${secondCluster.monomerOrCluster} is not selected`);
115
+ lstViewer!.modifyClusterSelection(secondCluster, {shiftPressed: true, ctrlPressed: false});
116
+ expect(lstViewer!.clusterSelection[secondCluster.positionOrClusterType].includes(secondCluster.monomerOrCluster),
117
+ true, `Cluster ${secondCluster.monomerOrCluster} is not selected`);
110
118
  expect(selection.trueCount, firstCluster.count + secondCluster.count, `Selection count is not equal to ` +
111
- `${firstCluster.count + secondCluster.count} for cluster ${firstCluster.monomerOrCluster} and cluster ${secondCluster.monomerOrCluster}`);
119
+ `${firstCluster.count + secondCluster.count} for cluster ${firstCluster.monomerOrCluster} and cluster
120
+ ${secondCluster.monomerOrCluster}`);
112
121
 
113
122
  // Deselect first cluster
114
- model.modifyClusterSelection(firstCluster, {shiftPressed: true, ctrlPressed: true});
115
- expect(model.clusterSelection[firstCluster.positionOrClusterType].includes(firstCluster.monomerOrCluster), false,
116
- `Cluster ${firstCluster.monomerOrCluster} is still selected after deselection`);
123
+ lstViewer!.modifyClusterSelection(firstCluster, {shiftPressed: true, ctrlPressed: true});
124
+ expect(lstViewer!.clusterSelection[firstCluster.positionOrClusterType].includes(firstCluster.monomerOrCluster),
125
+ false, `Cluster ${firstCluster.monomerOrCluster} is still selected after deselection`);
117
126
  expect(selection.trueCount, secondCluster.count, `Selection count is not equal to ${secondCluster.count} for ` +
118
127
  `cluster ${secondCluster.monomerOrCluster} after deselection of cluster ${firstCluster.monomerOrCluster}`);
119
128
 
120
129
  // Clear selection
121
- model.initClusterSelection();
122
- expect(model.isClusterSelectionEmpty, true, `Selection is not empty after clearing cluster selection`);
130
+ lstViewer!.initClusterSelection();
131
+ expect(lstViewer!.isClusterSelectionEmpty, true, `Selection is not empty after clearing cluster selection`);
123
132
  expect(selection.trueCount, 0, `Selection count is not equal to 0 after clearing cluster selection`);
124
133
  });
125
134
 
126
135
  test('Invariant Map selection', async () => {
127
136
  const selection = model.df.selection;
128
137
 
129
- for (const [position, filteredMonomers] of Object.entries(model.invariantMapSelection))
138
+ for (const [position, filteredMonomers] of Object.entries(model.webLogoSelection))
130
139
  expect(filteredMonomers.length, 0, `Filter is not empty for position ${position} after initialization`);
131
140
 
132
141
  // Select by second monomer-position pair
133
- model.modifyInvariantMapSelection(secondPair);
134
- expect(model.invariantMapSelection[secondPair.positionOrClusterType].includes(secondPair.monomerOrCluster), true,
142
+ model.modifyWebLogoSelection(secondPair);
143
+ expect(model.webLogoSelection[secondPair.positionOrClusterType].includes(secondPair.monomerOrCluster), true,
135
144
  `Monomer ${secondPair.monomerOrCluster} is not filtered at position ${secondPair.positionOrClusterType}`);
136
145
  expect(selection.trueCount, secondPair.imCount, `Filter count is not equal to ${secondPair.imCount} ` +
137
146
  `for monomer ${secondPair.monomerOrCluster} at position ${secondPair.positionOrClusterType}`);
138
147
 
139
148
  // Select by first monomer-position pair
140
- model.modifyInvariantMapSelection(firstPair, {shiftPressed: true, ctrlPressed: false});
141
- expect(model.invariantMapSelection[firstPair.positionOrClusterType].includes(firstPair.monomerOrCluster), true,
149
+ model.modifyWebLogoSelection(firstPair, {shiftPressed: true, ctrlPressed: false});
150
+ expect(model.webLogoSelection[firstPair.positionOrClusterType].includes(firstPair.monomerOrCluster), true,
142
151
  `Monomer ${firstPair.monomerOrCluster} is not filtered at position ${firstPair.positionOrClusterType}`);
143
152
  expect(selection.trueCount, secondPair.imCount, `Filter count is not equal to ${secondPair.imCount} ` +
144
153
  `for monomer ${firstPair.monomerOrCluster} at position ${firstPair.positionOrClusterType}`);
145
154
 
146
155
  // Deselect filter for second monomer-position pair
147
- model.modifyInvariantMapSelection(secondPair, {shiftPressed: true, ctrlPressed: true});
148
- expect(model.invariantMapSelection[secondPair.positionOrClusterType].includes(secondPair.monomerOrCluster), false,
149
- `Monomer ${secondPair.monomerOrCluster} is still filtered at position ${secondPair.positionOrClusterType} after ` +
150
- `deselection`);
156
+ model.modifyWebLogoSelection(secondPair, {shiftPressed: true, ctrlPressed: true});
157
+ expect(model.webLogoSelection[secondPair.positionOrClusterType].includes(secondPair.monomerOrCluster),
158
+ false, `Monomer ${secondPair.monomerOrCluster} is still filtered at position
159
+ ${secondPair.positionOrClusterType} after deselection`);
151
160
  expect(selection.trueCount, firstPair.imCount, `Filter count is not equal to ${firstPair.imCount} ` +
152
161
  `for monomer ${firstPair.monomerOrCluster} at position ${firstPair.positionOrClusterType} after deselection of ` +
153
162
  `monomer ${secondPair.monomerOrCluster} at position ${secondPair.positionOrClusterType}`);
154
163
 
155
164
  // Clear selection
156
- model.initInvariantMapSelection();
165
+ expect(model.positionColumns !== null, true, `Position columns are not initialized`);
166
+ model.webLogoSelection = initSelection(model.positionColumns!);
157
167
  expect(selection.trueCount, 0, `Filter count is not equal to ${0} after clearing monomer-position filter`);
158
168
 
159
- for (const [position, filteredMonomers] of Object.entries(model.invariantMapSelection)) {
169
+ for (const [position, filteredMonomers] of Object.entries(model.webLogoSelection)) {
160
170
  expect(filteredMonomers.length, 0, `Filter is not empty for position ${position} after clearing ` +
161
171
  `monomer-position filter`);
162
172
  }
@@ -1,81 +1,5 @@
1
- import * as DG from 'datagrok-api/dg';
2
-
3
- import {expect} from '@datagrok-libraries/utils/src/test';
4
- import {PeptideSimilaritySpaceWidget, createPeptideSimilaritySpaceViewer} from '../utils/peptide-similarity-space';
5
- import {
6
- createDimensinalityReducingWorker,
7
- } from '@datagrok-libraries/ml/src/workers/dimensionality-reducing-worker-creator';
8
- import {StringMetrics} from '@datagrok-libraries/ml/src/typed-metrics';
9
- import {IReduceDimensionalityResult} from '@datagrok-libraries/ml/src/reduce-dimensionality';
10
-
11
1
  export enum TEST_COLUMN_NAMES {
12
2
  SEQUENCE = 'sequence',
13
3
  ACTIVITY = 'activity',
14
4
  CLUSTER = 'cluster',
15
5
  }
16
-
17
- /**
18
- * Tests if a table has non zero rows and columns.
19
- *
20
- * @param {DG.DataFrame} table Target table.
21
- */
22
- export function _testTableIsNotEmpty(table: DG.DataFrame): void {
23
- expect(table.columns.length > 0 && table.rowCount > 0, true);
24
- }
25
-
26
- /**
27
- * Tests if peptide space viewer is drawing without exceptions.
28
- *
29
- * @param {DG.DataFrame} table Demo table.
30
- * @param {DG.TableView} view Demo view.
31
- */
32
- export async function _testViewerIsDrawing(table: DG.DataFrame, view: DG.TableView): Promise<void> {
33
- const widget = new PeptideSimilaritySpaceWidget(table.getCol('AlignedSequence'), view);
34
- await widget.draw();
35
- }
36
-
37
- /**
38
- * Tests if dimensionality reducer works for both the method and the measure chosen.
39
- *
40
- * @param {Array<string>} columnData Strings to process.
41
- * @param {string} method Embedding method.
42
- * @param {string} measure Measure to apply to a pair of strings.
43
- */
44
- export async function _testDimensionalityReducer(
45
- columnData: Array<string>, method: StringMetrics, measure: string): Promise<void> {
46
- const cyclesCount = 100;
47
-
48
- const reduceDimRes: IReduceDimensionalityResult = await createDimensinalityReducingWorker(
49
- {data: columnData, metric: measure as StringMetrics}, method, {cycles: cyclesCount});
50
- const embcols = reduceDimRes.embedding;
51
-
52
- const [X, Y] = embcols as Array<Float32Array>;
53
-
54
- expect(X.every((v) => v !== null && !Number.isNaN(v)), true);
55
- expect(Y.every((v) => v !== null && !Number.isNaN(v)), true);
56
- }
57
-
58
- /**
59
- * Tests if PeptideSimilaritySpaceViewer works for both the method and the measure chosen.
60
- *
61
- * @export
62
- * @param {DG.DataFrame} table Table.
63
- * @param {DG.Column} alignedSequencesColumn Aligned sequences column.
64
- * @param {string} method Embedding method.
65
- * @param {string} measure Strings similarity measure.
66
- * @param {number} cyclesCount Number of embedding iterations.
67
- * @param {(DG.TableView | null)} view Viewer to show graphics on.
68
- * @param {(string | null)} [activityColumnName] Name of column with activity.
69
- */
70
- export async function _testPeptideSimilaritySpaceViewer(table: DG.DataFrame, alignedSequencesColumn: DG.Column,
71
- method: string, measure: string, cyclesCount: number): Promise<void> {
72
- const viewer = await createPeptideSimilaritySpaceViewer(
73
- table, method, measure, cyclesCount, alignedSequencesColumn, undefined);
74
- const df = viewer.dataFrame;
75
-
76
- const axesNames = ['~X', '~Y', '~MW'];
77
- const axes = axesNames.map((v) => df.getCol(v).getRawData() as Float32Array);
78
-
79
- for (const ax of axes)
80
- expect(ax.every((v) => v !== null && !Number.isNaN(v)), true);
81
- }
@@ -1,26 +1,31 @@
1
1
  import * as DG from 'datagrok-api/dg';
2
2
 
3
3
  import {after, before, category, delay, expect, test, testViewer} from '@datagrok-libraries/utils/src/test';
4
- import {aligned1} from './test-data';
5
- import {CLUSTER_TYPE, PeptidesModel, VIEWER_TYPE} from '../model';
4
+ import {PeptidesModel, VIEWER_TYPE} from '../model';
6
5
  import {_package} from '../package-test';
7
6
  import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
8
7
  import {scaleActivity} from '../utils/misc';
9
8
  import {startAnalysis} from '../widgets/peptides';
10
- import {SELECTION_MODE, MonomerPosition, MostPotentResidues} from '../viewers/sar-viewer';
9
+ import {MonomerPosition, MostPotentResidues, SELECTION_MODE} from '../viewers/sar-viewer';
11
10
  import {SCALING_METHODS} from '../utils/constants';
12
- import {LST_PROPERTIES, LogoSummaryTable} from '../viewers/logo-summary';
11
+ import {CLUSTER_TYPE, LogoSummaryTable, LST_PROPERTIES} from '../viewers/logo-summary';
13
12
  import {PositionHeight} from '@datagrok-libraries/bio/src/viewers/web-logo';
14
13
  import {TEST_COLUMN_NAMES} from './utils';
15
14
  import {showTooltip} from '../utils/tooltips';
16
15
 
17
16
  category('Viewers: Basic', () => {
18
- const df = DG.DataFrame.fromCsv(aligned1);
17
+ let df: DG.DataFrame;
18
+
19
+ before(async () => {
20
+ df = DG.DataFrame.fromCsv(await _package.files.readAsText('tests/HELM_small.csv'));
21
+ await delay(500);
22
+ });
23
+
19
24
  const viewers = DG.Func.find({package: 'Peptides', tags: ['viewer']}).map((f) => f.friendlyName);
20
25
  for (const v of viewers) {
21
26
  test(v, async () => {
22
- await testViewer(v, df.clone(), {detectSemanticTypes: true});
23
- }, {skipReason: 'GROK-11534'});
27
+ await testViewer(v, df.clone(), {detectSemanticTypes: true, arbitraryDfTest: false});
28
+ });
24
29
  }
25
30
  });
26
31
 
@@ -57,8 +62,13 @@ category('Viewers: Monomer-Position', () => {
57
62
  const cellCoordinates = {col: '9', row: 6};
58
63
  const gc = mpViewer.viewerGrid.cell(cellCoordinates.col, cellCoordinates.row);
59
64
  const mp = mpViewer.getMonomerPosition(gc);
60
- expect(showTooltip(model.df, model.settings.columns!, {monomerPosition: mp, x: 0, y: 0, mpStats: model.monomerPositionStats}),
61
- true, `Tooltip is not shown for grid cell at column '${cellCoordinates.col}', row ${cellCoordinates.row}`);
65
+ expect(showTooltip(model.df, activityCol, Object.entries(model!.settings!.columns!), {
66
+ monomerPosition: mp,
67
+ x: 0,
68
+ y: 0,
69
+ mpStats: model!.monomerPositionStats!,
70
+ }),
71
+ true, `Tooltip is not shown for grid cell at column '${cellCoordinates.col}', row ${cellCoordinates.row}`);
62
72
  });
63
73
 
64
74
  test('Modes', async () => {
@@ -111,8 +121,13 @@ category('Viewers: Most Potent Residues', () => {
111
121
  const cellCoordinates = {col: 'Diff', row: 6};
112
122
  const gc = mprViewer.viewerGrid.cell(cellCoordinates.col, cellCoordinates.row);
113
123
  const mp = mprViewer.getMonomerPosition(gc);
114
- expect(showTooltip(model.df, model.settings.columns!, {monomerPosition: mp, x: 0, y: 0, mpStats: model.monomerPositionStats}),
115
- true, `Tooltip is not shown for grid cell at column '${cellCoordinates.col}', row ${cellCoordinates.row}`);
124
+ expect(showTooltip(model.df, activityCol, Object.entries(model!.settings!.columns!), {
125
+ monomerPosition: mp,
126
+ x: 0,
127
+ y: 0,
128
+ mpStats: model!.monomerPositionStats!,
129
+ }),
130
+ true, `Tooltip is not shown for grid cell at column '${cellCoordinates.col}', row ${cellCoordinates.row}`);
116
131
  });
117
132
  });
118
133
 
@@ -165,7 +180,10 @@ category('Viewers: Logo Summary Table', () => {
165
180
 
166
181
  test('Tooltip', async () => {
167
182
  const cluster = '0';
168
- const tooltipElement = lstViewer.showTooltip({monomerOrCluster: cluster, positionOrClusterType: CLUSTER_TYPE.ORIGINAL}, 0, 0);
183
+ const tooltipElement = lstViewer.showTooltip({
184
+ monomerOrCluster: cluster,
185
+ positionOrClusterType: CLUSTER_TYPE.ORIGINAL,
186
+ }, 0, 0);
169
187
  expect(tooltipElement !== null, true, `Tooltip is not shown for cluster '${cluster}'`);
170
188
  });
171
189
  }, {clear: false});
@@ -1,19 +1,20 @@
1
1
  import * as grok from 'datagrok-api/grok';
2
2
  import * as DG from 'datagrok-api/dg';
3
3
 
4
- import {category, test, before, expect, delay, after} from '@datagrok-libraries/utils/src/test';
4
+ import {after, before, category, delay, expect, test} from '@datagrok-libraries/utils/src/test';
5
5
  import {_package} from '../package-test';
6
- import {CLUSTER_TYPE, PeptidesModel, VIEWER_TYPE} from '../model';
6
+ import {PeptidesModel, VIEWER_TYPE} from '../model';
7
7
  import {scaleActivity} from '../utils/misc';
8
8
  import {startAnalysis} from '../widgets/peptides';
9
9
  import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
10
10
  import * as C from '../utils/constants';
11
- import {PANES_INPUTS, SETTINGS_PANES, getSettingsDialog} from '../widgets/settings';
11
+ import {getSettingsDialog, PANES_INPUTS, SETTINGS_PANES} from '../widgets/settings';
12
12
  import {getDistributionWidget} from '../widgets/distribution';
13
13
  import {mutationCliffsWidget} from '../widgets/mutation-cliffs';
14
14
  import {TEST_COLUMN_NAMES} from './utils';
15
15
  import wu from 'wu';
16
- import {LogoSummaryTable} from '../viewers/logo-summary';
16
+ import {CLUSTER_TYPE, LogoSummaryTable} from '../viewers/logo-summary';
17
+ import {MonomerPosition} from '../viewers/sar-viewer';
17
18
 
18
19
  category('Widgets: Settings', () => {
19
20
  let df: DG.DataFrame;
@@ -88,7 +89,14 @@ category('Widgets: Distribution panel', () => {
88
89
  after(async () => await delay(3000));
89
90
 
90
91
  test('UI', async () => {
91
- getDistributionWidget(model.df, model);
92
+ model.df.selection.set(0, true);
93
+ await delay(1000);
94
+ const lstViewer = model.findViewer(VIEWER_TYPE.LOGO_SUMMARY_TABLE) as LogoSummaryTable | null;
95
+ getDistributionWidget(model.df, {
96
+ peptideSelection: DG.BitSet.create(model.df.rowCount), columns: model.settings!.columns!,
97
+ activityCol: scaledActivityCol, clusterSelection: lstViewer!.clusterSelection, clusterColName: clusterCol.name,
98
+ monomerPositionSelection: model.webLogoSelection,
99
+ });
92
100
  });
93
101
  });
94
102
 
@@ -120,7 +128,18 @@ category('Widgets: Mutation cliffs', () => {
120
128
  after(async () => await delay(3000));
121
129
 
122
130
  test('UI', async () => {
123
- mutationCliffsWidget(model.df, model);
131
+ const sarViewer = model.findViewer(VIEWER_TYPE.MONOMER_POSITION) as MonomerPosition;
132
+ sarViewer.keyPressed = true; //required to emulate cell selection
133
+ sarViewer._viewerGrid!.dataFrame.currentCell = sarViewer._viewerGrid?.dataFrame.cell(0, '1')!;
134
+ await delay(1000);
135
+ mutationCliffsWidget(model.df, {
136
+ mutationCliffs: sarViewer.mutationCliffs!,
137
+ mutationCliffsSelection: sarViewer.mutationCliffsSelection,
138
+ gridColumns: model.analysisView.grid.columns,
139
+ sequenceColumnName: sarViewer.sequenceColumnName,
140
+ positionColumns: sarViewer.positionColumns,
141
+ activityCol: scaledActivityCol,
142
+ });
124
143
  });
125
144
  });
126
145
 
@@ -165,7 +184,7 @@ category('Widgets: Actions', () => {
165
184
  const currentTable = grok.shell.t;
166
185
 
167
186
  expect(currentTable.getTag(C.TAGS.MULTIPLE_VIEWS), '1', 'Current table is expected to have multiple views tag');
168
- expect(currentTable.getTag(C.TAGS.UUID), newViewId, 'Current table is expected to have the same UUID as new view');
187
+ expect(currentTable.getTag(DG.TAGS.ID), newViewId, 'Current table is expected to have the same UUID as new view');
169
188
  expect(currentTable.rowCount, 1, 'Current table is expected to have 1 row');
170
189
 
171
190
  await delay(500);
@@ -189,11 +208,11 @@ category('Widgets: Actions', () => {
189
208
  throw new Error('Logo summary table viewer is not found');
190
209
 
191
210
  // Check that custom clusters are not created yet
192
- expect(wu(model.customClusters).toArray().length, 0, 'Expected to have 0 custom clusters before creating one');
211
+ expect(wu(lstViewer.customClusters).toArray().length, 0, 'Expected to have 0 custom clusters before creating one');
193
212
 
194
213
  // Create custom cluster
195
214
  lstViewer.clusterFromSelection();
196
- const customClusterList = wu(model.customClusters).toArray();
215
+ const customClusterList = wu(lstViewer.customClusters).toArray();
197
216
  expect(customClusterList.length, 1, 'Expected to have 1 custom cluster');
198
217
  const clustName = customClusterList[0].name;
199
218
  expect(model.df.col(clustName) !== null, true, 'Expected to have custom cluster column in the table');
@@ -201,9 +220,9 @@ category('Widgets: Actions', () => {
201
220
  'Expected to have custom cluster in the Logo Summary Table');
202
221
 
203
222
  // Remove custom cluster
204
- model.modifyClusterSelection({monomerOrCluster: clustName, positionOrClusterType: CLUSTER_TYPE.CUSTOM});
223
+ lstViewer.modifyClusterSelection({monomerOrCluster: clustName, positionOrClusterType: CLUSTER_TYPE.CUSTOM});
205
224
  lstViewer.removeCluster();
206
- expect(wu(model.customClusters).toArray().length, 0, 'Expected to have 0 custom clusters after removing one');
225
+ expect(wu(lstViewer.customClusters).toArray().length, 0, 'Expected to have 0 custom clusters after removing one');
207
226
  expect(model.df.col(clustName) === null, true,
208
227
  'Expected to have no custom cluster column in the table');
209
228
  expect(lstViewer.viewerGrid.table.getCol(C.LST_COLUMN_NAMES.CLUSTER).categories.indexOf(clustName) === -1, true,