@datagrok/peptides 0.8.5 → 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 CHANGED
@@ -1,18 +1,16 @@
1
1
  {
2
2
  "name": "@datagrok/peptides",
3
- "version": "0.8.5",
3
+ "version": "0.8.9",
4
4
  "description": "",
5
5
  "dependencies": {
6
6
  "@biowasm/aioli": ">=2.4.0",
7
7
  "@datagrok-libraries/bio": ">=0.0.4",
8
- "@datagrok-libraries/ml": ">=0.0.10",
8
+ "@datagrok-libraries/ml": ">=0.0.14",
9
9
  "@datagrok-libraries/statistics": ">=0.1.5",
10
- "@datagrok-libraries/utils": ">=0.0.18",
11
- "@types/d3": "^7.0.0",
12
- "@types/jquery": "^3.5.6",
10
+ "@datagrok-libraries/utils": ">=0.0.22",
13
11
  "cash-dom": "latest",
14
12
  "d3": "latest",
15
- "datagrok-api": ">=0.104.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,20 +18,20 @@
20
18
  "rxjs": "^6.5.5"
21
19
  },
22
20
  "devDependencies": {
23
- "@typescript-eslint/eslint-plugin": "^4.29.1",
24
- "@typescript-eslint/parser": "^4.29.1",
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": "^7.32.0",
27
- "eslint-config-google": "^0.14.0",
26
+ "eslint": "latest",
27
+ "eslint-config-google": "latest",
28
28
  "style-loader": "^2.0.0",
29
- "ts-loader": "^9.2.5",
30
- "typescript": "^4.4.4",
29
+ "ts-loader": "latest",
30
+ "typescript": "latest",
31
31
  "webpack": "latest",
32
32
  "webpack-cli": "latest"
33
33
  },
34
34
  "sources": [
35
- "files/aligned.csv",
36
- "files/aligned_2.csv",
37
35
  "common/ngl_viewer/ngl.js"
38
36
  ],
39
37
  "scripts": {
package/setup.cmd ADDED
@@ -0,0 +1,18 @@
1
+ call npm unlink datagrok-api
2
+ call npm unlink @datagrok-libraries/utils
3
+ call npm unlink @datagrok-libraries/ml
4
+ cd ../../js-api
5
+ call npm install
6
+ call npm link
7
+ cd ../libraries/utils
8
+ call npm install
9
+ call npm link
10
+ call npm link datagrok-api
11
+ cd ../../libraries/ml
12
+ call npm install
13
+ call npm link
14
+ call npm link @datagrok-libraries/utils
15
+ cd ../../packages/Peptides
16
+ call npm install
17
+ call npm link datagrok-api @datagrok-libraries/utils @datagrok-libraries/ml
18
+ webpack
package/setup.sh ADDED
@@ -0,0 +1,15 @@
1
+ npm unlink datagrok-api
2
+ npm unlink @datagrok-libraries/utils
3
+ npm unlink @datagrok-libraries/ml
4
+ cd ../../js-api
5
+ npm install
6
+ npm link
7
+ cd ../libraries/utils
8
+ npm install
9
+ npm link
10
+ cd ../../libraries/ml
11
+ npm install
12
+ npm link datagrok-api @datagrok-libraries/utils
13
+ cd ../../packages/Peptides
14
+ npm install
15
+ npm link datagrok-api @datagrok-libraries/utils @datagrok-libraries/ml
package/src/describe.ts CHANGED
@@ -1,10 +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
+ import {StringDictionary} from '@datagrok-libraries/utils/src/type-declarations';
6
7
  import {ChemPalette} from './utils/chem-palette';
7
8
  import {setAARRenderer} from './utils/cell-renderer';
9
+ import {PeptidesController} from './peptides';
8
10
 
9
11
  const cp = new ChemPalette('grok');
10
12
 
@@ -53,80 +55,72 @@ const groupDescription: {[key: string]: {'description': string, 'aminoAcids': st
53
55
  }
54
56
  }*/
55
57
 
56
- function joinDataFrames(
57
- activityColumnScaled: string,
58
- df: DG.DataFrame,
59
- positionColumns: string[],
60
- splitSeqDf: DG.DataFrame,
61
- activityColumn: string,
62
- ) {
63
- if (df.col(activityColumnScaled)) {
64
- df.columns.remove(activityColumnScaled);
65
- }
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);
61
+
66
62
 
67
63
  //FIXME: this column usually duplicates, so remove it then
68
- if (df.col(`${activityColumnScaled} (2)`)) {
69
- df.columns.remove(`${activityColumnScaled} (2)`);
70
- }
64
+ // if (df.col(`${activityColumnScaled} (2)`))
65
+ // (df.columns as DG.ColumnList).remove(`${activityColumnScaled} (2)`);
66
+
71
67
 
72
68
  // append splitSeqDf columns to source table and make sure columns are not added more than once
73
- const dfColsSet = new Set(df.columns.names());
69
+ const dfColsSet = new Set((df.columns as DG.ColumnList).names());
74
70
  if (!positionColumns.every((col: string) => dfColsSet.has(col))) {
75
- df.join(splitSeqDf, [activityColumn], [activityColumn], df.columns.names(), positionColumns, 'inner', true);
71
+ df.join(
72
+ splitSeqDf, [activityColumn], [activityColumn], (df.columns as DG.ColumnList).names(), positionColumns, 'inner',
73
+ true);
76
74
  }
77
75
  }
78
76
 
79
77
  function sortSourceGrid(sourceGrid: DG.Grid) {
80
78
  if (sourceGrid) {
81
- const colNames:string[] = [];
82
- for (let i = 0; i < sourceGrid.columns.length; i++) {
83
- colNames.push(sourceGrid.columns.byIndex(i)!.name);
84
- }
79
+ const colNames: DG.GridColumn[] = [];
80
+ for (let i = 1; i < sourceGrid.columns.length; i++)
81
+ colNames.push(sourceGrid.columns.byIndex(i)!);
82
+
85
83
  colNames.sort((a, b)=>{
86
- if (sourceGrid.columns.byName(a)?.column?.semType == 'aminoAcids') {
87
- if (sourceGrid.columns.byName(b)?.column?.semType == 'aminoAcids') {
84
+ if (a.column!.semType == 'aminoAcids') {
85
+ if (b.column!.semType == 'aminoAcids')
88
86
  return 0;
89
- }
90
87
  return -1;
91
88
  }
92
- if (sourceGrid.columns.byName(b)?.column?.semType == 'aminoAcids') {
89
+ if (b.column!.semType == 'aminoAcids')
93
90
  return 1;
94
- }
95
91
  return 0;
96
92
  });
97
- sourceGrid?.columns.setOrder(colNames);
93
+ sourceGrid.columns.setOrder(colNames.map((v) => v.name));
98
94
  }
99
95
  }
100
96
 
101
- async function scaleActivity(
102
- activityScaling: string,
103
- activityColumn: string,
104
- activityColumnScaled: string,
105
- sourceGrid: DG.Grid,
106
- splitSeqDf: DG.DataFrame,
107
- ) {
108
- const df = sourceGrid.dataFrame!;
109
- switch (activityScaling) {
110
- case 'lg':
111
- await df.columns.addNewCalculated(activityColumnScaled, 'Log10(${' + activityColumn + '})');
112
- splitSeqDf.columns.add(df.getCol(activityColumnScaled));
113
- sourceGrid.col(activityColumnScaled)!.name = `Log10(${activityColumn})`;
114
- sourceGrid.columns.setOrder([`Log10(${activityColumn})`]);
115
- break;
116
- case '-lg':
117
- await df.columns.addNewCalculated(activityColumnScaled, '-1*Log10(${' + activityColumn + '})');
118
- splitSeqDf.columns.add(df.getCol(activityColumnScaled));
119
- sourceGrid.col(activityColumnScaled)!.name = `-Log10(${activityColumn})`;
120
- sourceGrid.columns.setOrder([`-Log10(${activityColumn})`]);
121
- break;
122
- default:
123
- await df.columns.addNewCalculated(activityColumnScaled, '${' + activityColumn + '}');
124
- splitSeqDf.columns.add(df.getCol(activityColumnScaled));
125
- sourceGrid.col(activityColumnScaled)!.name = `${activityColumn}`;
126
- sourceGrid.columns.setOrder([`${activityColumn}`]);
127
- break;
128
- }
129
- }
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
+ // }
130
124
 
131
125
  async function calculateStatistics(
132
126
  matrixDf: DG.DataFrame,
@@ -135,7 +129,7 @@ async function calculateStatistics(
135
129
  activityColumnScaled: string,
136
130
  peptidesCount: number,
137
131
  splitSeqDf: DG.DataFrame,
138
- groupMapping: {[key: string]: string},
132
+ groupMapping: StringDictionary,
139
133
  ) {
140
134
  matrixDf = matrixDf.groupBy([positionColName, aminoAcidResidue])
141
135
  .add('count', activityColumnScaled, 'Count')
@@ -147,12 +141,12 @@ async function calculateStatistics(
147
141
  matrixDf = matrixDf.clone(matrixDf.filter);
148
142
 
149
143
  // calculate additional stats
150
- await matrixDf.columns.addNewCalculated('Ratio', '${count}/'.concat(`${peptidesCount}`));
144
+ await (matrixDf.columns as DG.ColumnList).addNewCalculated('Ratio', '${count}/'.concat(`${peptidesCount}`));
151
145
 
152
146
  //calculate p-values based on t-test
153
147
  let pvalues: Float32Array = new Float32Array(matrixDf.rowCount).fill(1);
154
- const mdCol: DG.Column = matrixDf.columns.addNewFloat('Mean difference');
155
- 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');
156
150
  for (let i = 0; i < matrixDf.rowCount; i++) {
157
151
  const position = matrixDf.get(positionColName, i);
158
152
  const aar = matrixDf.get(aminoAcidResidue, i);
@@ -180,13 +174,13 @@ async function calculateStatistics(
180
174
  pvalues[i] = pvalue;
181
175
  }
182
176
 
183
- if (true) {
177
+ if (true)
184
178
  pvalues = fdrcorrection(pvalues)[1];
185
- }
186
179
 
187
- for (let i = 0; i < pvalues.length; ++i) {
180
+
181
+ for (let i = 0; i < pvalues.length; ++i)
188
182
  pValCol.set(i, pvalues[i]);
189
- }
183
+
190
184
 
191
185
  return matrixDf.clone();
192
186
  }
@@ -195,9 +189,9 @@ async function setCategoryOrder(
195
189
  twoColorMode: boolean, statsDf: DG.DataFrame, aminoAcidResidue: string, matrixDf: DG.DataFrame,
196
190
  ) {
197
191
  const sortArgument = twoColorMode ? 'Absolute Mean difference' : 'Mean difference';
198
- if (twoColorMode) {
199
- await statsDf.columns.addNewCalculated('Absolute Mean difference', 'Abs(${Mean difference})');
200
- }
192
+ if (twoColorMode)
193
+ await (statsDf.columns as DG.ColumnList).addNewCalculated('Absolute Mean difference', 'Abs(${Mean difference})');
194
+
201
195
  const aarWeightsDf = statsDf.groupBy([aminoAcidResidue]).sum(sortArgument, 'weight').aggregate();
202
196
  const aarList = aarWeightsDf.getCol(aminoAcidResidue).toList();
203
197
  const getWeight = (aar: string) => aarWeightsDf
@@ -256,28 +250,21 @@ function createGrids(
256
250
  sarVGrid.col('pValue')!.name = 'P-Value';
257
251
 
258
252
  if (!grouping) {
259
- let tempCol = matrixDf.columns.byName(aminoAcidResidue);
260
- if (tempCol) {
253
+ let tempCol = (matrixDf.columns as DG.ColumnList).byName(aminoAcidResidue);
254
+ if (tempCol)
261
255
  setAARRenderer(tempCol, sarGrid);
262
- }
263
- tempCol = sequenceDf.columns.byName(aminoAcidResidue);
264
- if (tempCol) {
256
+
257
+ tempCol = (sequenceDf.columns as DG.ColumnList).byName(aminoAcidResidue);
258
+ if (tempCol)
265
259
  setAARRenderer(tempCol, sarGrid);
266
- }
267
260
  }
268
261
 
269
262
  return [sarGrid, sarVGrid];
270
263
  }
271
264
 
272
265
  function setCellRendererFunc(
273
- renderColNames: string[],
274
- positionColName: string,
275
- aminoAcidResidue: string,
276
- statsDf: DG.DataFrame,
277
- twoColorMode: boolean,
278
- sarGrid: DG.Grid,
279
- sarVGrid: DG.Grid,
280
- ) {
266
+ renderColNames: string[], positionColName: string, aminoAcidResidue: string, statsDf: DG.DataFrame,
267
+ twoColorMode: boolean, sarGrid: DG.Grid, sarVGrid: DG.Grid) {
281
268
  const mdCol = statsDf.getCol('Mean difference');
282
269
  const cellRendererFunc = function(args: DG.GridCellRenderArgs) {
283
270
  args.g.save();
@@ -308,15 +295,15 @@ function setCellRendererFunc(
308
295
 
309
296
  let coef;
310
297
  const variant = args.cell.cell.value < 0;
311
- if (pVal < 0.01) {
298
+ if (pVal < 0.01)
312
299
  coef = variant && twoColorMode ? '#FF7900' : '#299617';
313
- } else if (pVal < 0.05) {
300
+ else if (pVal < 0.05)
314
301
  coef = variant && twoColorMode ? '#FFA500' : '#32CD32';
315
- } else if (pVal < 0.1) {
302
+ else if (pVal < 0.1)
316
303
  coef = variant && twoColorMode ? '#FBCEB1' : '#98FF98';
317
- } else {
304
+ else
318
305
  coef = DG.Color.toHtml(DG.Color.lightLightGray);
319
- }
306
+
320
307
 
321
308
  const chooseMin = () => twoColorMode ? 0 : mdCol.min;
322
309
  const chooseMax = () => twoColorMode ? Math.max(Math.abs(mdCol.min), mdCol.max) : mdCol.max;
@@ -330,12 +317,8 @@ function setCellRendererFunc(
330
317
  args.g.beginPath();
331
318
  args.g.fillStyle = coef;
332
319
  args.g.arc(
333
- args.bounds.x + args.bounds.width / 2,
334
- args.bounds.y + args.bounds.height / 2,
335
- radius < 3 ? 3 : radius,
336
- 0,
337
- Math.PI * 2,
338
- 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,
339
322
  );
340
323
  args.g.closePath();
341
324
 
@@ -350,27 +333,15 @@ function setCellRendererFunc(
350
333
  }
351
334
 
352
335
  function setTooltipFunc(
353
- renderColNames: string[],
354
- statsDf: DG.DataFrame,
355
- aminoAcidResidue: string,
356
- positionColName: string,
357
- peptidesCount: number,
358
- grouping: boolean,
359
- sarGrid: DG.Grid,
360
- sarVGrid: DG.Grid,
361
- ) {
362
- const onCellTooltipFunc = function(cell: DG.GridCell, x: number, y: number) {
336
+ renderColNames: string[], statsDf: DG.DataFrame, aminoAcidResidue: string, positionColName: string,
337
+ peptidesCount: number, grouping: boolean, sarGrid: DG.Grid, sarVGrid: DG.Grid) {
338
+ const onCellTooltipFunc = async function(cell: DG.GridCell, x: number, y: number) {
363
339
  if (
364
- !cell.isRowHeader &&
365
- !cell.isColHeader &&
366
- cell.tableColumn !== null &&
367
- cell.cell.value !== null &&
368
- cell.tableRowIndex !== null &&
369
- renderColNames.indexOf(cell.tableColumn.name) !== -1
370
- ) {
340
+ !cell.isRowHeader && !cell.isColHeader && cell.tableColumn !== null && cell.cell.value !== null &&
341
+ cell.tableRowIndex !== null && renderColNames.indexOf(cell.tableColumn.name) !== -1) {
371
342
  const tooltipMap: { [index: string]: string } = {};
372
343
 
373
- for (const col of statsDf.columns.names()) {
344
+ for (const col of (statsDf.columns as DG.ColumnList).names()) {
374
345
  if (col !== aminoAcidResidue && col !== positionColName) {
375
346
  const currentPosition = cell.tableColumn.name !== 'Mean difference' ?
376
347
  cell.tableColumn.name : cell.grid.table.get(positionColName, cell.tableRowIndex);
@@ -380,11 +351,11 @@ function setTooltipFunc(
380
351
  const textNum = statsDf.groupBy([col]).where(query).aggregate().get(col, 0);
381
352
  let text = `${col === 'Count' ? textNum : textNum.toFixed(5)}`;
382
353
 
383
- if (col === 'Count') {
354
+ if (col === 'Count')
384
355
  text += ` / ${peptidesCount}`;
385
- } else if (col === 'pValue') {
356
+ else if (col === 'pValue')
386
357
  text = parseFloat(text) !== 0 ? text : '<0.01';
387
- }
358
+
388
359
 
389
360
  tooltipMap[col === 'pValue' ? 'p-value' : col] = text;
390
361
  }
@@ -403,9 +374,8 @@ function setTooltipFunc(
403
374
  const currentGroup = groupDescription[cell.cell.value];
404
375
  const divText = ui.divText('Amino Acids in this group: ' + currentGroup['aminoAcids'].join(', '));
405
376
  ui.tooltip.show(ui.divV([ui.h3(currentGroup['description']), divText]), x, y);
406
- } else {
407
- cp.showTooltip(cell, x, y);
408
- }
377
+ } else
378
+ await cp.showTooltip(cell, x, y);
409
379
  }
410
380
  return true;
411
381
  };
@@ -416,7 +386,6 @@ function setTooltipFunc(
416
386
  function postProcessGrids(
417
387
  sourceGrid: DG.Grid,
418
388
  invalidIndexes: number[],
419
- matrixDf: DG.DataFrame,
420
389
  grouping: boolean,
421
390
  aminoAcidResidue: string,
422
391
  sarGrid: DG.Grid,
@@ -424,13 +393,23 @@ function postProcessGrids(
424
393
  ) {
425
394
  sourceGrid.onCellPrepare((cell: DG.GridCell) => {
426
395
  const currentRowIndex = cell.tableRowIndex;
427
- if (currentRowIndex && invalidIndexes.includes(currentRowIndex) && !cell.isRowHeader) {
396
+ if (currentRowIndex && invalidIndexes.includes(currentRowIndex) && !cell.isRowHeader)
428
397
  cell.style.backColor = DG.Color.lightLightGray;
429
- }
430
398
  });
431
399
 
432
- for (const col of matrixDf.columns.names()) {
433
- sarGrid.col(col)!.width = sarGrid.props.rowHeight;
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
+ }
434
413
  }
435
414
 
436
415
  if (grouping) {
@@ -450,33 +429,49 @@ export async function describe(
450
429
  twoColorMode: boolean,
451
430
  initialBitset: DG.BitSet | null,
452
431
  grouping: boolean,
453
- ): Promise<[DG.Grid, DG.Grid, DG.DataFrame, {[key: string]: string}]> {
432
+ ): Promise<[DG.Grid, DG.Grid, DG.DataFrame, StringDictionary]> {
454
433
  //Split the aligned sequence into separate AARs
455
434
  let splitSeqDf: DG.DataFrame | undefined;
456
435
  let invalidIndexes: number[];
457
- const col: DG.Column = df.columns.bySemType('alignedSequence');
458
- [splitSeqDf, invalidIndexes] = splitAlignedPeptides(col);
436
+ const col: DG.Column = (df.columns as DG.ColumnList).bySemType('alignedSequence')!;
437
+ [splitSeqDf, invalidIndexes] = PeptidesController.splitAlignedPeptides(col);
459
438
  splitSeqDf.name = 'Split sequence';
460
439
 
461
- const positionColumns = splitSeqDf.columns.names();
440
+ const positionColumns = (splitSeqDf.columns as DG.ColumnList).names();
462
441
  const activityColumnScaled = `${activityColumn}Scaled`;
463
- const renderColNames: string[] = splitSeqDf.columns.names();
464
- const positionColName = 'Position';
442
+ const renderColNames: string[] = (splitSeqDf.columns as DG.ColumnList).names();
443
+ const positionColName = 'Pos';
465
444
  const aminoAcidResidue = 'AAR';
466
445
 
467
- splitSeqDf.columns.add(df.getCol(activityColumn));
446
+ (splitSeqDf.columns as DG.ColumnList).add(df.getCol(activityColumn));
468
447
 
469
- joinDataFrames(activityColumnScaled, df, positionColumns, splitSeqDf, activityColumn);
448
+ joinDataFrames(df, positionColumns, splitSeqDf, activityColumn);
470
449
 
471
- for (const col of df.columns) {
472
- if (splitSeqDf.col(col.name) && col.name != activityColumn) {
450
+ for (const col of (df.columns as DG.ColumnList)) {
451
+ if (splitSeqDf.col(col.name) && col.name != activityColumn)
473
452
  setAARRenderer(col, sourceGrid);
474
- }
475
453
  }
476
454
 
477
455
  sortSourceGrid(sourceGrid);
478
456
 
479
- await scaleActivity(activityScaling, activityColumn, activityColumnScaled, sourceGrid, splitSeqDf);
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
+
480
475
  splitSeqDf = splitSeqDf.clone(initialBitset);
481
476
 
482
477
  //unpivot a table and handle duplicates
@@ -489,15 +484,15 @@ export async function describe(
489
484
  let matrixDf = splitSeqDf.unpivot([activityColumnScaled], positionColumns, positionColName, aminoAcidResidue);
490
485
 
491
486
  //TODO: move to chem palette
492
- let groupMapping: {[key: string]: string} = {};
487
+ let groupMapping: StringDictionary = {};
493
488
  if (grouping) {
494
489
  groupMapping = aarGroups;
495
490
  const aarCol = matrixDf.getCol(aminoAcidResidue);
496
491
  aarCol.init((index) => groupMapping[aarCol.get(index)[0]] ?? '-');
497
492
  aarCol.compact();
498
- } else {
493
+ } else
499
494
  Object.keys(aarGroups).forEach((value) => groupMapping[value] = value);
500
- }
495
+
501
496
 
502
497
  //statistics for specific AAR at a specific position
503
498
  const statsDf = await calculateStatistics(
@@ -532,7 +527,7 @@ export async function describe(
532
527
  renderColNames, statsDf, aminoAcidResidue, positionColName, peptidesCount, grouping, sarGrid, sarVGrid,
533
528
  );
534
529
 
535
- postProcessGrids(sourceGrid, invalidIndexes, matrixDf, grouping, aminoAcidResidue, sarGrid, sarVGrid);
530
+ postProcessGrids(sourceGrid, invalidIndexes, grouping, aminoAcidResidue, sarGrid, sarVGrid);
536
531
 
537
532
  //TODO: return class instead
538
533
  return [sarGrid, sarVGrid, statsDf, groupMapping];