@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/dist/package-test.js +58001 -2053
- package/dist/package.js +57942 -2009
- package/package.json +3 -3
- package/setup-unlink-clean.cmd +2 -0
- package/setup.cmd +2 -0
- package/setup.sh +38 -15
- package/src/model.ts +65 -44
- package/src/package-test.ts +4 -3
- package/src/tests/core.ts +18 -19
- package/src/utils/misc.ts +10 -12
- package/src/utils/types.ts +2 -1
- package/src/viewers/sar-viewer.ts +7 -5
- package/src/widgets/distribution.ts +10 -6
- package/src/widgets/peptides.ts +30 -53
- package/test-Peptides-916a90d7d48b-44350c85.html +0 -276
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datagrok/peptides",
|
|
3
|
-
"version": "1.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.
|
|
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.
|
|
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",
|
package/setup-unlink-clean.cmd
CHANGED
package/setup.cmd
CHANGED
package/setup.sh
CHANGED
|
@@ -1,15 +1,38 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
|
40
|
-
_invariantMapSelection
|
|
41
|
-
_logoSummarySelection
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
402
|
+
cols.add(newCol);
|
|
383
403
|
else {
|
|
384
|
-
|
|
385
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
422
|
-
gridCol.name =
|
|
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([
|
|
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
|
|
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.
|
|
983
|
+
if (this.mutationCliffsSelection[position].includes(positionCol.get(i)!))
|
|
968
984
|
return true;
|
|
969
985
|
}
|
|
970
|
-
if (this.
|
|
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
|
-
|
|
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.
|
|
986
|
-
result &&= aarList.length
|
|
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
|
-
|
|
989
|
-
}
|
|
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
|
-
|
|
1070
|
-
|
|
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 =
|
|
1101
|
+
scaledGridCol.name = scaledGridCol.column!.getTag('gridName');
|
|
1081
1102
|
scaledGridCol.format = '#.000';
|
|
1082
|
-
this.sourceGrid.columns.setOrder([
|
|
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;
|
package/src/package-test.ts
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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.
|
|
36
|
-
simpleAlignedSeqCol.
|
|
37
|
-
simpleAlignedSeqCol.
|
|
38
|
-
|
|
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.
|
|
57
|
-
complexAlignedSeqCol.
|
|
58
|
-
complexAlignedSeqCol.
|
|
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
|
-
|
|
60
|
+
complexScaledCol = scaleActivity('-lg', complexActivityCol);
|
|
61
61
|
|
|
62
62
|
model = await startAnalysis(
|
|
63
|
-
complexActivityCol, complexAlignedSeqCol, null, complexTable,
|
|
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.
|
|
79
|
-
simpleAlignedSeqCol.
|
|
80
|
-
simpleAlignedSeqCol.
|
|
81
|
-
|
|
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(
|
|
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 (
|
|
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 \`${
|
|
36
|
+
throw new Error(`ScalingError: method \`${scaling}\` is not available.`);
|
|
40
37
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
|
45
|
+
return scaledCol;
|
|
48
46
|
}
|
|
49
47
|
|
|
50
48
|
export function calculateBarsData(columns: DG.Column<string>[], selection: DG.BitSet): type.MonomerDfStats {
|
package/src/utils/types.ts
CHANGED
|
@@ -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 =
|
|
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
|
|
57
|
-
return this.dataFrame.getTag(C.TAGS.SAR_MODE) ?? '
|
|
56
|
+
get isMutationCliffsMode(): string {
|
|
57
|
+
return this.dataFrame.getTag(C.TAGS.SAR_MODE) ?? '1';
|
|
58
58
|
}
|
|
59
|
-
set
|
|
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.
|
|
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.
|
|
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 = !
|
|
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
|
-
|
|
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('',
|
|
161
|
+
const splitByAAR = ui.boolInput('', defaultValueAAR, updateDistributionHost);
|
|
158
162
|
splitByAAR.addPostfix('Split by monomer');
|
|
159
163
|
setDefaultProperties(splitByAAR);
|
|
160
164
|
|