@datagrok/peptides 1.3.3 → 1.3.5

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@datagrok/peptides",
3
- "version": "1.3.3",
3
+ "version": "1.3.5",
4
4
  "author": {
5
5
  "name": "Volodymyr Dyma",
6
6
  "email": "vdyma@datagrok.ai"
@@ -12,10 +12,10 @@
12
12
  "directory": "packages/Peptides"
13
13
  },
14
14
  "dependencies": {
15
- "@datagrok-libraries/bio": "^5.1.0",
15
+ "@datagrok-libraries/bio": "^5.5.0",
16
16
  "@datagrok-libraries/ml": "^2.0.1",
17
17
  "@datagrok-libraries/statistics": "^0.1.6",
18
- "@datagrok-libraries/utils": "^1.10.1",
18
+ "@datagrok-libraries/utils": "^1.11.1",
19
19
  "cash-dom": "latest",
20
20
  "datagrok-api": "^1.6.0",
21
21
  "file-loader": "^6.2.0",
@@ -5,6 +5,8 @@ set dirs=^
5
5
  \..\..\libraries\utils\ ^
6
6
  \..\..\libraries\ml\ ^
7
7
  \..\..\libraries\bio\ ^
8
+ \..\..\packages\Bio\ ^
9
+ \..\..\packages\Helm\ ^
8
10
  \
9
11
 
10
12
  call npm uninstall -g ^
package/setup.cmd CHANGED
@@ -7,6 +7,8 @@ set dirs=^
7
7
  \..\..\libraries\utils\ ^
8
8
  \..\..\libraries\ml\ ^
9
9
  \..\..\libraries\bio\ ^
10
+ \..\..\packages\Bio\ ^
11
+ \..\..\packages\Helm\ ^
10
12
  \
11
13
 
12
14
  for %%p in (%dirs%) do cd %package_dir%\%%p & call npm install
package/setup.sh CHANGED
@@ -1,15 +1,38 @@
1
- npm unlink datagrok-api
2
- npm unlink @datagrok-libraries/utils
3
- npm unlink @datagrok-libraries/ml
4
- cd ../../js-api
5
- npm install
6
- npm link
7
- cd ../libraries/utils
8
- npm install
9
- npm link
10
- cd ../../libraries/ml
11
- npm install
12
- npm link datagrok-api @datagrok-libraries/utils
13
- cd ../../packages/Peptides
14
- npm install
15
- npm link datagrok-api @datagrok-libraries/utils @datagrok-libraries/ml
1
+ #!/bin/bash
2
+
3
+ ./setup-unlink-clean.sh
4
+
5
+ GREEN='\e[0;32m'
6
+ NO_COLOR='\e[0m'
7
+
8
+ package_dir=$(pwd)
9
+
10
+ dirs=(
11
+ "../../js-api/"
12
+ "../../libraries/utils/"
13
+ "../../libraries/ml/"
14
+ "../../libraries/bio/"
15
+ )
16
+
17
+ for dir in ${dirs[@]}; do
18
+ cd $package_dir
19
+ cd $dir
20
+ echo -e $GREEN npm install in $(pwd) $NO_COLOR
21
+ npm install
22
+ echo -e $GREEN npm link in $(pwd) $NO_COLOR
23
+ npm link
24
+ done
25
+
26
+ for dir in ${dirs[@]}; do
27
+ cd $package_dir
28
+ cd $dir
29
+ if [ $dir != "../../js-api/" ]; then
30
+ echo -e $GREEN npm link-all in $(pwd) $NO_COLOR
31
+ npm run link-all
32
+ fi
33
+ echo -e $GREEN npm run build in$(pwd) $NO_COLOR
34
+ npm run build || exit
35
+ done
36
+
37
+ cd $package_dir
38
+ npm run link-all
package/src/model.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as ui from 'datagrok-api/ui';
2
2
  import * as grok from 'datagrok-api/grok';
3
3
  import * as DG from 'datagrok-api/dg';
4
+ import * as bio from '@datagrok-libraries/bio';
4
5
 
5
6
  import {splitAlignedSequences} from '@datagrok-libraries/bio/src/utils/splitter';
6
7
 
@@ -36,9 +37,9 @@ export class PeptidesModel {
36
37
  edf: DG.DataFrame | null = null;
37
38
  monomerPositionStatsDf!: DG.DataFrame;
38
39
  clusterStatsDf!: DG.DataFrame;
39
- _mutationCliffsSelection: type.PositionToAARList = {};
40
- _invariantMapSelection: type.PositionToAARList = {};
41
- _logoSummarySelection: number[] = [];
40
+ _mutationCliffsSelection!: type.PositionToAARList;
41
+ _invariantMapSelection!: type.PositionToAARList;
42
+ _logoSummarySelection!: number[];
42
43
  substitutionsInfo: type.SubstitutionsInfo = new Map();
43
44
  isInitialized = false;
44
45
  currentView!: DG.TableView;
@@ -49,12 +50,12 @@ export class PeptidesModel {
49
50
  mutationCliffsViewer!: MutationCliffsViewer;
50
51
  mostPotentResiduesViewer!: MostPotentResiduesViewer;
51
52
 
52
- _usedProperties: {[propName: string]: string | number | boolean} = {};
53
- monomerMap: {[key: string]: {molfile: string, fullName: string}} = {};
53
+ _usedProperties: { [propName: string]: string | number | boolean } = {};
54
+ monomerMap: { [key: string]: { molfile: string, fullName: string } } = {};
54
55
  barData: type.MonomerDfStats = {};
55
- barsBounds: {[position: string]: type.BarCoordinates} = {};
56
- cachedBarchartTooltip: {bar: string, tooltip: null | HTMLDivElement} = {bar: '', tooltip: null};
57
- monomerLib: any;
56
+ barsBounds: { [position: string]: type.BarCoordinates } = {};
57
+ cachedBarchartTooltip: { bar: string, tooltip: null | HTMLDivElement } = {bar: '', tooltip: null};
58
+ monomerLib: bio.IMonomerLib | null = null;
58
59
 
59
60
  private constructor(dataFrame: DG.DataFrame) {
60
61
  this.df = dataFrame;
@@ -82,6 +83,7 @@ export class PeptidesModel {
82
83
  this._mutationCliffsSelection ??= JSON.parse(this.df.tags[C.TAGS.SELECTION] || '{}');
83
84
  return this._mutationCliffsSelection;
84
85
  }
86
+
85
87
  set mutationCliffsSelection(selection: type.PositionToAARList) {
86
88
  this._mutationCliffsSelection = selection;
87
89
  this.df.tags[C.TAGS.SELECTION] = JSON.stringify(selection);
@@ -93,6 +95,7 @@ export class PeptidesModel {
93
95
  this._invariantMapSelection ??= JSON.parse(this.df.tags[C.TAGS.FILTER] || '{}');
94
96
  return this._invariantMapSelection;
95
97
  }
98
+
96
99
  set invariantMapSelection(selection: type.PositionToAARList) {
97
100
  this._invariantMapSelection = selection;
98
101
  this.df.tags[C.TAGS.FILTER] = JSON.stringify(selection);
@@ -104,6 +107,7 @@ export class PeptidesModel {
104
107
  this._logoSummarySelection ??= JSON.parse(this.df.tags[C.TAGS.CLUSTER_SELECTION] || '[]');
105
108
  return this._logoSummarySelection;
106
109
  }
110
+
107
111
  set logoSummarySelection(selection: number[]) {
108
112
  this._logoSummarySelection = selection;
109
113
  this.df.tags[C.TAGS.CLUSTER_SELECTION] = JSON.stringify(selection);
@@ -111,11 +115,12 @@ export class PeptidesModel {
111
115
  this.invalidateGrids();
112
116
  }
113
117
 
114
- get usedProperties(): {[propName: string]: string | number | boolean} {
118
+ get usedProperties(): { [propName: string]: string | number | boolean } {
115
119
  this._usedProperties = JSON.parse(this.df.tags['sarProperties'] ?? '{}');
116
120
  return this._usedProperties;
117
121
  }
118
- set usedProperties(properties: {[propName: string]: string | number | boolean}) {
122
+
123
+ set usedProperties(properties: { [propName: string]: string | number | boolean }) {
119
124
  this.df.tags['sarProperties'] = JSON.stringify(properties);
120
125
  this._usedProperties = properties;
121
126
  }
@@ -124,6 +129,7 @@ export class PeptidesModel {
124
129
  const splitByPosFlag = (this.df.tags['distributionSplit'] ?? '00')[0];
125
130
  return splitByPosFlag == '1' ? true : false;
126
131
  }
132
+
127
133
  set splitByPos(flag: boolean) {
128
134
  const splitByAARFlag = (this.df.tags['distributionSplit'] ?? '00')[1];
129
135
  this.df.tags['distributionSplit'] = `${flag ? 1 : 0}${splitByAARFlag}`;
@@ -133,6 +139,7 @@ export class PeptidesModel {
133
139
  const splitByPosFlag = (this.df.tags['distributionSplit'] ?? '00')[1];
134
140
  return splitByPosFlag == '1' ? true : false;
135
141
  }
142
+
136
143
  set splitByAAR(flag: boolean) {
137
144
  const splitByAARFlag = (this.df.tags['distributionSplit'] ?? '00')[0];
138
145
  this.df.tags['distributionSplit'] = `${splitByAARFlag}${flag ? 1 : 0}`;
@@ -141,10 +148,22 @@ export class PeptidesModel {
141
148
  get isInvariantMap(): boolean {
142
149
  return this.df.getTag('isInvariantMap') === '1';
143
150
  }
151
+
144
152
  set isInvariantMap(x: boolean) {
145
153
  this.df.setTag('isInvariantMap', x ? '1' : '0');
146
154
  }
147
155
 
156
+ get isMutationCliffSelectionEmpty(): boolean {
157
+ for (const aarList of Object.values(this.mutationCliffsSelection))
158
+ if (aarList.length !== 0)
159
+ return false;
160
+ return true;
161
+ }
162
+
163
+ get isLogoSummarySelectionEmpty(): boolean {
164
+ return this.logoSummarySelection.length === 0;
165
+ }
166
+
148
167
  createAccordion(): DG.Accordion {
149
168
  const acc = ui.accordion();
150
169
  acc.root.style.width = '100%';
@@ -295,7 +314,7 @@ export class PeptidesModel {
295
314
  continue;
296
315
 
297
316
  let substCounterFlag = false;
298
- const tempData: {pos: string, seq1monomer: string, seq2monomer: string, seq1Idx: number, seq2Idx: number}[] =
317
+ const tempData: { pos: string, seq1monomer: string, seq2monomer: string, seq1Idx: number, seq2Idx: number }[] =
299
318
  [];
300
319
  for (const currentPosCol of columnList) {
301
320
  const seq1monomer = currentPosCol.get(seq1Idx)!;
@@ -375,14 +394,15 @@ export class PeptidesModel {
375
394
  joinDataFrames(positionColumns: string[], splitSeqDf: DG.DataFrame, alphabet: string): void {
376
395
  // append splitSeqDf columns to source table and make sure columns are not added more than once
377
396
  const name = this.df.name;
397
+ const cols = this.df.columns;
378
398
  for (const colName of positionColumns) {
379
399
  const col = this.df.col(colName);
380
400
  const newCol = splitSeqDf.getCol(colName);
381
401
  if (col === null)
382
- this.df.columns.add(newCol);
402
+ cols.add(newCol);
383
403
  else {
384
- this.df.columns.remove(colName);
385
- this.df.columns.add(newCol);
404
+ cols.remove(colName);
405
+ cols.add(newCol);
386
406
  }
387
407
  CR.setAARRenderer(newCol, alphabet, this.sourceGrid);
388
408
  }
@@ -395,7 +415,7 @@ export class PeptidesModel {
395
415
  for (let i = 1; i < this.sourceGrid.columns.length; i++)
396
416
  colNames.push(this.sourceGrid.columns.byIndex(i)!);
397
417
 
398
- colNames.sort((a, b)=>{
418
+ colNames.sort((a, b) => {
399
419
  if (a.column!.semType == C.SEM_TYPES.MONOMER) {
400
420
  if (b.column!.semType == C.SEM_TYPES.MONOMER)
401
421
  return 0;
@@ -409,21 +429,15 @@ export class PeptidesModel {
409
429
  }
410
430
 
411
431
  createScaledCol(activityScaling: string, splitSeqDf: DG.DataFrame): void {
412
- const [scaledDf, _, newColName] =
413
- scaleActivity(activityScaling, this.df.getCol(C.COLUMNS_NAMES.ACTIVITY));
432
+ const scaledCol = scaleActivity(activityScaling, this.df.getCol(C.COLUMNS_NAMES.ACTIVITY));
414
433
  //TODO: make another func
415
- const scaledCol = scaledDf.getCol(C.COLUMNS_NAMES.ACTIVITY_SCALED);
416
- scaledCol.semType = C.SEM_TYPES.ACTIVITY_SCALED;
417
434
  splitSeqDf.columns.add(scaledCol);
418
- const oldScaledCol = this.df.getCol(C.COLUMNS_NAMES.ACTIVITY_SCALED);
419
- this.df.columns.replace(oldScaledCol, scaledCol);
435
+ this.df.columns.replace(C.COLUMNS_NAMES.ACTIVITY_SCALED, scaledCol);
420
436
  const gridCol = this.sourceGrid.col(C.COLUMNS_NAMES.ACTIVITY_SCALED);
421
- if (gridCol !== null) {
422
- gridCol.name = newColName;
423
- this.df.tags[C.COLUMNS_NAMES.ACTIVITY_SCALED] = newColName;
424
- }
437
+ if (gridCol)
438
+ gridCol.name = scaledCol.getTag('gridName');
425
439
 
426
- this.sourceGrid.columns.setOrder([newColName]);
440
+ this.sourceGrid.columns.setOrder([scaledCol.getTag('gridName')]);
427
441
  }
428
442
 
429
443
  calculateMonomerPositionStatistics(matrixDf: DG.DataFrame): DG.DataFrame {
@@ -431,7 +445,7 @@ export class PeptidesModel {
431
445
 
432
446
  //calculate p-values based on t-test
433
447
  const matrixCols = matrixDf.columns;
434
- const mdCol= matrixCols.addNewFloat(C.COLUMNS_NAMES.MEAN_DIFFERENCE);
448
+ const mdCol = matrixCols.addNewFloat(C.COLUMNS_NAMES.MEAN_DIFFERENCE);
435
449
  const pValCol = matrixCols.addNewFloat(C.COLUMNS_NAMES.P_VALUE);
436
450
  const countCol = matrixCols.addNewInt(C.COLUMNS_NAMES.COUNT);
437
451
  const ratioCol = matrixCols.addNewFloat(C.COLUMNS_NAMES.RATIO);
@@ -462,7 +476,7 @@ export class PeptidesModel {
462
476
  const statsDf = this.df.groupBy([C.COLUMNS_NAMES.CLUSTERS]).aggregate();
463
477
  const clustersCol = statsDf.getCol(C.COLUMNS_NAMES.CLUSTERS);
464
478
  const statsDfCols = statsDf.columns;
465
- const mdCol= statsDfCols.addNewFloat(C.COLUMNS_NAMES.MEAN_DIFFERENCE);
479
+ const mdCol = statsDfCols.addNewFloat(C.COLUMNS_NAMES.MEAN_DIFFERENCE);
466
480
  const pValCol = statsDfCols.addNewFloat(C.COLUMNS_NAMES.P_VALUE);
467
481
  const countCol = statsDfCols.addNewInt(C.COLUMNS_NAMES.COUNT);
468
482
  const ratioCol = statsDfCols.addNewFloat(C.COLUMNS_NAMES.RATIO);
@@ -512,7 +526,7 @@ export class PeptidesModel {
512
526
  .aggregate();
513
527
 
514
528
  let tempStats: DG.Stats;
515
- const maxAtPos: {[index: string]: number} = {};
529
+ const maxAtPos: { [index: string]: number } = {};
516
530
  const posColCategories = sequenceDf.getCol(C.COLUMNS_NAMES.POSITION).categories;
517
531
  const mdCol = sequenceDf.getCol(C.COLUMNS_NAMES.MEAN_DIFFERENCE);
518
532
  const posCol = sequenceDf.getCol(C.COLUMNS_NAMES.POSITION);
@@ -660,7 +674,7 @@ export class PeptidesModel {
660
674
  .subscribe((mouseMove: MouseEvent) => eventAction(mouseMove));
661
675
  }
662
676
 
663
- findAARandPosition(cell: DG.GridCell, ev: MouseEvent): {monomer: string, position: string} | null {
677
+ findAARandPosition(cell: DG.GridCell, ev: MouseEvent): { monomer: string, position: string } | null {
664
678
  const barCoords = this.barsBounds[cell.tableColumn!.name];
665
679
  for (const [monomer, coords] of Object.entries(barCoords)) {
666
680
  const isIntersectingX = ev.offsetX >= coords.x && ev.offsetX <= coords.x + coords.width;
@@ -672,7 +686,7 @@ export class PeptidesModel {
672
686
  return null;
673
687
  }
674
688
 
675
- requestBarchartAction(ev: MouseEvent, barPart: {position: string, monomer: string} | null): void {
689
+ requestBarchartAction(ev: MouseEvent, barPart: { position: string, monomer: string } | null): void {
676
690
  if (!barPart)
677
691
  return;
678
692
  const monomer = barPart.monomer;
@@ -798,7 +812,9 @@ export class PeptidesModel {
798
812
 
799
813
  showMonomerTooltip(aar: string, x: number, y: number): void {
800
814
  const tooltipElements: HTMLDivElement[] = [];
801
- const monomer: type.HELMMonomer = this.monomerLib[aar.toLowerCase()];
815
+ const monomerName = aar.toLowerCase();
816
+ const monomer: bio.Monomer = this.monomerLib!.get('HELM_AA', monomerName) ??
817
+ this.monomerLib!.get('HELM_CHEM', monomerName)!;
802
818
 
803
819
  if (monomer) {
804
820
  tooltipElements.push(ui.div(monomer.n));
@@ -964,10 +980,10 @@ export class PeptidesModel {
964
980
  const getBitAt = (i: number): boolean => {
965
981
  for (const position of positionList) {
966
982
  const positionCol: DG.Column<string> = this.df.getCol(position);
967
- if (this._mutationCliffsSelection[position].includes(positionCol.get(i)!))
983
+ if (this.mutationCliffsSelection[position].includes(positionCol.get(i)!))
968
984
  return true;
969
985
  }
970
- if (this._logoSummarySelection.includes(clusterCol?.get(i)!))
986
+ if (this.logoSummarySelection.includes(clusterCol?.get(i)!))
971
987
  return true;
972
988
  return false;
973
989
  };
@@ -979,14 +995,16 @@ export class PeptidesModel {
979
995
  selection.onChanged.subscribe(() => changeSelectionBitset(selection));
980
996
  filter.onChanged.subscribe(() => {
981
997
  const positionList = Object.keys(this.invariantMapSelection);
982
- filter.init((i) => {
998
+ for (let index = 0; index < this.df.rowCount; ++index) {
983
999
  let result = true;
984
1000
  for (const position of positionList) {
985
- const aarList = this._invariantMapSelection[position];
986
- result &&= aarList.length == 0 || aarList.includes(this.df.get(position, i));
1001
+ const aarList = this.invariantMapSelection[position];
1002
+ result &&= aarList.length === 0 || aarList.includes(this.df.get(position, index));
1003
+ if (!result)
1004
+ break;
987
1005
  }
988
- return result;
989
- }, false);
1006
+ filter.set(index, filter.get(index) && result, false);
1007
+ }
990
1008
  });
991
1009
  this.isBitsetChangedInitialized = true;
992
1010
  }
@@ -1049,7 +1067,7 @@ export class PeptidesModel {
1049
1067
  const [sourceViewer, targetViewer] = isSourceSAR ? [this.mutationCliffsViewer, this.mostPotentResiduesViewer] :
1050
1068
  [this.mostPotentResiduesViewer, this.mutationCliffsViewer];
1051
1069
  const properties = sourceViewer.props.getProperties();
1052
- const newProps: {[propName: string]: string | number | boolean} = {};
1070
+ const newProps: { [propName: string]: string | number | boolean } = {};
1053
1071
  for (const property of properties) {
1054
1072
  const propName = property.name;
1055
1073
  const propVal = property.get(sourceViewer);
@@ -1066,8 +1084,11 @@ export class PeptidesModel {
1066
1084
  if (this.isInitialized)
1067
1085
  return;
1068
1086
 
1069
- this.monomerLib =
1070
- JSON.parse(await grok.functions.call('Helm:getMonomerLib', {type: this.df.getTag('monomerType')}) as string);
1087
+ // Get monomer library through bio library
1088
+ this.monomerLib = (await bio.getMonomerLib()) as bio.IMonomerLib;
1089
+ this.monomerLib.onChanged.subscribe(() => {
1090
+ this.sourceGrid.invalidate();
1091
+ });
1071
1092
 
1072
1093
  this.currentView = this.df.tags[C.PEPTIDES_ANALYSIS] == 'true' ? grok.shell.v as DG.TableView :
1073
1094
  grok.shell.addTableView(this.df);
@@ -1077,9 +1098,9 @@ export class PeptidesModel {
1077
1098
 
1078
1099
  this.df.tags[C.PEPTIDES_ANALYSIS] = 'true';
1079
1100
  const scaledGridCol = this.sourceGrid.col(C.COLUMNS_NAMES.ACTIVITY_SCALED)!;
1080
- scaledGridCol.name = this.df.tags[C.COLUMNS_NAMES.ACTIVITY_SCALED];
1101
+ scaledGridCol.name = scaledGridCol.column!.getTag('gridName');
1081
1102
  scaledGridCol.format = '#.000';
1082
- this.sourceGrid.columns.setOrder([this.df.tags[C.COLUMNS_NAMES.ACTIVITY_SCALED]]);
1103
+ this.sourceGrid.columns.setOrder([scaledGridCol.name]);
1083
1104
  this.sourceGrid.props.allowColSelection = false;
1084
1105
 
1085
1106
  this.df.temp[C.EMBEDDING_STATUS] = false;
@@ -1,5 +1,5 @@
1
1
  import * as DG from 'datagrok-api/dg';
2
- import {runTests, tests} from '@datagrok-libraries/utils/src/test';
2
+ import {runTests, tests, TestContext} from '@datagrok-libraries/utils/src/test';
3
3
 
4
4
  import './tests/core';
5
5
  import './tests/peptide-space-test';
@@ -10,8 +10,9 @@ export {tests};
10
10
  //name: test
11
11
  //input: string category {optional: true}
12
12
  //input: string test {optional: true}
13
+ //input: object testContext {optional: true}
13
14
  //output: dataframe result
14
- export async function test(category: string, test: string): Promise<DG.DataFrame> {
15
- const data = await runTests({category, test: test});
15
+ export async function test(category: string, test: string, testContext: TestContext): Promise<DG.DataFrame> {
16
+ const data = await runTests({category, test, testContext});
16
17
  return DG.DataFrame.fromObjects(data)!;
17
18
  }
package/src/tests/core.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as grok from 'datagrok-api/grok';
2
2
  import * as DG from 'datagrok-api/dg';
3
+ import * as bio from '@datagrok-libraries/bio';
3
4
 
4
5
  import {category, test, expect, delay} from '@datagrok-libraries/utils/src/test';
5
6
 
@@ -13,14 +14,14 @@ category('Core', () => {
13
14
  let simpleTable: DG.DataFrame;
14
15
  let simpleActivityCol: DG.Column<number>;
15
16
  let simpleAlignedSeqCol: DG.Column<string>;
16
- let simpleScaledDf: DG.DataFrame;
17
+ let simpleScaledCol: DG.Column<number>;
17
18
  let scalingFormula: (x: number) => number;
18
19
  let simpleScaledColName: string;
19
20
 
20
21
  let complexTable: DG.DataFrame;
21
22
  let complexActivityCol: DG.Column<number>;
22
23
  let complexAlignedSeqCol: DG.Column<string>;
23
- let complexScaledDf: DG.DataFrame;
24
+ let complexScaledCol: DG.Column<number>;
24
25
  let complexScaledColName: string;
25
26
  const alignedSequenceCol = 'AlignedSequence';
26
27
 
@@ -32,13 +33,12 @@ category('Core', () => {
32
33
  simpleActivityCol = simpleTable.getCol(simpleActivityColName);
33
34
  simpleAlignedSeqCol = simpleTable.getCol(alignedSequenceCol);
34
35
  simpleAlignedSeqCol.semType = C.SEM_TYPES.MACROMOLECULE;
35
- simpleAlignedSeqCol.tags[C.TAGS.ALPHABET] = 'PT';
36
- simpleAlignedSeqCol.tags[DG.TAGS.UNITS] = 'fasta';
37
- simpleAlignedSeqCol.tags['aligned'] = 'SEQ.MSA';
38
- [simpleScaledDf, scalingFormula, simpleScaledColName] = scaleActivity('-lg', simpleActivityCol);
36
+ simpleAlignedSeqCol.setTag(C.TAGS.ALPHABET, bio.ALPHABET.PT);
37
+ simpleAlignedSeqCol.setTag(DG.TAGS.UNITS, bio.NOTATION.FASTA);
38
+ simpleAlignedSeqCol.setTag(bio.TAGS.aligned, bio.ALIGNMENT.SEQ_MSA);
39
+ simpleScaledCol = scaleActivity('-lg', simpleActivityCol);
39
40
 
40
- model = await startAnalysis(
41
- simpleActivityCol, simpleAlignedSeqCol, null, simpleTable, scalingFormula, simpleScaledColName, '-lg', []);
41
+ model = await startAnalysis(simpleActivityCol, simpleAlignedSeqCol, null, simpleTable, simpleScaledCol, '-lg');
42
42
  expect(model instanceof PeptidesModel, true);
43
43
 
44
44
  if (model != null) {
@@ -53,14 +53,14 @@ category('Core', () => {
53
53
  complexActivityCol = complexTable.getCol(complexActivityColName);
54
54
  complexAlignedSeqCol = complexTable.getCol('MSA');
55
55
  complexAlignedSeqCol.semType = C.SEM_TYPES.MACROMOLECULE;
56
- complexAlignedSeqCol.tags[C.TAGS.ALPHABET] = 'UN';
57
- complexAlignedSeqCol.tags[DG.TAGS.UNITS] = 'separator';
58
- complexAlignedSeqCol.tags['aligned'] = 'SEQ.MSA';
56
+ complexAlignedSeqCol.setTag(C.TAGS.ALPHABET, bio.ALPHABET.UN);
57
+ complexAlignedSeqCol.setTag(DG.TAGS.UNITS, bio.NOTATION.SEPARATOR);
58
+ complexAlignedSeqCol.setTag(bio.TAGS.aligned, bio.ALIGNMENT.SEQ_MSA);
59
59
  complexAlignedSeqCol.tags[C.TAGS.SEPARATOR] = '/';
60
- [complexScaledDf, scalingFormula, complexScaledColName] = scaleActivity('-lg', complexActivityCol);
60
+ complexScaledCol = scaleActivity('-lg', complexActivityCol);
61
61
 
62
62
  model = await startAnalysis(
63
- complexActivityCol, complexAlignedSeqCol, null, complexTable, scalingFormula, complexScaledColName, '-lg', []);
63
+ complexActivityCol, complexAlignedSeqCol, null, complexTable, complexScaledCol, '-lg');
64
64
  expect(model instanceof PeptidesModel, true);
65
65
 
66
66
  if (model != null) {
@@ -75,13 +75,12 @@ category('Core', () => {
75
75
  simpleActivityCol = simpleTable.getCol(simpleActivityColName);
76
76
  simpleAlignedSeqCol = simpleTable.getCol(alignedSequenceCol);
77
77
  simpleAlignedSeqCol.semType = C.SEM_TYPES.MACROMOLECULE;
78
- simpleAlignedSeqCol.tags[C.TAGS.ALPHABET] = 'PT';
79
- simpleAlignedSeqCol.tags[DG.TAGS.UNITS] = 'fasta';
80
- simpleAlignedSeqCol.tags['aligned'] = 'SEQ.MSA';
81
- [simpleScaledDf, scalingFormula, simpleScaledColName] = scaleActivity('-lg', simpleActivityCol);
78
+ simpleAlignedSeqCol.setTag(C.TAGS.ALPHABET, bio.ALPHABET.PT);
79
+ simpleAlignedSeqCol.setTag(DG.TAGS.UNITS, bio.NOTATION.FASTA);
80
+ simpleAlignedSeqCol.setTag(bio.TAGS.aligned, bio.ALIGNMENT.SEQ_MSA);
81
+ simpleScaledCol = scaleActivity('-lg', simpleActivityCol);
82
82
 
83
- model = await startAnalysis(
84
- simpleActivityCol, simpleAlignedSeqCol, null, simpleTable, scalingFormula, simpleScaledColName, '-lg', []);
83
+ model = await startAnalysis(simpleActivityCol, simpleAlignedSeqCol, null, simpleTable, simpleScaledCol, '-lg');
85
84
  let v = grok.shell.getTableView('Peptides analysis');
86
85
  const d = v.dataFrame;
87
86
  const layout = v.saveLayout();
package/src/utils/misc.ts CHANGED
@@ -18,13 +18,10 @@ export function getSeparator(col: DG.Column<string>): string {
18
18
  return col.getTag(C.TAGS.SEPARATOR) ?? '';
19
19
  }
20
20
 
21
- export function scaleActivity(activityScaling: string, activityCol: DG.Column<number>, indexes?: number[],
22
- ): [DG.DataFrame, (x: number) => number, string] {
23
- const tempDf = DG.DataFrame.create(activityCol.length);
24
-
21
+ export function scaleActivity(scaling: string, activityCol: DG.Column<number>): DG.Column<number> {
25
22
  let formula = (x: number): number => x;
26
23
  let newColName = 'activity';
27
- switch (activityScaling) {
24
+ switch (scaling) {
28
25
  case 'none':
29
26
  break;
30
27
  case 'lg':
@@ -36,15 +33,16 @@ export function scaleActivity(activityScaling: string, activityCol: DG.Column<nu
36
33
  newColName = `-Log10(${newColName})`;
37
34
  break;
38
35
  default:
39
- throw new Error(`ScalingError: method \`${activityScaling}\` is not available.`);
36
+ throw new Error(`ScalingError: method \`${scaling}\` is not available.`);
40
37
  }
41
- tempDf.columns.addNewVirtual(
42
- C.COLUMNS_NAMES.ACTIVITY_SCALED, (i) => {
43
- const val = activityCol.get(indexes ? indexes[i] : i);
44
- return val ? formula(val) : val;
45
- }, DG.TYPE.FLOAT);
38
+ const scaledCol = DG.Column.float(C.COLUMNS_NAMES.ACTIVITY_SCALED, activityCol.length).init((i) => {
39
+ const val = activityCol.get(i);
40
+ return val ? formula(val) : val;
41
+ });
42
+ scaledCol.semType = C.SEM_TYPES.ACTIVITY_SCALED;
43
+ scaledCol.setTag('gridName', newColName);
46
44
 
47
- return [tempDf, formula, newColName];
45
+ return scaledCol;
48
46
  }
49
47
 
50
48
  export function calculateBarsData(columns: DG.Column<string>[], selection: DG.BitSet): type.MonomerDfStats {
@@ -1,4 +1,5 @@
1
1
  import * as DG from 'datagrok-api/dg';
2
+ import * as bio from '@datagrok-libraries/bio';
2
3
 
3
4
  export type DataFrameDict = {[key: string]: DG.DataFrame};
4
5
 
@@ -7,7 +8,7 @@ export type UTypedArray = Uint8Array | Uint16Array | Uint32Array;
7
8
  export type SubstitutionsInfo = Map<string, Map<string, Map<number, number[] | UTypedArray>>>;
8
9
  export type PositionToAARList = {[postiton: string]: string[]};
9
10
 
10
- export type HELMMonomer = {at: {[key: string]: string}, id: string, m: string, na: string, n: string, rs: number};
11
+ export type HELMMonomer = bio.Monomer;
11
12
 
12
13
  export type MonomerColStats = {[monomer: string]: {count: number, selected: number}};
13
14
  export type MonomerDfStats = {[position: string]: MonomerColStats};
@@ -53,10 +53,10 @@ export class SARViewerBase extends DG.JsViewer {
53
53
 
54
54
  detach(): void {this.subs.forEach((sub) => sub.unsubscribe());}
55
55
 
56
- get state(): string {
57
- return this.dataFrame.getTag(C.TAGS.SAR_MODE) ?? '10';
56
+ get isMutationCliffsMode(): string {
57
+ return this.dataFrame.getTag(C.TAGS.SAR_MODE) ?? '1';
58
58
  }
59
- set state(s: string) {
59
+ set isMutationCliffsMode(s: string) {
60
60
  this.dataFrame.setTag(C.TAGS.SAR_MODE, s);
61
61
  }
62
62
 
@@ -67,22 +67,24 @@ export class SARViewerBase extends DG.JsViewer {
67
67
  $(this.root).empty();
68
68
  let switchHost = ui.div();
69
69
  if (this.name == 'MC') {
70
- const mutationCliffsMode = ui.boolInput('', this.state[0] === '1', () => {
70
+ const mutationCliffsMode = ui.boolInput('', this.isMutationCliffsMode === '1', () => {
71
71
  if (this.isModeChanging)
72
72
  return;
73
73
  this.isModeChanging = true;
74
74
  invariantMapMode.value = !invariantMapMode.value;
75
+ this.isMutationCliffsMode = '1';
75
76
  this.isModeChanging = false;
76
77
  this._titleHost.innerText = 'Mutation Cliffs';
77
78
  this.model.isInvariantMap = false;
78
79
  this.viewerGrid.invalidate();
79
80
  });
80
81
  mutationCliffsMode.addPostfix('Mutation Cliffs');
81
- const invariantMapMode = ui.boolInput('', this.state[1] === '1', () => {
82
+ const invariantMapMode = ui.boolInput('', this.isMutationCliffsMode === '0', () => {
82
83
  if (this.isModeChanging)
83
84
  return;
84
85
  this.isModeChanging = true;
85
86
  mutationCliffsMode.value = !mutationCliffsMode.value;
87
+ this.isMutationCliffsMode = '0';
86
88
  this.isModeChanging = false;
87
89
  this._titleHost.innerText = 'Invariant Map';
88
90
  this.model.isInvariantMap = true;
@@ -15,9 +15,6 @@ export function getDistributionWidget(table: DG.DataFrame, model: PeptidesModel)
15
15
  const activityScaledCol = table.columns.bySemType(C.SEM_TYPES.ACTIVITY_SCALED)!;
16
16
  const rowCount = activityScaledCol.length;
17
17
  const selectionObject = model.mutationCliffsSelection;
18
- let isMutationCliffsSelectionEmpty = true;
19
- for (const aarList of Object.values(selectionObject))
20
- isMutationCliffsSelectionEmpty &&= aarList.length === 0;
21
18
  const clustersObject = model.logoSummarySelection;
22
19
  const positions = Object.keys(selectionObject);
23
20
  const positionsLen = positions.length;
@@ -145,16 +142,23 @@ export function getDistributionWidget(table: DG.DataFrame, model: PeptidesModel)
145
142
  };
146
143
 
147
144
  const setDefaultProperties = (input: DG.InputBase): void => {
148
- input.enabled = !isMutationCliffsSelectionEmpty;
145
+ input.enabled = !model.isMutationCliffSelectionEmpty;
149
146
  $(input.root).find('.ui-input-editor').css('margin', '0px');
150
147
  $(input.root).find('.ui-input-description').css('padding', '0px').css('padding-left', '5px');
151
148
  };
152
149
 
153
- const splitByPosition = ui.boolInput('', model.splitByPos, updateDistributionHost);
150
+ let defaultValuePos = model.splitByPos;
151
+ let defaultValueAAR = model.splitByAAR;
152
+ if (!model.isLogoSummarySelectionEmpty && model.isMutationCliffSelectionEmpty) {
153
+ defaultValuePos = false;
154
+ defaultValueAAR = false;
155
+ }
156
+
157
+ const splitByPosition = ui.boolInput('', defaultValuePos, updateDistributionHost);
154
158
  splitByPosition.addPostfix('Split by position');
155
159
  setDefaultProperties(splitByPosition);
156
160
  $(splitByPosition.root).css('margin-right', '10px');
157
- const splitByAAR = ui.boolInput('', model.splitByAAR, updateDistributionHost);
161
+ const splitByAAR = ui.boolInput('', defaultValueAAR, updateDistributionHost);
158
162
  splitByAAR.addPostfix('Split by monomer');
159
163
  setDefaultProperties(splitByAAR);
160
164