@datagrok/peptides 1.9.0 → 1.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@datagrok/peptides",
3
3
  "friendlyName": "Peptides",
4
- "version": "1.9.0",
4
+ "version": "1.9.1",
5
5
  "author": {
6
6
  "name": "Volodymyr Dyma",
7
7
  "email": "vdyma@datagrok.ai"
package/src/model.ts CHANGED
@@ -115,6 +115,14 @@ export class PeptidesModel {
115
115
  return dataFrame.temp[PeptidesModel.modelName] as PeptidesModel;
116
116
  }
117
117
 
118
+ get id(): string {
119
+ const id = this.df.getTag(C.TAGS.UUID);
120
+ if (id === null || id === '')
121
+ throw new Error('PeptidesError: UUID is not defined');
122
+
123
+ return id;
124
+ }
125
+
118
126
  get treeHelper(): ITreeHelper {
119
127
  this._treeHelper ??= getTreeHelperInstance();
120
128
  return this._treeHelper;
@@ -202,9 +210,9 @@ export class PeptidesModel {
202
210
 
203
211
  get analysisView(): DG.TableView {
204
212
  this._analysisView ??=
205
- wu(grok.shell.tableViews).find(({dataFrame}) => dataFrame.getTag(C.TAGS.UUID) == this.df.getTag(C.TAGS.UUID)) ??
213
+ wu(grok.shell.tableViews).find(({dataFrame}) => dataFrame.getTag(C.TAGS.UUID) === this.id) ??
206
214
  grok.shell.addTableView(this.df);
207
- if (this.df.getTag(C.MULTIPLE_VIEWS) != '1')
215
+ if (this.df.getTag(C.TAGS.MULTIPLE_VIEWS) !== '1')
208
216
  grok.shell.v = this._analysisView;
209
217
 
210
218
  return this._analysisView;
@@ -271,7 +279,7 @@ export class PeptidesModel {
271
279
 
272
280
  get splitByPos(): boolean {
273
281
  const splitByPosFlag = (this.df.tags['distributionSplit'] || '00')[0];
274
- return splitByPosFlag == '1' ? true : false;
282
+ return splitByPosFlag === '1' ? true : false;
275
283
  }
276
284
 
277
285
  set splitByPos(flag: boolean) {
@@ -281,7 +289,7 @@ export class PeptidesModel {
281
289
 
282
290
  get splitByAAR(): boolean {
283
291
  const splitByPosFlag = (this.df.tags['distributionSplit'] || '00')[1];
284
- return splitByPosFlag == '1' ? true : false;
292
+ return splitByPosFlag === '1' ? true : false;
285
293
  }
286
294
 
287
295
  set splitByAAR(flag: boolean) {
@@ -410,7 +418,7 @@ export class PeptidesModel {
410
418
 
411
419
  const monomerCol = matrixDf.getCol(C.COLUMNS_NAMES.MONOMER);
412
420
  for (let i = 0; i < monomerCol.length; ++i) {
413
- if (monomerCol.get(i) == '') {
421
+ if (monomerCol.get(i) === '') {
414
422
  matrixDf.rows.removeAt(i);
415
423
  break;
416
424
  }
@@ -555,12 +563,12 @@ export class PeptidesModel {
555
563
  colNames.push(sourceGridCols.byIndex(i)!);
556
564
 
557
565
  colNames.sort((a, b) => {
558
- if (a.column!.semType == C.SEM_TYPES.MONOMER) {
559
- if (b.column!.semType == C.SEM_TYPES.MONOMER)
566
+ if (a.column!.semType === C.SEM_TYPES.MONOMER) {
567
+ if (b.column!.semType === C.SEM_TYPES.MONOMER)
560
568
  return 0;
561
569
  return -1;
562
570
  }
563
- if (b.column!.semType == C.SEM_TYPES.MONOMER)
571
+ if (b.column!.semType === C.SEM_TYPES.MONOMER)
564
572
  return 1;
565
573
  return 0;
566
574
  });
@@ -589,7 +597,7 @@ export class PeptidesModel {
589
597
 
590
598
  for (let categoryIndex = 0; categoryIndex < posColCateogries.length; ++categoryIndex) {
591
599
  const monomer = posColCateogries[categoryIndex];
592
- if (monomer == '')
600
+ if (monomer === '')
593
601
  continue;
594
602
 
595
603
  const bitArray = BitArray.fromSeq(sourceDfLen, (i: number) => posColData[i] === categoryIndex);
@@ -604,7 +612,7 @@ export class PeptidesModel {
604
612
  }
605
613
 
606
614
  getSummaryStats(genObj: SummaryStats, stats: Stats | null = null, summaryStats: SummaryStats | null = null): void {
607
- if (stats == null && summaryStats == null)
615
+ if (stats === null && summaryStats === null)
608
616
  throw new Error(`MonomerPositionStatsError: either stats or summaryStats must be present`);
609
617
 
610
618
  const possibleMaxCount = stats?.count ?? summaryStats!.maxCount;
@@ -671,9 +679,9 @@ export class PeptidesModel {
671
679
  const customClustStats: ClusterStats = {};
672
680
 
673
681
  for (let clustType = 0; clustType < 2; ++clustType) {
674
- const masks = clustType == 0 ? origClustMasks : customClustMasks;
675
- const clustNames = clustType == 0 ? origClustColCat : customClustColNamesList;
676
- const resultStats = clustType == 0 ? origClustStats : customClustStats;
682
+ const masks = clustType === 0 ? origClustMasks : customClustMasks;
683
+ const clustNames = clustType === 0 ? origClustColCat : customClustColNamesList;
684
+ const resultStats = clustType === 0 ? origClustStats : customClustStats;
677
685
  for (let maskIdx = 0; maskIdx < masks.length; ++maskIdx) {
678
686
  const mask = masks[maskIdx];
679
687
  const stats = getStats(activityColData, mask);
@@ -706,15 +714,15 @@ export class PeptidesModel {
706
714
 
707
715
  const filteredMonomerStats = Object.entries(positionStats).filter((v) => {
708
716
  const key = v[0];
709
- if (key == 'general')
717
+ if (key === 'general')
710
718
  return false;
711
719
 
712
- return (v[1] as Stats).pValue == generalPositionStats.minPValue;
720
+ return (v[1] as Stats).pValue === generalPositionStats.minPValue;
713
721
  }) as [string, Stats][];
714
722
 
715
723
  let maxEntry: [string, Stats];
716
724
  for (const [monomer, monomerStats] of filteredMonomerStats) {
717
- if (typeof maxEntry! == 'undefined' || maxEntry[1].meanDifference < monomerStats.meanDifference)
725
+ if (typeof maxEntry! === 'undefined' || maxEntry[1].meanDifference < monomerStats.meanDifference)
718
726
  maxEntry = [monomer, monomerStats];
719
727
  }
720
728
 
@@ -753,7 +761,7 @@ export class PeptidesModel {
753
761
  const sourceView = this.analysisView.grid;
754
762
  const eventAction = (ev: MouseEvent): void => {
755
763
  const cell = sourceView.hitTest(ev.offsetX, ev.offsetY);
756
- if (cell?.isColHeader && cell.tableColumn?.semType == C.SEM_TYPES.MONOMER) {
764
+ if (cell?.isColHeader && cell.tableColumn?.semType === C.SEM_TYPES.MONOMER) {
757
765
  const newBarPart = this.findAARandPosition(cell, ev);
758
766
  this.requestBarchartAction(ev, newBarPart);
759
767
  }
@@ -790,7 +798,7 @@ export class PeptidesModel {
790
798
  this.modifyMonomerPositionSelection(monomer, position, false);
791
799
  } else {
792
800
  const bar = `${position} = ${monomer}`;
793
- if (this.cachedWebLogoTooltip.bar == bar)
801
+ if (this.cachedWebLogoTooltip.bar === bar)
794
802
  ui.tooltip.show(this.cachedWebLogoTooltip.tooltip!, ev.clientX, ev.clientY);
795
803
  else
796
804
  this.cachedWebLogoTooltip = {bar: bar, tooltip: this.showTooltipAt(monomer, position, ev.clientX, ev.clientY)};
@@ -815,16 +823,16 @@ export class PeptidesModel {
815
823
  ctx.clip();
816
824
 
817
825
  //TODO: optimize
818
- if (gcArgs.cell.isColHeader && col?.semType == C.SEM_TYPES.MONOMER) {
826
+ if (gcArgs.cell.isColHeader && col?.semType === C.SEM_TYPES.MONOMER) {
819
827
  const stats = this.monomerPositionStats[col.name];
820
828
  //TODO: precalc on stats creation
821
829
  const sortedStatsOrder = Object.keys(stats).sort((a, b) => {
822
- if (a == '' || a == '-')
830
+ if (a === '' || a === '-')
823
831
  return -1;
824
- else if (b == '' || b == '-')
832
+ else if (b === '' || b === '-')
825
833
  return +1;
826
834
  return 0;
827
- }).filter((v) => v != 'general');
835
+ }).filter((v) => v !== 'general');
828
836
 
829
837
  this.webLogoBounds[col.name] = CR.drawLogoInBounds(ctx, bounds, stats, sortedStatsOrder, this.df.rowCount,
830
838
  this.cp, this.headerSelectedMonomers[col.name]);
@@ -1011,7 +1019,7 @@ export class PeptidesModel {
1011
1019
  this.headerSelectedMonomers = calculateSelected(this.df);
1012
1020
 
1013
1021
  const acc = this.createAccordion();
1014
- if (acc != null) {
1022
+ if (acc !== null) {
1015
1023
  grok.shell.o = acc.root;
1016
1024
  for (const pane of acc.panes)
1017
1025
  pane.expanded = true;
@@ -1092,7 +1100,7 @@ export class PeptidesModel {
1092
1100
  return;
1093
1101
  this.isInitialized = true;
1094
1102
 
1095
- if (!this.isRibbonSet && this.df.getTag(C.MULTIPLE_VIEWS) != '1') {
1103
+ if (!this.isRibbonSet && this.df.getTag(C.TAGS.MULTIPLE_VIEWS) !== '1') {
1096
1104
  //TODO: don't pass model, pass parameters instead
1097
1105
  const settingsButton = ui.iconFA('wrench', () => getSettingsDialog(this), 'Peptides analysis settings');
1098
1106
  this.analysisView.setRibbonPanels([[settingsButton]], false);
@@ -1158,18 +1166,21 @@ export class PeptidesModel {
1158
1166
  this.analysisView.grid.col(newClusterCol.name)!.visible = false;
1159
1167
  }
1160
1168
 
1161
- createNewView(): void {
1169
+ createNewView(): string {
1162
1170
  const rowMask = this.getCompoundBitset();
1163
- if (!rowMask.anyTrue)
1164
- return grok.shell.warning('Cannot create a new view, there are no visible selected rows in your dataset');
1171
+ const newDfId = uuid.v4();
1165
1172
 
1166
1173
  const newDf = this.df.clone(rowMask);
1167
1174
  for (const [tag, value] of newDf.tags)
1168
- newDf.setTag(tag, tag == C.TAGS.SETTINGS ? value : '');
1175
+ newDf.setTag(tag, tag === C.TAGS.SETTINGS ? value : '');
1176
+
1169
1177
  newDf.name = 'Peptides Multiple Views';
1170
- newDf.setTag(C.MULTIPLE_VIEWS, '1');
1171
- newDf.setTag(C.TAGS.UUID, uuid.v4());
1178
+ newDf.setTag(C.TAGS.MULTIPLE_VIEWS, '1');
1179
+ newDf.setTag(C.TAGS.UUID, newDfId);
1180
+
1172
1181
  const view = grok.shell.addTableView(newDf);
1173
- view.addViewer('logo-summary-viewer');
1182
+ view.addViewer(VIEWER_TYPE.LOGO_SUMMARY_TABLE);
1183
+
1184
+ return newDfId;
1174
1185
  }
1175
1186
  }
package/src/tests/core.ts CHANGED
@@ -39,7 +39,7 @@ category('Core', () => {
39
39
  simpleActivityCol, simpleAlignedSeqCol, null, simpleTable, simpleScaledCol, C.SCALING_METHODS.MINUS_LG);
40
40
  expect(model instanceof PeptidesModel, true);
41
41
 
42
- if (model != null)
42
+ if (model !== null)
43
43
  model.monomerPositionSelection = {'11': ['D']};
44
44
  });
45
45
 
@@ -59,7 +59,7 @@ category('Core', () => {
59
59
  complexActivityCol, complexAlignedSeqCol, null, complexTable, complexScaledCol, C.SCALING_METHODS.MINUS_LG);
60
60
  expect(model instanceof PeptidesModel, true);
61
61
 
62
- if (model != null)
62
+ if (model !== null)
63
63
  model.monomerPositionSelection = {'13': ['-']};
64
64
  });
65
65
 
@@ -8,6 +8,7 @@ import {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 {LogoSummaryTable} from '../viewers/logo-summary';
11
+ import {TEST_COLUMN_NAMES} from './utils';
11
12
 
12
13
  category('Model: Settings', () => {
13
14
  let df: DG.DataFrame;
@@ -22,12 +23,12 @@ category('Model: Settings', () => {
22
23
 
23
24
  before(async () => {
24
25
  df = DG.DataFrame.fromCsv(await _package.files.readAsText('tests/HELM_small.csv'));
25
- activityCol = df.getCol('activity');
26
- sequenceCol = df.getCol('sequence');
26
+ activityCol = df.getCol(TEST_COLUMN_NAMES.ACTIVITY);
27
+ sequenceCol = df.getCol(TEST_COLUMN_NAMES.SEQUENCE);
27
28
  sequenceCol.semType = DG.SEMTYPE.MACROMOLECULE;
28
29
  sequenceCol.setTag(DG.TAGS.UNITS, NOTATION.HELM);
29
30
  scaledActivityCol = scaleActivity(activityCol, SCALING_METHODS.NONE);
30
- clusterCol = df.getCol('cluster');
31
+ clusterCol = df.getCol(TEST_COLUMN_NAMES.CLUSTER);
31
32
  const tempModel = await startAnalysis(activityCol, sequenceCol, clusterCol, df, scaledActivityCol,
32
33
  SCALING_METHODS.NONE);
33
34
  if (tempModel === null)
@@ -7,6 +7,7 @@ import {startAnalysis} from '../widgets/peptides';
7
7
  import {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
+ import {TEST_COLUMN_NAMES} from './utils';
10
11
 
11
12
  category('Table view', () => {
12
13
  let df: DG.DataFrame;
@@ -24,12 +25,12 @@ category('Table view', () => {
24
25
 
25
26
  before(async () => {
26
27
  df = DG.DataFrame.fromCsv(await _package.files.readAsText('tests/HELM_small.csv'));
27
- activityCol = df.getCol('activity');
28
- sequenceCol = df.getCol('sequence');
28
+ activityCol = df.getCol(TEST_COLUMN_NAMES.ACTIVITY);
29
+ sequenceCol = df.getCol(TEST_COLUMN_NAMES.SEQUENCE);
29
30
  sequenceCol.semType = DG.SEMTYPE.MACROMOLECULE;
30
31
  sequenceCol.setTag(DG.TAGS.UNITS, NOTATION.HELM);
31
32
  scaledActivityCol = scaleActivity(activityCol, scaling);
32
- clusterCol = df.getCol('cluster');
33
+ clusterCol = df.getCol(TEST_COLUMN_NAMES.CLUSTER);
33
34
  const tempModel = await startAnalysis(activityCol, sequenceCol, clusterCol, df, scaledActivityCol, scaling);
34
35
  if (tempModel === null)
35
36
  throw new Error('Model is null');
@@ -50,7 +51,7 @@ category('Table view', () => {
50
51
  const tableColName = col.column!.name;
51
52
  const expectedVisibility = posCols.includes(tableColName) || (tableColName === COLUMNS_NAMES.ACTIVITY_SCALED) ||
52
53
  visibleColumns.includes(tableColName);
53
- expect(col.visible, expectedVisibility, `Column ${tableColName} is visible == ${col.visible} but should be ` +
54
+ expect(col.visible, expectedVisibility, `Column ${tableColName} is visible === ${col.visible} but should be ` +
54
55
  `${expectedVisibility}`);
55
56
  }
56
57
  });
@@ -8,6 +8,12 @@ import {
8
8
  } from '@datagrok-libraries/ml/src/workers/dimensionality-reducing-worker-creator';
9
9
  import {StringMetrics} from '@datagrok-libraries/ml/src/typed-metrics';
10
10
 
11
+ export enum TEST_COLUMN_NAMES {
12
+ SEQUENCE = 'sequence',
13
+ ACTIVITY = 'activity',
14
+ CLUSTER = 'cluster',
15
+ }
16
+
11
17
  /**
12
18
  * Tests if a table has non zero rows and columns.
13
19
  *
@@ -11,7 +11,7 @@ import {MONOMER_POSITION_MODE, MonomerPosition, MostPotentResiduesViewer, showTo
11
11
  import {SCALING_METHODS} from '../utils/constants';
12
12
  import {LST_PROPERTIES, LogoSummaryTable} from '../viewers/logo-summary';
13
13
  import {PositionHeight} from '@datagrok-libraries/bio/src/viewers/web-logo';
14
-
14
+ import {TEST_COLUMN_NAMES} from './utils';
15
15
 
16
16
  category('Viewers: Basic', () => {
17
17
  const df = DG.DataFrame.fromCsv(aligned1);
@@ -34,12 +34,12 @@ category('Viewers: Monomer-Position', () => {
34
34
 
35
35
  before(async () => {
36
36
  df = DG.DataFrame.fromCsv(await _package.files.readAsText('tests/HELM_small.csv'));
37
- activityCol = df.getCol('activity');
38
- sequenceCol = df.getCol('sequence');
37
+ activityCol = df.getCol(TEST_COLUMN_NAMES.ACTIVITY);
38
+ sequenceCol = df.getCol(TEST_COLUMN_NAMES.SEQUENCE);
39
39
  sequenceCol.semType = DG.SEMTYPE.MACROMOLECULE;
40
40
  sequenceCol.setTag(DG.TAGS.UNITS, NOTATION.HELM);
41
41
  scaledActivityCol = scaleActivity(activityCol, SCALING_METHODS.NONE);
42
- clusterCol = df.getCol('cluster');
42
+ clusterCol = df.getCol(TEST_COLUMN_NAMES.CLUSTER);
43
43
  const tempModel = await startAnalysis(
44
44
  activityCol, sequenceCol, clusterCol, df, scaledActivityCol, SCALING_METHODS.NONE);
45
45
  if (tempModel === null)
@@ -83,12 +83,12 @@ category('Viewers: Most Potent Residues', () => {
83
83
 
84
84
  before(async () => {
85
85
  df = DG.DataFrame.fromCsv(await _package.files.readAsText('tests/HELM_small.csv'));
86
- activityCol = df.getCol('activity');
87
- sequenceCol = df.getCol('sequence');
86
+ activityCol = df.getCol(TEST_COLUMN_NAMES.ACTIVITY);
87
+ sequenceCol = df.getCol(TEST_COLUMN_NAMES.SEQUENCE);
88
88
  sequenceCol.semType = DG.SEMTYPE.MACROMOLECULE;
89
89
  sequenceCol.setTag(DG.TAGS.UNITS, NOTATION.HELM);
90
90
  scaledActivityCol = scaleActivity(activityCol, SCALING_METHODS.NONE);
91
- clusterCol = df.getCol('cluster');
91
+ clusterCol = df.getCol(TEST_COLUMN_NAMES.CLUSTER);
92
92
  const tempModel = await startAnalysis(
93
93
  activityCol, sequenceCol, clusterCol, df, scaledActivityCol, SCALING_METHODS.NONE);
94
94
  if (tempModel === null)
@@ -116,12 +116,12 @@ category('Viewers: Logo Summary Table', () => {
116
116
 
117
117
  before(async () => {
118
118
  df = DG.DataFrame.fromCsv(await _package.files.readAsText('tests/HELM_small.csv'));
119
- activityCol = df.getCol('activity');
120
- sequenceCol = df.getCol('sequence');
119
+ activityCol = df.getCol(TEST_COLUMN_NAMES.ACTIVITY);
120
+ sequenceCol = df.getCol(TEST_COLUMN_NAMES.SEQUENCE);
121
121
  sequenceCol.semType = DG.SEMTYPE.MACROMOLECULE;
122
122
  sequenceCol.setTag(DG.TAGS.UNITS, NOTATION.HELM);
123
123
  scaledActivityCol = scaleActivity(activityCol, SCALING_METHODS.NONE);
124
- clusterCol = df.getCol('cluster');
124
+ clusterCol = df.getCol(TEST_COLUMN_NAMES.CLUSTER);
125
125
  const tempModel = await startAnalysis(
126
126
  activityCol, sequenceCol, clusterCol, df, scaledActivityCol, SCALING_METHODS.NONE);
127
127
  if (tempModel === null)
@@ -1,15 +1,19 @@
1
+ import * as grok from 'datagrok-api/grok';
1
2
  import * as DG from 'datagrok-api/dg';
2
3
 
3
- import {category, test, before, expect} from '@datagrok-libraries/utils/src/test';
4
+ import {category, test, before, expect, delay} from '@datagrok-libraries/utils/src/test';
4
5
  import {_package} from '../package-test';
5
- import {PeptidesModel} from '../model';
6
+ import {PeptidesModel, VIEWER_TYPE} from '../model';
6
7
  import {scaleActivity} from '../utils/misc';
7
8
  import {startAnalysis} from '../widgets/peptides';
8
9
  import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
9
- import {SCALING_METHODS} from '../utils/constants';
10
+ import * as C from '../utils/constants';
10
11
  import {PANES_INPUTS, SETTINGS_PANES, getSettingsDialog} from '../widgets/settings';
11
12
  import {getDistributionWidget} from '../widgets/distribution';
12
13
  import {mutationCliffsWidget} from '../widgets/mutation-cliffs';
14
+ import {TEST_COLUMN_NAMES} from './utils';
15
+ import wu from 'wu';
16
+ import {LogoSummaryTable} from '../viewers/logo-summary';
13
17
 
14
18
  category('Widgets: Settings', () => {
15
19
  let df: DG.DataFrame;
@@ -21,14 +25,14 @@ category('Widgets: Settings', () => {
21
25
 
22
26
  before(async () => {
23
27
  df = DG.DataFrame.fromCsv(await _package.files.readAsText('tests/HELM_small.csv'));
24
- activityCol = df.getCol('activity');
25
- sequenceCol = df.getCol('sequence');
28
+ activityCol = df.getCol(TEST_COLUMN_NAMES.ACTIVITY);
29
+ sequenceCol = df.getCol(TEST_COLUMN_NAMES.SEQUENCE);
26
30
  sequenceCol.semType = DG.SEMTYPE.MACROMOLECULE;
27
31
  sequenceCol.setTag(DG.TAGS.UNITS, NOTATION.HELM);
28
- scaledActivityCol = scaleActivity(activityCol, SCALING_METHODS.NONE);
29
- clusterCol = df.getCol('cluster');
32
+ scaledActivityCol = scaleActivity(activityCol, C.SCALING_METHODS.NONE);
33
+ clusterCol = df.getCol(TEST_COLUMN_NAMES.CLUSTER);
30
34
  const tempModel = await startAnalysis(activityCol, sequenceCol, clusterCol, df, scaledActivityCol,
31
- SCALING_METHODS.NONE);
35
+ C.SCALING_METHODS.NONE);
32
36
  if (tempModel === null)
33
37
  throw new Error('Model is null');
34
38
  model = tempModel;
@@ -62,14 +66,14 @@ category('Widgets: Distribution panel', () => {
62
66
 
63
67
  before(async () => {
64
68
  df = DG.DataFrame.fromCsv(await _package.files.readAsText('tests/HELM_small.csv'));
65
- activityCol = df.getCol('activity');
66
- sequenceCol = df.getCol('sequence');
69
+ activityCol = df.getCol(TEST_COLUMN_NAMES.ACTIVITY);
70
+ sequenceCol = df.getCol(TEST_COLUMN_NAMES.SEQUENCE);
67
71
  sequenceCol.semType = DG.SEMTYPE.MACROMOLECULE;
68
72
  sequenceCol.setTag(DG.TAGS.UNITS, NOTATION.HELM);
69
- scaledActivityCol = scaleActivity(activityCol, SCALING_METHODS.NONE);
70
- clusterCol = df.getCol('cluster');
73
+ scaledActivityCol = scaleActivity(activityCol, C.SCALING_METHODS.NONE);
74
+ clusterCol = df.getCol(TEST_COLUMN_NAMES.CLUSTER);
71
75
  const tempModel = await startAnalysis(activityCol, sequenceCol, clusterCol, df, scaledActivityCol,
72
- SCALING_METHODS.NONE);
76
+ C.SCALING_METHODS.NONE);
73
77
  if (tempModel === null)
74
78
  throw new Error('Model is null');
75
79
  model = tempModel;
@@ -94,14 +98,14 @@ category('Widgets: Mutation cliffs', () => {
94
98
 
95
99
  before(async () => {
96
100
  df = DG.DataFrame.fromCsv(await _package.files.readAsText('tests/HELM_small.csv'));
97
- activityCol = df.getCol('activity');
98
- sequenceCol = df.getCol('sequence');
101
+ activityCol = df.getCol(TEST_COLUMN_NAMES.ACTIVITY);
102
+ sequenceCol = df.getCol(TEST_COLUMN_NAMES.SEQUENCE);
99
103
  sequenceCol.semType = DG.SEMTYPE.MACROMOLECULE;
100
104
  sequenceCol.setTag(DG.TAGS.UNITS, NOTATION.HELM);
101
- scaledActivityCol = scaleActivity(activityCol, SCALING_METHODS.NONE);
102
- clusterCol = df.getCol('cluster');
105
+ scaledActivityCol = scaleActivity(activityCol, C.SCALING_METHODS.NONE);
106
+ clusterCol = df.getCol(TEST_COLUMN_NAMES.CLUSTER);
103
107
  const tempModel = await startAnalysis(activityCol, sequenceCol, clusterCol, df, scaledActivityCol,
104
- SCALING_METHODS.NONE);
108
+ C.SCALING_METHODS.NONE);
105
109
  if (tempModel === null)
106
110
  throw new Error('Model is null');
107
111
  model = tempModel;
@@ -121,15 +125,84 @@ category('Widgets: Mutation cliffs', () => {
121
125
  });
122
126
 
123
127
  category('Widgets: Actions', () => {
128
+ let df: DG.DataFrame;
129
+ let model: PeptidesModel;
130
+ let activityCol: DG.Column<number>;
131
+ let sequenceCol: DG.Column<string>;
132
+ let clusterCol: DG.Column<any>;
133
+ let scaledActivityCol: DG.Column<number>;
134
+
135
+ before(async () => {
136
+ df = DG.DataFrame.fromCsv(await _package.files.readAsText('tests/HELM_small.csv'));
137
+ activityCol = df.getCol(TEST_COLUMN_NAMES.ACTIVITY);
138
+ sequenceCol = df.getCol(TEST_COLUMN_NAMES.SEQUENCE);
139
+ sequenceCol.semType = DG.SEMTYPE.MACROMOLECULE;
140
+ sequenceCol.setTag(DG.TAGS.UNITS, NOTATION.HELM);
141
+ scaledActivityCol = scaleActivity(activityCol, C.SCALING_METHODS.NONE);
142
+ clusterCol = df.getCol(TEST_COLUMN_NAMES.CLUSTER);
143
+ const tempModel = await startAnalysis(activityCol, sequenceCol, clusterCol, df, scaledActivityCol,
144
+ C.SCALING_METHODS.NONE);
145
+ if (tempModel === null)
146
+ throw new Error('Model is null');
147
+ model = tempModel;
148
+ });
149
+
124
150
  test('New view', async () => {
151
+ // Set compound bitset: filter out 2 rows and select 1 among them
152
+ const filter = model.df.filter;
153
+ filter.setAll(false, false);
154
+ filter.set(0, true, false);
155
+ filter.set(1, true, false);
125
156
 
126
- }, {skipReason: 'Not implemented yet'});
157
+ const selection = model.df.selection;
158
+ selection.set(0, true, false);
127
159
 
128
- test('New cluster', async () => {
160
+ const newViewId = model.createNewView();
161
+ const currentTable = grok.shell.t;
129
162
 
130
- });
163
+ expect(currentTable.getTag(C.TAGS.MULTIPLE_VIEWS), '1', 'Current table is expected to have multiple views tag');
164
+ expect(currentTable.getTag(C.TAGS.UUID), newViewId, 'Current table is expected to have the same UUID as new view');
165
+ expect(currentTable.rowCount, 1, 'Current table is expected to have 1 row');
131
166
 
132
- test('Remove cluster', async () => {
167
+ await delay(500);
133
168
 
134
- }, {skipReason: 'Not implemented yet'});
169
+ const currentTableModel = currentTable.temp[PeptidesModel.modelName] as PeptidesModel;
170
+ const lstViewer = currentTableModel.findViewer(VIEWER_TYPE.LOGO_SUMMARY_TABLE);
171
+ expect(lstViewer !== null, true, 'New view is expected to have Logo Summary Table viewer attached');
172
+ });
173
+
174
+ test('Custom clusters', async () => {
175
+ // Set compound bitset: filter out 2 rows and select 1 among them
176
+ const filter = model.df.filter;
177
+ filter.setAll(false, false);
178
+ filter.set(0, true, false);
179
+ filter.set(1, true, false);
180
+
181
+ const selection = model.df.selection;
182
+ selection.set(0, true, false);
183
+
184
+ const lstViewer = model.findViewer(VIEWER_TYPE.LOGO_SUMMARY_TABLE) as LogoSummaryTable;
185
+
186
+ // Check that custom clusters are not created yet
187
+ expect(wu(model.customClusters).toArray().length, 0, 'Expected to have 0 custom clusters before creating one');
188
+
189
+ // Create custom cluster
190
+ model._newClusterSubject.next();
191
+ const customClusterList = wu(model.customClusters).toArray();
192
+ expect(customClusterList.length, 1, 'Expected to have 1 custom cluster');
193
+ const clustName = customClusterList[0].name;
194
+ expect(model.df.col(clustName) !== null, true,
195
+ 'Expected to have custom cluster column in the table');
196
+ expect(lstViewer.viewerGrid.table.getCol(C.LST_COLUMN_NAMES.CLUSTER).categories.indexOf(clustName) !== -1, true,
197
+ 'Expected to have custom cluster in the Logo Summary Table');
198
+
199
+ // Remove custom cluster
200
+ model.modifyClusterSelection(clustName);
201
+ model._removeClusterSubject.next();
202
+ expect(wu(model.customClusters).toArray().length, 0, 'Expected to have 0 custom clusters after removing one');
203
+ expect(model.df.col(clustName) === null, true,
204
+ 'Expected to have no custom cluster column in the table');
205
+ expect(lstViewer.viewerGrid.table.getCol(C.LST_COLUMN_NAMES.CLUSTER).categories.indexOf(clustName) === -1, true,
206
+ 'Expected to have no custom cluster in the Logo Summary Table');
207
+ });
135
208
  });
@@ -8,7 +8,7 @@ export function findMutations(activityArray: type.RawData, monomerInfoArray: typ
8
8
  settings: type.PeptidesSettings = {},
9
9
  targetOptions: {targetCol?: type.RawColumn | null, currentTarget?: string | null} = {}): type.MutationCliffs {
10
10
  const nCols = monomerInfoArray.length;
11
- if (nCols == 0)
11
+ if (nCols === 0)
12
12
  throw new Error(`PepAlgorithmError: Couldn't find any column of semType '${C.SEM_TYPES.MONOMER}'`);
13
13
 
14
14
  settings.minActivityDelta ??= 0;
@@ -37,7 +37,7 @@ export function findMutations(activityArray: type.RawData, monomerInfoArray: typ
37
37
  for (const monomerInfo of monomerInfoArray) {
38
38
  const seq1category = monomerInfo.rawData[seq1Idx];
39
39
  const seq2category = monomerInfo.rawData[seq2Idx];
40
- if (seq1category == seq2category)
40
+ if (seq1category === seq2category)
41
41
  continue;
42
42
 
43
43
  substCounter++;
@@ -54,7 +54,7 @@ export function findMutations(activityArray: type.RawData, monomerInfoArray: typ
54
54
  });
55
55
  }
56
56
 
57
- if (substCounterFlag || substCounter == 0)
57
+ if (substCounterFlag || substCounter === 0)
58
58
  continue;
59
59
 
60
60
  for (const tempDataElement of tempData) {
@@ -67,7 +67,7 @@ export function renderMutationCliffCell(canvasContext: CanvasRenderingContext2D,
67
67
  canvasContext.shadowColor = DG.Color.toHtml(DG.Color.white);
68
68
  let substValue = 0;
69
69
  substitutionsInfo.get(currentAAR)?.get(currentPosition)?.forEach((idxs) => substValue += idxs.length);
70
- if (substValue && substValue != 0)
70
+ if (substValue && substValue !== 0)
71
71
  canvasContext.fillText(substValue.toString(), midX, midY);
72
72
  }
73
73
 
@@ -38,6 +38,7 @@ export enum TAGS {
38
38
  CUSTOM_CLUSTER = 'customCluster',
39
39
  UUID = 'pep-uuid',
40
40
  MONOMER_POSITION_MODE = 'monomerPositionMode',
41
+ MULTIPLE_VIEWS = 'isMultipleViews',
41
42
  }
42
43
 
43
44
  export enum SEM_TYPES {
@@ -47,8 +48,6 @@ export enum SEM_TYPES {
47
48
 
48
49
  export const EMBEDDING_STATUS = 'embeddingStatus';
49
50
 
50
- export const MULTIPLE_VIEWS = 'isMultipleViews';
51
-
52
51
  export enum SCALING_METHODS {
53
52
  NONE = 'none',
54
53
  LG = 'lg',
package/src/utils/misc.ts CHANGED
@@ -59,8 +59,8 @@ export function calculateSelected(df: DG.DataFrame): type.MonomerSelectionStats
59
59
  }
60
60
 
61
61
  // export function isGridCellInvalid(gc: DG.GridCell | null): boolean {
62
- // return !gc || !gc.cell.value || !gc.tableColumn || gc.tableRowIndex == null || gc.tableRowIndex == -1 ||
63
- // gc.cell.value == DG.INT_NULL || gc.cell.value == DG.FLOAT_NULL;
62
+ // return !gc || !gc.cell.value || !gc.tableColumn || gc.tableRowIndex === null || gc.tableRowIndex === -1 ||
63
+ // gc.cell.value === DG.INT_NULL || gc.cell.value === DG.FLOAT_NULL;
64
64
  // }
65
65
 
66
66
  export function extractColInfo(col: DG.Column<string>): type.RawColumn {
@@ -68,7 +68,7 @@ export async function createPeptideSimilaritySpaceViewer(table: DG.DataFrame, me
68
68
  const axisCol = table.col(axis);
69
69
  const newCol = edf.getCol(axis);
70
70
 
71
- if (axisCol != null) {
71
+ if (axisCol !== null) {
72
72
  for (let i = 0; i < newCol.length; ++i) {
73
73
  const v = newCol.get(i);
74
74
  table.set(axis, i, v);
@@ -204,7 +204,7 @@ export class PeptideSimilaritySpaceWidget {
204
204
  for (const v of this.view.viewers) {
205
205
  const opts = v.getOptions() as {[name: string]: any};
206
206
 
207
- if (opts.type == 'Scatter plot' && opts.look.xColumnName == '~X' && opts.look.yColumnName == '~Y')
207
+ if (opts.type === 'Scatter plot' && opts.look.xColumnName === '~X' && opts.look.yColumnName === '~Y')
208
208
  found = true;
209
209
  }
210
210