@datagrok/peptides 0.8.8 → 0.8.9
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/package.json +10 -10
- package/src/describe.ts +96 -97
- package/src/model.ts +96 -75
- package/src/monomer-library.ts +10 -12
- package/src/package-test.ts +3 -3
- package/src/package.ts +39 -59
- package/src/peptides.ts +218 -108
- package/src/tests/peptide-space-test.ts +1 -1
- package/src/tests/peptides-tests.ts +6 -6
- package/src/tests/utils.ts +3 -2
- package/src/utils/cell-renderer.ts +89 -61
- package/src/utils/chem-palette.ts +66 -32
- package/src/utils/peptide-similarity-space.ts +18 -28
- package/src/utils/split-aligned.ts +55 -55
- package/src/viewers/logo-viewer.ts +5 -4
- package/src/viewers/sar-viewer.ts +88 -110
- package/src/viewers/stacked-barchart-viewer.ts +359 -359
- package/src/viewers/subst-viewer.ts +108 -73
- package/src/widgets/analyze-peptides.ts +26 -26
- package/src/widgets/manual-alignment.ts +7 -4
- package/src/widgets/multiple-sequence-alignment.ts +9 -0
- package/src/widgets/peptide-molecule.ts +5 -3
- package/src/widgets/subst-table.ts +65 -0
- package/src/workers/dimensionality-reducer.ts +1 -1
|
@@ -80,7 +80,7 @@ export function measureAAR(s: string): number {
|
|
|
80
80
|
function printLeftOrCentered(
|
|
81
81
|
x: number, y: number, w: number, h: number,
|
|
82
82
|
g: CanvasRenderingContext2D, s: string, color = ChemPalette.undefinedColor,
|
|
83
|
-
pivot: number = 0, left = false, hideMod = false, transparencyRate: number = 1.0
|
|
83
|
+
pivot: number = 0, left = false, hideMod = false, transparencyRate: number = 1.0,
|
|
84
84
|
) {
|
|
85
85
|
g.textAlign = 'start';
|
|
86
86
|
let colorPart = pivot == -1 ? s.substring(0) : s.substring(0, pivot);
|
|
@@ -145,37 +145,57 @@ function printLeftOrCentered(
|
|
|
145
145
|
* @extends {DG.GridCellRenderer}
|
|
146
146
|
*/
|
|
147
147
|
export class AminoAcidsCellRenderer extends DG.GridCellRenderer {
|
|
148
|
-
|
|
148
|
+
chemPalette: ChemPalette | null;
|
|
149
149
|
|
|
150
|
-
|
|
150
|
+
/**
|
|
151
151
|
* Renderer name.
|
|
152
152
|
*
|
|
153
153
|
* @readonly
|
|
154
154
|
* @memberof AminoAcidsCellRenderer
|
|
155
155
|
*/
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
156
|
+
get name() {
|
|
157
|
+
return 'aminoAcidsCR';
|
|
158
|
+
}
|
|
159
159
|
|
|
160
|
-
|
|
160
|
+
/**
|
|
161
161
|
* Cell type.
|
|
162
162
|
*
|
|
163
163
|
* @readonly
|
|
164
164
|
* @memberof AminoAcidsCellRenderer
|
|
165
165
|
*/
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
166
|
+
get cellType() {
|
|
167
|
+
return 'aminoAcids';
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Cell height.
|
|
172
|
+
*
|
|
173
|
+
* @readonly
|
|
174
|
+
* @memberof AminoAcidsCellRenderer
|
|
175
|
+
*/
|
|
176
|
+
get defaultHeight() {
|
|
177
|
+
return 15;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Cell width.
|
|
182
|
+
*
|
|
183
|
+
* @readonly
|
|
184
|
+
* @memberof AminoAcidsCellRenderer
|
|
185
|
+
*/
|
|
186
|
+
get defaultWidth() {
|
|
187
|
+
return 30;
|
|
188
|
+
}
|
|
169
189
|
|
|
170
|
-
|
|
190
|
+
/**
|
|
171
191
|
* Constructor.
|
|
172
192
|
*/
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
193
|
+
constructor() {
|
|
194
|
+
super();
|
|
195
|
+
this.chemPalette = null;
|
|
196
|
+
}
|
|
177
197
|
|
|
178
|
-
|
|
198
|
+
/**
|
|
179
199
|
* Cell renderer function.
|
|
180
200
|
*
|
|
181
201
|
* @param {CanvasRenderingContext2D} g Canvas rendering context.
|
|
@@ -186,22 +206,26 @@ export class AminoAcidsCellRenderer extends DG.GridCellRenderer {
|
|
|
186
206
|
* @param {DG.GridCell} gridCell Grid cell.
|
|
187
207
|
* @param {DG.GridCellStyle} cellStyle Cell style.
|
|
188
208
|
*/
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
209
|
+
render(
|
|
210
|
+
g: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, gridCell: DG.GridCell,
|
|
211
|
+
cellStyle: DG.GridCellStyle) {
|
|
212
|
+
this.chemPalette ??= new ChemPalette('grok', gridCell.tableColumn?.getTag('groups') ? true : false);
|
|
213
|
+
|
|
214
|
+
y -= 2;
|
|
215
|
+
g.save();
|
|
216
|
+
g.beginPath();
|
|
217
|
+
g.rect(x, y, w, h);
|
|
218
|
+
g.clip();
|
|
219
|
+
g.font = `12px monospace`;
|
|
220
|
+
g.textBaseline = 'top';
|
|
221
|
+
const s: string = gridCell.cell.value ? gridCell.cell.value : '-';
|
|
222
|
+
let [color, outerS, innerS, pivot] = cp.getColorAAPivot(s);
|
|
223
|
+
if (innerS)
|
|
224
|
+
outerS = s;
|
|
225
|
+
|
|
226
|
+
printLeftOrCentered(x, y, w, h, g, outerS, color, pivot, false, true);
|
|
227
|
+
g.restore();
|
|
228
|
+
}
|
|
205
229
|
}
|
|
206
230
|
|
|
207
231
|
/**
|
|
@@ -232,13 +256,23 @@ export class AlignedSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
232
256
|
return 'alignedSequence';
|
|
233
257
|
}
|
|
234
258
|
|
|
259
|
+
/**
|
|
260
|
+
* Cell height.
|
|
261
|
+
*
|
|
262
|
+
* @readonly
|
|
263
|
+
* @memberof AlignedSequenceCellRenderer
|
|
264
|
+
*/
|
|
265
|
+
get defaultHeight() {
|
|
266
|
+
return 30;
|
|
267
|
+
}
|
|
268
|
+
|
|
235
269
|
/**
|
|
236
270
|
* Cell width.
|
|
237
271
|
*
|
|
238
272
|
* @readonly
|
|
239
273
|
* @memberof AlignedSequenceCellRenderer
|
|
240
274
|
*/
|
|
241
|
-
|
|
275
|
+
get defaultWidth() {
|
|
242
276
|
return 230;
|
|
243
277
|
}
|
|
244
278
|
|
|
@@ -260,13 +294,12 @@ export class AlignedSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
260
294
|
) {
|
|
261
295
|
const grid = gridCell.dart.grid ? gridCell.grid : gridCell.dart.grid;
|
|
262
296
|
const cell = gridCell.cell;
|
|
263
|
-
|
|
264
297
|
w = grid ? Math.min(grid.canvas.width - x, w) : g.canvas.width - x;
|
|
265
298
|
g.save();
|
|
266
299
|
g.beginPath();
|
|
267
300
|
g.rect(x, y, w, h);
|
|
268
301
|
g.clip();
|
|
269
|
-
g.font = '
|
|
302
|
+
g.font = '12px monospace';
|
|
270
303
|
g.textBaseline = 'top';
|
|
271
304
|
const s: string = cell.value ?? '';
|
|
272
305
|
|
|
@@ -277,13 +310,13 @@ export class AlignedSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
277
310
|
x = Math.max(x, x + (w - textSize.width) / 2);
|
|
278
311
|
|
|
279
312
|
subParts.forEach((amino: string, index) => {
|
|
280
|
-
|
|
313
|
+
let [color, outerAmino,, pivot] = cp.getColorAAPivot(amino);
|
|
281
314
|
g.fillStyle = ChemPalette.undefinedColor;
|
|
282
315
|
if (index + 1 < subParts.length) {
|
|
283
|
-
const gap = simplified?'':' ';
|
|
284
|
-
|
|
316
|
+
const gap = simplified ? '' : ' ';
|
|
317
|
+
outerAmino += `${outerAmino?'':'-'}${gap}`;
|
|
285
318
|
}
|
|
286
|
-
x = printLeftOrCentered(x, y, w, h, g,
|
|
319
|
+
x = printLeftOrCentered(x, y, w, h, g, outerAmino, color, pivot, true);
|
|
287
320
|
});
|
|
288
321
|
|
|
289
322
|
g.restore();
|
|
@@ -321,7 +354,7 @@ export function processSequence(subParts: string[]): [string[], boolean] {
|
|
|
321
354
|
* @class AlignedSequenceDifferenceCellRenderer
|
|
322
355
|
* @extends {DG.GridCellRenderer}
|
|
323
356
|
*/
|
|
324
|
-
|
|
357
|
+
export class AlignedSequenceDifferenceCellRenderer extends DG.GridCellRenderer {
|
|
325
358
|
/**
|
|
326
359
|
* Renderer name.
|
|
327
360
|
*
|
|
@@ -358,8 +391,8 @@ export function processSequence(subParts: string[]): [string[], boolean] {
|
|
|
358
391
|
* @readonly
|
|
359
392
|
* @memberof AlignedSequenceDifferenceCellRenderer
|
|
360
393
|
*/
|
|
361
|
-
|
|
362
|
-
return
|
|
394
|
+
get defaultWidth() {
|
|
395
|
+
return 230;
|
|
363
396
|
}
|
|
364
397
|
|
|
365
398
|
/**
|
|
@@ -382,12 +415,11 @@ export function processSequence(subParts: string[]): [string[], boolean] {
|
|
|
382
415
|
const cell = gridCell.cell;
|
|
383
416
|
|
|
384
417
|
w = grid ? Math.min(grid.canvas.width - x, w) : g.canvas.width - x;
|
|
385
|
-
y += 2;
|
|
386
418
|
g.save();
|
|
387
419
|
g.beginPath();
|
|
388
420
|
g.rect(x, y, w, h);
|
|
389
421
|
g.clip();
|
|
390
|
-
g.font = '
|
|
422
|
+
g.font = '12px monospace';
|
|
391
423
|
g.textBaseline = 'top';
|
|
392
424
|
const s: string = cell.value ?? '';
|
|
393
425
|
|
|
@@ -395,33 +427,29 @@ export function processSequence(subParts: string[]): [string[], boolean] {
|
|
|
395
427
|
const [s1, s2] = s.split('#');
|
|
396
428
|
const subParts1 = s1.split('-');
|
|
397
429
|
const subParts2 = s2.split('-');
|
|
398
|
-
const [text
|
|
430
|
+
const [text] = processSequence(subParts1);
|
|
399
431
|
const textSize = g.measureText(text.join(''));
|
|
400
432
|
x = Math.max(x, x + (w - textSize.width) / 2);
|
|
401
433
|
|
|
402
434
|
subParts1.forEach((amino1: string, index) => {
|
|
403
|
-
let color, pivot;
|
|
404
435
|
let amino2 = subParts2[index];
|
|
436
|
+
const [color1, amino1Outer, amino1Inner, pivot1] = cp.getColorAAPivot(amino1);
|
|
437
|
+
const [color2, amino2Outer, amino2Inner, pivot2] = cp.getColorAAPivot(amino2);
|
|
405
438
|
|
|
406
|
-
if (amino1 != '')
|
|
407
|
-
[color, pivot] = cp.getColorPivot(amino1);
|
|
408
|
-
else
|
|
409
|
-
[color, pivot] = cp.getColorPivot(amino2);
|
|
410
|
-
|
|
411
439
|
if (amino1 != amino2) {
|
|
412
440
|
const verticalShift = 7;
|
|
413
441
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
442
|
+
amino1 = amino1Outer + (amino1Inner !== '' ? '(' + amino1Inner + ')' : '');
|
|
443
|
+
amino2 = amino2Outer + (amino2Inner !== '' ? '(' + amino2Inner + ')' : '');
|
|
444
|
+
amino1 = amino1 === '' ? '-' : amino1;
|
|
445
|
+
amino2 = amino2 === '' ? '-' : amino2;
|
|
418
446
|
|
|
419
|
-
printLeftOrCentered(x, y - verticalShift, w, h, g, amino1,
|
|
420
|
-
x = printLeftOrCentered(x, y + verticalShift, w, h, g, amino2,
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
447
|
+
const x1 = printLeftOrCentered(x, y - verticalShift, w, h, g, amino1, color1, pivot1, true);
|
|
448
|
+
x = printLeftOrCentered(x, y + verticalShift, w, h, g, amino2, color2, pivot2, true);
|
|
449
|
+
x = Math.max(x, x1) + 4;
|
|
450
|
+
} else
|
|
451
|
+
x = printLeftOrCentered(x, y, w, h, g, amino1 ? amino1 : '-', color1, pivot1, true, true, 0.5) + 4;
|
|
424
452
|
});
|
|
425
453
|
g.restore();
|
|
426
454
|
}
|
|
427
|
-
}
|
|
455
|
+
}
|
|
@@ -36,26 +36,31 @@ export class ChemPalette {
|
|
|
36
36
|
* @param {number} y y coordinate of the mouse pointer.
|
|
37
37
|
*/
|
|
38
38
|
async showTooltip(cell: DG.GridCell, x: number, y: number) {
|
|
39
|
-
if(!this.isInit)
|
|
39
|
+
if (!this.isInit)
|
|
40
40
|
this.monomerLib = new MonomerLibrary(await _package.files.readAsText(`HELMMonomers_June10.sdf`));
|
|
41
41
|
|
|
42
42
|
const s = cell.cell.value as string;
|
|
43
43
|
let toDisplay = [ui.divText(s)];
|
|
44
|
-
const [,
|
|
45
|
-
|
|
46
|
-
if (
|
|
47
|
-
|
|
44
|
+
const [, aarOuter, aarInner] = this.getColorAAPivot(s);
|
|
45
|
+
for (const aar of [aarOuter, aarInner]) {
|
|
46
|
+
if (this.monomerLib!.monomerNames.includes(aar)) {
|
|
47
|
+
if (aar in ChemPalette.AANames)
|
|
48
|
+
toDisplay = [ui.divText(ChemPalette.AANames[aar])];
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
if (aar in ChemPalette.AAFullNames)
|
|
51
|
+
toDisplay = [ui.divText(ChemPalette.AANames[ChemPalette.AAFullNames[aar]])];
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
53
|
+
const options = {
|
|
54
|
+
autoCrop: true,
|
|
55
|
+
autoCropMargin: 0,
|
|
56
|
+
suppressChiralText: true,
|
|
57
|
+
};
|
|
58
|
+
const sketch = grok.chem.svgMol(this.monomerLib!.getMonomerMol(aar), undefined, undefined, options);
|
|
59
|
+
if (toDisplay.length == 2)
|
|
60
|
+
toDisplay.push(ui.divText('Modified'));
|
|
61
|
+
|
|
62
|
+
toDisplay.push(sketch);
|
|
63
|
+
}
|
|
59
64
|
}
|
|
60
65
|
ui.tooltip.show(ui.divV(toDisplay), x, y);
|
|
61
66
|
}
|
|
@@ -70,25 +75,54 @@ export class ChemPalette {
|
|
|
70
75
|
return color;
|
|
71
76
|
}
|
|
72
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Retursn divided amino with its content in the bracket, if the conetent is number, then its omitted
|
|
80
|
+
*
|
|
81
|
+
* @param {string} c raw amino
|
|
82
|
+
* @return {[string, string]} outer and inner content
|
|
83
|
+
*/
|
|
84
|
+
private getInnerOuter(c: string): [string, string] {
|
|
85
|
+
let isInner = 0;
|
|
86
|
+
let inner = '';
|
|
87
|
+
let outer = '';
|
|
88
|
+
|
|
89
|
+
for (let i = 0; i < c.length; ++i) {
|
|
90
|
+
if (c[i] == '(')
|
|
91
|
+
isInner++;
|
|
92
|
+
else if (c[i] == ')')
|
|
93
|
+
isInner--;
|
|
94
|
+
else if (isInner)
|
|
95
|
+
inner += c[i];
|
|
96
|
+
else
|
|
97
|
+
outer += c[i];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return !isNaN(parseInt(inner)) ? [outer, ''] : [outer, inner];
|
|
101
|
+
}
|
|
102
|
+
|
|
73
103
|
/**
|
|
74
104
|
* Get color for the provided amino acid residue pivot
|
|
75
105
|
* @param {string} [c=''] Amino acid residue string.
|
|
76
106
|
* @return {[string, string, number]}
|
|
77
107
|
*/
|
|
78
|
-
getColorAAPivot(c: string = ''): [string, string, number] {
|
|
108
|
+
getColorAAPivot(c: string = ''): [string, string, string, number] {
|
|
109
|
+
let [outerC, innerC] = this.getInnerOuter(c);
|
|
110
|
+
outerC = (outerC.length > 6 ? outerC.slice(0, 3) + '...' : outerC);
|
|
111
|
+
innerC = (innerC.length > 6 ? innerC.slice(0, 3) + '...' : innerC);
|
|
112
|
+
|
|
79
113
|
if (c.length == 1 || c[1] == '(') {
|
|
80
114
|
const amino = c[0]?.toUpperCase()!;
|
|
81
115
|
return amino in this.cp?
|
|
82
|
-
[this.cp[amino], amino, 1]:
|
|
83
|
-
[ChemPalette.undefinedColor,
|
|
116
|
+
[this.cp[amino], amino, innerC, 1]:
|
|
117
|
+
[ChemPalette.undefinedColor, outerC, innerC, 1];
|
|
84
118
|
}
|
|
85
119
|
|
|
86
120
|
if (c[0] == 'd' && c[1]! in this.cp) {
|
|
87
121
|
if (c.length == 2 || c[2] == '(') {
|
|
88
122
|
const amino = c[1]?.toUpperCase()!;
|
|
89
123
|
return amino in this.cp?
|
|
90
|
-
[this.cp[amino], amino, 2]:
|
|
91
|
-
[ChemPalette.undefinedColor,
|
|
124
|
+
[this.cp[amino], amino, innerC, 2]:
|
|
125
|
+
[ChemPalette.undefinedColor, outerC, innerC, 2];
|
|
92
126
|
}
|
|
93
127
|
}
|
|
94
128
|
|
|
@@ -96,8 +130,8 @@ export class ChemPalette {
|
|
|
96
130
|
if (c.length == 3 || c[3] == '(') {
|
|
97
131
|
const amino = ChemPalette.AAFullNames[c.substr(0, 3)];
|
|
98
132
|
return amino in this.cp?
|
|
99
|
-
[this.cp[amino], amino, 3]:
|
|
100
|
-
[ChemPalette.undefinedColor,
|
|
133
|
+
[this.cp[amino], amino, innerC, 3]:
|
|
134
|
+
[ChemPalette.undefinedColor, outerC, innerC, 3];
|
|
101
135
|
}
|
|
102
136
|
}
|
|
103
137
|
|
|
@@ -106,13 +140,13 @@ export class ChemPalette {
|
|
|
106
140
|
if (c.length == 4 || c[4] == '(') {
|
|
107
141
|
const amino = ChemPalette.AAFullNames[c.substr(1, 3)];
|
|
108
142
|
return amino in this.cp?
|
|
109
|
-
[this.cp[amino], amino, 4]:
|
|
110
|
-
[ChemPalette.undefinedColor,
|
|
143
|
+
[this.cp[amino], amino, innerC, 4]:
|
|
144
|
+
[ChemPalette.undefinedColor, outerC, innerC, 4];
|
|
111
145
|
}
|
|
112
146
|
}
|
|
113
147
|
}
|
|
114
148
|
|
|
115
|
-
return [ChemPalette.undefinedColor,
|
|
149
|
+
return [ChemPalette.undefinedColor, outerC, innerC, 0];
|
|
116
150
|
}
|
|
117
151
|
|
|
118
152
|
/**
|
|
@@ -123,7 +157,7 @@ export class ChemPalette {
|
|
|
123
157
|
*/
|
|
124
158
|
getColorPivot(c = ''): [string, number] {
|
|
125
159
|
//TODO: merge with getColorAAPivot?
|
|
126
|
-
const [color
|
|
160
|
+
const [color,,, pivot] = this.getColorAAPivot(c);
|
|
127
161
|
return [color, pivot];
|
|
128
162
|
};
|
|
129
163
|
|
|
@@ -155,7 +189,7 @@ export class ChemPalette {
|
|
|
155
189
|
'gray': ['rgb(127,127,127)', 'rgb(199,199,199)', 'rgb(196,156,148)', 'rgb(222, 222, 180)'],
|
|
156
190
|
'yellow': ['rgb(188,189,34)'],
|
|
157
191
|
'white': ['rgb(230,230,230)'],
|
|
158
|
-
}
|
|
192
|
+
};
|
|
159
193
|
|
|
160
194
|
/**
|
|
161
195
|
* Grok color scheme groups.
|
|
@@ -171,7 +205,7 @@ export class ChemPalette {
|
|
|
171
205
|
'light_blue': ['R', 'H', 'K'],
|
|
172
206
|
'dark_blue': ['D', 'E'],
|
|
173
207
|
'orange': ['S', 'T', 'N', 'Q'],
|
|
174
|
-
}
|
|
208
|
+
};
|
|
175
209
|
|
|
176
210
|
/**
|
|
177
211
|
* Lesk color scheme groups.
|
|
@@ -186,7 +220,7 @@ export class ChemPalette {
|
|
|
186
220
|
'magenta': ['N', 'Q', 'H'],
|
|
187
221
|
'red': ['D', 'E'],
|
|
188
222
|
'all_blue': ['K', 'R'],
|
|
189
|
-
}
|
|
223
|
+
};
|
|
190
224
|
|
|
191
225
|
/**
|
|
192
226
|
* Undefined color.
|
|
@@ -245,7 +279,7 @@ export class ChemPalette {
|
|
|
245
279
|
'I': 'Isoleucine',
|
|
246
280
|
'M': 'Methionine',
|
|
247
281
|
'T': 'Threonine',
|
|
248
|
-
}
|
|
282
|
+
};
|
|
249
283
|
|
|
250
284
|
/**
|
|
251
285
|
* Amino acid residue SMILES.
|
|
@@ -275,7 +309,7 @@ export class ChemPalette {
|
|
|
275
309
|
'I': 'N[C@H]([C@H](C)CC)C(=O)O',
|
|
276
310
|
'M': 'NC(CCSC)C(=O)O',
|
|
277
311
|
'T': 'NC(C(O)C)C(=O)O',
|
|
278
|
-
}
|
|
312
|
+
};
|
|
279
313
|
|
|
280
314
|
/**
|
|
281
315
|
* Amino acid residue truncated SMILES.
|
|
@@ -305,7 +339,7 @@ export class ChemPalette {
|
|
|
305
339
|
'I': 'CC[C@H](C)[C@H](*)*',
|
|
306
340
|
'M': 'CSCCC(*)*',
|
|
307
341
|
'T': 'CC(O)C(*)*',
|
|
308
|
-
}
|
|
342
|
+
};
|
|
309
343
|
|
|
310
344
|
/**
|
|
311
345
|
* Amino acid residue full names.
|
|
@@ -335,7 +369,7 @@ export class ChemPalette {
|
|
|
335
369
|
'Trp': 'W',
|
|
336
370
|
'Tyr': 'Y',
|
|
337
371
|
'Val': 'V',
|
|
338
|
-
}
|
|
372
|
+
};
|
|
339
373
|
|
|
340
374
|
/**
|
|
341
375
|
* Get Datagrok palette.
|
|
@@ -52,40 +52,30 @@ export function cleanAlignedSequencesColumn(col: DG.Column): Array<string> {
|
|
|
52
52
|
* @return {Promise<DG.ScatterPlotViewer>} A viewer.
|
|
53
53
|
*/
|
|
54
54
|
export async function createPeptideSimilaritySpaceViewer(
|
|
55
|
-
table: DG.DataFrame,
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
measure: string,
|
|
59
|
-
cyclesCount: number,
|
|
60
|
-
view: DG.TableView | null,
|
|
61
|
-
activityColumnName?: string | null,
|
|
62
|
-
): Promise<DG.ScatterPlotViewer> {
|
|
63
|
-
const pi = DG.TaskBarProgressIndicator.create('Creating embedding.');
|
|
55
|
+
table: DG.DataFrame, alignedSequencesColumn: DG.Column, method: string, measure: string, cyclesCount: number,
|
|
56
|
+
view: DG.TableView | null, activityColumnName?: string | null): Promise<DG.ScatterPlotViewer> {
|
|
57
|
+
const pi = DG.TaskBarProgressIndicator.create('Creating embedding...');
|
|
64
58
|
|
|
65
59
|
activityColumnName = activityColumnName ?? inferActivityColumnsName(table);
|
|
66
60
|
|
|
67
61
|
const axesNames = ['~X', '~Y', '~MW'];
|
|
68
62
|
const columnData = alignedSequencesColumn.toList().map((v, _) => AlignedSequenceEncoder.clean(v));
|
|
69
63
|
|
|
70
|
-
const embcols = await createDimensinalityReducingWorker(
|
|
64
|
+
const embcols = await createDimensinalityReducingWorker(
|
|
65
|
+
{data: columnData, metric: measure as StringMetrics}, method, cyclesCount);
|
|
71
66
|
|
|
72
67
|
const columns = Array.from(
|
|
73
|
-
embcols as Coordinates,
|
|
74
|
-
|
|
75
|
-
)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
for (let i = 0; i < sequences.length; ++i) {
|
|
82
|
-
currentSequence = sequences[i];
|
|
83
|
-
mw[i] = currentSequence == null ? 0 : getSequenceMolecularWeight(currentSequence);
|
|
84
|
-
}
|
|
68
|
+
embcols as Coordinates, (v: Float32Array, k) => DG.Column.fromFloat32Array(axesNames[k], v));
|
|
69
|
+
|
|
70
|
+
function _getMW(sequences: string[]) {
|
|
71
|
+
const mw: Float32Array = new Float32Array(sequences.length);
|
|
72
|
+
|
|
73
|
+
mw.map((_, index) => getSequenceMolecularWeight(sequences[index] ?? ''));
|
|
74
|
+
|
|
85
75
|
return mw;
|
|
86
76
|
}
|
|
87
77
|
|
|
88
|
-
columns.push(DG.Column.fromFloat32Array('~MW', _getMW()));
|
|
78
|
+
columns.push(DG.Column.fromFloat32Array('~MW', _getMW(columnData)));
|
|
89
79
|
|
|
90
80
|
const edf = DG.DataFrame.fromColumns(columns);
|
|
91
81
|
|
|
@@ -103,11 +93,11 @@ export async function createPeptideSimilaritySpaceViewer(
|
|
|
103
93
|
table.columns.insert(newCol);
|
|
104
94
|
}
|
|
105
95
|
|
|
106
|
-
const viewerOptions = {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
96
|
+
const viewerOptions = {
|
|
97
|
+
x: '~X', y: '~Y', color: activityColumnName ?? '~MW', size: '~MW', title: 'Peptide Space', showYSelector: false,
|
|
98
|
+
showXSelector: false, showColorSelector: false, showSizeSelector: false,
|
|
99
|
+
};
|
|
100
|
+
const viewer = table.plot.scatter(viewerOptions);
|
|
111
101
|
|
|
112
102
|
pi.close();
|
|
113
103
|
return viewer;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as DG from 'datagrok-api/dg';
|
|
1
|
+
// import * as DG from 'datagrok-api/dg';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Split aligned sequence string into separate parts containing amino acid residues.
|
|
@@ -8,65 +8,65 @@ import * as DG from 'datagrok-api/dg';
|
|
|
8
8
|
* @param {boolean} [filter=true] Filter out columns with all the same residues.
|
|
9
9
|
* @return {[DG.DataFrame, number[]]} DataFrame containing split sequence and a list of invalid indexes.
|
|
10
10
|
*/
|
|
11
|
-
export function splitAlignedPeptides(peptideColumn: DG.Column, filter: boolean = true): [DG.DataFrame, number[]] {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
// export function splitAlignedPeptides(peptideColumn: DG.Column, filter: boolean = true): [DG.DataFrame, number[]] {
|
|
12
|
+
// const splitPeptidesArray: string[][] = [];
|
|
13
|
+
// let currentSplitPeptide: string[];
|
|
14
|
+
// let modeMonomerCount = 0;
|
|
15
|
+
// let currentLength;
|
|
16
|
+
// const colLength = peptideColumn.length;
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
18
|
+
// // splitting data
|
|
19
|
+
// const monomerLengths: {[index: string]: number} = {};
|
|
20
|
+
// for (let i = 0; i < colLength; i++) {
|
|
21
|
+
// currentSplitPeptide = peptideColumn.get(i).split('-').map((value: string) => value ? value : '-');
|
|
22
|
+
// splitPeptidesArray.push(currentSplitPeptide);
|
|
23
|
+
// currentLength = currentSplitPeptide.length;
|
|
24
|
+
// monomerLengths[currentLength + ''] =
|
|
25
|
+
// monomerLengths[currentLength + ''] ? monomerLengths[currentLength + ''] + 1 : 1;
|
|
26
|
+
// }
|
|
27
|
+
// //@ts-ignore: what I do here is converting string to number the most effective way I could find. parseInt is slow
|
|
28
|
+
// modeMonomerCount = 1 * Object.keys(monomerLengths).reduce((a, b) => monomerLengths[a] > monomerLengths[b] ? a : b);
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
30
|
+
// // making sure all of the sequences are of the same size
|
|
31
|
+
// // and marking invalid sequences
|
|
32
|
+
// let nTerminal: string;
|
|
33
|
+
// const invalidIndexes: number[] = [];
|
|
34
|
+
// let splitColumns: string[][] = Array.from({length: modeMonomerCount}, (_) => []);
|
|
35
|
+
// modeMonomerCount--; // minus N-terminal
|
|
36
|
+
// for (let i = 0; i < colLength; i++) {
|
|
37
|
+
// currentSplitPeptide = splitPeptidesArray[i];
|
|
38
|
+
// nTerminal = currentSplitPeptide.pop()!; // it is guaranteed that there will be at least one element
|
|
39
|
+
// currentLength = currentSplitPeptide.length;
|
|
40
|
+
// if (currentLength !== modeMonomerCount)
|
|
41
|
+
// invalidIndexes.push(i);
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
// for (let j = 0; j < modeMonomerCount; j++)
|
|
44
|
+
// splitColumns[j].push(j < currentLength ? currentSplitPeptide[j] : '-');
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
// splitColumns[modeMonomerCount].push(nTerminal);
|
|
47
|
+
// }
|
|
48
|
+
// modeMonomerCount--; // minus C-terminal
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
// //create column names list
|
|
51
|
+
// const columnNames = Array.from({length: modeMonomerCount}, (, index) => `${index + 1 < 10 ? 0 : ''}${index + 1 }`);
|
|
52
|
+
// columnNames.splice(0, 0, 'N-terminal');
|
|
53
|
+
// columnNames.push('C-terminal');
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
// // filter out the columns with the same values
|
|
56
|
+
// if (filter) {
|
|
57
|
+
// splitColumns = splitColumns.filter((positionArray, index) => {
|
|
58
|
+
// const isRetained = new Set(positionArray).size > 1;
|
|
59
|
+
// if (!isRetained)
|
|
60
|
+
// columnNames.splice(index, 1);
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
// return isRetained;
|
|
63
|
+
// });
|
|
64
|
+
// }
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
66
|
+
// return [
|
|
67
|
+
// DG.DataFrame.fromColumns(splitColumns.map((positionArray, index) => {
|
|
68
|
+
// return DG.Column.fromList('string', columnNames[index], positionArray);
|
|
69
|
+
// })),
|
|
70
|
+
// invalidIndexes,
|
|
71
|
+
// ];
|
|
72
|
+
// }
|