@datagrok/peptides 1.2.0 → 1.3.0
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 +309 -393
- package/dist/package.js +363 -393
- package/package.json +1 -1
- package/src/model.ts +246 -159
- package/src/package.ts +13 -13
- package/src/styles.css +1 -0
- package/src/tests/core.ts +5 -5
- package/src/tests/peptide-space-test.ts +32 -32
- package/src/utils/cell-renderer.ts +27 -59
- package/src/utils/constants.ts +3 -0
- package/src/utils/types.ts +1 -1
- package/src/viewers/logo-summary.ts +42 -0
- package/src/viewers/sar-viewer.ts +31 -13
- package/src/widgets/analyze-peptides.ts +15 -6
- package/src/widgets/distribution.ts +1 -1
- package/src/widgets/mutation-cliffs.ts +1 -1
- package/test-Peptides-7770371320b2-8cac318e.html +246 -0
- package/src/utils/invariant-map.ts +0 -163
package/src/package.ts
CHANGED
|
@@ -8,10 +8,10 @@ import * as C from './utils/constants';
|
|
|
8
8
|
import {analyzePeptidesWidget} from './widgets/analyze-peptides';
|
|
9
9
|
import {PeptideSimilaritySpaceWidget} from './utils/peptide-similarity-space';
|
|
10
10
|
import {manualAlignmentWidget} from './widgets/manual-alignment';
|
|
11
|
-
import {
|
|
11
|
+
import {MutationCliffsViewer, MostPotentResiduesViewer} from './viewers/sar-viewer';
|
|
12
12
|
|
|
13
13
|
import {PeptideSpaceViewer} from './viewers/peptide-space-viewer';
|
|
14
|
-
import {
|
|
14
|
+
import {LogoSummary} from './viewers/logo-summary';
|
|
15
15
|
|
|
16
16
|
export const _package = new DG.Package();
|
|
17
17
|
let currentTable: DG.DataFrame;
|
|
@@ -84,16 +84,23 @@ export async function peptidesPanel(col: DG.Column): Promise<DG.Widget> {
|
|
|
84
84
|
//description: Peptides SAR Viewer
|
|
85
85
|
//tags: viewer
|
|
86
86
|
//output: viewer result
|
|
87
|
-
export function sar():
|
|
88
|
-
return new
|
|
87
|
+
export function sar(): MutationCliffsViewer {
|
|
88
|
+
return new MutationCliffsViewer();
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
//name: peptide-sar-viewer-vertical
|
|
92
92
|
//description: Peptides Vertical SAR Viewer
|
|
93
93
|
//tags: viewer
|
|
94
94
|
//output: viewer result
|
|
95
|
-
export function sarVertical():
|
|
96
|
-
return new
|
|
95
|
+
export function sarVertical(): MostPotentResiduesViewer {
|
|
96
|
+
return new MostPotentResiduesViewer();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
//name: logo-summary-viewer
|
|
100
|
+
//tags: viewer
|
|
101
|
+
//output: viewer result
|
|
102
|
+
export function logoSummary(): LogoSummary {
|
|
103
|
+
return new LogoSummary();
|
|
97
104
|
}
|
|
98
105
|
|
|
99
106
|
//name: peptide-space-viewer
|
|
@@ -154,10 +161,3 @@ function getOrDefine(dataframe?: DG.DataFrame, column?: DG.Column | null): [DG.D
|
|
|
154
161
|
|
|
155
162
|
return [dataframe, column];
|
|
156
163
|
}
|
|
157
|
-
|
|
158
|
-
//name: Invariant Map Filter
|
|
159
|
-
//tags: filter
|
|
160
|
-
//output: filter result
|
|
161
|
-
export function invariantMapFilter() {
|
|
162
|
-
return new InvariantMap();
|
|
163
|
-
}
|
package/src/styles.css
CHANGED
package/src/tests/core.ts
CHANGED
|
@@ -37,11 +37,11 @@ category('Core', () => {
|
|
|
37
37
|
[simpleScaledDf, simpleScaledColName] = scaleActivity('-lg', simpleTable, simpleActivityColName, true);
|
|
38
38
|
|
|
39
39
|
model = await startAnalysis(
|
|
40
|
-
simpleActivityCol, simpleAlignedSeqCol, simpleTable, simpleScaledDf, simpleScaledColName);
|
|
40
|
+
simpleActivityCol, simpleAlignedSeqCol, null, simpleTable, simpleScaledDf, simpleScaledColName);
|
|
41
41
|
expect(model instanceof PeptidesModel, true);
|
|
42
42
|
|
|
43
43
|
if (model != null) {
|
|
44
|
-
model.
|
|
44
|
+
model.mutationCliffsSelection = {'11': ['D']};
|
|
45
45
|
grok.shell.closeTable(model.df);
|
|
46
46
|
}
|
|
47
47
|
});
|
|
@@ -59,11 +59,11 @@ category('Core', () => {
|
|
|
59
59
|
[complexScaledDf, complexScaledColName] = scaleActivity('-lg', complexTable, complexActivityColName, true);
|
|
60
60
|
|
|
61
61
|
model = await startAnalysis(
|
|
62
|
-
complexActivityCol, complexAlignedSeqCol, complexTable, complexScaledDf, complexScaledColName);
|
|
62
|
+
complexActivityCol, complexAlignedSeqCol, null, complexTable, complexScaledDf, complexScaledColName);
|
|
63
63
|
expect(model instanceof PeptidesModel, true);
|
|
64
64
|
|
|
65
65
|
if (model != null) {
|
|
66
|
-
model.
|
|
66
|
+
model.mutationCliffsSelection = {'13': ['-']};
|
|
67
67
|
grok.shell.closeTable(model.df);
|
|
68
68
|
}
|
|
69
69
|
});
|
|
@@ -80,7 +80,7 @@ category('Core', () => {
|
|
|
80
80
|
[simpleScaledDf, simpleScaledColName] = scaleActivity('-lg', simpleTable, simpleActivityColName, true);
|
|
81
81
|
|
|
82
82
|
model = await startAnalysis(
|
|
83
|
-
simpleActivityCol, simpleAlignedSeqCol, simpleTable, simpleScaledDf, simpleScaledColName);
|
|
83
|
+
simpleActivityCol, simpleAlignedSeqCol, null, simpleTable, simpleScaledDf, simpleScaledColName);
|
|
84
84
|
let v = grok.shell.getTableView('Peptides analysis');
|
|
85
85
|
const d = v.dataFrame;
|
|
86
86
|
const layout = v.saveLayout();
|
|
@@ -58,40 +58,40 @@ category('Peptide space', async () => {
|
|
|
58
58
|
});
|
|
59
59
|
});
|
|
60
60
|
|
|
61
|
-
category('Peptide Space Performance', () => {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
61
|
+
// category('Peptide Space Performance', () => {
|
|
62
|
+
// test('test_compute_weights_performance', async () => {
|
|
63
|
+
// const table = DG.DataFrame.fromCsv(await _package.files.readAsText('peptides_large.csv'));
|
|
64
|
+
// const results: {[key: string]: {[key: string]: {[key: string]: number}}} = {};
|
|
65
|
+
// const sliceVolumes = [1, 2, 3, 4, 5, 7, 10];
|
|
66
|
+
// const methods = DimensionalityReducer.availableMethods;
|
|
67
|
+
// const metrics = DimensionalityReducer.availableMetricsByType('String');
|
|
68
|
+
// const totalRuns = sliceVolumes.length * methods.length * metrics.length;
|
|
69
|
+
// console.log('Started Peptide Space Performance benchmark...');
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
71
|
+
// let run = 0;
|
|
72
|
+
// for (const slice of sliceVolumes) {
|
|
73
|
+
// const bitset = DG.BitSet.create(table.rowCount, (i) => i < slice * 1000);
|
|
74
|
+
// const tableSlice = table.clone(bitset);
|
|
75
|
+
// const col = tableSlice.getCol('sequence');
|
|
76
|
+
// const methodObj: {[key: string]: {[key: string]: number}} = {};
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
// for (const method of methods) {
|
|
79
|
+
// const measureObj: {[key: string]: number} = {};
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
// for (const metric of metrics) {
|
|
82
|
+
// console.log(`Run ${run++}/${totalRuns}`);
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
// const start = new Date();
|
|
85
|
+
// await computeWeights(tableSlice, method, metric, 100, col);
|
|
86
|
+
// const stop = new Date();
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
});
|
|
88
|
+
// measureObj[metric] = stop.getTime() - start.getTime();
|
|
89
|
+
// }
|
|
90
|
+
// methodObj[method] = measureObj;
|
|
91
|
+
// }
|
|
92
|
+
// results[`${slice}k`] = methodObj;
|
|
93
|
+
// }
|
|
94
|
+
// console.log('Peptide Space Performance benchmark finished...');
|
|
95
|
+
// console.log(results);
|
|
96
|
+
// });
|
|
97
|
+
// });
|
|
@@ -5,65 +5,24 @@ import * as C from './constants';
|
|
|
5
5
|
import {getPalleteByType} from './misc';
|
|
6
6
|
import * as types from './types';
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
* @param {DG.Column} col Column to expand.
|
|
13
|
-
* @param {DG.Grid} grid Grid containing colum for expansion.
|
|
14
|
-
* @param {(cellVal: string) => number} cellRenderSize An anonymous function that calculates cell value length.
|
|
15
|
-
* @param {number} [textSizeMult=10] Text size muliplier.
|
|
16
|
-
* @param {number} [minSize=30] Minimal column width.
|
|
17
|
-
* @param {number} [maxSize=650] Maximum column width.
|
|
18
|
-
* @param {number} [timeout=500] Timeout value.
|
|
19
|
-
*/
|
|
20
|
-
export function expandColumn(col: DG.Column, grid: DG.Grid, cellRenderSize: (cellVal: string) => number,
|
|
21
|
-
textSizeMult = 10, minSize = 30, maxSize = 650, timeout = 500): void {
|
|
22
|
-
let maxLen = 0;
|
|
23
|
-
col.categories.forEach((ent: string) => {
|
|
24
|
-
const len = cellRenderSize(ent);
|
|
25
|
-
if (len > maxLen)
|
|
26
|
-
maxLen = len;
|
|
27
|
-
});
|
|
28
|
-
setTimeout(() => {
|
|
29
|
-
grid.columns.byName(col.name)!.width = Math.min(Math.max(maxLen * textSizeMult, minSize), maxSize);
|
|
30
|
-
},
|
|
31
|
-
timeout);
|
|
8
|
+
function renderCellSelection(canvasContext: CanvasRenderingContext2D, bound: DG.Rect): void {
|
|
9
|
+
canvasContext.strokeStyle = '#000';
|
|
10
|
+
canvasContext.lineWidth = 1;
|
|
11
|
+
canvasContext.strokeRect(bound.x + 1, bound.y + 1, bound.width - 1, bound.height - 1);
|
|
32
12
|
}
|
|
33
13
|
|
|
34
|
-
/**
|
|
35
|
-
|
|
36
|
-
*
|
|
37
|
-
* @export
|
|
38
|
-
* @param {DG.Column} col Column to set renderer for.
|
|
39
|
-
* @param {(DG.Grid | null)} [grid=null] Grid that contains the col column.
|
|
40
|
-
* @param {boolean} [grouping=false] Is grouping enabled.
|
|
41
|
-
*/
|
|
42
|
-
export function setAARRenderer(col: DG.Column, alphabet: string, grid?: DG.Grid): void {
|
|
14
|
+
/** A function that sets amino acid residue cell renderer to the specified column */
|
|
15
|
+
export function setAARRenderer(col: DG.Column, alphabet: string, grid: DG.Grid, timeout: number = 500): void {
|
|
43
16
|
col.semType = C.SEM_TYPES.MONOMER;
|
|
44
17
|
col.setTag('cell.renderer', C.SEM_TYPES.MONOMER);
|
|
45
18
|
col.tags[C.TAGS.ALPHABET] = alphabet;
|
|
46
|
-
|
|
47
|
-
if (grid)
|
|
48
|
-
expandColumn(col, grid, (ent) => measureAAR(ent));
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* A function to measure amino acid residue
|
|
53
|
-
*
|
|
54
|
-
* @export
|
|
55
|
-
* @param {string} s Amino acid residue string.
|
|
56
|
-
* @return {number} Amino acid residue size.
|
|
57
|
-
*/
|
|
58
|
-
export function measureAAR(s: string): number {
|
|
59
|
-
const end = s.lastIndexOf(')');
|
|
60
|
-
const beg = s.indexOf('(');
|
|
61
|
-
return end == beg ? s.length : s.length - (end - beg) + 1;
|
|
19
|
+
setTimeout(() => grid.columns.byName(col.name)!.width = 60, timeout);
|
|
62
20
|
}
|
|
63
21
|
|
|
64
|
-
export function
|
|
65
|
-
statsDf: DG.DataFrame, twoColorMode: boolean, mdCol: DG.Column<number>, bound: DG.Rect,
|
|
66
|
-
|
|
22
|
+
export function renderMutationCliffCell(canvasContext: CanvasRenderingContext2D, currentAAR: string,
|
|
23
|
+
currentPosition: string, statsDf: DG.DataFrame, twoColorMode: boolean, mdCol: DG.Column<number>, bound: DG.Rect,
|
|
24
|
+
cellValue: number, mutationCliffsSelection: types.PositionToAARList, substitutionsInfo: types.SubstitutionsInfo,
|
|
25
|
+
): void {
|
|
67
26
|
const queryAAR = `${C.COLUMNS_NAMES.MONOMER} = ${currentAAR}`;
|
|
68
27
|
const query = `${queryAAR} and ${C.COLUMNS_NAMES.POSITION} = ${currentPosition}`;
|
|
69
28
|
const pVal: number = statsDf
|
|
@@ -112,13 +71,22 @@ export function renderSARCell(canvasContext: CanvasRenderingContext2D, currentAA
|
|
|
112
71
|
canvasContext.fillText(substValue.toString(), midX, midY);
|
|
113
72
|
}
|
|
114
73
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
74
|
+
const aarSelection = mutationCliffsSelection[currentPosition];
|
|
75
|
+
if (aarSelection && aarSelection.includes(currentAAR))
|
|
76
|
+
renderCellSelection(canvasContext, bound);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function renderInvaraintMapCell(canvasContext: CanvasRenderingContext2D, currentAAR: string,
|
|
80
|
+
currentPosition: string, invariantMapSelection: types.PositionToAARList, cellValue: number, bound: DG.Rect): void {
|
|
81
|
+
canvasContext.font = '13px Roboto, Roboto Local, sans-serif';
|
|
82
|
+
canvasContext.textAlign = 'center';
|
|
83
|
+
canvasContext.textBaseline = 'middle';
|
|
84
|
+
canvasContext.fillStyle = '#000';
|
|
85
|
+
canvasContext.fillText(cellValue.toString(), bound.x + (bound.width / 2), bound.y + (bound.height / 2), bound.width);
|
|
86
|
+
|
|
87
|
+
const aarSelection = invariantMapSelection[currentPosition];
|
|
88
|
+
if (aarSelection && aarSelection.includes(currentAAR))
|
|
89
|
+
renderCellSelection(canvasContext, bound);
|
|
122
90
|
}
|
|
123
91
|
|
|
124
92
|
export function renderBarchart(ctx: CanvasRenderingContext2D, col: DG.Column, monomerColStats: types.MonomerColStats,
|
package/src/utils/constants.ts
CHANGED
|
@@ -9,6 +9,7 @@ export enum COLUMNS_NAMES {
|
|
|
9
9
|
MEAN_DIFFERENCE = 'Mean difference',
|
|
10
10
|
COUNT = 'Count',
|
|
11
11
|
RATIO = 'Ratio',
|
|
12
|
+
CLUSTERS = '~clusters',
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
export enum CATEGORIES {
|
|
@@ -22,6 +23,8 @@ export enum TAGS {
|
|
|
22
23
|
SEPARATOR = 'separator',
|
|
23
24
|
SELECTION = 'selection',
|
|
24
25
|
ALPHABET = 'alphabet',
|
|
26
|
+
FILTER = 'filter',
|
|
27
|
+
CLUSTERS = 'clusters',
|
|
25
28
|
}
|
|
26
29
|
|
|
27
30
|
export enum SEM_TYPES {
|
package/src/utils/types.ts
CHANGED
|
@@ -5,7 +5,7 @@ export type DataFrameDict = {[key: string]: DG.DataFrame};
|
|
|
5
5
|
export type UTypedArray = Uint8Array | Uint16Array | Uint32Array;
|
|
6
6
|
//AAR: (Position: (index: indexList))
|
|
7
7
|
export type SubstitutionsInfo = Map<string, Map<string, Map<number, number[] | UTypedArray>>>;
|
|
8
|
-
export type
|
|
8
|
+
export type PositionToAARList = {[postiton: string]: string[]};
|
|
9
9
|
|
|
10
10
|
export type HELMMonomer = {at: {[key: string]: string}, id: string, m: string, na: string, n: string, rs: number};
|
|
11
11
|
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import * as grok from 'datagrok-api/grok';
|
|
2
|
+
import * as ui from 'datagrok-api/ui';
|
|
3
|
+
import * as DG from 'datagrok-api/dg';
|
|
4
|
+
|
|
5
|
+
import $ from 'cash-dom';
|
|
6
|
+
import * as C from '../utils/constants';
|
|
7
|
+
import {PeptidesModel} from '../model';
|
|
8
|
+
|
|
9
|
+
export class LogoSummary extends DG.JsViewer {
|
|
10
|
+
model!: PeptidesModel;
|
|
11
|
+
viewerGrid!: DG.Grid;
|
|
12
|
+
initialized: boolean = false;
|
|
13
|
+
|
|
14
|
+
constructor() {
|
|
15
|
+
super();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async onTableAttached(): Promise<void> {
|
|
19
|
+
super.onTableAttached();
|
|
20
|
+
|
|
21
|
+
this.model = await PeptidesModel.getInstance(this.dataFrame);
|
|
22
|
+
|
|
23
|
+
this.subs.push(this.model.onLogoSummaryGridChanged.subscribe((grid) => {
|
|
24
|
+
this.viewerGrid = grid;
|
|
25
|
+
this.render();
|
|
26
|
+
}));
|
|
27
|
+
this.model.updateDefault();
|
|
28
|
+
this.viewerGrid = this.model.logoSummaryGrid;
|
|
29
|
+
this.initialized = true;
|
|
30
|
+
this.render();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
detach(): void {this.subs.forEach(sub => sub.unsubscribe());}
|
|
34
|
+
|
|
35
|
+
render(): void {
|
|
36
|
+
if (this.initialized) {
|
|
37
|
+
$(this.root).empty();
|
|
38
|
+
this.root.appendChild(this.viewerGrid.root);
|
|
39
|
+
this.viewerGrid.invalidate();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -20,6 +20,7 @@ export class SARViewerBase extends DG.JsViewer {
|
|
|
20
20
|
_titleHost = ui.divText('SAR Viewer', {id: 'pep-viewer-title'});
|
|
21
21
|
initialized = false;
|
|
22
22
|
isPropertyChanging: boolean = false;
|
|
23
|
+
_isVertical = false;
|
|
23
24
|
|
|
24
25
|
constructor() {
|
|
25
26
|
super();
|
|
@@ -30,6 +31,8 @@ export class SARViewerBase extends DG.JsViewer {
|
|
|
30
31
|
this.minActivityDelta = this.float('minActivityDelta', 0);
|
|
31
32
|
}
|
|
32
33
|
|
|
34
|
+
get name(): string {return '';}
|
|
35
|
+
|
|
33
36
|
async onTableAttached(): Promise<void> {
|
|
34
37
|
super.onTableAttached();
|
|
35
38
|
this.sourceGrid = this.view?.grid ?? (grok.shell.v as DG.TableView).grid;
|
|
@@ -54,9 +57,19 @@ export class SARViewerBase extends DG.JsViewer {
|
|
|
54
57
|
return;
|
|
55
58
|
if (!refreshOnly) {
|
|
56
59
|
$(this.root).empty();
|
|
60
|
+
const switchHost = ui.div();
|
|
61
|
+
if (this.name == 'MC') {
|
|
62
|
+
const modeSwitch = ui.switchInput('Invariant Map', this.model.isInvariantMap, () => {
|
|
63
|
+
this.model.isInvariantMap = modeSwitch.value;
|
|
64
|
+
this._titleHost.innerText = modeSwitch.value ? 'Invariant Map' : 'Mutation Cliffs';
|
|
65
|
+
this.viewerGrid.invalidate();
|
|
66
|
+
});
|
|
67
|
+
modeSwitch.root.style.position = 'absolute';
|
|
68
|
+
switchHost.appendChild(modeSwitch.root);
|
|
69
|
+
}
|
|
57
70
|
const viewerRoot = this.viewerGrid.root;
|
|
58
71
|
viewerRoot.style.width = 'auto';
|
|
59
|
-
this.root.appendChild(ui.divV([this._titleHost, viewerRoot]));
|
|
72
|
+
this.root.appendChild(ui.divV([ui.divH([switchHost, this._titleHost]), viewerRoot]));
|
|
60
73
|
}
|
|
61
74
|
this.viewerGrid?.invalidate();
|
|
62
75
|
}
|
|
@@ -88,9 +101,10 @@ export class SARViewerBase extends DG.JsViewer {
|
|
|
88
101
|
/**
|
|
89
102
|
* Structure-activity relationship viewer.
|
|
90
103
|
*/
|
|
91
|
-
export class
|
|
104
|
+
export class MutationCliffsViewer extends SARViewerBase {
|
|
92
105
|
_titleHost = ui.divText('Mutation Cliffs', {id: 'pep-viewer-title'});
|
|
93
|
-
_name = '
|
|
106
|
+
_name = 'MC';
|
|
107
|
+
_isVertical = false;
|
|
94
108
|
|
|
95
109
|
constructor() {super();}
|
|
96
110
|
|
|
@@ -98,26 +112,29 @@ export class SARViewer extends SARViewerBase {
|
|
|
98
112
|
|
|
99
113
|
async onTableAttached(): Promise<void> {
|
|
100
114
|
await super.onTableAttached();
|
|
101
|
-
this.model.
|
|
115
|
+
this.model.mutationCliffsViewer ??= this;
|
|
102
116
|
|
|
103
|
-
this.subs.push(this.model.
|
|
117
|
+
this.subs.push(this.model.onMutationCliffsGridChanged.subscribe((data) => {
|
|
104
118
|
this.viewerGrid = data;
|
|
105
119
|
this.render();
|
|
106
120
|
}));
|
|
107
121
|
|
|
108
122
|
this.model.updateDefault();
|
|
109
|
-
this.viewerGrid = this.model.
|
|
123
|
+
this.viewerGrid = this.model.mutationCliffsGrid;
|
|
110
124
|
this.initialized = true;
|
|
111
125
|
this.render();
|
|
112
126
|
}
|
|
113
127
|
|
|
114
|
-
isInitialized(): DG.Grid {return this.model?.
|
|
128
|
+
isInitialized(): DG.Grid {return this.model?.mutationCliffsGrid;}
|
|
115
129
|
|
|
116
130
|
//1. debouncing in rxjs; 2. flags?
|
|
117
131
|
onPropertyChanged(property: DG.Property): void {
|
|
118
132
|
if (!this.isInitialized() || IS_PROPERTY_CHANGING)
|
|
119
133
|
return;
|
|
120
134
|
|
|
135
|
+
if (property.name == 'invariantMap')
|
|
136
|
+
this._titleHost = ui.divText(property.get(this) ? 'Invariant Map' : 'Mutation Cliffs', {id: 'pep-viewer-title'});
|
|
137
|
+
|
|
121
138
|
super.onPropertyChanged(property);
|
|
122
139
|
IS_PROPERTY_CHANGING = true;
|
|
123
140
|
this.model.syncProperties(true);
|
|
@@ -126,9 +143,10 @@ export class SARViewer extends SARViewerBase {
|
|
|
126
143
|
}
|
|
127
144
|
|
|
128
145
|
/** Vertical structure activity relationship viewer. */
|
|
129
|
-
export class
|
|
130
|
-
_name = '
|
|
146
|
+
export class MostPotentResiduesViewer extends SARViewerBase {
|
|
147
|
+
_name = 'MPR';
|
|
131
148
|
_titleHost = ui.divText('Most Potent Residues', {id: 'pep-viewer-title'});
|
|
149
|
+
_isVertical = true;
|
|
132
150
|
|
|
133
151
|
constructor() {
|
|
134
152
|
super();
|
|
@@ -138,21 +156,21 @@ export class SARViewerVertical extends SARViewerBase {
|
|
|
138
156
|
|
|
139
157
|
async onTableAttached(): Promise<void> {
|
|
140
158
|
await super.onTableAttached();
|
|
141
|
-
this.model.
|
|
159
|
+
this.model.mostPotentResiduesViewer ??= this;
|
|
142
160
|
|
|
143
|
-
this.subs.push(this.model.
|
|
161
|
+
this.subs.push(this.model.onMostPotentResiduesGridChanged.subscribe((data) => {
|
|
144
162
|
this.viewerGrid = data;
|
|
145
163
|
this.render();
|
|
146
164
|
}));
|
|
147
165
|
|
|
148
166
|
this.model.updateDefault();
|
|
149
|
-
this.viewerGrid = this.model.
|
|
167
|
+
this.viewerGrid = this.model.mostPotentResiduesGrid;
|
|
150
168
|
|
|
151
169
|
this.initialized = true;
|
|
152
170
|
this.render();
|
|
153
171
|
}
|
|
154
172
|
|
|
155
|
-
isInitialized(): DG.Grid {return this.model?.
|
|
173
|
+
isInitialized(): DG.Grid {return this.model?.mostPotentResiduesGrid;}
|
|
156
174
|
|
|
157
175
|
onPropertyChanged(property: DG.Property): void {
|
|
158
176
|
if (!this.isInitialized() || IS_PROPERTY_CHANGING)
|
|
@@ -64,13 +64,15 @@ export async function analyzePeptidesWidget(currentDf: DG.DataFrame, col: DG.Col
|
|
|
64
64
|
activityScalingMethod.fireChanged();
|
|
65
65
|
};
|
|
66
66
|
const activityColumnChoice = ui.columnInput('Activity', currentDf, defaultColumn, activityScalingMethodState);
|
|
67
|
+
const clustersColumnChoice = ui.columnInput('Clusters', currentDf, null);
|
|
67
68
|
activityColumnChoice.fireChanged();
|
|
68
69
|
activityScalingMethod.fireChanged();
|
|
69
70
|
|
|
70
|
-
const inputsList = [activityColumnChoice, activityScalingMethod];
|
|
71
|
+
const inputsList = [activityColumnChoice, activityScalingMethod, clustersColumnChoice];
|
|
71
72
|
|
|
72
73
|
const startBtn = ui.button('Launch SAR', async () => {
|
|
73
|
-
await startAnalysis(
|
|
74
|
+
await startAnalysis(
|
|
75
|
+
activityColumnChoice.value, col, clustersColumnChoice.value, currentDf, scaledDf, newScaledColName);
|
|
74
76
|
});
|
|
75
77
|
startBtn.style.alignSelf = 'center';
|
|
76
78
|
|
|
@@ -85,21 +87,24 @@ export async function analyzePeptidesWidget(currentDf: DG.DataFrame, col: DG.Col
|
|
|
85
87
|
ui.splitH([
|
|
86
88
|
ui.splitV([ui.inputs(inputsList), startBtn]),
|
|
87
89
|
histogramHost,
|
|
88
|
-
], {style: {height: '
|
|
90
|
+
], {style: {height: '215px'}}),
|
|
89
91
|
]),
|
|
90
92
|
);
|
|
91
93
|
}
|
|
92
94
|
|
|
93
95
|
export async function startAnalysis(
|
|
94
|
-
activityColumn: DG.Column<number> | null, alignedSeqCol: DG.Column<string>,
|
|
95
|
-
scaledDf: DG.DataFrame, newScaledColName: string): Promise<PeptidesModel | null> {
|
|
96
|
+
activityColumn: DG.Column<number> | null, alignedSeqCol: DG.Column<string>, clustersColumn: DG.Column | null,
|
|
97
|
+
currentDf: DG.DataFrame, scaledDf: DG.DataFrame, newScaledColName: string): Promise<PeptidesModel | null> {
|
|
96
98
|
const progress = DG.TaskBarProgressIndicator.create('Loading SAR...');
|
|
97
99
|
let model = null;
|
|
98
100
|
if (activityColumn?.type === DG.TYPE.FLOAT) {
|
|
99
101
|
const activityColumnName: string = activityColumn.name;
|
|
102
|
+
const cloneColList = [alignedSeqCol.name, activityColumnName];
|
|
103
|
+
if (clustersColumn)
|
|
104
|
+
cloneColList.push(clustersColumn.name);
|
|
100
105
|
|
|
101
106
|
//prepare new DF
|
|
102
|
-
const newDf = currentDf.clone(currentDf.filter,
|
|
107
|
+
const newDf = currentDf.clone(currentDf.filter, cloneColList);
|
|
103
108
|
const activityCol = newDf.getCol(activityColumnName);
|
|
104
109
|
activityCol.name = C.COLUMNS_NAMES.ACTIVITY;
|
|
105
110
|
activityCol.semType = C.SEM_TYPES.ACTIVITY;
|
|
@@ -109,6 +114,10 @@ export async function startAnalysis(
|
|
|
109
114
|
newDf.columns.add(activityScaledCol);
|
|
110
115
|
newDf.name = 'Peptides analysis';
|
|
111
116
|
newDf.tags[C.COLUMNS_NAMES.ACTIVITY_SCALED] = newScaledColName;
|
|
117
|
+
if (clustersColumn) {
|
|
118
|
+
newDf.getCol(clustersColumn.name).name = C.COLUMNS_NAMES.CLUSTERS;
|
|
119
|
+
newDf.tags[C.TAGS.CLUSTERS] = C.COLUMNS_NAMES.CLUSTERS;
|
|
120
|
+
}
|
|
112
121
|
// newDf.tags[C.PEPTIDES_ANALYSIS] = 'true';
|
|
113
122
|
|
|
114
123
|
let monomerType = 'HELM_AA';
|
|
@@ -14,7 +14,7 @@ const otherConst = 'Other';
|
|
|
14
14
|
export function getDistributionWidget(table: DG.DataFrame, model: PeptidesModel): DG.Widget {
|
|
15
15
|
const activityScaledCol = table.columns.bySemType(C.SEM_TYPES.ACTIVITY_SCALED)!;
|
|
16
16
|
const rowCount = activityScaledCol.length;
|
|
17
|
-
const selectionObject = model.
|
|
17
|
+
const selectionObject = model.mutationCliffsSelection;
|
|
18
18
|
const positions = Object.keys(selectionObject);
|
|
19
19
|
const positionsLen = positions.length;
|
|
20
20
|
let aarStr = allConst;
|
|
@@ -7,7 +7,7 @@ import {getSeparator} from '../utils/misc';
|
|
|
7
7
|
|
|
8
8
|
export function mutationCliffsWidget(table: DG.DataFrame, model: PeptidesModel): DG.Widget {
|
|
9
9
|
const substInfo = model.substitutionsInfo;
|
|
10
|
-
const currentCell = model.
|
|
10
|
+
const currentCell = model.mutationCliffsSelection;
|
|
11
11
|
const positions = Object.keys(currentCell);
|
|
12
12
|
|
|
13
13
|
if (!positions.length)
|