@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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datagrok/peptides",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.9",
|
|
4
4
|
"description": "",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@biowasm/aioli": ">=2.4.0",
|
|
@@ -8,11 +8,9 @@
|
|
|
8
8
|
"@datagrok-libraries/ml": ">=0.0.14",
|
|
9
9
|
"@datagrok-libraries/statistics": ">=0.1.5",
|
|
10
10
|
"@datagrok-libraries/utils": ">=0.0.22",
|
|
11
|
-
"@types/d3": "^7.0.0",
|
|
12
|
-
"@types/jquery": "^3.5.6",
|
|
13
11
|
"cash-dom": "latest",
|
|
14
12
|
"d3": "latest",
|
|
15
|
-
"datagrok-api": ">=0.
|
|
13
|
+
"datagrok-api": ">=0.123.0",
|
|
16
14
|
"dayjs": "latest",
|
|
17
15
|
"file-loader": "^6.2.0",
|
|
18
16
|
"jstat": "^1.9.5",
|
|
@@ -20,14 +18,16 @@
|
|
|
20
18
|
"rxjs": "^6.5.5"
|
|
21
19
|
},
|
|
22
20
|
"devDependencies": {
|
|
23
|
-
"@
|
|
24
|
-
"@
|
|
21
|
+
"@types/d3": "^7.0.0",
|
|
22
|
+
"@types/jquery": "^3.5.6",
|
|
23
|
+
"@typescript-eslint/eslint-plugin": "latest",
|
|
24
|
+
"@typescript-eslint/parser": "latest",
|
|
25
25
|
"css-loader": "^5.2.4",
|
|
26
|
-
"eslint": "
|
|
27
|
-
"eslint-config-google": "
|
|
26
|
+
"eslint": "latest",
|
|
27
|
+
"eslint-config-google": "latest",
|
|
28
28
|
"style-loader": "^2.0.0",
|
|
29
|
-
"ts-loader": "
|
|
30
|
-
"typescript": "
|
|
29
|
+
"ts-loader": "latest",
|
|
30
|
+
"typescript": "latest",
|
|
31
31
|
"webpack": "latest",
|
|
32
32
|
"webpack-cli": "latest"
|
|
33
33
|
},
|
package/src/describe.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import * as ui from 'datagrok-api/ui';
|
|
2
2
|
import * as DG from 'datagrok-api/dg';
|
|
3
|
-
import {splitAlignedPeptides} from './utils/split-aligned';
|
|
3
|
+
// import {splitAlignedPeptides} from './utils/split-aligned';
|
|
4
4
|
import {tTest} from '@datagrok-libraries/statistics/src/tests';
|
|
5
5
|
import {fdrcorrection} from '@datagrok-libraries/statistics/src/multiple-tests';
|
|
6
6
|
import {StringDictionary} from '@datagrok-libraries/utils/src/type-declarations';
|
|
7
7
|
import {ChemPalette} from './utils/chem-palette';
|
|
8
8
|
import {setAARRenderer} from './utils/cell-renderer';
|
|
9
|
+
import {PeptidesController} from './peptides';
|
|
9
10
|
|
|
10
11
|
const cp = new ChemPalette('grok');
|
|
11
12
|
|
|
@@ -54,26 +55,23 @@ const groupDescription: {[key: string]: {'description': string, 'aminoAcids': st
|
|
|
54
55
|
}
|
|
55
56
|
}*/
|
|
56
57
|
|
|
57
|
-
function joinDataFrames(
|
|
58
|
-
activityColumnScaled
|
|
59
|
-
df
|
|
60
|
-
positionColumns: string[],
|
|
61
|
-
splitSeqDf: DG.DataFrame,
|
|
62
|
-
activityColumn: string,
|
|
63
|
-
) {
|
|
64
|
-
if (df.col(activityColumnScaled))
|
|
65
|
-
(df.columns as DG.ColumnList).remove(activityColumnScaled);
|
|
58
|
+
function joinDataFrames(df: DG.DataFrame, positionColumns: string[], splitSeqDf: DG.DataFrame, activityColumn: string) {
|
|
59
|
+
// if (df.col(activityColumnScaled))
|
|
60
|
+
// (df.columns as DG.ColumnList).remove(activityColumnScaled);
|
|
66
61
|
|
|
67
62
|
|
|
68
63
|
//FIXME: this column usually duplicates, so remove it then
|
|
69
|
-
if (df.col(`${activityColumnScaled} (2)`))
|
|
70
|
-
|
|
64
|
+
// if (df.col(`${activityColumnScaled} (2)`))
|
|
65
|
+
// (df.columns as DG.ColumnList).remove(`${activityColumnScaled} (2)`);
|
|
71
66
|
|
|
72
67
|
|
|
73
68
|
// append splitSeqDf columns to source table and make sure columns are not added more than once
|
|
74
|
-
const dfColsSet = new Set(df.columns.names());
|
|
75
|
-
if (!positionColumns.every((col: string) => dfColsSet.has(col)))
|
|
76
|
-
df.join(
|
|
69
|
+
const dfColsSet = new Set((df.columns as DG.ColumnList).names());
|
|
70
|
+
if (!positionColumns.every((col: string) => dfColsSet.has(col))) {
|
|
71
|
+
df.join(
|
|
72
|
+
splitSeqDf, [activityColumn], [activityColumn], (df.columns as DG.ColumnList).names(), positionColumns, 'inner',
|
|
73
|
+
true);
|
|
74
|
+
}
|
|
77
75
|
}
|
|
78
76
|
|
|
79
77
|
function sortSourceGrid(sourceGrid: DG.Grid) {
|
|
@@ -96,35 +94,33 @@ function sortSourceGrid(sourceGrid: DG.Grid) {
|
|
|
96
94
|
}
|
|
97
95
|
}
|
|
98
96
|
|
|
99
|
-
async function scaleActivity(
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
}
|
|
97
|
+
// export async function scaleActivity(
|
|
98
|
+
// activityScaling: string, activityColumn: string, activityColumnScaled: string, df: DG.DataFrame,
|
|
99
|
+
// ): Promise<[DG.DataFrame, string]> {
|
|
100
|
+
// // const df = sourceGrid.dataFrame!;
|
|
101
|
+
// const tempDf = df.clone(null, [activityColumn]);
|
|
102
|
+
|
|
103
|
+
// let formula = '${' + activityColumn + '}';
|
|
104
|
+
// let newColName = activityColumn;
|
|
105
|
+
// switch (activityScaling) {
|
|
106
|
+
// case 'none':
|
|
107
|
+
// break;
|
|
108
|
+
// case 'lg':
|
|
109
|
+
// formula = `Log10(${formula})`;
|
|
110
|
+
// newColName = `Log10(${newColName})`;
|
|
111
|
+
// break;
|
|
112
|
+
// case '-lg':
|
|
113
|
+
// formula = `-1*Log10(${formula})`;
|
|
114
|
+
// newColName = `-Log10(${newColName})`;
|
|
115
|
+
// break;
|
|
116
|
+
// default:
|
|
117
|
+
// throw new Error(`ScalingError: method \`${activityScaling}\` is not available.`);
|
|
118
|
+
// }
|
|
119
|
+
|
|
120
|
+
// await (tempDf.columns as DG.ColumnList).addNewCalculated(activityColumnScaled, formula);
|
|
121
|
+
|
|
122
|
+
// return [tempDf, newColName];
|
|
123
|
+
// }
|
|
128
124
|
|
|
129
125
|
async function calculateStatistics(
|
|
130
126
|
matrixDf: DG.DataFrame,
|
|
@@ -145,12 +141,12 @@ async function calculateStatistics(
|
|
|
145
141
|
matrixDf = matrixDf.clone(matrixDf.filter);
|
|
146
142
|
|
|
147
143
|
// calculate additional stats
|
|
148
|
-
await matrixDf.columns.addNewCalculated('Ratio', '${count}/'.concat(`${peptidesCount}`));
|
|
144
|
+
await (matrixDf.columns as DG.ColumnList).addNewCalculated('Ratio', '${count}/'.concat(`${peptidesCount}`));
|
|
149
145
|
|
|
150
146
|
//calculate p-values based on t-test
|
|
151
147
|
let pvalues: Float32Array = new Float32Array(matrixDf.rowCount).fill(1);
|
|
152
|
-
const mdCol: DG.Column = matrixDf.columns.addNewFloat('Mean difference');
|
|
153
|
-
const pValCol: DG.Column = matrixDf.columns.addNewFloat('pValue');
|
|
148
|
+
const mdCol: DG.Column = (matrixDf.columns as DG.ColumnList).addNewFloat('Mean difference');
|
|
149
|
+
const pValCol: DG.Column = (matrixDf.columns as DG.ColumnList).addNewFloat('pValue');
|
|
154
150
|
for (let i = 0; i < matrixDf.rowCount; i++) {
|
|
155
151
|
const position = matrixDf.get(positionColName, i);
|
|
156
152
|
const aar = matrixDf.get(aminoAcidResidue, i);
|
|
@@ -194,7 +190,7 @@ async function setCategoryOrder(
|
|
|
194
190
|
) {
|
|
195
191
|
const sortArgument = twoColorMode ? 'Absolute Mean difference' : 'Mean difference';
|
|
196
192
|
if (twoColorMode)
|
|
197
|
-
await statsDf.columns.addNewCalculated('Absolute Mean difference', 'Abs(${Mean difference})');
|
|
193
|
+
await (statsDf.columns as DG.ColumnList).addNewCalculated('Absolute Mean difference', 'Abs(${Mean difference})');
|
|
198
194
|
|
|
199
195
|
const aarWeightsDf = statsDf.groupBy([aminoAcidResidue]).sum(sortArgument, 'weight').aggregate();
|
|
200
196
|
const aarList = aarWeightsDf.getCol(aminoAcidResidue).toList();
|
|
@@ -254,11 +250,11 @@ function createGrids(
|
|
|
254
250
|
sarVGrid.col('pValue')!.name = 'P-Value';
|
|
255
251
|
|
|
256
252
|
if (!grouping) {
|
|
257
|
-
let tempCol = matrixDf.columns.byName(aminoAcidResidue);
|
|
253
|
+
let tempCol = (matrixDf.columns as DG.ColumnList).byName(aminoAcidResidue);
|
|
258
254
|
if (tempCol)
|
|
259
255
|
setAARRenderer(tempCol, sarGrid);
|
|
260
256
|
|
|
261
|
-
tempCol = sequenceDf.columns.byName(aminoAcidResidue);
|
|
257
|
+
tempCol = (sequenceDf.columns as DG.ColumnList).byName(aminoAcidResidue);
|
|
262
258
|
if (tempCol)
|
|
263
259
|
setAARRenderer(tempCol, sarGrid);
|
|
264
260
|
}
|
|
@@ -267,14 +263,8 @@ function createGrids(
|
|
|
267
263
|
}
|
|
268
264
|
|
|
269
265
|
function setCellRendererFunc(
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
aminoAcidResidue: string,
|
|
273
|
-
statsDf: DG.DataFrame,
|
|
274
|
-
twoColorMode: boolean,
|
|
275
|
-
sarGrid: DG.Grid,
|
|
276
|
-
sarVGrid: DG.Grid,
|
|
277
|
-
) {
|
|
266
|
+
renderColNames: string[], positionColName: string, aminoAcidResidue: string, statsDf: DG.DataFrame,
|
|
267
|
+
twoColorMode: boolean, sarGrid: DG.Grid, sarVGrid: DG.Grid) {
|
|
278
268
|
const mdCol = statsDf.getCol('Mean difference');
|
|
279
269
|
const cellRendererFunc = function(args: DG.GridCellRenderArgs) {
|
|
280
270
|
args.g.save();
|
|
@@ -327,12 +317,8 @@ function setCellRendererFunc(
|
|
|
327
317
|
args.g.beginPath();
|
|
328
318
|
args.g.fillStyle = coef;
|
|
329
319
|
args.g.arc(
|
|
330
|
-
args.bounds.x + args.bounds.width / 2,
|
|
331
|
-
|
|
332
|
-
radius < 3 ? 3 : radius,
|
|
333
|
-
0,
|
|
334
|
-
Math.PI * 2,
|
|
335
|
-
true,
|
|
320
|
+
args.bounds.x + args.bounds.width / 2, args.bounds.y + args.bounds.height / 2, radius < 3 ? 3 : radius, 0,
|
|
321
|
+
Math.PI * 2, true,
|
|
336
322
|
);
|
|
337
323
|
args.g.closePath();
|
|
338
324
|
|
|
@@ -347,27 +333,15 @@ function setCellRendererFunc(
|
|
|
347
333
|
}
|
|
348
334
|
|
|
349
335
|
function setTooltipFunc(
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
aminoAcidResidue: string,
|
|
353
|
-
positionColName: string,
|
|
354
|
-
peptidesCount: number,
|
|
355
|
-
grouping: boolean,
|
|
356
|
-
sarGrid: DG.Grid,
|
|
357
|
-
sarVGrid: DG.Grid,
|
|
358
|
-
) {
|
|
336
|
+
renderColNames: string[], statsDf: DG.DataFrame, aminoAcidResidue: string, positionColName: string,
|
|
337
|
+
peptidesCount: number, grouping: boolean, sarGrid: DG.Grid, sarVGrid: DG.Grid) {
|
|
359
338
|
const onCellTooltipFunc = async function(cell: DG.GridCell, x: number, y: number) {
|
|
360
339
|
if (
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
cell.tableColumn !== null &&
|
|
364
|
-
cell.cell.value !== null &&
|
|
365
|
-
cell.tableRowIndex !== null &&
|
|
366
|
-
renderColNames.indexOf(cell.tableColumn.name) !== -1
|
|
367
|
-
) {
|
|
340
|
+
!cell.isRowHeader && !cell.isColHeader && cell.tableColumn !== null && cell.cell.value !== null &&
|
|
341
|
+
cell.tableRowIndex !== null && renderColNames.indexOf(cell.tableColumn.name) !== -1) {
|
|
368
342
|
const tooltipMap: { [index: string]: string } = {};
|
|
369
343
|
|
|
370
|
-
for (const col of statsDf.columns.names()) {
|
|
344
|
+
for (const col of (statsDf.columns as DG.ColumnList).names()) {
|
|
371
345
|
if (col !== aminoAcidResidue && col !== positionColName) {
|
|
372
346
|
const currentPosition = cell.tableColumn.name !== 'Mean difference' ?
|
|
373
347
|
cell.tableColumn.name : cell.grid.table.get(positionColName, cell.tableRowIndex);
|
|
@@ -412,7 +386,6 @@ function setTooltipFunc(
|
|
|
412
386
|
function postProcessGrids(
|
|
413
387
|
sourceGrid: DG.Grid,
|
|
414
388
|
invalidIndexes: number[],
|
|
415
|
-
matrixDf: DG.DataFrame,
|
|
416
389
|
grouping: boolean,
|
|
417
390
|
aminoAcidResidue: string,
|
|
418
391
|
sarGrid: DG.Grid,
|
|
@@ -424,9 +397,20 @@ function postProcessGrids(
|
|
|
424
397
|
cell.style.backColor = DG.Color.lightLightGray;
|
|
425
398
|
});
|
|
426
399
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
400
|
+
const mdCol: DG.GridColumn = sarVGrid.col('Mean difference')!;
|
|
401
|
+
mdCol.name = 'Diff';
|
|
402
|
+
|
|
403
|
+
for (const grid of [sarGrid, sarVGrid]) {
|
|
404
|
+
grid.props.rowHeight = 20;
|
|
405
|
+
grid.columns.rowHeader!.width = 20;
|
|
406
|
+
for (let i = 0; i < grid.columns.length; ++i) {
|
|
407
|
+
const col = grid.columns.byIndex(i)!;
|
|
408
|
+
if (grid == sarVGrid && col.name !== 'Diff' && col.name !== 'AAR')
|
|
409
|
+
col.width = 45;
|
|
410
|
+
else
|
|
411
|
+
col.width = grid.props.rowHeight;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
430
414
|
|
|
431
415
|
if (grouping) {
|
|
432
416
|
sarGrid.col(aminoAcidResidue)!.name = 'Groups';
|
|
@@ -435,8 +419,6 @@ function postProcessGrids(
|
|
|
435
419
|
|
|
436
420
|
sarGrid.props.allowEdit = false;
|
|
437
421
|
sarVGrid.props.allowEdit = false;
|
|
438
|
-
|
|
439
|
-
sarVGrid.col('Mean difference')!.name = 'Diff';
|
|
440
422
|
}
|
|
441
423
|
|
|
442
424
|
export async function describe(
|
|
@@ -451,28 +433,45 @@ export async function describe(
|
|
|
451
433
|
//Split the aligned sequence into separate AARs
|
|
452
434
|
let splitSeqDf: DG.DataFrame | undefined;
|
|
453
435
|
let invalidIndexes: number[];
|
|
454
|
-
const col: DG.Column = df.columns.bySemType('alignedSequence')
|
|
455
|
-
[splitSeqDf, invalidIndexes] = splitAlignedPeptides(col);
|
|
436
|
+
const col: DG.Column = (df.columns as DG.ColumnList).bySemType('alignedSequence')!;
|
|
437
|
+
[splitSeqDf, invalidIndexes] = PeptidesController.splitAlignedPeptides(col);
|
|
456
438
|
splitSeqDf.name = 'Split sequence';
|
|
457
439
|
|
|
458
|
-
const positionColumns = splitSeqDf.columns.names();
|
|
440
|
+
const positionColumns = (splitSeqDf.columns as DG.ColumnList).names();
|
|
459
441
|
const activityColumnScaled = `${activityColumn}Scaled`;
|
|
460
|
-
const renderColNames: string[] = splitSeqDf.columns.names();
|
|
461
|
-
const positionColName = '
|
|
442
|
+
const renderColNames: string[] = (splitSeqDf.columns as DG.ColumnList).names();
|
|
443
|
+
const positionColName = 'Pos';
|
|
462
444
|
const aminoAcidResidue = 'AAR';
|
|
463
445
|
|
|
464
|
-
splitSeqDf.columns.add(df.getCol(activityColumn));
|
|
446
|
+
(splitSeqDf.columns as DG.ColumnList).add(df.getCol(activityColumn));
|
|
465
447
|
|
|
466
|
-
joinDataFrames(
|
|
448
|
+
joinDataFrames(df, positionColumns, splitSeqDf, activityColumn);
|
|
467
449
|
|
|
468
|
-
for (const col of df.columns) {
|
|
450
|
+
for (const col of (df.columns as DG.ColumnList)) {
|
|
469
451
|
if (splitSeqDf.col(col.name) && col.name != activityColumn)
|
|
470
452
|
setAARRenderer(col, sourceGrid);
|
|
471
453
|
}
|
|
472
454
|
|
|
473
455
|
sortSourceGrid(sourceGrid);
|
|
474
456
|
|
|
475
|
-
|
|
457
|
+
const [scaledDf, newColName] = await PeptidesController.scaleActivity(
|
|
458
|
+
activityScaling, activityColumn, activityColumnScaled, df);
|
|
459
|
+
//TODO: make another func
|
|
460
|
+
const scaledCol = scaledDf.getCol(activityColumnScaled);
|
|
461
|
+
const oldScaledCol = df.getCol(activityColumnScaled);
|
|
462
|
+
const oldScaledColGridName = oldScaledCol.temp['gridName'];
|
|
463
|
+
const oldScaledGridCol = sourceGrid.col(oldScaledColGridName);
|
|
464
|
+
|
|
465
|
+
(splitSeqDf.columns as DG.ColumnList).add(scaledCol);
|
|
466
|
+
(df.columns as DG.ColumnList).replace(oldScaledCol, scaledCol);
|
|
467
|
+
if (newColName === activityColumn)
|
|
468
|
+
sourceGrid.col(activityColumn)!.name = `~${activityColumn}`;
|
|
469
|
+
if (oldScaledGridCol !== null) {
|
|
470
|
+
oldScaledGridCol.name = newColName;
|
|
471
|
+
oldScaledGridCol.visible = true;
|
|
472
|
+
}
|
|
473
|
+
sourceGrid.columns.setOrder([newColName]);
|
|
474
|
+
|
|
476
475
|
splitSeqDf = splitSeqDf.clone(initialBitset);
|
|
477
476
|
|
|
478
477
|
//unpivot a table and handle duplicates
|
|
@@ -528,7 +527,7 @@ export async function describe(
|
|
|
528
527
|
renderColNames, statsDf, aminoAcidResidue, positionColName, peptidesCount, grouping, sarGrid, sarVGrid,
|
|
529
528
|
);
|
|
530
529
|
|
|
531
|
-
postProcessGrids(sourceGrid, invalidIndexes,
|
|
530
|
+
postProcessGrids(sourceGrid, invalidIndexes, grouping, aminoAcidResidue, sarGrid, sarVGrid);
|
|
532
531
|
|
|
533
532
|
//TODO: return class instead
|
|
534
533
|
return [sarGrid, sarVGrid, statsDf, groupMapping];
|
package/src/model.ts
CHANGED
|
@@ -1,104 +1,125 @@
|
|
|
1
1
|
import * as DG from 'datagrok-api/dg';
|
|
2
2
|
|
|
3
3
|
import {describe} from './describe';
|
|
4
|
-
import {Subject} from 'rxjs';
|
|
4
|
+
import {Subject, Observable} from 'rxjs';
|
|
5
5
|
import {StringDictionary} from '@datagrok-libraries/utils/src/type-declarations';
|
|
6
|
+
import {addViewerToHeader, StackedBarChart} from './viewers/stacked-barchart-viewer';
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class SARViewerModel {
|
|
13
|
-
private viewerGrid: Subject<DG.Grid> = new Subject<DG.Grid>();
|
|
14
|
-
private viewerVGrid: Subject<DG.Grid> = new Subject<DG.Grid>();
|
|
15
|
-
private statsDf: Subject<DG.DataFrame> = new Subject<DG.DataFrame>();
|
|
16
|
-
private groupMapping: Subject<StringDictionary> = new Subject<StringDictionary>();
|
|
17
|
-
public viewerGrid$;
|
|
18
|
-
public viewerVGrid$;
|
|
19
|
-
public statsDf$;
|
|
20
|
-
public groupMapping$;
|
|
8
|
+
export class PeptidesModel {
|
|
9
|
+
// private _viewerGrid: DG.Grid;
|
|
10
|
+
// private viewerVGrid: DG.Grid;
|
|
11
|
+
// private _statsDf: DG.DataFrame;
|
|
12
|
+
// private groupMapping: StringDictionary;
|
|
21
13
|
private dataFrame: DG.DataFrame | null;
|
|
22
14
|
private activityColumn: string | null;
|
|
23
15
|
private activityScaling: string | null;
|
|
24
16
|
private sourceGrid: DG.Grid | null;
|
|
25
17
|
private twoColorMode: boolean | null;
|
|
26
18
|
private initialBitset: DG.BitSet | null;
|
|
27
|
-
private isUpdating = false;
|
|
28
|
-
grouping: boolean;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
19
|
+
private isUpdating: boolean = false;
|
|
20
|
+
private grouping: boolean = false;
|
|
21
|
+
private substFlag = false;
|
|
22
|
+
private statsDataFrameSubject = new Subject<DG.DataFrame>();
|
|
23
|
+
private sarGridSubject = new Subject<DG.Grid>();
|
|
24
|
+
private sarVGridSubject = new Subject<DG.Grid>();
|
|
25
|
+
private groupMappingSubject = new Subject<StringDictionary>();
|
|
26
|
+
private substFlagSubject = new Subject<boolean>();
|
|
27
|
+
private static _modelName = 'peptidesModel';
|
|
28
|
+
|
|
29
|
+
private constructor(dataFrame: DG.DataFrame) {
|
|
30
|
+
this.dataFrame = dataFrame;
|
|
37
31
|
this.activityColumn = null;
|
|
38
32
|
this.activityScaling = null;
|
|
39
33
|
this.sourceGrid = null;
|
|
40
34
|
this.twoColorMode = null;
|
|
41
35
|
this.initialBitset = null;
|
|
42
|
-
|
|
43
|
-
this.
|
|
44
|
-
this.
|
|
45
|
-
this.
|
|
46
|
-
this.groupMapping
|
|
36
|
+
|
|
37
|
+
// this._statsDf = DG.DataFrame.create();
|
|
38
|
+
// this._viewerGrid = DG.Grid.create(this.statsDf);
|
|
39
|
+
// this.viewerVGrid = DG.Grid.create(this.statsDf);
|
|
40
|
+
// this.groupMapping = {};
|
|
41
|
+
|
|
42
|
+
// this.statsDataFrameObservable = new Observable(subject => subject.next(this.statsDf));
|
|
43
|
+
// this.sarGridObservable = new Observable(subject => subject.next(this.viewerGrid));
|
|
44
|
+
// this.sarVGridObservable = new Observable(subject => subject.next(this.viewerVGrid));
|
|
45
|
+
// this.groupMappingObservable = new Observable(subject => subject.next(this.groupMapping));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// get statsDf() {
|
|
49
|
+
// return this._statsDf;
|
|
50
|
+
// }
|
|
51
|
+
|
|
52
|
+
// get viewerGrid() {
|
|
53
|
+
// return this._viewerGrid;
|
|
54
|
+
// }
|
|
55
|
+
|
|
56
|
+
get onStatsDataFrameChanged(): Observable<DG.DataFrame> {
|
|
57
|
+
return this.statsDataFrameSubject.asObservable();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
get onSARGridChanged(): Observable<DG.Grid> {
|
|
61
|
+
return this.sarGridSubject.asObservable();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
get onSARVGridChanged(): Observable<DG.Grid> {
|
|
65
|
+
return this.sarVGridSubject.asObservable();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
get onGroupMappingChanged(): Observable<StringDictionary> {
|
|
69
|
+
return this.groupMappingSubject.asObservable();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
get onSubstFlagChanged(): Observable<boolean> {
|
|
73
|
+
return this.substFlagSubject.asObservable();
|
|
47
74
|
}
|
|
48
75
|
|
|
49
|
-
/**
|
|
50
|
-
* Updates data with using specified parameters.
|
|
51
|
-
*
|
|
52
|
-
* @param {DG.DataFrame} df Working table.
|
|
53
|
-
* @param {string} activityCol Activity column name.
|
|
54
|
-
* @param {string} activityScaling Activity scaling method.
|
|
55
|
-
* @param {DG.Grid} sourceGrid Working table grid.
|
|
56
|
-
* @param {boolean} twoColorMode Bidirectional analysis enabled.
|
|
57
|
-
* @param {(DG.BitSet | null)} initialBitset Initial bitset.
|
|
58
|
-
* @param {boolean} grouping Grouping enabled.
|
|
59
|
-
* @memberof SARViewerModel
|
|
60
|
-
*/
|
|
61
76
|
async updateData(
|
|
62
|
-
df: DG.DataFrame,
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
this.
|
|
71
|
-
this.activityColumn = activityCol;
|
|
72
|
-
this.activityScaling = activityScaling;
|
|
73
|
-
this.sourceGrid = sourceGrid;
|
|
74
|
-
this.twoColorMode = twoColorMode;
|
|
75
|
-
this.initialBitset = initialBitset;
|
|
76
|
-
this.grouping = grouping;
|
|
77
|
+
df: DG.DataFrame | null, activityCol: string | null, activityScaling: string | null, sourceGrid: DG.Grid | null,
|
|
78
|
+
twoColorMode: boolean | null, initialBitset: DG.BitSet | null, grouping: boolean | null) {
|
|
79
|
+
this.dataFrame = df ?? this.dataFrame;
|
|
80
|
+
this.activityColumn = activityCol ?? this.activityColumn;
|
|
81
|
+
this.activityScaling = activityScaling ?? this.activityScaling;
|
|
82
|
+
this.sourceGrid = sourceGrid ?? this.sourceGrid;
|
|
83
|
+
this.twoColorMode = twoColorMode ?? this.twoColorMode;
|
|
84
|
+
this.initialBitset = initialBitset ?? this.initialBitset;
|
|
85
|
+
this.grouping = grouping ?? this.grouping;
|
|
77
86
|
await this.updateDefault();
|
|
78
87
|
}
|
|
79
88
|
|
|
80
|
-
/**
|
|
81
|
-
* Update data using current parameters.
|
|
82
|
-
*
|
|
83
|
-
* @memberof SARViewerModel
|
|
84
|
-
*/
|
|
85
89
|
async updateDefault() {
|
|
86
|
-
if (
|
|
87
|
-
|
|
88
|
-
this.sourceGrid && this.twoColorMode !== null && !this.isUpdating
|
|
89
|
-
) {
|
|
90
|
+
if (this.dataFrame && this.activityColumn && this.activityScaling && this.sourceGrid &&
|
|
91
|
+
this.twoColorMode !== null && !this.isUpdating) {
|
|
90
92
|
this.isUpdating = true;
|
|
91
93
|
const [viewerGrid, viewerVGrid, statsDf, groupMapping] = await describe(
|
|
92
|
-
this.dataFrame, this.activityColumn, this.activityScaling,
|
|
93
|
-
this.
|
|
94
|
-
);
|
|
95
|
-
this.
|
|
96
|
-
this.
|
|
97
|
-
this.
|
|
98
|
-
this.
|
|
94
|
+
this.dataFrame, this.activityColumn, this.activityScaling, this.sourceGrid, this.twoColorMode,
|
|
95
|
+
this.initialBitset, this.grouping);
|
|
96
|
+
this.statsDataFrameSubject.next(statsDf);
|
|
97
|
+
this.groupMappingSubject.next(groupMapping);
|
|
98
|
+
this.sarGridSubject.next(viewerGrid);
|
|
99
|
+
this.sarVGridSubject.next(viewerVGrid);
|
|
100
|
+
this.substFlag = !this.substFlag;
|
|
101
|
+
this.substFlagSubject.next(this.substFlag);
|
|
102
|
+
|
|
103
|
+
this.sourceGrid.invalidate();
|
|
104
|
+
|
|
99
105
|
this.isUpdating = false;
|
|
100
106
|
}
|
|
107
|
+
|
|
108
|
+
await this.updateBarchart();
|
|
101
109
|
}
|
|
102
|
-
}
|
|
103
110
|
|
|
104
|
-
|
|
111
|
+
async updateBarchart() {
|
|
112
|
+
const stackedBarchart = await this.dataFrame?.plot.fromType('StackedBarChartAA') as StackedBarChart;
|
|
113
|
+
if (stackedBarchart && this.sourceGrid)
|
|
114
|
+
addViewerToHeader(this.sourceGrid, stackedBarchart);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
static get modelName() {
|
|
118
|
+
return PeptidesModel._modelName;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
static getOrInit(dataFrame: DG.DataFrame): PeptidesModel {
|
|
122
|
+
dataFrame.temp[PeptidesModel.modelName] ??= new PeptidesModel(dataFrame);
|
|
123
|
+
return dataFrame.temp[PeptidesModel.modelName];
|
|
124
|
+
}
|
|
125
|
+
}
|
package/src/monomer-library.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import * as ui from 'datagrok-api/ui';
|
|
2
|
-
import * as DG from 'datagrok-api/dg';
|
|
3
|
-
import * as grok from 'datagrok-api/grok';
|
|
4
|
-
|
|
5
1
|
/** HELM associated sdf libraries with monomer processing*/
|
|
6
2
|
export class MonomerLibrary {
|
|
7
|
-
private monomerFields: string[] = [
|
|
3
|
+
private monomerFields: string[] = [
|
|
4
|
+
'molecule', 'MonomerType', 'MonomerNaturalAnalogCode', 'MonomerName', 'MonomerCode', 'MonomerCaps', 'BranchMonomer',
|
|
5
|
+
];
|
|
8
6
|
private library: {
|
|
9
7
|
[name: string]: {
|
|
10
8
|
mol: string,
|
|
@@ -17,13 +15,13 @@ export class MonomerLibrary {
|
|
|
17
15
|
|
|
18
16
|
constructor(sdf: string) {
|
|
19
17
|
const sdfReader = new SDFReader();
|
|
20
|
-
const data = sdfReader.
|
|
18
|
+
const data = sdfReader.getColls(sdf);
|
|
21
19
|
this.monomerFields.forEach((f) => {
|
|
22
20
|
if (!(f in data))
|
|
23
|
-
throw `Monomer library was not compiled: ${f} field is absent in provided file
|
|
21
|
+
throw new Error(`Monomer library was not compiled: ${f} field is absent in provided file`);
|
|
24
22
|
|
|
25
23
|
if (data[f].length != data.molecule.length)
|
|
26
|
-
throw `Monomer library was not compiled: ${f} field is not presented for each monomer
|
|
24
|
+
throw new Error(`Monomer library was not compiled: ${f} field is not presented for each monomer`);
|
|
27
25
|
});
|
|
28
26
|
|
|
29
27
|
for (let i = 0; i < data.molecule.length; i++) {
|
|
@@ -45,7 +43,7 @@ export class MonomerLibrary {
|
|
|
45
43
|
/** getting full monomer information from monomer library*/
|
|
46
44
|
public getMonomerEntry(name: string) {
|
|
47
45
|
if (!this.monomers.includes(name))
|
|
48
|
-
throw `Monomer library do not contain ${name} monomer
|
|
46
|
+
throw new Error(`Monomer library do not contain ${name} monomer`);
|
|
49
47
|
|
|
50
48
|
|
|
51
49
|
return this.library[name];
|
|
@@ -54,7 +52,7 @@ export class MonomerLibrary {
|
|
|
54
52
|
/** getting mol as string for monomer*/
|
|
55
53
|
public getMonomerMol(name: string) {
|
|
56
54
|
if (!this.monomers.includes(name))
|
|
57
|
-
throw `Monomer library do not contain ${name} monomer
|
|
55
|
+
throw new Error(`Monomer library do not contain ${name} monomer`);
|
|
58
56
|
|
|
59
57
|
|
|
60
58
|
const entry = this.library[name];
|
|
@@ -77,7 +75,7 @@ export class MonomerLibrary {
|
|
|
77
75
|
private getLinkData(mol: string, caps: string, name: string) {
|
|
78
76
|
const rawData = mol.match(/M RGP .+/);
|
|
79
77
|
if (rawData === null)
|
|
80
|
-
throw `Monomer library was not compiled: ${name} entry has no RGP
|
|
78
|
+
throw new Error(`Monomer library was not compiled: ${name} entry has no RGP`);
|
|
81
79
|
|
|
82
80
|
|
|
83
81
|
const types: { [code: string]: string } = {};
|
|
@@ -118,7 +116,7 @@ class SDFReader {
|
|
|
118
116
|
this.dataColls = {'molecule': []};
|
|
119
117
|
}
|
|
120
118
|
|
|
121
|
-
|
|
119
|
+
getColls(content: string) {
|
|
122
120
|
this.read(content);
|
|
123
121
|
return this.dataColls;
|
|
124
122
|
}
|
package/src/package-test.ts
CHANGED
|
@@ -10,10 +10,10 @@ export const _package = new DG.Package();
|
|
|
10
10
|
|
|
11
11
|
//name: test
|
|
12
12
|
//input: string category {optional: true}
|
|
13
|
-
//input: string
|
|
13
|
+
//input: string t {optional: true}
|
|
14
14
|
//output: dataframe result
|
|
15
15
|
//top-menu: Tools | Dev | JS API Tests
|
|
16
|
-
export async function test(category: string,
|
|
17
|
-
const data = await runTests({category, test});
|
|
16
|
+
export async function test(category: string, t: string): Promise<DG.DataFrame> {
|
|
17
|
+
const data = await runTests({category, test: t});
|
|
18
18
|
return DG.DataFrame.fromObjects(data)!;
|
|
19
19
|
}
|