@datagrok/peptides 0.3.0 → 0.5.6

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.
@@ -4,8 +4,15 @@ import * as DG from 'datagrok-api/dg';
4
4
 
5
5
  import $ from 'cash-dom';
6
6
 
7
- import { model } from './model';
8
-
7
+ import {model} from './model';
8
+
9
+ /**
10
+ * Structure-activity relationship viewer.
11
+ *
12
+ * @export
13
+ * @class SARViewer
14
+ * @extends {DG.JsViewer}
15
+ */
9
16
  export class SARViewer extends DG.JsViewer {
10
17
  protected viewerGrid: DG.Grid | null;
11
18
  protected sourceGrid: DG.Grid | null;
@@ -20,16 +27,24 @@ export class SARViewer extends DG.JsViewer {
20
27
  protected _initialBitset: DG.BitSet | null;
21
28
  protected viewerVGrid: DG.Grid | null;
22
29
  protected currentBitset: DG.BitSet | null;
23
- // private df: DG.DataFrame | null;
30
+ grouping: boolean;
31
+ groupMapping: {[key: string]: string} | null;
24
32
  // protected pValueThreshold: number;
25
33
  // protected amountOfBestAARs: number;
26
34
  // duplicatesHandingMethod: string;
35
+
36
+ /**
37
+ * Creates an instance of SARViewer.
38
+ *
39
+ * @memberof SARViewer
40
+ */
27
41
  constructor() {
28
42
  super();
29
-
43
+
30
44
  this.viewerGrid = null;
31
45
  this.viewerVGrid = null;
32
46
  this.statsDf = null;
47
+ this.groupMapping = null;
33
48
  this.initialized = false;
34
49
  this.aminoAcidResidue = 'AAR';
35
50
  this._initialBitset = null;
@@ -41,6 +56,7 @@ export class SARViewer extends DG.JsViewer {
41
56
  this.activityScalingMethod = this.string('activityScalingMethod', 'none', {choices: ['none', 'lg', '-lg']});
42
57
  this.filterMode = this.bool('filterMode', false);
43
58
  this.bidirectionalAnalysis = this.bool('bidirectionalAnalysis', false);
59
+ this.grouping = this.bool('grouping', false);
44
60
  // this.pValueThreshold = this.float('pValueThreshold', 0.1);
45
61
  // this.amountOfBestAARs = this.int('amountOfBestAAR', 1);
46
62
  // this.duplicatesHandingMethod = this.string('duplicatesHandlingMethod', 'median', {choices: ['median']});
@@ -48,27 +64,49 @@ export class SARViewer extends DG.JsViewer {
48
64
  this.sourceGrid = null;
49
65
  }
50
66
 
67
+ /**
68
+ * Initializes SARViewer.
69
+ *
70
+ * @memberof SARViewer
71
+ */
51
72
  init() {
52
73
  this._initialBitset = this.dataFrame!.filter.clone();
53
74
  this.initialized = true;
54
- this.subs.push(model.statsDf$.subscribe(data => this.statsDf = data));
55
- this.subs.push(model.viewerGrid$.subscribe(data => {
75
+ this.subs.push(model.statsDf$.subscribe((data) => this.statsDf = data));
76
+ this.subs.push(model.viewerGrid$.subscribe((data) => {
56
77
  this.viewerGrid = data;
57
78
  this.render();
58
79
  }));
59
- this.subs.push(model.viewerVGrid$.subscribe(data => this.viewerVGrid = data));
80
+ this.subs.push(model.viewerVGrid$.subscribe((data) => this.viewerVGrid = data));
81
+ this.subs.push(model.groupMapping$.subscribe((data) => this.groupMapping = data));
60
82
  }
61
83
 
84
+ /**
85
+ * Function that is executed when the table is attached.
86
+ *
87
+ * @memberof SARViewer
88
+ */
62
89
  onTableAttached() {
63
90
  this.sourceGrid = this.view.grid;
64
91
  this.sourceGrid?.dataFrame?.setTag('dataType', 'peptides');
65
92
  this.render();
66
93
  }
67
94
 
95
+ /**
96
+ * Function that is executed when the viewer is detached from the table.
97
+ *
98
+ * @memberof SARViewer
99
+ */
68
100
  detach() {
69
101
  this.subs.forEach((sub) => sub.unsubscribe());
70
102
  }
71
103
 
104
+ /**
105
+ * Function that is executed when the property is changed.
106
+ *
107
+ * @param {DG.Property} property New property.
108
+ * @memberof SARViewer
109
+ */
72
110
  onPropertyChanged(property: DG.Property) {
73
111
  super.onPropertyChanged(property);
74
112
 
@@ -93,6 +131,12 @@ export class SARViewer extends DG.JsViewer {
93
131
  this.render();
94
132
  }
95
133
 
134
+ /**
135
+ * Filtering/selecting sequences with the specified amino acid residue at specified position.
136
+ *
137
+ * @private
138
+ * @memberof SARViewer
139
+ */
96
140
  private applyBitset() {
97
141
  if (
98
142
  this.dataFrame &&
@@ -114,25 +158,13 @@ export class SARViewer extends DG.JsViewer {
114
158
  splitCol = this.dataFrame.columns.addNew(splitColName, 'string');
115
159
  }
116
160
 
117
- const isChosen = (i: number) => this.dataFrame!.get(currentPosition, i) === currentAAR;
161
+ const isChosen = (i: number) => this.groupMapping![this.dataFrame!.get(currentPosition, i)] === currentAAR;
118
162
  splitCol!.init((i) => isChosen(i) ? aarLabel : otherLabel);
119
163
 
120
164
  //TODO: use column.compact
121
-
122
- // if (this.filterMode) {
123
- // this.dataFrame.selection.setAll(false, false);
124
- // this.dataFrame.filter.init(isChosen).and(this._initialBitset!, false);
125
- // } else {
126
- // this.dataFrame.filter.copyFrom(this._initialBitset!);
127
- // this.dataFrame.selection.init(isChosen).and(this._initialBitset!, false);
128
- // }
129
165
  this.currentBitset = DG.BitSet.create(this.dataFrame.rowCount, isChosen).and(this._initialBitset!);
130
- // (this.filterMode ? this.dataFrame.selection.setAll(false) :
131
- // this.dataFrame.filter.copyFrom(this._initialBitset!)).fireChanged();
132
166
  this.sourceFilteringFunc();
133
167
 
134
-
135
- // df.getCol(splitColName).setCategoryOrder([otherLabel, aarLabel]);
136
168
  const colorMap: {[index: string]: string | number} = {};
137
169
  colorMap[otherLabel] = DG.Color.blue;
138
170
  colorMap[aarLabel] = DG.Color.orange;
@@ -141,6 +173,12 @@ export class SARViewer extends DG.JsViewer {
141
173
  }
142
174
  }
143
175
 
176
+ /**
177
+ * Selecting/filtering sequences according to the current bitset.
178
+ *
179
+ * @private
180
+ * @memberof SARViewer
181
+ */
144
182
  private sourceFilteringFunc() {
145
183
  if (this.filterMode) {
146
184
  this.dataFrame!.selection.setAll(false, false);
@@ -151,6 +189,13 @@ export class SARViewer extends DG.JsViewer {
151
189
  }
152
190
  }
153
191
 
192
+ /**
193
+ * Property panel accordion construction function.
194
+ *
195
+ * @private
196
+ * @param {DG.Accordion} accordion Accordion.
197
+ * @memberof SARViewer
198
+ */
154
199
  private accordionFunc(accordion: DG.Accordion) {
155
200
  if (accordion.context instanceof DG.RowGroup) {
156
201
  const originalDf: DG.DataFrame = DG.toJs(accordion.context.dataFrame);
@@ -211,7 +256,13 @@ export class SARViewer extends DG.JsViewer {
211
256
  }
212
257
  }
213
258
 
214
- syncGridsFunc(sourceVertical: boolean) { //TODO: refactor
259
+ /**
260
+ * Function for viewer girds synchronization.
261
+ *
262
+ * @param {boolean} sourceVertical Event source is vertical viewer.
263
+ * @memberof SARViewer
264
+ */
265
+ syncGridsFunc(sourceVertical: boolean) { //TODO: refactor, move
215
266
  if (this.viewerGrid && this.viewerGrid.dataFrame && this.viewerVGrid && this.viewerVGrid.dataFrame) {
216
267
  if (sourceVertical) {
217
268
  const dfCell = this.viewerVGrid.dataFrame.currentCell;
@@ -253,8 +304,13 @@ export class SARViewer extends DG.JsViewer {
253
304
  }
254
305
  }
255
306
  }
256
- // argument compute data can be used to just redraw grids.
257
- // Probably iirelevant since mostly grids are updating themselves, and render is only used to update data.
307
+
308
+ /**
309
+ * Viewer render function.
310
+ *
311
+ * @param {boolean} [computeData=true] Recalculate data.
312
+ * @memberof SARViewer
313
+ */
258
314
  async render(computeData = true) {
259
315
  if (!this.initialized) {
260
316
  return;
@@ -262,14 +318,6 @@ export class SARViewer extends DG.JsViewer {
262
318
  //TODO: optimize. Don't calculate everything again if only view changes
263
319
  if (computeData) {
264
320
  if (typeof this.dataFrame !== 'undefined' && this.activityColumnColumnName && this.sourceGrid) {
265
- // [this.viewerGrid, this.viewerVGrid, this.statsDf] = await describe(
266
- // this.dataFrame,
267
- // this.activityColumnColumnName,
268
- // this.activityScalingMethod,
269
- // this.sourceGrid,
270
- // this.bidirectionalAnalysis,
271
- // this._initialBitset,
272
- // );
273
321
  await model?.updateData(
274
322
  this.dataFrame!,
275
323
  this.activityColumnColumnName,
@@ -277,6 +325,7 @@ export class SARViewer extends DG.JsViewer {
277
325
  this.sourceGrid,
278
326
  this.bidirectionalAnalysis,
279
327
  this._initialBitset,
328
+ this.grouping,
280
329
  );
281
330
 
282
331
  if (this.viewerGrid !== null && this.viewerVGrid !== null) {
@@ -297,18 +346,36 @@ export class SARViewer extends DG.JsViewer {
297
346
  }
298
347
  }
299
348
 
349
+ /**
350
+ * Vertical structure activity relationship viewer.
351
+ *
352
+ * @export
353
+ * @class SARViewerVertical
354
+ * @extends {DG.JsViewer}
355
+ */
300
356
  export class SARViewerVertical extends DG.JsViewer {
301
357
  viewerVGrid: DG.Grid | null;
358
+
359
+ /**
360
+ * Creates an instance of SARViewerVertical.
361
+ *
362
+ * @memberof SARViewerVertical
363
+ */
302
364
  constructor() {
303
365
  super();
304
366
 
305
367
  this.viewerVGrid = null;
306
- this.subs.push(model.viewerVGrid$.subscribe(data => {
368
+ this.subs.push(model.viewerVGrid$.subscribe((data) => {
307
369
  this.viewerVGrid = data;
308
370
  this.render();
309
371
  }));
310
372
  }
311
373
 
374
+ /**
375
+ * Viewer render function.
376
+ *
377
+ * @memberof SARViewerVertical
378
+ */
312
379
  render() {
313
380
  if (this.viewerVGrid) {
314
381
  $(this.root).empty();
@@ -316,4 +383,4 @@ export class SARViewerVertical extends DG.JsViewer {
316
383
  }
317
384
  this.viewerVGrid?.invalidate();
318
385
  }
319
- }
386
+ }
@@ -0,0 +1,97 @@
1
+ import * as DG from 'datagrok-api/dg';
2
+ import {_toJson} from 'datagrok-api/src/utils';
3
+
4
+ import {assert, argSort} from '@datagrok-libraries/utils/src/operations';
5
+ import {Options} from '@datagrok-libraries/utils/src/type-declarations';
6
+
7
+ const api = <any>window;
8
+
9
+ /**
10
+ * Draws 2D scatter plot from 1D series.
11
+ *
12
+ * @export
13
+ * @class SpiralPlot
14
+ * @extends {DG.ScatterPlotViewer}
15
+ */
16
+ export class SpiralPlot extends DG.ScatterPlotViewer {
17
+ static axesNames = ['~X', '~Y'];
18
+ static valuesKey = 'valuesColumnName';
19
+
20
+ /**
21
+ * Calculates coordinates of the projection into a spiral.
22
+ *
23
+ * @static
24
+ * @param {DG.DataFrame} t Source data frame.
25
+ * @param {Options} options Options to read values column name from. Must include {valuesColumnName: string}.
26
+ * @return {DG.DataFrame} Updated dataframe.
27
+ * @memberof SpiralPlot
28
+ */
29
+ static updateCoordinates(t: DG.DataFrame, options: Options): DG.DataFrame {
30
+ assert(options[SpiralPlot.valuesKey] != undefined);
31
+
32
+ const values = t.getCol(options[SpiralPlot.valuesKey]).getRawData() as Float32Array;
33
+ const columns = _calcSpiralProjection(values);
34
+ const cdf = DG.DataFrame.fromColumns(
35
+ Array.from(columns).map((v, i) => DG.Column.fromFloat32Array(SpiralPlot.axesNames[i], v)),
36
+ );
37
+ return _updateCoordinates(t, cdf);
38
+ }
39
+
40
+ /**
41
+ * Creates new SpiralPlot from a data frame with selected values column.
42
+ *
43
+ * @static
44
+ * @param {DG.DataFrame} t A data frame.
45
+ * @param {Options} options Controlling options.
46
+ * @return {SpiralPlot} The plot.
47
+ * @memberof SpiralPlot
48
+ */
49
+ static fromTable(t: DG.DataFrame, options: Options): SpiralPlot {
50
+ t = SpiralPlot.updateCoordinates(t, options);
51
+ [options.x, options.y] = SpiralPlot.axesNames;
52
+ options.color = options[SpiralPlot.valuesKey];
53
+ return new SpiralPlot(api.grok_Viewer_ScatterPlot(t.dart, _toJson(options)));
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Calculates 2D projection of 1D series as a spiral.
59
+ *
60
+ * @param {(number[] | Float32Array)} values The series.
61
+ * @return {[Float32Array, Float32Array]} X and Y componenets of the projection.
62
+ */
63
+ function _calcSpiralProjection(values: number[] | Float32Array): [Float32Array, Float32Array] {
64
+ const nItems = values.length;
65
+ const order = argSort(Array.from(values), true);
66
+ const maxV = values[order[0]];
67
+ const X = new Float32Array(nItems).fill(0);
68
+ const Y = new Float32Array(nItems).fill(0);
69
+
70
+ for (const i of order) {
71
+ const v = maxV - values[i];
72
+ X[i] = v * Math.cos(Math.PI * v) - Math.random() * 1.5 + 0.75;
73
+ Y[i] = v * Math.sin(Math.PI * v) - Math.random() * 1.5 + 0.75;
74
+ }
75
+ return [X, Y];
76
+ }
77
+
78
+ /**
79
+ * Adds new columns from one data frame into another one.
80
+ *
81
+ * @param {DG.DataFrame} table Destination data frame.
82
+ * @param {DG.DataFrame} coords Source data frame.
83
+ * @return {DG.DataFrame} Updated data frame.
84
+ */
85
+ function _updateCoordinates(table: DG.DataFrame, coords: DG.DataFrame): DG.DataFrame {
86
+ const coordsColNames: string[] = coords.columns.names();
87
+ const tableColNames: string[] = table.columns.names();
88
+ const restColNames = tableColNames.filter((v: string) => !coordsColNames.includes(v));
89
+
90
+ if (tableColNames.length == restColNames.length) {
91
+ for (const col of coords.columns) {
92
+ table.columns.add(col);
93
+ }
94
+ return table;
95
+ }
96
+ return table.join(coords, coordsColNames, coordsColNames, restColNames, [], 'right', false);
97
+ }
@@ -5,6 +5,8 @@ import {ChemPalette} from '../utils/chem-palette';
5
5
  import * as rxjs from 'rxjs';
6
6
  const cp = new ChemPalette('grok');
7
7
 
8
+ import {CorrelationAnalysisVisualizer} from '../utils/correlation-analysis';
9
+
8
10
  //TODO: the function should not accept promise. Await the parameters where it is used
9
11
  export function addViewerToHeader(grid: DG.Grid, viewer: Promise<DG.Widget>) {
10
12
  viewer.then((viewer) => {
@@ -42,7 +44,10 @@ export function addViewerToHeader(grid: DG.Grid, viewer: Promise<DG.Widget>) {
42
44
  return true;
43
45
  } else {
44
46
  if (barchart.highlighted) {
45
- ui.tooltip.show(ui.divV([ui.divText(barchart.highlighted.aaName)]), x, y);
47
+ let elements: HTMLElement[] = [];
48
+ elements = elements.concat([ui.divText(barchart.highlighted.aaName)]);
49
+ elements = elements.concat(barchart.getTooltipElements(cell.tableColumn.name, barchart.aminoColumnNames));
50
+ ui.tooltip.show(ui.divV(elements), x, y);
46
51
  }
47
52
  return true;
48
53
  }
@@ -54,6 +59,7 @@ export function addViewerToHeader(grid: DG.Grid, viewer: Promise<DG.Widget>) {
54
59
  args.g.beginPath();
55
60
  args.g.rect(args.bounds.x, args.bounds.y, args.bounds.width, args.bounds.height);
56
61
  args.g.clip();
62
+
57
63
  if (args.cell.isColHeader && barchart.aminoColumnNames.includes(args.cell.gridColumn.name)) {
58
64
  barchart.renderBarToCanvas(
59
65
  args.g,
@@ -95,11 +101,13 @@ export class StackedBarChart extends DG.JsViewer {
95
101
  private barStats: {[Key: string]: {'name': string, 'count': number, 'selectedCount': number}[]} = {};
96
102
  tableCanvas: HTMLCanvasElement | undefined;
97
103
  private registered: {[Key: string]: DG.GridCell} = {};
104
+ protected corrViz: CorrelationAnalysisVisualizer | undefined;
98
105
 
99
106
  constructor() {
100
107
  super();
101
108
  this.dataEmptyAA = this.string('dataEmptyAA', '-');
102
109
  this.initialized = false;
110
+ this.corrViz = undefined;
103
111
  }
104
112
 
105
113
  init() {
@@ -115,8 +123,8 @@ export class StackedBarChart extends DG.JsViewer {
115
123
  let i = 0;
116
124
  for (const value of Object.values(groups)) {
117
125
  i++;
118
- for (const obj in value) {
119
- this.ord[value[obj]] = i;
126
+ for (const obj of value) {
127
+ this.ord[obj] = i;
120
128
  }
121
129
  }
122
130
  this.yScale = scaleLinear();
@@ -249,9 +257,17 @@ export class StackedBarChart extends DG.JsViewer {
249
257
  });
250
258
  }
251
259
  this.max = df.filter.trueCount;
260
+ this.corrViz = new CorrelationAnalysisVisualizer(df, this.aminoColumnNames);
252
261
  }
253
262
 
254
- renderBarToCanvas(g: CanvasRenderingContext2D, cell: DG.GridCell, x: number, y: number, w: number, h: number) {
263
+ renderBarToCanvas(
264
+ g: CanvasRenderingContext2D,
265
+ cell: DG.GridCell,
266
+ x: number,
267
+ y: number,
268
+ w: number,
269
+ h: number,
270
+ ) {
255
271
  const margin = 0.2;
256
272
  const innerMargin = 0.02;
257
273
  const selectLineRatio = 0.1;
@@ -268,6 +284,14 @@ export class StackedBarChart extends DG.JsViewer {
268
284
  g.fillText(name,
269
285
  x + (w - colNameSize)/2,
270
286
  y + h + h * margin / 4);
287
+ this.higlightCorrelatedPositionHeader(
288
+ g,
289
+ name,
290
+ x + (w - colNameSize)/2,
291
+ y + h + h * margin / 4,
292
+ colNameSize,
293
+ margin,
294
+ );
271
295
  const barData = this.barStats[name]? this.barStats[name]: this.barStats[name];
272
296
  let sum = 0;
273
297
  barData.forEach((obj) => {
@@ -287,8 +311,7 @@ export class StackedBarChart extends DG.JsViewer {
287
311
  if (h * margin / 2 <= sBarHeight - gapSize && h * margin / 2 <= w) {
288
312
  g.fillStyle = 'rgb(0,0,0)';
289
313
  g.font = `${h * margin / 2}px`;
290
- // eslint-disable-next-line no-unused-vars
291
- const [_c, aar, _p] = cp.getColorAAPivot(obj['name']);
314
+ const [, aar] = cp.getColorAAPivot(obj['name']);
292
315
  g.fillText(aar,
293
316
  x + w / 2 - h * margin / 8,
294
317
  y + h * (this.max - sum + curSum) / this.max + gapSize / 2 + (sBarHeight - gapSize)/2 - h * margin / 8);
@@ -398,11 +421,63 @@ export class StackedBarChart extends DG.JsViewer {
398
421
  return;
399
422
  }
400
423
  this.dataFrame!.selection.handleClick((i) => {
401
- //let selected = true;
402
424
  // @ts-ignore
403
425
  return this.highlighted!['aaName'] === (this.dataFrame.getCol(this.highlighted!['colName']).get(i));
404
-
405
- //&& (scope.dataFrame.selection.get(i) === selected);
406
426
  }, event);
407
427
  }
428
+
429
+ /**
430
+ * Highlights column header if the corresponding position is correlated with any other.
431
+ *
432
+ * @protected
433
+ * @param {CanvasRenderingContext2D} g A context to draw on.
434
+ * @param {string} name The name of the column.
435
+ * @param {number} x X coordinate to draw at.
436
+ * @param {number} y Y coordinate to draw at.
437
+ * @param {number} width The width to take to draw the highlighting.
438
+ * @param {number} margin The margin to take into account.
439
+ * @memberof StackedBarChart
440
+ */
441
+ protected higlightCorrelatedPositionHeader(
442
+ g: CanvasRenderingContext2D,
443
+ name: string,
444
+ x: number,
445
+ y: number,
446
+ width: number,
447
+ margin: number,
448
+ ) {
449
+ if (this.corrViz?.isPositionCorrelating(name)) {
450
+ const height = width/name.length; //TODO: measure height more precisely.s
451
+ g.fillRect(x, y + height + margin * 20, width, 2);
452
+ }
453
+ }
454
+
455
+ /**
456
+ * Formats HTML elements with the correlation analysis to add to the tooltip.
457
+ *
458
+ * @param {string} name A column name to consider.
459
+ * @param {string[]} positions Optional list of columns containing positions.
460
+ * @return {HTMLElement[]} The list of elements. Is empty if the position is not correlating.
461
+ * @memberof StackedBarChart
462
+ */
463
+ getTooltipElements(name: string, positions: string[]): HTMLElement[] {
464
+ const pos1 = parseInt(name);
465
+
466
+ if (this.corrViz?.isPositionCorrelating(name)) {
467
+ const padLen = Math.round(Math.log10(positions.length))+1;
468
+
469
+ const elements: HTMLElement[] = [];
470
+ elements.push(ui.divText(name, {style: {fontWeight: 'bold', fontSize: 10}}));
471
+ elements.push(ui.divText('Found correlations with:\n'));
472
+
473
+ for (const [pos2, weight] of Object.entries(this.corrViz.path[pos1])) {
474
+ const w = (weight as number);
475
+ const style = {style: {color: w > 0 ? 'red' : 'blue'}};
476
+ elements.push(ui.divText(`${pos2.padStart(padLen, '0')}: R = ${w.toFixed(2)}\n`, style));
477
+ }
478
+
479
+ return elements;
480
+ }
481
+ return [];
482
+ }
408
483
  }
@@ -1,10 +1,18 @@
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 {createPeptideSimilaritySpaceViewer} from '../utils/peptide-similarity-space';
5
- import {addViewerToHeader} from '../viewers/stacked-barchart-viewer';
6
- import {model} from '../viewers/model';
4
+ import {Peptides} from '../peptides';
7
5
 
6
+ /**
7
+ * Peptide analysis widget.
8
+ *
9
+ * @export
10
+ * @param {DG.Column} col Aligned sequence column.
11
+ * @param {DG.TableView} view Working view.
12
+ * @param {DG.Grid} tableGrid Working table grid.
13
+ * @param {DG.DataFrame} currentDf Working table.
14
+ * @return {Promise<DG.Widget>} Widget containing peptide analysis.
15
+ */
8
16
  export async function analyzePeptidesWidget(
9
17
  col: DG.Column, view: DG.TableView, tableGrid: DG.Grid, currentDf: DG.DataFrame,
10
18
  ): Promise<DG.Widget> {
@@ -18,12 +26,13 @@ export async function analyzePeptidesWidget(
18
26
  let hist: DG.Viewer;
19
27
 
20
28
  const activityScalingMethod = ui.choiceInput(
21
- 'Activity scaling',
29
+ 'Scaling',
22
30
  'none',
23
31
  ['none', 'lg', '-lg'],
24
32
  async (currentMethod: string) => {
25
33
  const currentActivityCol = activityColumnChoice.value.name;
26
34
  const tempDf = currentDf.clone(currentDf.filter, [currentActivityCol]);
35
+ //TODO: merge with scaling in describe
27
36
  switch (currentMethod) {
28
37
  case 'lg':
29
38
  await tempDf.columns.addNewCalculated('scaledActivity', 'Log10(${' + currentActivityCol + '})');
@@ -55,7 +64,7 @@ export async function analyzePeptidesWidget(
55
64
  activityScalingMethod.fireChanged();
56
65
  };
57
66
  const activityColumnChoice = ui.columnInput(
58
- 'Activity column',
67
+ 'Activity',
59
68
  currentDf,
60
69
  defaultColumn,
61
70
  activityScalingMethodState,
@@ -64,45 +73,20 @@ export async function analyzePeptidesWidget(
64
73
  activityScalingMethod.fireChanged();
65
74
 
66
75
  const startBtn = ui.button('Launch SAR', async () => {
67
- const progress = DG.TaskBarProgressIndicator.create('Loading SAR...');
68
76
  if (activityColumnChoice.value.type === DG.TYPE.FLOAT) {
77
+ const progress = DG.TaskBarProgressIndicator.create('Loading SAR...');
69
78
  const options: {[key: string]: string} = {
70
79
  'activityColumnColumnName': activityColumnChoice.value.name,
71
80
  'activityScalingMethod': activityScalingMethod.value,
72
81
  };
73
- for (let i = 0; i < tableGrid.columns.length; i++) {
74
- const col = tableGrid.columns.byIndex(i);
75
- if (col &&
76
- col.name &&
77
- col.column?.semType != 'aminoAcids'
78
- ) {
79
- //@ts-ignore
80
- tableGrid.columns.byIndex(i)?.visible = false;
81
- }
82
- }
83
82
 
84
- const sarViewer = view.addViewer('peptide-sar-viewer', options);
85
- const sarViewerVertical = view.addViewer('peptide-sar-viewer-vertical');
86
- const peptideSpaceViewer = await createPeptideSimilaritySpaceViewer(
87
- currentDf,
88
- col,
89
- 't-SNE',
90
- 'Levenshtein',
91
- 100,
92
- `${activityColumnChoice}Scaled`,
93
- );
94
- let refNode = view.dockManager.dock(peptideSpaceViewer, 'down');
95
- refNode = view.dockManager.dock(sarViewer, 'right', refNode);
96
- view.dockManager.dock(sarViewerVertical, 'right', refNode);
83
+ const peptides = new Peptides();
84
+ await peptides.init(tableGrid, view, currentDf, options, col, activityColumnChoice.value.name);
97
85
 
98
- const StackedBarchartProm = currentDf.plot.fromType('StackedBarChartAA');
99
- addViewerToHeader(tableGrid, StackedBarchartProm);
100
-
101
- // currentDf.onValuesChanged.subscribe(async () => await model.updateDefault());
86
+ progress.close();
102
87
  } else {
103
88
  grok.shell.error('The activity column must be of floating point number type!');
104
89
  }
105
- progress.close();
106
90
  });
107
91
 
108
92
  const viewer = await currentDf.plot.fromType('peptide-logo-viewer');
@@ -2,9 +2,16 @@ import * as ui from 'datagrok-api/ui';
2
2
  import * as DG from 'datagrok-api/dg';
3
3
 
4
4
  import $ from 'cash-dom';
5
- import { model } from '../viewers/model';
6
- import { splitAlignedPeptides } from '../utils/split-aligned';
5
+ import {model} from '../viewers/model';
6
+ import {splitAlignedPeptides} from '../utils/split-aligned';
7
7
 
8
+ /**
9
+ * Manual sequence alignment widget.
10
+ *
11
+ * @param {DG.Column} alignedSequenceCol Aligned sequence column.
12
+ * @param {DG.DataFrame} currentDf Working table.
13
+ * @returns {DG.Widget} Widget for manual sequence alignment.
14
+ */
8
15
  export function manualAlignmentWidget(alignedSequenceCol: DG.Column, currentDf: DG.DataFrame) {
9
16
  const sequenceInput = ui.textInput('', alignedSequenceCol.get(currentDf.currentRowIdx));
10
17
  (sequenceInput.input as HTMLElement).style.height = '50px';
@@ -13,12 +20,13 @@ export function manualAlignmentWidget(alignedSequenceCol: DG.Column, currentDf:
13
20
  const applyChangesBtn = ui.button('Apply', async () => {
14
21
  const newSequence = sequenceInput.value;
15
22
  const affectedRowIndex = currentDf.currentRowIdx;
16
- const [splitSequence,] = splitAlignedPeptides(DG.Column.fromStrings('splitSequence', [newSequence]), false);
23
+ const [splitSequence] = splitAlignedPeptides(DG.Column.fromStrings('splitSequence', [newSequence]), false);
17
24
 
18
25
  alignedSequenceCol.set(affectedRowIndex, newSequence);
19
26
  for (const part of splitSequence.columns) {
20
- if (currentDf.col(part.name) !== null)
27
+ if (currentDf.col(part.name) !== null) {
21
28
  currentDf.set(part.name, affectedRowIndex, part.get(0));
29
+ }
22
30
  }
23
31
 
24
32
  await model.updateDefault();
@@ -3,6 +3,13 @@ import * as ui from 'datagrok-api/ui';
3
3
  import * as DG from 'datagrok-api/dg';
4
4
  import {ChemPalette} from '../utils/chem-palette';
5
5
 
6
+ /**
7
+ * 3D representation widget of peptide molecule.
8
+ *
9
+ * @export
10
+ * @param {string} pep Peptide string.
11
+ * @return {Promise<DG.Widget>} Widget.
12
+ */
6
13
  export async function peptideMoleculeWidget(pep: string): Promise<DG.Widget> {
7
14
  const pi = DG.TaskBarProgressIndicator.create('Creating NGL view');
8
15
 
@@ -39,4 +46,4 @@ export async function peptideMoleculeWidget(pep: string): Promise<DG.Widget> {
39
46
  pi.close();
40
47
 
41
48
  return new DG.Widget(ui.div([panel, nglHost]));
42
- }
49
+ }
@@ -1,5 +1,5 @@
1
1
  import {DimensionalityReducer} from '@datagrok-libraries/utils/src/reduce-dimensionality';
2
- import {Coordinates} from '@datagrok-libraries/utils/src/type_declarations';
2
+ import {Coordinates} from '@datagrok-libraries/utils/src/type-declarations';
3
3
 
4
4
  /**
5
5
  * Worker thread receiving data function.