@datagrok/peptides 0.3.0 → 0.5.6
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/.eslintrc.json +29 -0
- package/package.json +4 -4
- package/src/describe.ts +92 -41
- package/src/package.ts +13 -35
- package/src/peptides.ts +93 -0
- package/src/utils/cell-renderer.ts +185 -60
- package/src/utils/chem-palette.ts +316 -208
- package/src/utils/correlation-analysis.ts +165 -70
- package/src/utils/peptide-similarity-space.ts +29 -25
- package/src/utils/split-aligned.ts +8 -1
- package/src/viewers/logo-viewer.ts +48 -5
- package/src/viewers/model.ts +56 -16
- package/src/viewers/sar-viewer.ts +100 -33
- package/src/viewers/spiral-plot.ts +97 -0
- package/src/viewers/stacked-barchart-viewer.ts +84 -9
- package/src/widgets/analyze-peptides.ts +18 -34
- package/src/widgets/manual-alignment.ts +12 -4
- package/src/widgets/peptide-molecule.ts +8 -1
- package/src/workers/dimensionality-reducer.ts +1 -1
|
@@ -1,109 +1,204 @@
|
|
|
1
1
|
/* Do not change these import lines. Datagrok will import API library in exactly the same manner */
|
|
2
|
-
//import * as grok from 'datagrok-api/grok';
|
|
3
|
-
//import * as ui from 'datagrok-api/ui';
|
|
4
2
|
import * as DG from 'datagrok-api/dg';
|
|
5
3
|
|
|
6
4
|
import {AlignedSequenceEncoder} from '@datagrok-libraries/utils/src/sequence-encoder';
|
|
7
|
-
import {assert
|
|
8
|
-
import {
|
|
5
|
+
import {assert} from '@datagrok-libraries/utils/src/operations';
|
|
6
|
+
import {Matrix} from '@datagrok-libraries/utils/src/type-declarations';
|
|
7
|
+
import {kendallsTau} from '@datagrok-libraries/statistics/src/correlation-coefficient';
|
|
9
8
|
|
|
10
9
|
/**
|
|
11
|
-
*
|
|
10
|
+
* Converts a Matrix into a DataFrame.
|
|
12
11
|
*
|
|
13
12
|
* @export
|
|
14
|
-
* @param {
|
|
15
|
-
* @return {DG.DataFrame} The
|
|
13
|
+
* @param {Matrix} matrix A matrix.
|
|
14
|
+
* @return {DG.DataFrame} The data frame.
|
|
16
15
|
*/
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const enc = new AlignedSequenceEncoder();
|
|
20
|
-
const encSeqs = sequences.map((v) => Vector.from(enc.encode(v)));
|
|
21
|
-
const positions = transposeMatrix(encSeqs);
|
|
22
|
-
return matrix2DataFrame(positions);
|
|
16
|
+
function matrix2DataFrame(matrix: Matrix): DG.DataFrame {
|
|
17
|
+
return DG.DataFrame.fromColumns(matrix.map((v, i) => DG.Column.fromFloat32Array(`${i+1}`, v)));
|
|
23
18
|
}
|
|
24
19
|
|
|
25
20
|
/**
|
|
26
|
-
*
|
|
21
|
+
* Encodes sequence into a certain scale.
|
|
27
22
|
*
|
|
28
|
-
* @
|
|
29
|
-
* @param {
|
|
30
|
-
* @return {DG.DataFrame} The
|
|
23
|
+
* @param {DG.DataFrame} df A data frame containing the sequences.
|
|
24
|
+
* @param {string[]} [positionColumns] If given instructs which columns to consider as sequences containing.
|
|
25
|
+
* @return {DG.DataFrame} The data frame with seqences encoded.
|
|
31
26
|
*/
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
for (
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
27
|
+
function encodeSequences(df: DG.DataFrame, positionColumns?: string[]): DG.DataFrame {
|
|
28
|
+
const [nCols, nRows] = [positionColumns ? positionColumns.length : df.columns.length, df.rowCount];
|
|
29
|
+
const enc = new AlignedSequenceEncoder('WimleyWhite');
|
|
30
|
+
const positions = new Array(nCols).fill(0).map((_) => new Float32Array(nRows));
|
|
31
|
+
|
|
32
|
+
for (let i = 0; i < nCols; ++i) {
|
|
33
|
+
const col: DG.Column = positionColumns ? df.getCol(positionColumns[i]) : df.columns.byIndex(i);
|
|
34
|
+
|
|
35
|
+
for (let j = 0; j < nRows; ++j) {
|
|
36
|
+
const letter = col.get(j);
|
|
37
|
+
positions[i][j] = enc.encodeLettter(letter);
|
|
38
|
+
}
|
|
41
39
|
}
|
|
42
|
-
|
|
43
|
-
return
|
|
40
|
+
const posDF = DG.DataFrame.fromColumns(positions.map((v, i) => DG.Column.fromFloat32Array(df.columns.names()[i], v)));
|
|
41
|
+
return posDF;
|
|
44
42
|
}
|
|
45
43
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Formats an adjacency matrix into <category1>-<category2>-<value> format.
|
|
46
|
+
*
|
|
47
|
+
* @param {DG.DataFrame} adjMatrix A data matrix to deal with.
|
|
48
|
+
* @return {DG.DataFrame} The resulting data frame.
|
|
49
|
+
*/
|
|
50
|
+
function createNetwork(adjMatrix: DG.DataFrame): DG.DataFrame {
|
|
51
|
+
const nCols = adjMatrix.columns.length;
|
|
52
|
+
const nRows = adjMatrix.rowCount;
|
|
50
53
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
assert(nCols == nRows);
|
|
55
|
+
|
|
56
|
+
const pos1: Array<number> = [];
|
|
57
|
+
const pos2: Array<number> = [];
|
|
58
|
+
const weight: Array<number> = [];
|
|
59
|
+
|
|
60
|
+
for (let i = 0; i < nCols; ++i) {
|
|
61
|
+
const c = adjMatrix.columns.byIndex(i);
|
|
62
|
+
|
|
63
|
+
for (let j = i+1; j < nRows; ++j) {
|
|
64
|
+
const r = c.getRawData()[j];
|
|
65
|
+
|
|
66
|
+
if (Math.abs(r) > 0) {
|
|
67
|
+
pos1.push(i+1);
|
|
68
|
+
pos2.push(j+1);
|
|
69
|
+
weight.push(r);
|
|
70
|
+
}
|
|
55
71
|
}
|
|
56
72
|
}
|
|
57
|
-
|
|
58
|
-
|
|
73
|
+
|
|
74
|
+
const pos1Col = DG.Column.fromList('int', 'pos1', pos1);
|
|
75
|
+
const pos2Col = DG.Column.fromList('int', 'pos2', pos2);
|
|
76
|
+
const weightCol = DG.Column.fromList('double', 'weight', weight);
|
|
77
|
+
|
|
78
|
+
return DG.DataFrame.fromColumns([pos1Col, pos2Col, weightCol]);
|
|
79
|
+
}
|
|
59
80
|
|
|
60
81
|
/**
|
|
61
|
-
* Calculates
|
|
82
|
+
* Calculates Kendall's tau rank correlation matrix.
|
|
62
83
|
*
|
|
63
|
-
* @export
|
|
64
84
|
* @param {DG.DataFrame} df A data frame to process.
|
|
85
|
+
* @param {number} [alpha=0.05] The significance threshold.
|
|
86
|
+
* @param {number} [rAbsCutoff=0.5] The absolute R cutoff.
|
|
65
87
|
* @return {DG.DataFrame} The correlation matrix.
|
|
66
88
|
*/
|
|
67
|
-
|
|
89
|
+
function calcKendallTauMatrix(df: DG.DataFrame, alpha: number = 0.05, rAbsCutoff = 0.5): DG.DataFrame {
|
|
68
90
|
const nItems = df.columns.length;
|
|
69
|
-
const
|
|
91
|
+
const tau = new Array(nItems).fill(0).map((_) => new Float32Array(nItems).fill(0));
|
|
70
92
|
|
|
71
93
|
for (let i = 0; i < nItems; ++i) {
|
|
72
94
|
for (let j = i+1; j < nItems; ++j) {
|
|
73
|
-
|
|
74
|
-
|
|
95
|
+
const res = kendallsTau(df.columns.byIndex(i).getRawData(), df.columns.byIndex(j).getRawData());
|
|
96
|
+
tau[i][j] = (res.prob < alpha) && (Math.abs(res.test) >= rAbsCutoff) ? res.test : 0;
|
|
97
|
+
tau[j][i] = tau[i][j];
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return matrix2DataFrame(tau);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Calculates a correlation matrix via method chosen.
|
|
105
|
+
*
|
|
106
|
+
* @param {DG.DataFrame} df A data frame.
|
|
107
|
+
* @return {DG.DataFrame} The correlation matrix.
|
|
108
|
+
*/
|
|
109
|
+
function calcCorrelationMatrix(df: DG.DataFrame): DG.DataFrame {
|
|
110
|
+
return calcKendallTauMatrix(df);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
type Weights = {[pos: number]: number};
|
|
114
|
+
type Guide = {[pos: number]: Weights};
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Calculates a dictionary with the keys containing the first correlating positions.
|
|
118
|
+
* Values correspond to a dictionary containing the positions and corresponding R-value
|
|
119
|
+
* which the given position correlating with.
|
|
120
|
+
*
|
|
121
|
+
* @param {DG.DataFrame} network A network to process.
|
|
122
|
+
* @return {Guide} The formatted dictionary.
|
|
123
|
+
*/
|
|
124
|
+
function calcGuide(network: DG.DataFrame): Guide {
|
|
125
|
+
assert(network.columns.length == 3);
|
|
126
|
+
|
|
127
|
+
const guide: Guide = {};
|
|
128
|
+
let [pos1Col, pos2Col, weightCol] = Array.from(network.columns);
|
|
129
|
+
|
|
130
|
+
pos1Col = pos1Col.getRawData();
|
|
131
|
+
pos2Col = pos2Col.getRawData();
|
|
132
|
+
weightCol = weightCol.getRawData();
|
|
133
|
+
|
|
134
|
+
function _addWeight(pos1: number, pos2: number, weight: number) {
|
|
135
|
+
if (guide[pos1] == undefined) {
|
|
136
|
+
guide[pos1] = {};
|
|
75
137
|
}
|
|
138
|
+
guide[pos1][pos2] = weight;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
for (let i = 0; i < network.rowCount; ++i) {
|
|
142
|
+
const [pos1, pos2, weight] = [pos1Col[i], pos2Col[i], weightCol[i]];
|
|
143
|
+
_addWeight(pos1, pos2, weight);
|
|
144
|
+
_addWeight(pos2, pos1, weight);
|
|
76
145
|
}
|
|
77
|
-
return
|
|
146
|
+
return guide;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function calcCorrelations(df: DG.DataFrame, positionColumns?: string[]): Guide {
|
|
150
|
+
const posDF = encodeSequences(df, positionColumns);
|
|
151
|
+
const ccDF = calcCorrelationMatrix(posDF);
|
|
152
|
+
const nwDF = createNetwork(ccDF);
|
|
153
|
+
const guide = calcGuide(nwDF);
|
|
154
|
+
return guide;
|
|
78
155
|
}
|
|
79
156
|
|
|
80
157
|
/**
|
|
81
|
-
*
|
|
158
|
+
* Formats correlating positions to place in the corresponding tooltips.
|
|
159
|
+
* Higlights correlating positions' headers.
|
|
82
160
|
*
|
|
83
161
|
* @export
|
|
84
|
-
* @
|
|
85
|
-
* @return {[DG.Viewer, DG.Viewer]} These two plots.
|
|
162
|
+
* @class CorrelationAnalysisVisualizer
|
|
86
163
|
*/
|
|
87
|
-
export
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
164
|
+
export class CorrelationAnalysisVisualizer {
|
|
165
|
+
protected guide: Guide;
|
|
166
|
+
protected highlightedColumns: number[];
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Creates an instance of CorrelationAnalysisVisualizer.
|
|
170
|
+
* @param {DG.DataFrame} df A data frame to take sequences from.
|
|
171
|
+
* @param {string[]} positionColumns Optional columns list to take the sequences from.
|
|
172
|
+
* @memberof CorrelationAnalysisVisualizer
|
|
173
|
+
*/
|
|
174
|
+
constructor(df: DG.DataFrame, positionColumns: string[]) {
|
|
175
|
+
if (df) {
|
|
176
|
+
this.guide = calcCorrelations(df, positionColumns);
|
|
177
|
+
this.highlightedColumns = Object.keys(this.guide).map((v) => parseInt(v));
|
|
178
|
+
} else {
|
|
179
|
+
throw new Error('Dataframe was not found in the grid.');
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Returns a dictionary with the correlating positions and their R-value.
|
|
185
|
+
*
|
|
186
|
+
* @readonly
|
|
187
|
+
* @type {Guide} The dictionary.
|
|
188
|
+
* @memberof CorrelationAnalysisVisualizer
|
|
189
|
+
*/
|
|
190
|
+
get path(): Guide {
|
|
191
|
+
return this.guide;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Checks if the position column name is found among correlelating ones.
|
|
196
|
+
*
|
|
197
|
+
* @param {string} name The name of the column.
|
|
198
|
+
* @return {boolean} True if the position is correlating with any oter.
|
|
199
|
+
* @memberof CorrelationAnalysisVisualizer
|
|
200
|
+
*/
|
|
201
|
+
public isPositionCorrelating(name: string): boolean {
|
|
202
|
+
return this.highlightedColumns.includes(parseInt(name));
|
|
203
|
+
}
|
|
109
204
|
}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
/* Do not change these import lines. Datagrok will import API library in exactly the same manner */
|
|
2
|
-
// eslint-disable-next-line no-unused-vars
|
|
3
|
-
import * as grok from 'datagrok-api/grok';
|
|
4
2
|
import * as ui from 'datagrok-api/ui';
|
|
5
3
|
import * as DG from 'datagrok-api/dg';
|
|
6
4
|
|
|
@@ -8,16 +6,16 @@ import {getSequenceMolecularWeight} from './molecular-measure';
|
|
|
8
6
|
import {AlignedSequenceEncoder} from '@datagrok-libraries/utils/src/sequence-encoder';
|
|
9
7
|
import {DimensionalityReducer} from '@datagrok-libraries/utils/src/reduce-dimensionality';
|
|
10
8
|
import {Measurer} from '@datagrok-libraries/utils/src/string-measure';
|
|
11
|
-
import {Coordinates} from '@datagrok-libraries/utils/src/
|
|
9
|
+
import {Coordinates} from '@datagrok-libraries/utils/src/type-declarations';
|
|
12
10
|
|
|
13
11
|
/**
|
|
14
|
-
*
|
|
12
|
+
* A worker to perform dimensionality reduction.
|
|
15
13
|
*
|
|
16
|
-
* @param {any[]} columnData
|
|
17
|
-
* @param {string} method
|
|
18
|
-
* @param {string} measure
|
|
19
|
-
* @param {number} cyclesCount Number of
|
|
20
|
-
* @return {Promise<unknown>}
|
|
14
|
+
* @param {any[]} columnData The data to process.
|
|
15
|
+
* @param {string} method A method of dimensionality reduction.
|
|
16
|
+
* @param {string} measure A distance metrics.
|
|
17
|
+
* @param {number} cyclesCount Number of iterations to run.
|
|
18
|
+
* @return {Promise<unknown>} Resulting embedding.
|
|
21
19
|
*/
|
|
22
20
|
function createDimensinalityReducingWorker(
|
|
23
21
|
columnData: any[],
|
|
@@ -49,7 +47,6 @@ function inferActivityColumnsName(table: DG.DataFrame): string | null {
|
|
|
49
47
|
const re = /activity|ic50/i;
|
|
50
48
|
for (const name of table.columns.names()) {
|
|
51
49
|
if (name.match(re)) {
|
|
52
|
-
console.log(`${name} found.`);
|
|
53
50
|
return name;
|
|
54
51
|
}
|
|
55
52
|
}
|
|
@@ -65,6 +62,7 @@ function inferActivityColumnsName(table: DG.DataFrame): string | null {
|
|
|
65
62
|
* @param {string} method Embedding method to apply.
|
|
66
63
|
* @param {string} measure Distance metric.
|
|
67
64
|
* @param {number} cyclesCount Number of cycles to repeat.
|
|
65
|
+
* @param {(DG.TableView | null)} view View to add scatter plot to
|
|
68
66
|
* @param {(string | null)} [activityColumnName] Activity containing column to assign it to points radius.
|
|
69
67
|
* @param {boolean} [zoom=false] Whether to fit view.
|
|
70
68
|
* @return {Promise<DG.ScatterPlotViewer>} A viewer.
|
|
@@ -75,6 +73,7 @@ export async function createPeptideSimilaritySpaceViewer(
|
|
|
75
73
|
method: string,
|
|
76
74
|
measure: string,
|
|
77
75
|
cyclesCount: number,
|
|
76
|
+
view: DG.TableView | null,
|
|
78
77
|
activityColumnName?: string | null,
|
|
79
78
|
zoom: boolean = false,
|
|
80
79
|
): Promise<DG.ScatterPlotViewer> {
|
|
@@ -110,24 +109,25 @@ export async function createPeptideSimilaritySpaceViewer(
|
|
|
110
109
|
// Add new axes.
|
|
111
110
|
for (const axis of axesNames) {
|
|
112
111
|
const col = table.col(axis);
|
|
112
|
+
const newCol = edf.getCol(axis);
|
|
113
113
|
|
|
114
|
-
if (col
|
|
115
|
-
|
|
114
|
+
if (col != null) {
|
|
115
|
+
for (let i = 0; i < newCol.length; ++i) {
|
|
116
|
+
const v = newCol.get(i);
|
|
117
|
+
table.set(axis, i, v);
|
|
118
|
+
}
|
|
116
119
|
} else {
|
|
117
|
-
table.columns.
|
|
120
|
+
table.columns.insert(newCol);
|
|
118
121
|
}
|
|
119
122
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
table.getCol('~Y').max,
|
|
129
|
-
);
|
|
130
|
-
}*/
|
|
123
|
+
|
|
124
|
+
const viewerOptions = {x: '~X', y: '~Y', color: activityColumnName ?? '~MW', size: '~MW'};
|
|
125
|
+
const viewer = DG.Viewer.scatterPlot(table, viewerOptions);
|
|
126
|
+
|
|
127
|
+
if (view !== null) {
|
|
128
|
+
view.addViewer(viewer);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
131
|
pi.close();
|
|
132
132
|
return viewer;
|
|
133
133
|
}
|
|
@@ -147,13 +147,15 @@ export class PeptideSimilaritySpaceWidget {
|
|
|
147
147
|
protected availableMethods: string[];
|
|
148
148
|
protected availableMetrics: string[];
|
|
149
149
|
protected viewer: HTMLElement;
|
|
150
|
+
view: DG.TableView;
|
|
150
151
|
|
|
151
152
|
/**
|
|
152
153
|
* Creates an instance of PeptideSimilaritySpaceWidget.
|
|
153
154
|
* @param {DG.Column} alignedSequencesColumn The column to get amino acid sequences from.
|
|
155
|
+
* @param {DG.TableView} view Current view
|
|
154
156
|
* @memberof PeptideSimilaritySpaceWidget
|
|
155
157
|
*/
|
|
156
|
-
constructor(alignedSequencesColumn: DG.Column) {
|
|
158
|
+
constructor(alignedSequencesColumn: DG.Column, view: DG.TableView) {
|
|
157
159
|
this.availableMethods = DimensionalityReducer.availableMethods;
|
|
158
160
|
this.availableMetrics = Measurer.availableMeasures;
|
|
159
161
|
this.method = this.availableMethods[0];
|
|
@@ -161,6 +163,7 @@ export class PeptideSimilaritySpaceWidget {
|
|
|
161
163
|
this.currentDf = alignedSequencesColumn.dataFrame;
|
|
162
164
|
this.alignedSequencesColumn = alignedSequencesColumn;
|
|
163
165
|
this.viewer = ui.div([]);
|
|
166
|
+
this.view = view;
|
|
164
167
|
}
|
|
165
168
|
|
|
166
169
|
/**
|
|
@@ -177,6 +180,7 @@ export class PeptideSimilaritySpaceWidget {
|
|
|
177
180
|
this.metrics,
|
|
178
181
|
this.cycles,
|
|
179
182
|
null,
|
|
183
|
+
null,
|
|
180
184
|
true,
|
|
181
185
|
);
|
|
182
186
|
viewer.root.style.width = 'auto';
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import * as DG from 'datagrok-api/dg';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Split aligned sequence string into separate parts containing amino acid residues.
|
|
5
|
+
*
|
|
6
|
+
* @export
|
|
7
|
+
* @param {DG.Column} peptideColumn Column containing aligned sequences.
|
|
8
|
+
* @param {boolean} [filter=true] Filter out columns with all the same residues.
|
|
9
|
+
* @return {[DG.DataFrame, number[]]} DataFrame containing split sequence and a list of invalid indexes.
|
|
10
|
+
*/
|
|
3
11
|
export function splitAlignedPeptides(peptideColumn: DG.Column, filter: boolean = true): [DG.DataFrame, number[]] {
|
|
4
12
|
const splitPeptidesArray: string[][] = [];
|
|
5
13
|
let currentSplitPeptide: string[];
|
|
@@ -45,7 +53,6 @@ export function splitAlignedPeptides(peptideColumn: DG.Column, filter: boolean =
|
|
|
45
53
|
columnNames.push('C-terminal');
|
|
46
54
|
|
|
47
55
|
// filter out the columns with the same values
|
|
48
|
-
|
|
49
56
|
if (filter) {
|
|
50
57
|
splitColumns = splitColumns.filter((positionArray, index) => {
|
|
51
58
|
const isRetained = new Set(positionArray).size > 1;
|
|
@@ -7,6 +7,13 @@ import * as logojs from 'logojs-react';
|
|
|
7
7
|
import {splitAlignedPeptides} from '../utils/split-aligned';
|
|
8
8
|
import {ChemPalette} from '../utils/chem-palette';
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Logo viewer.
|
|
12
|
+
*
|
|
13
|
+
* @export
|
|
14
|
+
* @class Logo
|
|
15
|
+
* @extends {DG.JsViewer}
|
|
16
|
+
*/
|
|
10
17
|
export class Logo extends DG.JsViewer {
|
|
11
18
|
initialized: boolean;
|
|
12
19
|
option: any;
|
|
@@ -18,6 +25,11 @@ export class Logo extends DG.JsViewer {
|
|
|
18
25
|
LET_COLORS: Array<any>;
|
|
19
26
|
target: DG.DataFrame | undefined | null;
|
|
20
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Creates an instance of Logo.
|
|
30
|
+
*
|
|
31
|
+
* @memberof Logo
|
|
32
|
+
*/
|
|
21
33
|
constructor() {
|
|
22
34
|
super();
|
|
23
35
|
this.initialized = false;
|
|
@@ -59,9 +71,13 @@ export class Logo extends DG.JsViewer {
|
|
|
59
71
|
];
|
|
60
72
|
}
|
|
61
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Initializer function.
|
|
76
|
+
*
|
|
77
|
+
* @memberof Logo
|
|
78
|
+
*/
|
|
62
79
|
init() {
|
|
63
80
|
this.initialized = true;
|
|
64
|
-
// this.reactHost = ui.div([]);
|
|
65
81
|
console.log('INIT');
|
|
66
82
|
this.target = this.dataFrame;
|
|
67
83
|
[this.splitted] = splitAlignedPeptides(this.dataFrame!.columns.bySemType(this.colSemType));
|
|
@@ -70,6 +86,11 @@ export class Logo extends DG.JsViewer {
|
|
|
70
86
|
this.root.style.maxHeight = '200px';
|
|
71
87
|
}
|
|
72
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Function to execute when the table is attached.
|
|
91
|
+
*
|
|
92
|
+
* @memberof Logo
|
|
93
|
+
*/
|
|
73
94
|
onTableAttached() {
|
|
74
95
|
if (typeof this.dataFrame !== 'undefined') {
|
|
75
96
|
if (!this.initialized) {
|
|
@@ -84,16 +105,32 @@ export class Logo extends DG.JsViewer {
|
|
|
84
105
|
this.render();
|
|
85
106
|
}
|
|
86
107
|
|
|
108
|
+
/**
|
|
109
|
+
* Function that is executed when the viewer is detached.
|
|
110
|
+
*
|
|
111
|
+
* @memberof Logo
|
|
112
|
+
*/
|
|
87
113
|
detach() {
|
|
88
114
|
this.subs.forEach((sub) => sub.unsubscribe());
|
|
89
115
|
}
|
|
90
116
|
|
|
117
|
+
/**
|
|
118
|
+
* Function that is executed when the viewer property is changed.
|
|
119
|
+
*
|
|
120
|
+
* @param {DG.Property} property
|
|
121
|
+
* @memberof Logo
|
|
122
|
+
*/
|
|
91
123
|
onPropertyChanged(property: DG.Property) {
|
|
92
124
|
super.onPropertyChanged(property);
|
|
93
125
|
|
|
94
126
|
this.render();
|
|
95
127
|
}
|
|
96
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Function that renders the viewer.
|
|
131
|
+
*
|
|
132
|
+
* @memberof Logo
|
|
133
|
+
*/
|
|
97
134
|
async render() {
|
|
98
135
|
const bits = this.dataFrame!.selection;
|
|
99
136
|
let selected = false;
|
|
@@ -111,18 +148,24 @@ export class Logo extends DG.JsViewer {
|
|
|
111
148
|
|
|
112
149
|
if (typeof this.dataFrame !== 'undefined') {
|
|
113
150
|
this.findLogo();
|
|
114
|
-
|
|
115
|
-
// if (this.reactHost !== null) {
|
|
116
|
-
// this.root.appendChild(this.reactHost);
|
|
117
|
-
// }
|
|
118
151
|
}
|
|
119
152
|
}
|
|
120
153
|
|
|
154
|
+
/**
|
|
155
|
+
* Create logo.
|
|
156
|
+
*
|
|
157
|
+
* @memberof Logo
|
|
158
|
+
*/
|
|
121
159
|
async findLogo() {
|
|
122
160
|
this.getInfoFromDf();
|
|
123
161
|
logojs.embedProteinLogo(this.root, {alphabet: this.LET_COLORS, ppm: this.ppm});
|
|
124
162
|
}
|
|
125
163
|
|
|
164
|
+
/**
|
|
165
|
+
* Retrieves information for building logo from the dataframe.
|
|
166
|
+
*
|
|
167
|
+
* @memberof Logo
|
|
168
|
+
*/
|
|
126
169
|
getInfoFromDf() {
|
|
127
170
|
let index: number = 0;
|
|
128
171
|
this.ppm = [];
|
package/src/viewers/model.ts
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
import * as DG from 'datagrok-api/dg';
|
|
2
2
|
|
|
3
3
|
import {describe} from '../describe';
|
|
4
|
-
import {
|
|
4
|
+
import {Subject} from 'rxjs';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Model class for SAR viewers that retrieves and stores data.
|
|
8
|
+
*
|
|
9
|
+
* @class SARViewerModel
|
|
10
|
+
*/
|
|
6
11
|
class SARViewerModel {
|
|
7
12
|
private viewerGrid: Subject<DG.Grid> = new Subject<DG.Grid>();
|
|
8
13
|
private viewerVGrid: Subject<DG.Grid> = new Subject<DG.Grid>();
|
|
9
14
|
private statsDf: Subject<DG.DataFrame> = new Subject<DG.DataFrame>();
|
|
10
|
-
|
|
11
|
-
public
|
|
12
|
-
public
|
|
15
|
+
private groupMapping: Subject<{[key: string]: string}> = new Subject<{[key: string]: string}>();
|
|
16
|
+
public viewerGrid$;
|
|
17
|
+
public viewerVGrid$;
|
|
18
|
+
public statsDf$;
|
|
19
|
+
public groupMapping$;
|
|
13
20
|
private dataFrame: DG.DataFrame | null;
|
|
14
21
|
private activityColumn: string | null;
|
|
15
22
|
private activityScaling: string | null;
|
|
@@ -17,7 +24,13 @@ class SARViewerModel {
|
|
|
17
24
|
private twoColorMode: boolean | null;
|
|
18
25
|
private initialBitset: DG.BitSet | null;
|
|
19
26
|
private isUpdating = false;
|
|
27
|
+
grouping: boolean;
|
|
20
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Creates an instance of SARViewerModel.
|
|
31
|
+
*
|
|
32
|
+
* @memberof SARViewerModel
|
|
33
|
+
*/
|
|
21
34
|
constructor() {
|
|
22
35
|
this.dataFrame = null;
|
|
23
36
|
this.activityColumn = null;
|
|
@@ -25,39 +38,66 @@ class SARViewerModel {
|
|
|
25
38
|
this.sourceGrid = null;
|
|
26
39
|
this.twoColorMode = null;
|
|
27
40
|
this.initialBitset = null;
|
|
41
|
+
this.grouping = false;
|
|
42
|
+
this.viewerGrid$ = this.viewerGrid.asObservable();
|
|
43
|
+
this.viewerVGrid$ = this.viewerVGrid.asObservable();
|
|
44
|
+
this.statsDf$ = this.statsDf.asObservable();
|
|
45
|
+
this.groupMapping$ = this.groupMapping.asObservable();
|
|
28
46
|
}
|
|
29
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Updates data with using specified parameters.
|
|
50
|
+
*
|
|
51
|
+
* @param {DG.DataFrame} df Working table.
|
|
52
|
+
* @param {string} activityCol Activity column name.
|
|
53
|
+
* @param {string} activityScaling Activity scaling method.
|
|
54
|
+
* @param {DG.Grid} sourceGrid Working table grid.
|
|
55
|
+
* @param {boolean} twoColorMode Bidirectional analysis enabled.
|
|
56
|
+
* @param {(DG.BitSet | null)} initialBitset Initial bitset.
|
|
57
|
+
* @param {boolean} grouping Grouping enabled.
|
|
58
|
+
* @memberof SARViewerModel
|
|
59
|
+
*/
|
|
30
60
|
async updateData(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
61
|
+
df: DG.DataFrame,
|
|
62
|
+
activityCol: string,
|
|
63
|
+
activityScaling: string,
|
|
64
|
+
sourceGrid: DG.Grid,
|
|
65
|
+
twoColorMode: boolean,
|
|
66
|
+
initialBitset: DG.BitSet | null,
|
|
67
|
+
grouping: boolean,
|
|
68
|
+
) {
|
|
38
69
|
this.dataFrame = df;
|
|
39
70
|
this.activityColumn = activityCol;
|
|
40
71
|
this.activityScaling = activityScaling;
|
|
41
72
|
this.sourceGrid = sourceGrid;
|
|
42
73
|
this.twoColorMode = twoColorMode;
|
|
43
74
|
this.initialBitset = initialBitset;
|
|
75
|
+
this.grouping = grouping;
|
|
44
76
|
await this.updateDefault();
|
|
45
77
|
}
|
|
46
78
|
|
|
79
|
+
/**
|
|
80
|
+
* Update data using current parameters.
|
|
81
|
+
*
|
|
82
|
+
* @memberof SARViewerModel
|
|
83
|
+
*/
|
|
47
84
|
async updateDefault() {
|
|
48
|
-
if (
|
|
85
|
+
if (
|
|
86
|
+
this.dataFrame && this.activityColumn && this.activityScaling &&
|
|
87
|
+
this.sourceGrid && this.twoColorMode !== null && !this.isUpdating
|
|
88
|
+
) {
|
|
49
89
|
this.isUpdating = true;
|
|
50
|
-
const [viewerGrid, viewerVGrid, statsDf] = await describe(
|
|
90
|
+
const [viewerGrid, viewerVGrid, statsDf, groupMapping] = await describe(
|
|
51
91
|
this.dataFrame, this.activityColumn, this.activityScaling,
|
|
52
|
-
this.sourceGrid, this.twoColorMode, this.initialBitset
|
|
92
|
+
this.sourceGrid, this.twoColorMode, this.initialBitset, this.grouping,
|
|
53
93
|
);
|
|
54
94
|
this.viewerGrid.next(viewerGrid);
|
|
55
95
|
this.viewerVGrid.next(viewerVGrid);
|
|
56
96
|
this.statsDf.next(statsDf);
|
|
97
|
+
this.groupMapping.next(groupMapping);
|
|
57
98
|
this.isUpdating = false;
|
|
58
99
|
}
|
|
59
100
|
}
|
|
60
101
|
}
|
|
61
102
|
|
|
62
|
-
export
|
|
63
|
-
|
|
103
|
+
export const model = new SARViewerModel();
|