@datagrok/peptides 0.8.14 → 1.0.1

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 +1451 -2252
  3. package/dist/package.js +1277 -2105
  4. package/dist/vendors-node_modules_datagrok-libraries_ml_src_workers_dimensionality-reducer_js.js +9 -25
  5. package/package.json +10 -14
  6. package/package.png +0 -0
  7. package/src/model.ts +565 -599
  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 +86 -151
  16. package/src/utils/chem-palette.ts +3 -14
  17. package/src/utils/constants.ts +7 -0
  18. package/src/utils/filtering-statistics.ts +21 -53
  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 +11 -8
  23. package/src/utils/types.ts +5 -2
  24. package/src/viewers/peptide-space-viewer.ts +66 -40
  25. package/src/viewers/sar-viewer.ts +35 -38
  26. package/src/viewers/stacked-barchart-viewer.ts +42 -83
  27. package/src/widgets/analyze-peptides.ts +64 -76
  28. package/src/widgets/distribution.ts +172 -47
  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 +2 -7
  33. package/{test-Peptides-2f94f62b59a8-c6d7c434.html → test-Peptides-34f75e5127b8-4210edfc.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
@@ -1,29 +1,21 @@
1
1
  import * as DG from 'datagrok-api/dg';
2
2
  import * as rxjs from 'rxjs';
3
- import * as ui from 'datagrok-api/ui';
4
3
  import {MonomerLibrary} from '../monomer-library';
5
- import {PeptidesController} from '../peptides';
6
4
 
7
5
  import * as C from '../utils/constants';
8
6
  import * as type from '../utils/types';
7
+ import {PeptidesModel} from '../model';
9
8
 
10
- export function addViewerToHeader(grid: DG.Grid, barchart: StackedBarChart) {
9
+ export function addViewerToHeader(grid: DG.Grid, barchart: StackedBarChart): void {
11
10
  if (grid.temp['containsBarchart'])
12
11
  return;
13
-
14
- const compareBarParts = (bar1: type.BarChart.BarPart | null, bar2: type.BarChart.BarPart | null) =>
15
- bar1 && bar2 && bar1.aaName === bar2.aaName && bar1.colName === bar2.colName;
16
12
 
17
- const eventAction = (mouseMove: MouseEvent) => {
18
- const cell = grid.hitTest(mouseMove.offsetX, mouseMove.offsetY);
13
+ const eventAction = (ev: MouseEvent): void => {
14
+ const cell = grid.hitTest(ev.offsetX, ev.offsetY);
19
15
  if (cell?.isColHeader && cell.tableColumn?.semType == C.SEM_TYPES.AMINO_ACIDS) {
20
- const newBarPart = barchart.findAARandPosition(cell, mouseMove);
21
- const previousClickedBarPart = barchart._previousClickedBarPart;
22
- if (mouseMove.type === 'click' && compareBarParts(newBarPart, previousClickedBarPart))
23
- barchart.isSameBarClicked = true;
24
- else
25
- barchart.currentBarPart = newBarPart;
26
- barchart.requestAction(mouseMove);
16
+ const newBarPart = barchart.findAARandPosition(cell, ev);
17
+ // barchart._currentBarPart = newBarPart;
18
+ barchart.requestAction(ev, newBarPart);
27
19
  barchart.computeData();
28
20
  }
29
21
  };
@@ -31,7 +23,7 @@ export function addViewerToHeader(grid: DG.Grid, barchart: StackedBarChart) {
31
23
  // The following events makes the barchart interactive
32
24
  rxjs.fromEvent<MouseEvent>(grid.overlay, 'mousemove').subscribe((mouseMove: MouseEvent) => eventAction(mouseMove));
33
25
  rxjs.fromEvent<MouseEvent>(grid.overlay, 'click').subscribe((mouseMove: MouseEvent) => eventAction(mouseMove));
34
- rxjs.fromEvent<MouseEvent>(grid.overlay, 'mouseout').subscribe(() => barchart.unhighlight());
26
+ rxjs.fromEvent<MouseEvent>(grid.overlay, 'mouseout').subscribe(() => barchart.computeData());
35
27
 
36
28
  barchart.tableCanvas = grid.canvas;
37
29
 
@@ -39,17 +31,11 @@ export function addViewerToHeader(grid: DG.Grid, barchart: StackedBarChart) {
39
31
  grid.setOptions({'colHeaderHeight': 130});
40
32
 
41
33
  grid.onCellTooltip((cell, x, y) => {
42
- if (
43
- cell.tableColumn &&
44
- [C.SEM_TYPES.AMINO_ACIDS, C.SEM_TYPES.ALIGNED_SEQUENCE].includes(cell.tableColumn.semType as C.SEM_TYPES)
45
- ) {
34
+ const colSemType = cell.tableColumn?.semType as C.SEM_TYPES;
35
+ if (colSemType == C.SEM_TYPES.ALIGNED_SEQUENCE || colSemType == C.SEM_TYPES.AMINO_ACIDS) {
46
36
  if (!cell.isColHeader) {
47
37
  const monomerLib = cell.cell.dataFrame.temp[MonomerLibrary.id];
48
- PeptidesController.chemPalette.showTooltip(cell, x, y, monomerLib);
49
- } else if (barchart.currentBarPart) {
50
- let elements: HTMLElement[] = [];
51
- elements = elements.concat([ui.divText(barchart.currentBarPart.aaName)]);
52
- ui.tooltip.show(ui.divV(elements), x, y);
38
+ PeptidesModel.chemPalette.showTooltip(cell, x, y, monomerLib);
53
39
  }
54
40
  }
55
41
  return true;
@@ -75,14 +61,10 @@ export function addViewerToHeader(grid: DG.Grid, barchart: StackedBarChart) {
75
61
  });
76
62
 
77
63
  grid.temp['containsBarchart'] = true;
78
- //FIXME: for some reason barchat didn't show when running analysis. This fixes it, but it's bad. Find a way to fix
79
- // the problem
80
- barchart.unhighlight();
81
64
  }
82
65
 
83
66
  export class StackedBarChart extends DG.JsViewer {
84
67
  dataEmptyAA: string;
85
- _currentBarPart: type.BarChart.BarPart | null = null;
86
68
  tableCanvas: HTMLCanvasElement | undefined;
87
69
  aminoColumnNames: string[] = [];
88
70
  ord: { [Key: string]: number; } = {};
@@ -92,22 +74,14 @@ export class StackedBarChart extends DG.JsViewer {
92
74
  barStats: {[Key: string]: type.BarChart.BarStatsObject[]} = {};
93
75
  selected: type.BarChart.BarPart[] = [];
94
76
  aggregatedSelectedTables: type.DataFrameDict = {};
95
- controller!: PeptidesController;
96
- isSameBarClicked: boolean = false;
97
- _previousClickedBarPart: type.BarChart.BarPart | null = null;
77
+ model!: PeptidesModel;
98
78
 
99
79
  constructor() {
100
80
  super();
101
81
  this.dataEmptyAA = this.string('dataEmptyAA', '-');
102
82
  }
103
83
 
104
- get currentBarPart() { return this._currentBarPart; }
105
- set currentBarPart(barPart: type.BarChart.BarPart | null) {
106
- this._currentBarPart = barPart;
107
- this.isSameBarClicked = false;
108
- }
109
-
110
- init() {
84
+ init(): void {
111
85
  const groups: {[key: string]: string[]} = {
112
86
  'yellow': ['C', 'U'],
113
87
  'red': ['G', 'P'],
@@ -127,30 +101,31 @@ export class StackedBarChart extends DG.JsViewer {
127
101
  }
128
102
 
129
103
  // Stream subscriptions
130
- async onTableAttached() {
104
+ async onTableAttached(): Promise<void> {
131
105
  this.init();
132
- this.controller = await PeptidesController.getInstance(this.dataFrame);
133
- this.controller.init(this.dataFrame);
106
+ this.model = await PeptidesModel.getInstance(this.dataFrame);
107
+ // this.controller.init(this.dataFrame);
134
108
  if (this.dataFrame) {
135
109
  this.subs.push(DG.debounce(this.dataFrame.selection.onChanged, 50).subscribe((_) => this.computeData()));
136
110
  this.subs.push(DG.debounce(this.dataFrame.filter.onChanged, 50).subscribe((_) => this.computeData()));
137
111
  this.subs.push(DG.debounce(this.dataFrame.onValuesChanged, 50).subscribe(() => this.computeData()));
138
112
  }
113
+ this.computeData();
139
114
  }
140
115
 
141
116
  // Cancel subscriptions when the viewer is detached
142
- detach() {
117
+ detach(): void {
143
118
  this.subs.forEach((sub) => sub.unsubscribe());
144
119
  }
145
120
 
146
- computeData() {
121
+ computeData(): void {
147
122
  this.aminoColumnNames = [];
148
123
  this.aminoColumnIndices = {};
149
124
 
150
- this.dataFrame!.columns.names().forEach((name: string) => {
151
- if (this.dataFrame!.getCol(name).semType === C.SEM_TYPES.AMINO_ACIDS &&
152
- !this.dataFrame!.getCol(name).categories.includes('COOH') &&
153
- !this.dataFrame!.getCol(name).categories.includes('NH2')) {
125
+ this.dataFrame.columns.names().forEach((name: string) => {
126
+ if (this.dataFrame.getCol(name).semType === C.SEM_TYPES.AMINO_ACIDS &&
127
+ !this.dataFrame.getCol(name).categories.includes('COOH') &&
128
+ !this.dataFrame.getCol(name).categories.includes('NH2')) {
154
129
  this.aminoColumnIndices[name] = this.aminoColumnNames.length + 1;
155
130
  this.aminoColumnNames.push(name);
156
131
  }
@@ -160,15 +135,15 @@ export class StackedBarChart extends DG.JsViewer {
160
135
  this.aggregatedSelectedTables = {};
161
136
  //TODO: optimize it, why store so many tables?
162
137
  this.aminoColumnNames.forEach((name) => {
163
- this.aggregatedFilterTables[name] = this.dataFrame!
138
+ this.aggregatedFilterTables[name] = this.dataFrame
164
139
  .groupBy([name])
165
- .whereRowMask(this.dataFrame!.filter)
140
+ .whereRowMask(this.dataFrame.filter)
166
141
  .add('count', name, `${name}_count`)
167
142
  .aggregate();
168
143
 
169
- this.aggregatedSelectedTables[name] = this.dataFrame!
144
+ this.aggregatedSelectedTables[name] = this.dataFrame
170
145
  .groupBy([name])
171
- .whereRowMask(this.dataFrame!.selection)
146
+ .whereRowMask(this.dataFrame.selection)
172
147
  .add('count', name, `${name}_count`)
173
148
  .aggregate();
174
149
  });
@@ -206,10 +181,10 @@ export class StackedBarChart extends DG.JsViewer {
206
181
  colData.sort((o1, o2) => this.ord[o2['name']] - this.ord[o1['name']]);
207
182
  }
208
183
 
209
- this.max = this.dataFrame!.filter.trueCount;
184
+ this.max = this.dataFrame.filter.trueCount;
210
185
  }
211
186
 
212
- renderBarToCanvas(g: CanvasRenderingContext2D, cell: DG.GridCell, x: number, y: number, w: number, h: number) {
187
+ renderBarToCanvas(g: CanvasRenderingContext2D, cell: DG.GridCell, x: number, y: number, w: number, h: number): void {
213
188
  const name = cell.tableColumn!.name;
214
189
  const colNameSize = g.measureText(name).width;
215
190
  const barData = this.barStats[name];
@@ -236,7 +211,7 @@ export class StackedBarChart extends DG.JsViewer {
236
211
  const sBarHeight = h * obj['count'] / this.max;
237
212
  const gapSize = sBarHeight * innerMargin;
238
213
  const verticalShift = (this.max - sum) / this.max;
239
- const [color, aarOuter] = PeptidesController.chemPalette.getColorAAPivot(obj['name']);
214
+ const [color, aarOuter] = PeptidesModel.chemPalette.getColorAAPivot(obj['name']);
240
215
  const textSize = g.measureText(aarOuter);
241
216
  const fontSize = 11;
242
217
  const leftMargin = (w - (aarOuter.length > 1 ? fontSize : textSize.width - 8)) / 2;
@@ -252,7 +227,7 @@ export class StackedBarChart extends DG.JsViewer {
252
227
  if (textSize.width <= subBartHeight) {
253
228
  const origTransform = g.getTransform();
254
229
 
255
- if (color != PeptidesController.chemPalette.undefinedColor) {
230
+ if (color != PeptidesModel.chemPalette.undefinedColor) {
256
231
  g.fillRect(x + xStart, y + yStart, barWidth, subBartHeight);
257
232
  g.fillStyle = 'black';
258
233
  } else
@@ -287,7 +262,8 @@ export class StackedBarChart extends DG.JsViewer {
287
262
  });
288
263
  }
289
264
 
290
- findAARandPosition(cell: DG.GridCell, mouseEvent: MouseEvent) {
265
+ //TODO: refactor and simplify it
266
+ findAARandPosition(cell: DG.GridCell, mouseEvent: MouseEvent): {colName: string, aaName: string} | null {
291
267
  if (!cell.tableColumn?.name || !this.aminoColumnNames.includes(cell.tableColumn.name))
292
268
  return null;
293
269
 
@@ -330,33 +306,16 @@ export class StackedBarChart extends DG.JsViewer {
330
306
  return null;
331
307
  }
332
308
 
333
- unhighlight() {
334
- ui.tooltip.hide();
335
- this.computeData();
336
- }
337
-
338
- /**
339
- * Requests highlight/select/filter action based on currentBarPart
340
- * @param event
341
- * @returns
342
- */
343
- requestAction(event: MouseEvent) {
344
- if (!this._currentBarPart)
309
+ /** Requests highlight/select/filter action based on currentBarPart */
310
+ requestAction(event: MouseEvent, barPart: {colName: string, aaName: string} | null): void {
311
+ if (!barPart)
345
312
  return;
346
- let aar = this._currentBarPart!['aaName'];
347
- let position = this._currentBarPart!['colName'];
313
+ const aar = barPart['aaName'];
314
+ const position = barPart['colName'];
348
315
  if (event.type === 'click') {
349
- if (this.isSameBarClicked) {
350
- aar = position = C.CATEGORIES.ALL;
351
- this.currentBarPart = null;
352
- }
353
- this.controller.setSARGridCellAt(aar, position);
354
- this._previousClickedBarPart = this._currentBarPart;
355
- } else {
356
- ui.tooltip.showRowGroup(this.dataFrame, (i) => {
357
- const currentAAR = this.dataFrame.get(position, i);
358
- return currentAAR === aar;
359
- }, event.offsetX, event.offsetY);
360
- }
316
+ event.shiftKey ? this.model.modifyCurrentSelection(aar, position) :
317
+ this.model.initCurrentSelection(aar, position);
318
+ } else
319
+ this.model.showTooltip(aar, position, event.clientX, event.clientY);
361
320
  }
362
321
  }
@@ -1,44 +1,40 @@
1
1
  import * as grok from 'datagrok-api/grok';
2
2
  import * as ui from 'datagrok-api/ui';
3
3
  import * as DG from 'datagrok-api/dg';
4
- import {callMVA} from '../utils/multivariate-analysis';
5
- import {PeptidesController} from '../peptides';
6
4
  import '../styles.css';
7
- import {StringDictionary} from '@datagrok-libraries/utils/src/type-declarations';
8
5
  import * as C from '../utils/constants';
9
- import {FilteringStatistics} from '../utils/filtering-statistics';
6
+ import {getSeparator} from '../utils/misc';
7
+ import {PeptidesModel} from '../model';
8
+ import {_package} from '../package';
9
+ import $ from 'cash-dom';
10
10
 
11
- /**
12
- * Peptide analysis widget.
11
+ /** Peptide analysis widget.
13
12
  *
14
- * @export
15
- * @param {DG.Column} col Aligned sequence column.
16
- * @param {DG.TableView} view Working view.
17
- * @param {DG.Grid} tableGrid Working table grid.
18
- * @param {DG.DataFrame} currentDf Working table.
19
- * @return {Promise<DG.Widget>} Widget containing peptide analysis.
20
- */
13
+ * @param {DG.DataFrame} currentDf Working table
14
+ * @param {DG.Column} col Aligned sequence column
15
+ * @return {Promise<DG.Widget>} Widget containing peptide analysis */
21
16
  export async function analyzePeptidesWidget(currentDf: DG.DataFrame, col: DG.Column): Promise<DG.Widget> {
22
17
  let tempCol = null;
23
- let tempDf: DG.DataFrame;
18
+ let scaledDf: DG.DataFrame;
24
19
  let newScaledColName: string;
20
+ const separator = getSeparator(col);
21
+ col.tags[C.TAGS.SEPARATOR] ??= separator;
25
22
 
26
23
  for (const column of currentDf.columns.numerical)
27
24
  tempCol = column.type === DG.TYPE.FLOAT ? column : null;
28
25
 
29
- const defaultColumn: DG.Column = currentDf.col('activity') || currentDf.col('IC50') || tempCol;
26
+ const defaultColumn: DG.Column<number> | null = currentDf.col('activity') || currentDf.col('IC50') || tempCol;
30
27
  const histogramHost = ui.div([], {id: 'pep-hist-host'});
31
28
 
32
29
  const activityScalingMethod = ui.choiceInput(
33
30
  'Scaling', 'none', ['none', 'lg', '-lg'],
34
- async (currentMethod: string) => {
35
- const currentActivityCol = activityColumnChoice.value.name;
36
-
31
+ async (currentMethod: string): Promise<void> => {
32
+ const currentActivityCol = activityColumnChoice.value?.name;
37
33
 
38
- [tempDf, newScaledColName] = await PeptidesController.scaleActivity(
34
+ [scaledDf, newScaledColName] = await PeptidesModel.scaleActivity(
39
35
  currentMethod, currentDf, currentActivityCol, true);
40
36
 
41
- const hist = tempDf.plot.histogram({
37
+ const hist = scaledDf.plot.histogram({
42
38
  filteringEnabled: false,
43
39
  valueColumnName: C.COLUMNS_NAMES.ACTIVITY_SCALED,
44
40
  legendVisibility: 'Never',
@@ -46,83 +42,75 @@ export async function analyzePeptidesWidget(currentDf: DG.DataFrame, col: DG.Col
46
42
  showColumnSelector: false,
47
43
  showRangeSlider: false,
48
44
  showBinSelector: false,
49
- // bins: b,
50
45
  });
51
46
  histogramHost.lastChild?.remove();
52
47
  histogramHost.appendChild(hist.root);
53
48
  });
54
49
  activityScalingMethod.setTooltip('Function to apply for each value in activity column');
55
50
 
56
- const activityScalingMethodState = function(_: any) {
57
- activityScalingMethod.enabled =
58
- activityColumnChoice.value && DG.Stats.fromColumn(activityColumnChoice.value, currentDf.filter).min > 0;
51
+ const activityScalingMethodState = (_: any): void => {
52
+ activityScalingMethod.enabled = (activityColumnChoice.value ?? false) &&
53
+ DG.Stats.fromColumn(activityColumnChoice.value!, currentDf.filter).min > 0;
59
54
  activityScalingMethod.fireChanged();
60
55
  };
61
- const activityColumnChoice = ui.columnInput(
62
- 'Activity',
63
- currentDf,
64
- defaultColumn,
65
- activityScalingMethodState,
66
- );
56
+ const activityColumnChoice = ui.columnInput('Activity', currentDf, defaultColumn, activityScalingMethodState);
67
57
  activityColumnChoice.fireChanged();
68
58
  activityScalingMethod.fireChanged();
69
59
 
70
- const startBtn = ui.button('Launch SAR', async () => {
71
- const progress = DG.TaskBarProgressIndicator.create('Loading SAR...');
72
- if (activityColumnChoice.value.type === DG.TYPE.FLOAT) {
73
- const activityColumn: string = activityColumnChoice.value.name;
74
- // const activityColumnScaled = `${activityColumn}Scaled`;
75
- // const originalDfColumns = (currentDf.columns as DG.ColumnList).names();
76
- const options: StringDictionary = {
77
- 'scaling': activityScalingMethod.value,
78
- };
79
-
80
- //prepare new DF
81
- const newDf = currentDf.clone(currentDf.filter, [col.name, activityColumn]);
82
- newDf.getCol(activityColumn).name = C.COLUMNS_NAMES.ACTIVITY;
83
- newDf.getCol(col.name).name = C.COLUMNS_NAMES.ALIGNED_SEQUENCE;
84
- const activityScaledCol = tempDf.getCol(C.COLUMNS_NAMES.ACTIVITY_SCALED);
85
- (newDf.columns as DG.ColumnList).add(activityScaledCol);
86
- // newDf.temp[C.COLUMNS_NAMES.ACTIVITY] = activityColumn;
87
- newDf.name = 'Peptides analysis';
88
- newDf.temp[C.COLUMNS_NAMES.ACTIVITY_SCALED] = newScaledColName;
89
- newDf.tags['isPeptidesAnalysis'] = 'true';
60
+ const inputsList = [activityColumnChoice, activityScalingMethod];
90
61
 
91
- const peptides = await PeptidesController.getInstance(newDf);
92
- await peptides.init(newDf);
93
- } else
94
- grok.shell.error('The activity column must be of floating point number type!');
95
- progress.close();
62
+ const startBtn = ui.button('Launch SAR', async () => {
63
+ await startAnalysis(activityColumnChoice.value, col, currentDf, scaledDf, newScaledColName);
96
64
  });
97
65
  startBtn.style.alignSelf = 'center';
98
66
 
99
- // const startMVABtn = ui.button('Launch MVA', async () => {
100
- // if (activityColumnChoice.value.type === DG.TYPE.FLOAT) {
101
- // const progress = DG.TaskBarProgressIndicator.create('Loading MVA...');
102
-
103
- // const options: {[key: string]: string} = {
104
- // 'activityColumnName': activityColumnChoice.value.name,
105
- // 'scaling': activityScalingMethod.value,
106
- // };
107
-
108
- // await callMVA(tableGrid, view, currentDf, options, col);
109
-
110
- // progress.close();
111
- // } else
112
- // grok.shell.error('The activity column must be of floating point number type!');
113
- // });
114
-
115
-
116
- const viewer = await currentDf.plot.fromType('peptide-logo-viewer');
67
+ const bioList = (await grok.dapi.packages.list({filter: 'name = "Bio"'})).filter(p => p.name == 'Bio');
68
+ const logoHost = ui.div('Install Bio package to see WebLogo');
69
+ if (bioList.length > 0) {
70
+ const viewer = await currentDf.plot.fromType('WebLogo');
71
+ viewer.root.style.setProperty('height', '130px');
72
+ $(logoHost).empty().append(viewer.root);
73
+ } else {
74
+ logoHost.style.color = DG.Color.toHtml(DG.Color.red);
75
+ logoHost.style.alignSelf = 'center';
76
+ logoHost.style.margin = '10px';
77
+ }
117
78
 
118
79
  return new DG.Widget(
119
80
  ui.divV([
120
- viewer.root,
81
+ logoHost,
121
82
  ui.splitH([
122
- ui.splitV([ui.inputs([activityColumnChoice, activityScalingMethod]), startBtn]),
83
+ ui.splitV([ui.inputs(inputsList), startBtn]),
123
84
  histogramHost,
124
85
  ], {style: {height: 'unset'}}),
125
- // histogramHost,
126
86
  ]),
127
87
  );
128
88
  }
89
+
90
+ export async function startAnalysis(
91
+ activityColumn: DG.Column<number> | null, alignedSeqCol: DG.Column<string>, currentDf: DG.DataFrame,
92
+ scaledDf: DG.DataFrame, newScaledColName: string, dgPackage?: DG.Package): Promise<PeptidesModel | null> {
93
+ const progress = DG.TaskBarProgressIndicator.create('Loading SAR...');
94
+ let model = null;
95
+ if (activityColumn?.type === DG.TYPE.FLOAT) {
96
+ const activityColumnName: string = activityColumn.name;
97
+
98
+ //prepare new DF
99
+ const newDf = currentDf.clone(currentDf.filter, [alignedSeqCol.name, activityColumnName]);
100
+ const activityCol = newDf.getCol(activityColumnName);
101
+ activityCol.name = C.COLUMNS_NAMES.ACTIVITY;
102
+ activityCol.semType = C.SEM_TYPES.ACTIVITY;
103
+ newDf.getCol(alignedSeqCol.name).name = C.COLUMNS_NAMES.ALIGNED_SEQUENCE;
104
+ const activityScaledCol = scaledDf.getCol(C.COLUMNS_NAMES.ACTIVITY_SCALED);
105
+ activityScaledCol.semType = C.SEM_TYPES.ACTIVITY_SCALED;
106
+ newDf.columns.add(activityScaledCol);
107
+ newDf.name = 'Peptides analysis';
108
+ newDf.tags[C.COLUMNS_NAMES.ACTIVITY_SCALED] = newScaledColName;
109
+ // newDf.tags[C.PEPTIDES_ANALYSIS] = 'true';
110
+
111
+ model = await PeptidesModel.getInstance(newDf, dgPackage ?? _package);
112
+ } else
113
+ grok.shell.error('The activity column must be of floating point number type!');
114
+ progress.close();
115
+ return model;
116
+ }