@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.
Files changed (39) hide show
  1. package/.eslintrc.json +5 -2
  2. package/dist/package-test.js +1268 -1766
  3. package/dist/package.js +1097 -1622
  4. package/dist/vendors-node_modules_datagrok-libraries_ml_src_workers_dimensionality-reducer_js.js +120 -62
  5. package/package.json +13 -17
  6. package/package.png +0 -0
  7. package/src/model.ts +504 -448
  8. package/src/monomer-library.ts +31 -30
  9. package/src/package-test.ts +5 -6
  10. package/src/package.ts +52 -70
  11. package/src/tests/core.ts +67 -0
  12. package/src/tests/msa-tests.ts +3 -3
  13. package/src/tests/peptide-space-test.ts +65 -45
  14. package/src/tests/utils.ts +20 -50
  15. package/src/utils/cell-renderer.ts +25 -151
  16. package/src/utils/chem-palette.ts +3 -14
  17. package/src/utils/constants.ts +5 -0
  18. package/src/utils/filtering-statistics.ts +2 -2
  19. package/src/utils/misc.ts +29 -0
  20. package/src/utils/multiple-sequence-alignment.ts +5 -18
  21. package/src/utils/multivariate-analysis.ts +5 -8
  22. package/src/utils/peptide-similarity-space.ts +12 -9
  23. package/src/utils/types.ts +5 -2
  24. package/src/viewers/peptide-space-viewer.ts +67 -39
  25. package/src/viewers/sar-viewer.ts +34 -37
  26. package/src/viewers/stacked-barchart-viewer.ts +38 -61
  27. package/src/widgets/analyze-peptides.ts +53 -75
  28. package/src/widgets/distribution.ts +34 -18
  29. package/src/widgets/manual-alignment.ts +8 -12
  30. package/src/widgets/peptide-molecule.ts +48 -25
  31. package/src/widgets/subst-table.ts +53 -52
  32. package/src/workers/dimensionality-reducer.ts +8 -13
  33. package/{test-Peptides-f8114def7953-4bf59d70.html → test-Peptides-69a4761f6044-40ac3a0c.html} +2 -2
  34. package/src/peptides.ts +0 -327
  35. package/src/semantics.ts +0 -5
  36. package/src/tests/peptides-tests.ts +0 -60
  37. package/src/utils/SAR-multiple-filter.ts +0 -439
  38. package/src/utils/SAR-multiple-selection.ts +0 -177
  39. package/src/viewers/logo-viewer.ts +0 -195
@@ -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
- let noException = true;
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(columnData: Array<string>, method: StringMetrics, measure: string) {
46
- let noException = true;
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
- try {
51
- embcols = await createDimensinalityReducingWorker(
52
- {data: columnData, metric: measure as StringMetrics}, method, cyclesCount);
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
- table: DG.DataFrame,
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
- try {
88
- viewer = await createPeptideSimilaritySpaceViewer(
89
- table, method, measure, cyclesCount, undefined, alignedSequencesColumn);
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
- noException = true;
75
+ const axesNames = ['~X', '~Y', '~MW'];
76
+ const axes = axesNames.map((v) => df.getCol(v).getRawData() as Float32Array);
98
77
 
99
- try {
100
- const axesNames = ['~X', '~Y', '~MW'];
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 subParts1 = s1.split('-');
422
- const subParts2 = s2.split('-');
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
- switch (scheme) {
285
- case 'grok':
275
+ if (scheme == 'grok')
286
276
  return ChemPalette.getDatagrok();
287
- default:
277
+ else
288
278
  throw new Error(`ChemPalette: scheme \`${scheme}\` does not exist`);
289
- }
290
279
  }
291
280
  }
@@ -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
- //@ts-ignore
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 (let i = 0; i < seq.length; ++i) {
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 = SEMTYPE.ALIGNED;
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
- const df = DG.DataFrame.fromColumns(positions.map(
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
- const columnData = (col ?? table.getCol(C.COLUMNS_NAMES.ALIGNED_SEQUENCE)).toList()
47
- .map((v) => AlignedSequenceEncoder.clean(v));
47
+ col ??= table.columns.bySemType(C.SEM_TYPES.ALIGNED_SEQUENCE)!;
48
+ const columnData = col.toList().map((v) => AlignedSequenceEncoder.clean(v));
48
49
 
49
- const embcols = await createDimensinalityReducingWorker(
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 col = table.col(axis);
71
+ const axisCol = table.col(axis);
70
72
  const newCol = edf.getCol(axis);
71
73
 
72
- if (col != null) {
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: C.COLUMNS_NAMES.ACTIVITY ?? '~MW', size: '~MW', title: 'Peptide Space',
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);