@datagrok/peptides 0.8.13 → 1.0.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/.eslintrc.json +5 -2
- package/dist/package-test.js +1268 -1766
- package/dist/package.js +1097 -1622
- package/dist/vendors-node_modules_datagrok-libraries_ml_src_workers_dimensionality-reducer_js.js +120 -62
- package/package.json +13 -17
- package/package.png +0 -0
- package/src/model.ts +504 -448
- package/src/monomer-library.ts +31 -30
- package/src/package-test.ts +5 -6
- package/src/package.ts +52 -70
- package/src/tests/core.ts +67 -0
- package/src/tests/msa-tests.ts +3 -3
- package/src/tests/peptide-space-test.ts +65 -45
- package/src/tests/utils.ts +20 -50
- package/src/utils/cell-renderer.ts +25 -151
- package/src/utils/chem-palette.ts +3 -14
- package/src/utils/constants.ts +5 -0
- package/src/utils/filtering-statistics.ts +2 -2
- package/src/utils/misc.ts +29 -0
- package/src/utils/multiple-sequence-alignment.ts +5 -18
- package/src/utils/multivariate-analysis.ts +5 -8
- package/src/utils/peptide-similarity-space.ts +12 -9
- package/src/utils/types.ts +5 -2
- package/src/viewers/peptide-space-viewer.ts +67 -39
- package/src/viewers/sar-viewer.ts +34 -37
- package/src/viewers/stacked-barchart-viewer.ts +38 -61
- package/src/widgets/analyze-peptides.ts +53 -75
- package/src/widgets/distribution.ts +34 -18
- package/src/widgets/manual-alignment.ts +8 -12
- package/src/widgets/peptide-molecule.ts +48 -25
- package/src/widgets/subst-table.ts +53 -52
- package/src/workers/dimensionality-reducer.ts +8 -13
- package/{test-Peptides-f8114def7953-4bf59d70.html → test-Peptides-69a4761f6044-40ac3a0c.html} +2 -2
- package/src/peptides.ts +0 -327
- package/src/semantics.ts +0 -5
- package/src/tests/peptides-tests.ts +0 -60
- package/src/utils/SAR-multiple-filter.ts +0 -439
- package/src/utils/SAR-multiple-selection.ts +0 -177
- package/src/viewers/logo-viewer.ts +0 -195
package/src/tests/utils.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {expect} from '@datagrok-libraries/utils/src/test';
|
|
|
4
4
|
import {PeptideSimilaritySpaceWidget, createPeptideSimilaritySpaceViewer} from '../utils/peptide-similarity-space';
|
|
5
5
|
import {
|
|
6
6
|
createDimensinalityReducingWorker,
|
|
7
|
+
IReduceDimensionalityResult,
|
|
7
8
|
} from '@datagrok-libraries/ml/src/workers/dimensionality-reducing-worker-creator';
|
|
8
9
|
import {runKalign} from '../utils/multiple-sequence-alignment';
|
|
9
10
|
import {StringMetrics} from '@datagrok-libraries/ml/src/typed-metrics';
|
|
@@ -13,7 +14,7 @@ import {StringMetrics} from '@datagrok-libraries/ml/src/typed-metrics';
|
|
|
13
14
|
*
|
|
14
15
|
* @param {DG.DataFrame} table Target table.
|
|
15
16
|
*/
|
|
16
|
-
export function _testTableIsNotEmpty(table: DG.DataFrame) {
|
|
17
|
+
export function _testTableIsNotEmpty(table: DG.DataFrame): void {
|
|
17
18
|
expect(table.columns.length > 0 && table.rowCount > 0, true);
|
|
18
19
|
}
|
|
19
20
|
|
|
@@ -23,16 +24,9 @@ export function _testTableIsNotEmpty(table: DG.DataFrame) {
|
|
|
23
24
|
* @param {DG.DataFrame} table Demo table.
|
|
24
25
|
* @param {DG.TableView} view Demo view.
|
|
25
26
|
*/
|
|
26
|
-
export async function _testViewerIsDrawing(table: DG.DataFrame, view: DG.TableView) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
try {
|
|
30
|
-
const widget = new PeptideSimilaritySpaceWidget(table.getCol('AlignedSequence'), view);
|
|
31
|
-
await widget.draw();
|
|
32
|
-
} catch (error) {
|
|
33
|
-
noException = false;
|
|
34
|
-
}
|
|
35
|
-
expect(noException, true);
|
|
27
|
+
export async function _testViewerIsDrawing(table: DG.DataFrame, view: DG.TableView): Promise<void> {
|
|
28
|
+
const widget = new PeptideSimilaritySpaceWidget(table.getCol('AlignedSequence'), view);
|
|
29
|
+
await widget.draw();
|
|
36
30
|
}
|
|
37
31
|
|
|
38
32
|
/**
|
|
@@ -42,18 +36,14 @@ export async function _testViewerIsDrawing(table: DG.DataFrame, view: DG.TableVi
|
|
|
42
36
|
* @param {string} method Embedding method.
|
|
43
37
|
* @param {string} measure Measure to apply to a pair of strings.
|
|
44
38
|
*/
|
|
45
|
-
export async function _testDimensionalityReducer(
|
|
46
|
-
|
|
39
|
+
export async function _testDimensionalityReducer(
|
|
40
|
+
columnData: Array<string>, method: StringMetrics, measure: string): Promise<void> {
|
|
47
41
|
const cyclesCount = 100;
|
|
48
42
|
let embcols;
|
|
49
43
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
} catch (error) {
|
|
54
|
-
noException = false;
|
|
55
|
-
}
|
|
56
|
-
expect(noException, true);
|
|
44
|
+
const reduceDimRes: IReduceDimensionalityResult = await createDimensinalityReducingWorker(
|
|
45
|
+
{data: columnData, metric: measure as StringMetrics}, method, {cycles: cyclesCount});
|
|
46
|
+
embcols = reduceDimRes.embedding;
|
|
57
47
|
|
|
58
48
|
const [X, Y] = embcols as Array<Float32Array>;
|
|
59
49
|
|
|
@@ -73,39 +63,20 @@ export async function _testDimensionalityReducer(columnData: Array<string>, meth
|
|
|
73
63
|
* @param {(DG.TableView | null)} view Viewer to show graphics on.
|
|
74
64
|
* @param {(string | null)} [activityColumnName] Name of column with activity.
|
|
75
65
|
*/
|
|
76
|
-
export async function _testPeptideSimilaritySpaceViewer(
|
|
77
|
-
|
|
78
|
-
alignedSequencesColumn: DG.Column,
|
|
79
|
-
method: string,
|
|
80
|
-
measure: string,
|
|
81
|
-
cyclesCount: number,
|
|
82
|
-
) {
|
|
83
|
-
let noException = true;
|
|
66
|
+
export async function _testPeptideSimilaritySpaceViewer(table: DG.DataFrame, alignedSequencesColumn: DG.Column,
|
|
67
|
+
method: string, measure: string, cyclesCount: number): Promise<void> {
|
|
84
68
|
let viewer;
|
|
85
69
|
let df: DG.DataFrame;
|
|
86
70
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
df = viewer.dataFrame!;
|
|
91
|
-
} catch (error) {
|
|
92
|
-
noException = false;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
expect(noException, true);
|
|
71
|
+
viewer = await createPeptideSimilaritySpaceViewer(
|
|
72
|
+
table, method, measure, cyclesCount, undefined, alignedSequencesColumn);
|
|
73
|
+
df = viewer.dataFrame;
|
|
96
74
|
|
|
97
|
-
|
|
75
|
+
const axesNames = ['~X', '~Y', '~MW'];
|
|
76
|
+
const axes = axesNames.map((v) => df.getCol(v).getRawData() as Float32Array);
|
|
98
77
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const axes = axesNames.map((v) => df?.getCol(v).getRawData() as Float32Array);
|
|
102
|
-
|
|
103
|
-
for (const ax of axes)
|
|
104
|
-
expect(ax.every((v) => v !== null && v !== NaN), true);
|
|
105
|
-
} catch (error) {
|
|
106
|
-
noException = false;
|
|
107
|
-
}
|
|
108
|
-
expect(noException, true);
|
|
78
|
+
for (const ax of axes)
|
|
79
|
+
expect(ax.every((v) => v !== null && v !== NaN), true);
|
|
109
80
|
}
|
|
110
81
|
|
|
111
82
|
/**
|
|
@@ -114,8 +85,7 @@ export async function _testPeptideSimilaritySpaceViewer(
|
|
|
114
85
|
* @export
|
|
115
86
|
* @param {DG.Column} col Aligned sequences column.
|
|
116
87
|
*/
|
|
117
|
-
export async function _testMSAIsCorrect(col: DG.Column) {
|
|
88
|
+
export async function _testMSAIsCorrect(col: DG.Column): Promise<void> {
|
|
118
89
|
const msaCol = await runKalign(col, true);
|
|
119
90
|
expect(msaCol.toList().every((v, i) => v == col.get(i)), true);
|
|
120
91
|
}
|
|
121
|
-
|
|
@@ -2,6 +2,7 @@ import {ChemPalette} from './chem-palette';
|
|
|
2
2
|
import * as DG from 'datagrok-api/dg';
|
|
3
3
|
|
|
4
4
|
import * as C from './constants';
|
|
5
|
+
import {getSeparator} from './misc';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* A function to expand column size based on its contents.
|
|
@@ -18,7 +19,7 @@ import * as C from './constants';
|
|
|
18
19
|
export function expandColumn(
|
|
19
20
|
col: DG.Column, grid: DG.Grid, cellRenderSize: (cellVal: string) => number,
|
|
20
21
|
textSizeMult = 10, minSize = 30, maxSize = 650, timeout = 500,
|
|
21
|
-
) {
|
|
22
|
+
): void {
|
|
22
23
|
let maxLen = 0;
|
|
23
24
|
col.categories.forEach((ent: string) => {
|
|
24
25
|
const len = cellRenderSize(ent);
|
|
@@ -39,7 +40,7 @@ export function expandColumn(
|
|
|
39
40
|
* @param {(DG.Grid | null)} [grid=null] Grid that contains the col column.
|
|
40
41
|
* @param {boolean} [grouping=false] Is grouping enabled.
|
|
41
42
|
*/
|
|
42
|
-
export function setAARRenderer(col: DG.Column, grid: DG.Grid | null = null, grouping = false) {
|
|
43
|
+
export function setAARRenderer(col: DG.Column, grid: DG.Grid | null = null, grouping = false): void {
|
|
43
44
|
col.semType = C.SEM_TYPES.AMINO_ACIDS;
|
|
44
45
|
col.setTag('cell.renderer', C.SEM_TYPES.AMINO_ACIDS);
|
|
45
46
|
if (grouping)
|
|
@@ -48,6 +49,7 @@ export function setAARRenderer(col: DG.Column, grid: DG.Grid | null = null, grou
|
|
|
48
49
|
if (grid)
|
|
49
50
|
expandColumn(col, grid, (ent) => measureAAR(ent));
|
|
50
51
|
}
|
|
52
|
+
|
|
51
53
|
/**
|
|
52
54
|
* A function to measure amino acid residue
|
|
53
55
|
*
|
|
@@ -81,7 +83,7 @@ function printLeftOrCentered(
|
|
|
81
83
|
x: number, y: number, w: number, h: number,
|
|
82
84
|
g: CanvasRenderingContext2D, s: string, color = ChemPalette.undefinedColor,
|
|
83
85
|
pivot: number = 0, left = false, hideMod = false, transparencyRate: number = 1.0,
|
|
84
|
-
) {
|
|
86
|
+
): number {
|
|
85
87
|
g.textAlign = 'start';
|
|
86
88
|
let colorPart = pivot == -1 ? s.substring(0) : s.substring(0, pivot);
|
|
87
89
|
if (colorPart.length == 1)
|
|
@@ -112,7 +114,7 @@ function printLeftOrCentered(
|
|
|
112
114
|
const colorTextSize = g.measureText(colorPart);
|
|
113
115
|
const dy = (textSize.fontBoundingBoxAscent + textSize.fontBoundingBoxDescent) / 2;
|
|
114
116
|
|
|
115
|
-
function draw(dx1: number, dx2: number) {
|
|
117
|
+
function draw(dx1: number, dx2: number): void {
|
|
116
118
|
g.fillStyle = color;
|
|
117
119
|
g.globalAlpha = transparencyRate;
|
|
118
120
|
g.fillText(colorPart, x + dx1, y + dy);
|
|
@@ -131,59 +133,17 @@ function printLeftOrCentered(
|
|
|
131
133
|
}
|
|
132
134
|
}
|
|
133
135
|
|
|
134
|
-
/**
|
|
135
|
-
* Amino acid residue cell renderer.
|
|
136
|
-
*
|
|
137
|
-
* @export
|
|
138
|
-
* @class AminoAcidsCellRenderer
|
|
139
|
-
* @extends {DG.GridCellRenderer}
|
|
140
|
-
*/
|
|
141
136
|
export class AminoAcidsCellRenderer extends DG.GridCellRenderer {
|
|
142
137
|
chemPalette: ChemPalette | null;
|
|
143
138
|
|
|
144
|
-
|
|
145
|
-
* Renderer name.
|
|
146
|
-
*
|
|
147
|
-
* @readonly
|
|
148
|
-
* @memberof AminoAcidsCellRenderer
|
|
149
|
-
*/
|
|
150
|
-
get name() {
|
|
151
|
-
return 'aminoAcidsCR';
|
|
152
|
-
}
|
|
139
|
+
get name(): string {return 'aminoAcidsCR';}
|
|
153
140
|
|
|
154
|
-
|
|
155
|
-
* Cell type.
|
|
156
|
-
*
|
|
157
|
-
* @readonly
|
|
158
|
-
* @memberof AminoAcidsCellRenderer
|
|
159
|
-
*/
|
|
160
|
-
get cellType() {
|
|
161
|
-
return C.SEM_TYPES.AMINO_ACIDS;
|
|
162
|
-
}
|
|
141
|
+
get cellType(): string {return C.SEM_TYPES.AMINO_ACIDS;}
|
|
163
142
|
|
|
164
|
-
|
|
165
|
-
* Cell height.
|
|
166
|
-
*
|
|
167
|
-
* @readonly
|
|
168
|
-
* @memberof AminoAcidsCellRenderer
|
|
169
|
-
*/
|
|
170
|
-
get defaultHeight() {
|
|
171
|
-
return 15;
|
|
172
|
-
}
|
|
143
|
+
get defaultHeight(): number {return 15;}
|
|
173
144
|
|
|
174
|
-
|
|
175
|
-
* Cell width.
|
|
176
|
-
*
|
|
177
|
-
* @readonly
|
|
178
|
-
* @memberof AminoAcidsCellRenderer
|
|
179
|
-
*/
|
|
180
|
-
get defaultWidth() {
|
|
181
|
-
return 30;
|
|
182
|
-
}
|
|
145
|
+
get defaultWidth(): number {return 30;}
|
|
183
146
|
|
|
184
|
-
/**
|
|
185
|
-
* Constructor.
|
|
186
|
-
*/
|
|
187
147
|
constructor() {
|
|
188
148
|
super();
|
|
189
149
|
this.chemPalette = null;
|
|
@@ -202,9 +162,7 @@ export class AminoAcidsCellRenderer extends DG.GridCellRenderer {
|
|
|
202
162
|
*/
|
|
203
163
|
render(
|
|
204
164
|
g: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, gridCell: DG.GridCell,
|
|
205
|
-
cellStyle: DG.GridCellStyle) {
|
|
206
|
-
// this.chemPalette ??= new ChemPalette('grok', gridCell.tableColumn?.getTag('groups') ? true : false);
|
|
207
|
-
|
|
165
|
+
cellStyle: DG.GridCellStyle): void {
|
|
208
166
|
y -= 2;
|
|
209
167
|
g.save();
|
|
210
168
|
g.beginPath();
|
|
@@ -222,53 +180,14 @@ export class AminoAcidsCellRenderer extends DG.GridCellRenderer {
|
|
|
222
180
|
}
|
|
223
181
|
}
|
|
224
182
|
|
|
225
|
-
/**
|
|
226
|
-
* Aligned sequence cell renderer.
|
|
227
|
-
*
|
|
228
|
-
* @export
|
|
229
|
-
* @class AlignedSequenceCellRenderer
|
|
230
|
-
* @extends {DG.GridCellRenderer}
|
|
231
|
-
*/
|
|
232
183
|
export class AlignedSequenceCellRenderer extends DG.GridCellRenderer {
|
|
233
|
-
|
|
234
|
-
* Renderer name.
|
|
235
|
-
*
|
|
236
|
-
* @readonly
|
|
237
|
-
* @memberof AlignedSequenceCellRenderer
|
|
238
|
-
*/
|
|
239
|
-
get name() {
|
|
240
|
-
return 'alignedSequenceCR';
|
|
241
|
-
}
|
|
184
|
+
get name(): string {return 'alignedSequenceCR';}
|
|
242
185
|
|
|
243
|
-
|
|
244
|
-
* Cell type.
|
|
245
|
-
*
|
|
246
|
-
* @readonly
|
|
247
|
-
* @memberof AlignedSequenceCellRenderer
|
|
248
|
-
*/
|
|
249
|
-
get cellType() {
|
|
250
|
-
return C.SEM_TYPES.ALIGNED_SEQUENCE;
|
|
251
|
-
}
|
|
186
|
+
get cellType(): string {return C.SEM_TYPES.ALIGNED_SEQUENCE;}
|
|
252
187
|
|
|
253
|
-
|
|
254
|
-
* Cell height.
|
|
255
|
-
*
|
|
256
|
-
* @readonly
|
|
257
|
-
* @memberof AlignedSequenceCellRenderer
|
|
258
|
-
*/
|
|
259
|
-
get defaultHeight() {
|
|
260
|
-
return 30;
|
|
261
|
-
}
|
|
188
|
+
get defaultHeight(): number {return 30;}
|
|
262
189
|
|
|
263
|
-
|
|
264
|
-
* Cell width.
|
|
265
|
-
*
|
|
266
|
-
* @readonly
|
|
267
|
-
* @memberof AlignedSequenceCellRenderer
|
|
268
|
-
*/
|
|
269
|
-
get defaultWidth() {
|
|
270
|
-
return 230;
|
|
271
|
-
}
|
|
190
|
+
get defaultWidth(): number {return 230;}
|
|
272
191
|
|
|
273
192
|
/**
|
|
274
193
|
* Cell renderer function.
|
|
@@ -285,7 +204,7 @@ export class AlignedSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
285
204
|
render(
|
|
286
205
|
g: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, gridCell: DG.GridCell,
|
|
287
206
|
cellStyle: DG.GridCellStyle,
|
|
288
|
-
) {
|
|
207
|
+
): void {
|
|
289
208
|
const grid = gridCell.grid;
|
|
290
209
|
const cell = gridCell.cell;
|
|
291
210
|
w = grid ? Math.min(grid.canvas.width - x, w) : g.canvas.width - x;
|
|
@@ -298,7 +217,7 @@ export class AlignedSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
298
217
|
const s: string = cell.value ?? '';
|
|
299
218
|
|
|
300
219
|
//TODO: can this be replaced/merged with splitSequence?
|
|
301
|
-
const subParts = s.split(
|
|
220
|
+
const subParts = s.split(getSeparator(cell.column));
|
|
302
221
|
const [text, simplified] = processSequence(subParts);
|
|
303
222
|
const textSize = g.measureText(text.join(''));
|
|
304
223
|
let x1 = Math.max(x, x + (w - textSize.width) / 2);
|
|
@@ -317,13 +236,6 @@ export class AlignedSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
317
236
|
}
|
|
318
237
|
}
|
|
319
238
|
|
|
320
|
-
/**
|
|
321
|
-
* Function for sequence processing.
|
|
322
|
-
*
|
|
323
|
-
* @export
|
|
324
|
-
* @param {string[]} subParts Sequence subparts.
|
|
325
|
-
* @return {[string[], boolean]}
|
|
326
|
-
*/
|
|
327
239
|
export function processSequence(subParts: string[]): [string[], boolean] {
|
|
328
240
|
const simplified = !subParts.some((amino, index) =>
|
|
329
241
|
amino.length > 1 &&
|
|
@@ -341,53 +253,14 @@ export function processSequence(subParts: string[]): [string[], boolean] {
|
|
|
341
253
|
return [text, simplified];
|
|
342
254
|
}
|
|
343
255
|
|
|
344
|
-
/**
|
|
345
|
-
* Aligned sequence difference cell renderer.
|
|
346
|
-
*
|
|
347
|
-
* @export
|
|
348
|
-
* @class AlignedSequenceDifferenceCellRenderer
|
|
349
|
-
* @extends {DG.GridCellRenderer}
|
|
350
|
-
*/
|
|
351
256
|
export class AlignedSequenceDifferenceCellRenderer extends DG.GridCellRenderer {
|
|
352
|
-
|
|
353
|
-
* Renderer name.
|
|
354
|
-
*
|
|
355
|
-
* @readonly
|
|
356
|
-
* @memberof AlignedSequenceDifferenceCellRenderer
|
|
357
|
-
*/
|
|
358
|
-
get name() {
|
|
359
|
-
return 'alignedSequenceDifferenceCR';
|
|
360
|
-
}
|
|
257
|
+
get name(): string {return 'alignedSequenceDifferenceCR';}
|
|
361
258
|
|
|
362
|
-
|
|
363
|
-
* Cell type.
|
|
364
|
-
*
|
|
365
|
-
* @readonly
|
|
366
|
-
* @memberof AlignedSequenceDifferenceCellRenderer
|
|
367
|
-
*/
|
|
368
|
-
get cellType() {
|
|
369
|
-
return 'alignedSequenceDifference';
|
|
370
|
-
}
|
|
259
|
+
get cellType(): string {return C.SEM_TYPES.ALIGNED_SEQUENCE_DIFFERENCE;}
|
|
371
260
|
|
|
372
|
-
|
|
373
|
-
* Cell height.
|
|
374
|
-
*
|
|
375
|
-
* @readonly
|
|
376
|
-
* @memberof AlignedSequenceDifferenceCellRenderer
|
|
377
|
-
*/
|
|
378
|
-
get defaultHeight() {
|
|
379
|
-
return 30;
|
|
380
|
-
}
|
|
261
|
+
get defaultHeight(): number {return 30;}
|
|
381
262
|
|
|
382
|
-
|
|
383
|
-
* Cell width.
|
|
384
|
-
*
|
|
385
|
-
* @readonly
|
|
386
|
-
* @memberof AlignedSequenceDifferenceCellRenderer
|
|
387
|
-
*/
|
|
388
|
-
get defaultWidth() {
|
|
389
|
-
return 230;
|
|
390
|
-
}
|
|
263
|
+
get defaultWidth(): number {return 230;}
|
|
391
264
|
|
|
392
265
|
/**
|
|
393
266
|
* Cell renderer function.
|
|
@@ -403,7 +276,7 @@ export class AlignedSequenceDifferenceCellRenderer extends DG.GridCellRenderer {
|
|
|
403
276
|
*/
|
|
404
277
|
render(
|
|
405
278
|
g: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, gridCell: DG.GridCell,
|
|
406
|
-
cellStyle: DG.GridCellStyle) {
|
|
279
|
+
cellStyle: DG.GridCellStyle): void {
|
|
407
280
|
const grid = gridCell.grid;
|
|
408
281
|
const cell = gridCell.cell;
|
|
409
282
|
|
|
@@ -418,8 +291,9 @@ export class AlignedSequenceDifferenceCellRenderer extends DG.GridCellRenderer {
|
|
|
418
291
|
|
|
419
292
|
//TODO: can this be replaced/merged with splitSequence?
|
|
420
293
|
const [s1, s2] = s.split('#');
|
|
421
|
-
const
|
|
422
|
-
const
|
|
294
|
+
const separator = getSeparator(gridCell.tableColumn!);
|
|
295
|
+
const subParts1 = s1.split(separator);
|
|
296
|
+
const subParts2 = s2.split(separator);
|
|
423
297
|
const [text] = processSequence(subParts1);
|
|
424
298
|
const textSize = g.measureText(text.join(''));
|
|
425
299
|
let updatedX = Math.max(x, x + (w - (textSize.width + subParts1.length * 4)) / 2);
|
|
@@ -31,15 +31,7 @@ export class ChemPalette {
|
|
|
31
31
|
* @param {number} y y coordinate of the mouse pointer.
|
|
32
32
|
* @param {MonomerLibrary} monomerLib Monomer Library instance
|
|
33
33
|
*/
|
|
34
|
-
static showTooltip(cell: DG.GridCell, x: number, y: number, monomerLib: MonomerLibrary) {
|
|
35
|
-
// if (!this.isInit) {
|
|
36
|
-
// const validPackage = _package ?? _packageTest;
|
|
37
|
-
// if (!validPackage)
|
|
38
|
-
// throw new Error('No package instance found');
|
|
39
|
-
// this.monomerLib = new MonomerLibrary(await validPackage.files.readAsText(`HELMMonomers_June10.sdf`));
|
|
40
|
-
// this.isInit = true;
|
|
41
|
-
// }
|
|
42
|
-
|
|
34
|
+
static showTooltip(cell: DG.GridCell, x: number, y: number, monomerLib: MonomerLibrary): void {
|
|
43
35
|
const s = cell.cell.value as string;
|
|
44
36
|
let toDisplay = [ui.divText(s)];
|
|
45
37
|
const [, aarOuter, aarInner] = ChemPalette.getColorAAPivot(s);
|
|
@@ -92,7 +84,6 @@ export class ChemPalette {
|
|
|
92
84
|
}
|
|
93
85
|
|
|
94
86
|
static getColorAAPivot(monomer: string = '', scheme: 'grok' = 'grok'): [string, string, string, number] {
|
|
95
|
-
// const chemPaletteInstance = ChemPalette.getDatagrok();
|
|
96
87
|
const chemPaletteInstance = ChemPalette.getPalette(scheme);
|
|
97
88
|
let [outerMonomer, innerMonomer] = ChemPalette.getInnerOuter(monomer);
|
|
98
89
|
outerMonomer = (outerMonomer.length > 6 ? `${outerMonomer.slice(0, 3)}...` : outerMonomer);
|
|
@@ -281,11 +272,9 @@ export class ChemPalette {
|
|
|
281
272
|
}
|
|
282
273
|
|
|
283
274
|
static getPalette(scheme: 'grok'): StringDictionary {
|
|
284
|
-
|
|
285
|
-
case 'grok':
|
|
275
|
+
if (scheme == 'grok')
|
|
286
276
|
return ChemPalette.getDatagrok();
|
|
287
|
-
|
|
277
|
+
else
|
|
288
278
|
throw new Error(`ChemPalette: scheme \`${scheme}\` does not exist`);
|
|
289
|
-
}
|
|
290
279
|
}
|
|
291
280
|
}
|
package/src/utils/constants.ts
CHANGED
|
@@ -17,11 +17,16 @@ export enum CATEGORIES {
|
|
|
17
17
|
export enum TAGS {
|
|
18
18
|
AAR = 'AAR',
|
|
19
19
|
POSITION = 'Pos',
|
|
20
|
+
SEPARATOR = 'monomer-separator',
|
|
21
|
+
SELECTION = 'selection',
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
export enum SEM_TYPES {
|
|
23
25
|
AMINO_ACIDS = 'aminoAcids',
|
|
24
26
|
ALIGNED_SEQUENCE = 'alignedSequence',
|
|
27
|
+
ALIGNED_SEQUENCE_DIFFERENCE = 'alignedSequenceDifference',
|
|
28
|
+
ACTIVITY = 'activity',
|
|
29
|
+
ACTIVITY_SCALED = 'activityScaled',
|
|
25
30
|
}
|
|
26
31
|
|
|
27
32
|
export const STATS = 'stats';
|
|
@@ -21,13 +21,13 @@ export class FilteringStatistics {
|
|
|
21
21
|
* Sets values to make statistical analysis.
|
|
22
22
|
* @param {Float32Array} data Those values.
|
|
23
23
|
*/
|
|
24
|
-
setData(data: Float32Array) {this.data = data;}
|
|
24
|
+
setData(data: Float32Array): void {this.data = data;}
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* Sets bit mask to split population into two groups.
|
|
28
28
|
* @param {DG.BitSet} mask The mask to perform splitting.
|
|
29
29
|
*/
|
|
30
|
-
setMask(mask: DG.BitSet) {
|
|
30
|
+
setMask(mask: DG.BitSet): void {
|
|
31
31
|
if (!this.data)
|
|
32
32
|
return;
|
|
33
33
|
const selected = this.data.filter((_, i) => mask.get(i));
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as DG from 'datagrok-api/dg';
|
|
2
|
+
|
|
3
|
+
import * as C from './constants';
|
|
4
|
+
|
|
5
|
+
export function stringToBool(str: string): boolean {
|
|
6
|
+
return str === 'true' ? true : false;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function getSeparator(col: DG.Column<string>): string {
|
|
10
|
+
const separator = col.tags[C.TAGS.SEPARATOR];
|
|
11
|
+
if (separator)
|
|
12
|
+
return separator as string;
|
|
13
|
+
|
|
14
|
+
const defaultSeparators = ['.', '-', ' '];
|
|
15
|
+
const categories = col.categories;
|
|
16
|
+
const catLen = categories.length;
|
|
17
|
+
for (const potentialSeparator of defaultSeparators) {
|
|
18
|
+
if (categories.filter((sequence) => sequence.includes(potentialSeparator)).length == catLen)
|
|
19
|
+
return potentialSeparator;
|
|
20
|
+
}
|
|
21
|
+
return separator as string ?? '';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function getTypedArrayConstructor(
|
|
25
|
+
maxNum: number): Uint8ArrayConstructor | Uint16ArrayConstructor | Uint32ArrayConstructor {
|
|
26
|
+
return maxNum < 256 ? Uint8Array :
|
|
27
|
+
maxNum < 65536 ? Uint16Array :
|
|
28
|
+
Uint32Array;
|
|
29
|
+
}
|
|
@@ -4,10 +4,7 @@ import * as DG from 'datagrok-api/dg';
|
|
|
4
4
|
import Aioli from '@biowasm/aioli';
|
|
5
5
|
|
|
6
6
|
import {AlignedSequenceEncoder} from '@datagrok-libraries/bio/src/sequence-encoder';
|
|
7
|
-
|
|
8
|
-
import {SEMTYPE} from '../semantics';
|
|
9
|
-
|
|
10
|
-
// let CLI: any = undefined;
|
|
7
|
+
import * as C from './constants';
|
|
11
8
|
|
|
12
9
|
/**
|
|
13
10
|
* Converts array of sequences into simple fasta string.
|
|
@@ -38,10 +35,9 @@ function _fastaToStrings(fasta: string): string[] {
|
|
|
38
35
|
function _castAligned(seq: string): string {
|
|
39
36
|
let delimited = '';
|
|
40
37
|
|
|
41
|
-
for (
|
|
42
|
-
const char = seq[i];
|
|
38
|
+
for (const char of seq)
|
|
43
39
|
delimited += char == '-' ? char : `-${char}`;
|
|
44
|
-
|
|
40
|
+
|
|
45
41
|
return `NH2${delimited}-COOH`;
|
|
46
42
|
}
|
|
47
43
|
|
|
@@ -81,12 +77,6 @@ export async function runKalign(col: DG.Column, isAligned = false) : Promise<DG.
|
|
|
81
77
|
reinit: true,
|
|
82
78
|
});
|
|
83
79
|
|
|
84
|
-
// if (!CLI) {
|
|
85
|
-
// CLI = await new Aioli('kalign/3.3.1');
|
|
86
|
-
// console.info('kalign CLI was first initialized.');
|
|
87
|
-
// } else
|
|
88
|
-
// console.info('Initialized kalign CLI was reused.');
|
|
89
|
-
|
|
90
80
|
console.log(['fasta.length =', fasta.length]);
|
|
91
81
|
|
|
92
82
|
await CLI.fs.writeFile('input.fa', fasta);
|
|
@@ -95,16 +85,13 @@ export async function runKalign(col: DG.Column, isAligned = false) : Promise<DG.
|
|
|
95
85
|
|
|
96
86
|
console.warn(output);
|
|
97
87
|
|
|
98
|
-
// if (!buf)
|
|
99
|
-
// console.warn(buf);
|
|
100
|
-
|
|
101
88
|
const aligned = _fastaToStrings(buf).slice(0, sequences.length);
|
|
102
89
|
const alignedCol = DG.Column.fromStrings(`(${col.name})msa`, _stringsToAligned(aligned));
|
|
103
|
-
alignedCol.semType =
|
|
90
|
+
alignedCol.semType = C.SEM_TYPES.ALIGNED_SEQUENCE;
|
|
104
91
|
return alignedCol;
|
|
105
92
|
}
|
|
106
93
|
|
|
107
|
-
export async function testMSAEnoughMemory(col: DG.Column) {
|
|
94
|
+
export async function testMSAEnoughMemory(col: DG.Column): Promise<void> {
|
|
108
95
|
const sequencesCount = col.length;
|
|
109
96
|
const delta = sequencesCount/100;
|
|
110
97
|
|
|
@@ -6,21 +6,19 @@ import * as C from './constants';
|
|
|
6
6
|
import {AlignedSequenceEncoder} from '@datagrok-libraries/bio/src/sequence-encoder';
|
|
7
7
|
|
|
8
8
|
export async function callMVA(
|
|
9
|
-
tableGrid: DG.Grid,
|
|
10
|
-
view: DG.View,
|
|
11
9
|
currentDf: DG.DataFrame,
|
|
12
10
|
options: {[name: string]: string},
|
|
13
11
|
sequencesCol: DG.Column,
|
|
14
|
-
) {
|
|
12
|
+
): Promise<void> {
|
|
15
13
|
const activityCol = await _scaleColumn(currentDf.getCol(options['activityColumnName']), options['scaling']);
|
|
16
14
|
const encDf = _encodeSequences(sequencesCol);
|
|
17
|
-
// const scaledColName = `${options['activityColumnName']}scaled`;
|
|
18
15
|
|
|
16
|
+
//TODO: is it correct? Is it needed?
|
|
19
17
|
_insertColumns(
|
|
20
18
|
currentDf,
|
|
21
19
|
[DG.Column.fromList('double', C.COLUMNS_NAMES.ACTIVITY_SCALED, activityCol.toList())],
|
|
22
20
|
);
|
|
23
|
-
_insertColumns(currentDf, encDf.columns);
|
|
21
|
+
_insertColumns(currentDf, encDf.columns.toList());
|
|
24
22
|
|
|
25
23
|
const res = await grok.functions.call('MultivariateAnalysis', {
|
|
26
24
|
table: currentDf,
|
|
@@ -50,10 +48,9 @@ function _encodeSequences(sequencesCol: DG.Column): DG.DataFrame {
|
|
|
50
48
|
for (let i = 0; i < nCols; ++i)
|
|
51
49
|
positions[i][j] = enc.encodeLettter(s[i]);
|
|
52
50
|
}
|
|
53
|
-
|
|
51
|
+
return DG.DataFrame.fromColumns(positions.map(
|
|
54
52
|
(v, i) => DG.Column.fromFloat32Array((i+1).toString(), v),
|
|
55
53
|
));
|
|
56
|
-
return df;
|
|
57
54
|
}
|
|
58
55
|
|
|
59
56
|
async function _scaleColumn(column: DG.Column, method: string): Promise<DG.Column> {
|
|
@@ -67,7 +64,7 @@ async function _scaleColumn(column: DG.Column, method: string): Promise<DG.Colum
|
|
|
67
64
|
if (newCol == null)
|
|
68
65
|
throw new Error('Column formula returned unexpected null.');
|
|
69
66
|
|
|
70
|
-
return newCol
|
|
67
|
+
return newCol;
|
|
71
68
|
}
|
|
72
69
|
|
|
73
70
|
function _insertColumns(targetDf: DG.DataFrame, columns: DG.Column[]): DG.DataFrame {
|
|
@@ -7,6 +7,7 @@ import {AlignedSequenceEncoder} from '@datagrok-libraries/bio/src/sequence-encod
|
|
|
7
7
|
import {DimensionalityReducer} from '@datagrok-libraries/ml/src/reduce-dimensionality';
|
|
8
8
|
import {
|
|
9
9
|
createDimensinalityReducingWorker,
|
|
10
|
+
IReduceDimensionalityResult,
|
|
10
11
|
} from '@datagrok-libraries/ml/src/workers/dimensionality-reducing-worker-creator';
|
|
11
12
|
import {Measure, StringMetrics} from '@datagrok-libraries/ml/src/typed-metrics';
|
|
12
13
|
import {Coordinates} from '@datagrok-libraries/utils/src/type-declarations';
|
|
@@ -43,16 +44,17 @@ export async function createPeptideSimilaritySpaceViewer(
|
|
|
43
44
|
const pi = DG.TaskBarProgressIndicator.create('Creating embedding...');
|
|
44
45
|
|
|
45
46
|
const axesNames = ['~X', '~Y', '~MW'];
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
col ??= table.columns.bySemType(C.SEM_TYPES.ALIGNED_SEQUENCE)!;
|
|
48
|
+
const columnData = col.toList().map((v) => AlignedSequenceEncoder.clean(v));
|
|
48
49
|
|
|
49
|
-
const
|
|
50
|
-
{data: columnData, metric: measure as StringMetrics}, method, cyclesCount);
|
|
50
|
+
const reduceDimRes: IReduceDimensionalityResult = await createDimensinalityReducingWorker(
|
|
51
|
+
{data: columnData, metric: measure as StringMetrics}, method, {cycles: cyclesCount});
|
|
51
52
|
|
|
53
|
+
const embcols = reduceDimRes.embedding;
|
|
52
54
|
const columns = Array.from(
|
|
53
55
|
embcols as Coordinates, (v: Float32Array, k) => DG.Column.fromFloat32Array(axesNames[k], v));
|
|
54
56
|
|
|
55
|
-
function _getMW(sequences: string[]) {
|
|
57
|
+
function _getMW(sequences: string[]): Float32Array {
|
|
56
58
|
const mw: Float32Array = new Float32Array(sequences.length);
|
|
57
59
|
|
|
58
60
|
mw.map((_, index) => getSequenceMolecularWeight(sequences[index] ?? ''));
|
|
@@ -66,10 +68,10 @@ export async function createPeptideSimilaritySpaceViewer(
|
|
|
66
68
|
|
|
67
69
|
// Add new axes.
|
|
68
70
|
for (const axis of axesNames) {
|
|
69
|
-
const
|
|
71
|
+
const axisCol = table.col(axis);
|
|
70
72
|
const newCol = edf.getCol(axis);
|
|
71
73
|
|
|
72
|
-
if (
|
|
74
|
+
if (axisCol != null) {
|
|
73
75
|
for (let i = 0; i < newCol.length; ++i) {
|
|
74
76
|
const v = newCol.get(i);
|
|
75
77
|
table.set(axis, i, v);
|
|
@@ -78,8 +80,9 @@ export async function createPeptideSimilaritySpaceViewer(
|
|
|
78
80
|
table.columns.insert(newCol);
|
|
79
81
|
}
|
|
80
82
|
|
|
83
|
+
const colorColName = table.columns.bySemType(C.SEM_TYPES.ACTIVITY)?.name ?? '~MW';
|
|
81
84
|
const viewerOptions = {
|
|
82
|
-
x: '~X', y: '~Y', color:
|
|
85
|
+
x: '~X', y: '~Y', color: colorColName, size: '~MW', title: 'Peptide Space',
|
|
83
86
|
showYSelector: false, showXSelector: false, showColorSelector: false, showSizeSelector: false,
|
|
84
87
|
};
|
|
85
88
|
const viewer = table.plot.scatter(viewerOptions);
|
|
@@ -144,7 +147,7 @@ export class PeptideSimilaritySpaceWidget {
|
|
|
144
147
|
* @protected
|
|
145
148
|
* @memberof PeptideSimilaritySpaceWidget
|
|
146
149
|
*/
|
|
147
|
-
protected async updateViewer() {
|
|
150
|
+
protected async updateViewer(): Promise<void> {
|
|
148
151
|
const viewer = await this.drawViewer();
|
|
149
152
|
this.viewer.lastChild?.remove();
|
|
150
153
|
this.viewer.appendChild(viewer.root);
|