@datagrok/peptides 1.0.2 → 1.2.0

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.
@@ -6,7 +6,6 @@ import {
6
6
  createDimensinalityReducingWorker,
7
7
  IReduceDimensionalityResult,
8
8
  } from '@datagrok-libraries/ml/src/workers/dimensionality-reducing-worker-creator';
9
- import {runKalign} from '../utils/multiple-sequence-alignment';
10
9
  import {StringMetrics} from '@datagrok-libraries/ml/src/typed-metrics';
11
10
 
12
11
  /**
@@ -39,11 +38,10 @@ export async function _testViewerIsDrawing(table: DG.DataFrame, view: DG.TableVi
39
38
  export async function _testDimensionalityReducer(
40
39
  columnData: Array<string>, method: StringMetrics, measure: string): Promise<void> {
41
40
  const cyclesCount = 100;
42
- let embcols;
43
41
 
44
42
  const reduceDimRes: IReduceDimensionalityResult = await createDimensinalityReducingWorker(
45
43
  {data: columnData, metric: measure as StringMetrics}, method, {cycles: cyclesCount});
46
- embcols = reduceDimRes.embedding;
44
+ const embcols = reduceDimRes.embedding;
47
45
 
48
46
  const [X, Y] = embcols as Array<Float32Array>;
49
47
 
@@ -65,12 +63,9 @@ export async function _testDimensionalityReducer(
65
63
  */
66
64
  export async function _testPeptideSimilaritySpaceViewer(table: DG.DataFrame, alignedSequencesColumn: DG.Column,
67
65
  method: string, measure: string, cyclesCount: number): Promise<void> {
68
- let viewer;
69
- let df: DG.DataFrame;
70
-
71
- viewer = await createPeptideSimilaritySpaceViewer(
66
+ const viewer = await createPeptideSimilaritySpaceViewer(
72
67
  table, method, measure, cyclesCount, undefined, alignedSequencesColumn);
73
- df = viewer.dataFrame;
68
+ const df = viewer.dataFrame;
74
69
 
75
70
  const axesNames = ['~X', '~Y', '~MW'];
76
71
  const axes = axesNames.map((v) => df.getCol(v).getRawData() as Float32Array);
@@ -1,4 +1,4 @@
1
- import {SeqPalette, SeqPaletteBase} from '@datagrok-libraries/bio/src/seq-palettes';
1
+ import {SeqPaletteBase} from '@datagrok-libraries/bio/src/seq-palettes';
2
2
  import * as DG from 'datagrok-api/dg';
3
3
 
4
4
  import * as C from './constants';
@@ -63,8 +63,8 @@ export function measureAAR(s: string): number {
63
63
 
64
64
  export function renderSARCell(canvasContext: CanvasRenderingContext2D, currentAAR: string, currentPosition: string,
65
65
  statsDf: DG.DataFrame, twoColorMode: boolean, mdCol: DG.Column<number>, bound: DG.Rect, cellValue: number,
66
- currentSelection: types.SelectionObject, substitutionsInfo: types.SubstitutionsInfo | null): void {
67
- const queryAAR = `${C.COLUMNS_NAMES.AMINO_ACID_RESIDUE} = ${currentAAR}`;
66
+ currentSelection: types.SelectionObject, substitutionsInfo: types.SubstitutionsInfo): void {
67
+ const queryAAR = `${C.COLUMNS_NAMES.MONOMER} = ${currentAAR}`;
68
68
  const query = `${queryAAR} and ${C.COLUMNS_NAMES.POSITION} = ${currentPosition}`;
69
69
  const pVal: number = statsDf
70
70
  .groupBy([C.COLUMNS_NAMES.P_VALUE])
@@ -101,7 +101,7 @@ export function renderSARCell(canvasContext: CanvasRenderingContext2D, currentAA
101
101
  canvasContext.closePath();
102
102
 
103
103
  canvasContext.fill();
104
- if (substitutionsInfo) {
104
+ if (substitutionsInfo.size > 0) {
105
105
  canvasContext.textBaseline = 'middle';
106
106
  canvasContext.textAlign = 'center';
107
107
  canvasContext.fillStyle = DG.Color.toHtml(DG.Color.getContrastColor(DG.Color.fromHtml(coef)));
@@ -136,7 +136,7 @@ export function renderBarchart(ctx: CanvasRenderingContext2D, col: DG.Column, mo
136
136
  const yMargin = bounds.y + bounds.height * margin / 4;
137
137
  const wMargin = bounds.width - bounds.width * margin * 2;
138
138
  const hMargin = bounds.height - bounds.height * margin;
139
- const barWidth = wMargin - 10;
139
+ const barWidth = 10;
140
140
  ctx.fillStyle = 'black';
141
141
  ctx.textBaseline = 'top';
142
142
  ctx.font = `${hMargin * margin / 2}px`;
@@ -3,7 +3,7 @@ export enum COLUMNS_NAMES {
3
3
  ACTIVITY = '~activity',
4
4
  ACTIVITY_SCALED = 'activity_scaled',
5
5
  ALIGNED_SEQUENCE = '~aligned_sequence',
6
- AMINO_ACID_RESIDUE = 'AAR',
6
+ MONOMER = 'AAR',
7
7
  POSITION = 'Pos',
8
8
  P_VALUE = 'pValue',
9
9
  MEAN_DIFFERENCE = 'Mean difference',
@@ -0,0 +1,163 @@
1
+ import * as ui from 'datagrok-api/ui';
2
+ import * as DG from 'datagrok-api/dg';
3
+
4
+ import * as C from './constants';
5
+ import {PeptidesModel} from '../model';
6
+ import {isGridCellInvalid} from './misc';
7
+
8
+ const CELL_SIZE = 20; // 20px cell height and width
9
+
10
+ export class InvariantMap extends DG.Filter {
11
+ model: PeptidesModel | null = null;
12
+ chosenCells: {[position: string]: string[]} = {};
13
+
14
+ constructor() {
15
+ super();
16
+ }
17
+
18
+ get caption(): string {return 'Invariant Map';}
19
+
20
+ get filterSummary(): string {
21
+ let summary = '';
22
+ for (const [pos, aarList] of Object.entries(this.chosenCells))
23
+ if (aarList.length > 0)
24
+ summary += `${pos}: ${aarList}\n`;
25
+
26
+ return summary;
27
+ }
28
+
29
+ get isFiltering(): boolean {return true && super.isFiltering;}
30
+
31
+ get isReadyToApplyFilter(): boolean {return this.model != null;}
32
+
33
+ async attach(df: DG.DataFrame): Promise<void> {
34
+ super.attach(df);
35
+ this.model = await PeptidesModel.getInstance(df);
36
+ this.render(true);
37
+ }
38
+
39
+ saveState(): any {
40
+ const state = super.saveState();
41
+ state.chosenCells = JSON.stringify(this.chosenCells);
42
+ return state;
43
+ }
44
+
45
+ applyState(state: any): void {
46
+ super.applyState(state);
47
+ if (state.chosenCells) {
48
+ this.chosenCells = JSON.parse(state.chosenCells);
49
+ this.render();
50
+ }
51
+ }
52
+
53
+ applyFilter(): void {
54
+ this.dataFrame?.filter.init((bitsetIndex) => {
55
+ for (const [position, aarList] of Object.entries(this.chosenCells)) {
56
+ if (aarList.length != 0 && !aarList.includes(this.dataFrame!.get(position, bitsetIndex)))
57
+ return false;
58
+ }
59
+ return true;
60
+ });
61
+ }
62
+
63
+ render(initChosenCells: boolean = false): void {
64
+ if (this.model == null)
65
+ return;
66
+
67
+ const invariantDf = this.model.statsDf.groupBy([C.COLUMNS_NAMES.MONOMER])
68
+ .pivot(C.COLUMNS_NAMES.POSITION)
69
+ .add('first', C.COLUMNS_NAMES.COUNT, '')
70
+ .aggregate();
71
+ invariantDf.getCol(C.COLUMNS_NAMES.MONOMER).semType = C.SEM_TYPES.MONOMER;
72
+ const orderedColNames = invariantDf.columns.names().sort((a, b) => {
73
+ const aInt = parseInt(a);
74
+ const bInt = parseInt(b);
75
+ if (isNaN(aInt))
76
+ return -1;
77
+ else if (isNaN(bInt))
78
+ return 1;
79
+ return aInt - bInt;
80
+ });
81
+
82
+ // Create grid and set properties
83
+ const invariantGrid = invariantDf.plot.grid();
84
+ const gridCols = invariantGrid.columns;
85
+ gridCols.rowHeader!.visible = false;
86
+ gridCols.setOrder(orderedColNames);
87
+
88
+ for (let gridColIndex = 0; gridColIndex < gridCols.length; ++gridColIndex) {
89
+ const gridCol = gridCols.byIndex(gridColIndex)!
90
+ if (gridCol.name != C.COLUMNS_NAMES.MONOMER)
91
+ gridCol.width = CELL_SIZE;
92
+ }
93
+
94
+ if (initChosenCells) {
95
+ this.chosenCells = {};
96
+ for (const col of invariantDf.columns)
97
+ if (col.name != C.COLUMNS_NAMES.MONOMER)
98
+ this.chosenCells[col.name] = [];
99
+ }
100
+
101
+ invariantGrid.root.addEventListener('click', (ev) => {
102
+ invariantDf.currentRowIdx = -1;
103
+ const gridCell = invariantGrid.hitTest(ev.offsetX, ev.offsetY);
104
+ if (isGridCellInvalid(gridCell) || gridCell!.tableColumn!.name == C.COLUMNS_NAMES.MONOMER)
105
+ return;
106
+
107
+ const position = gridCell!.tableColumn!.name;
108
+ const aar = invariantDf.get(C.COLUMNS_NAMES.MONOMER, gridCell!.tableRowIndex!);
109
+ const aarList = this.chosenCells[position];
110
+ const aarIndex = aarList.indexOf(aar);
111
+
112
+ if (aarIndex != -1)
113
+ aarList.splice(aarIndex, 1);
114
+ else
115
+ aarList.push(aar);
116
+
117
+ invariantGrid.invalidate();
118
+ this.applyFilter();
119
+ });
120
+
121
+ invariantGrid.onCellRender.subscribe((args) => {
122
+ //FIXME: for some reason it doesn't work when I set right away
123
+ const gridProps = invariantGrid.props;
124
+ gridProps.allowBlockSelection = false;
125
+ gridProps.allowColSelection = false;
126
+ gridProps.allowRowSelection = false;
127
+ gridProps.allowEdit = false;
128
+ gridProps.rowHeight = CELL_SIZE;
129
+
130
+ const gc = args.cell;
131
+ const tableColName = gc.tableColumn?.name;
132
+ const tableRowIndex = gc.tableRowIndex;
133
+
134
+ if (isGridCellInvalid(gc) || tableColName == C.COLUMNS_NAMES.MONOMER ||
135
+ tableRowIndex == null || tableRowIndex == -1)
136
+ return;
137
+
138
+ const currentPosition: string = tableColName !== C.COLUMNS_NAMES.MEAN_DIFFERENCE ?
139
+ tableColName : invariantDf.get(C.COLUMNS_NAMES.POSITION, tableRowIndex);
140
+ const currentAAR: string = invariantDf.get(C.COLUMNS_NAMES.MONOMER, tableRowIndex);
141
+ const canvasContext = args.g;
142
+ const bound = args.bounds;
143
+
144
+ canvasContext.font = '10px Roboto';
145
+ canvasContext.textAlign = 'center';
146
+ canvasContext.textBaseline = 'middle';
147
+ canvasContext.fillStyle = '#000';
148
+ canvasContext.fillText(gc.cell.value, bound.x + (bound.width / 2), bound.y + (bound.height / 2), bound.width);
149
+
150
+ const aarSelection = this.chosenCells[currentPosition];
151
+ if (aarSelection.includes(currentAAR)) {
152
+ canvasContext.strokeStyle = '#000';
153
+ canvasContext.lineWidth = 1;
154
+ canvasContext.strokeRect(bound.x + 1, bound.y + 1, bound.width - 1, bound.height - 1);
155
+ }
156
+ args.preventDefault();
157
+ });
158
+
159
+ const gridHost = ui.box(invariantGrid.root);
160
+ gridHost.style.width = '100%';
161
+ this.root.appendChild(gridHost);
162
+ }
163
+ }
package/src/utils/misc.ts CHANGED
@@ -6,7 +6,6 @@ import {AminoacidsPalettes} from '@datagrok-libraries/bio/src/aminoacids';
6
6
  import {NucleotidesPalettes} from '@datagrok-libraries/bio/src/nucleotides';
7
7
  import {UnknownSeqPalettes} from '@datagrok-libraries/bio/src/unknown';
8
8
  import {SeqPalette} from '@datagrok-libraries/bio/src/seq-palettes';
9
- import {WebLogo} from '@datagrok-libraries/bio/src/viewers/web-logo';
10
9
 
11
10
  export function getPalleteByType(paletteType: string): SeqPalette {
12
11
  switch (paletteType) {
@@ -33,28 +32,6 @@ export function getSeparator(col: DG.Column<string>): string {
33
32
  return col.getTag(C.TAGS.SEPARATOR) ?? '';
34
33
  }
35
34
 
36
- export function splitAlignedPeptides(peptideColumn: DG.Column<string>): DG.DataFrame {
37
- const splitter = WebLogo.getSplitterForColumn(peptideColumn);
38
- const colLen = peptideColumn.length;
39
- const resultDf = DG.DataFrame.create(colLen);
40
- let monomerList = splitter(peptideColumn.get(0)!);
41
- const columnList: DG.Column<string>[] = [];
42
-
43
- // create columns and fill the first row for faster values filling in the next loop
44
- for (let i = 0; i < monomerList.length; i++) {
45
- const col = resultDf.columns.addNewString((i + 1).toString());
46
- col.set(0, monomerList[i] || '-', false);
47
- columnList.push(col);
48
- }
49
-
50
- for (let rowIndex = 1; rowIndex < colLen; rowIndex++) {
51
- monomerList = splitter(peptideColumn.get(rowIndex)!);
52
- monomerList.forEach((monomer, colIndex) => columnList[colIndex].set(rowIndex, monomer || '-', false));
53
- }
54
-
55
- return resultDf;
56
- }
57
-
58
35
  export function scaleActivity(
59
36
  activityScaling: string, df: DG.DataFrame, originalActivityName?: string, cloneBitset = false,
60
37
  ): [DG.DataFrame, string] {
@@ -64,17 +41,17 @@ export function scaleActivity(
64
41
  currentActivityColName = flag ? currentActivityColName : C.COLUMNS_NAMES.ACTIVITY;
65
42
  const tempDf = df.clone(cloneBitset ? df.filter : null, [currentActivityColName]);
66
43
 
67
- let formula = (v: number) => v;
44
+ let formula = (v: number): number => v;
68
45
  let newColName = 'activity';
69
46
  switch (activityScaling) {
70
47
  case 'none':
71
48
  break;
72
49
  case 'lg':
73
- formula = (v: number) => Math.log10(v);
50
+ formula = (v: number): number => Math.log10(v);
74
51
  newColName = `Log10(${newColName})`;
75
52
  break;
76
53
  case '-lg':
77
- formula = (v: number) => -Math.log10(v);
54
+ formula = (v: number): number => -Math.log10(v);
78
55
  newColName = `-Log10(${newColName})`;
79
56
  break;
80
57
  default:
@@ -95,13 +72,13 @@ export function calculateBarsData(columns: DG.Column<string>[], selection: DG.Bi
95
72
 
96
73
  for (let colIndex = 0; colIndex < columnsLen; colIndex++) {
97
74
  const col = columns[colIndex];
98
- dfStats[col.name] = calculateBarData(col, selection);
75
+ dfStats[col.name] = calculateSingleBarData(col, selection);
99
76
  }
100
77
 
101
78
  return dfStats;
102
79
  }
103
80
 
104
- export function calculateBarData(col: DG.Column<string>, selection: DG.BitSet): type.MonomerColStats {
81
+ export function calculateSingleBarData(col: DG.Column<string>, selection: DG.BitSet): type.MonomerColStats {
105
82
  const colLen = col.length;
106
83
  const colStats: type.MonomerColStats = {};
107
84
  col.categories.forEach((monomer) => colStats[monomer] = {count: 0, selected: 0});
@@ -114,3 +91,8 @@ export function calculateBarData(col: DG.Column<string>, selection: DG.BitSet):
114
91
 
115
92
  return colStats;
116
93
  }
94
+
95
+ export function isGridCellInvalid(gc: DG.GridCell | null): boolean {
96
+ return !gc || !gc.cell.value || !gc.tableColumn || gc.tableRowIndex == null || gc.tableRowIndex == -1 ||
97
+ gc.cell.value == DG.INT_NULL || gc.cell.value == DG.FLOAT_NULL;
98
+ }
@@ -15,7 +15,6 @@ export class SARViewerBase extends DG.JsViewer {
15
15
  model!: PeptidesModel;
16
16
  scaling: string;
17
17
  bidirectionalAnalysis: boolean;
18
- showSubstitution: boolean;
19
18
  maxSubstitutions: number;
20
19
  minActivityDelta: number;
21
20
  _titleHost = ui.divText('SAR Viewer', {id: 'pep-viewer-title'});
@@ -27,23 +26,20 @@ export class SARViewerBase extends DG.JsViewer {
27
26
 
28
27
  this.scaling = this.string('scaling', 'none', {choices: ['none', 'lg', '-lg']});
29
28
  this.bidirectionalAnalysis = this.bool('bidirectionalAnalysis', false);
30
- this.showSubstitution = this.bool('showSubstitution', true);
31
- this.maxSubstitutions = this.int('maxSubstitutions', 2);
32
- this.minActivityDelta = this.float('minActivityDelta', 1);
29
+ this.maxSubstitutions = this.int('maxSubstitutions', 1);
30
+ this.minActivityDelta = this.float('minActivityDelta', 0);
33
31
  }
34
32
 
35
33
  async onTableAttached(): Promise<void> {
36
34
  super.onTableAttached();
37
35
  this.sourceGrid = this.view?.grid ?? (grok.shell.v as DG.TableView).grid;
38
36
  this.model = await PeptidesModel.getInstance(this.dataFrame);
39
- // this.model.init(this.dataFrame);
40
37
  this.helpUrl = '/help/domains/bio/peptides.md';
41
- // await this.requestDataUpdate();
42
38
 
43
39
  this.initProperties();
44
40
  }
45
41
 
46
- initProperties() {
42
+ initProperties(): void {
47
43
  const props = this.model.usedProperties;
48
44
  IS_PROPERTY_CHANGING = true;
49
45
  for (const [propName, propVal] of Object.entries(props))
@@ -65,11 +61,6 @@ export class SARViewerBase extends DG.JsViewer {
65
61
  this.viewerGrid?.invalidate();
66
62
  }
67
63
 
68
- // async requestDataUpdate(): Promise<void> {
69
- // await this.model.updateData(this.scaling, this.sourceGrid, this.bidirectionalAnalysis,
70
- // this.minActivityDelta, this.maxSubstitutions, this.showSubstitution);
71
- // }
72
-
73
64
  onPropertyChanged(property: DG.Property): void {
74
65
  super.onPropertyChanged(property);
75
66
  this.dataFrame.tags[property.name] = `${property.get(this)}`;
@@ -89,10 +80,6 @@ export class SARViewerBase extends DG.JsViewer {
89
80
  }
90
81
  }
91
82
 
92
- if (!this.showSubstitution && ['maxSubstitutions', 'activityLimit'].includes(propName))
93
- return;
94
-
95
- // await this.requestDataUpdate();
96
83
  this.model.updateDefault();
97
84
  this.render(true);
98
85
  }
@@ -102,7 +89,7 @@ export class SARViewerBase extends DG.JsViewer {
102
89
  * Structure-activity relationship viewer.
103
90
  */
104
91
  export class SARViewer extends SARViewerBase {
105
- _titleHost = ui.divText('Monomer-Positions', {id: 'pep-viewer-title'});
92
+ _titleHost = ui.divText('Mutation Cliffs', {id: 'pep-viewer-title'});
106
93
  _name = 'Structure-Activity Relationship';
107
94
 
108
95
  constructor() {super();}
@@ -112,7 +99,6 @@ export class SARViewer extends SARViewerBase {
112
99
  async onTableAttached(): Promise<void> {
113
100
  await super.onTableAttached();
114
101
  this.model.sarViewer ??= this;
115
- // this.dataFrame.temp['sarViewer'] = this;
116
102
 
117
103
  this.subs.push(this.model.onSARGridChanged.subscribe((data) => {
118
104
  this.viewerGrid = data;
@@ -7,7 +7,6 @@ import {WebLogo} from '@datagrok-libraries/bio/src/viewers/web-logo';
7
7
  import '../styles.css';
8
8
  import * as C from '../utils/constants';
9
9
  import {PeptidesModel} from '../model';
10
- import {_package} from '../package';
11
10
  import $ from 'cash-dom';
12
11
  import {scaleActivity} from '../utils/misc';
13
12
 
@@ -17,9 +16,17 @@ import {scaleActivity} from '../utils/misc';
17
16
  * @param {DG.Column} col Aligned sequence column
18
17
  * @return {Promise<DG.Widget>} Widget containing peptide analysis */
19
18
  export async function analyzePeptidesWidget(currentDf: DG.DataFrame, col: DG.Column): Promise<DG.Widget> {
20
- const funcs = DG.Func.find({package: 'Bio', name: 'webLogoViewer'});
19
+ if (!col.tags['aligned']?.includes('MSA') && col.tags[DG.TAGS.UNITS].toLowerCase() != 'helm')
20
+ return new DG.Widget(ui.divText('Peptides analysis only works with aligned sequences'));
21
+
22
+ let funcs = DG.Func.find({package: 'Bio', name: 'webLogoViewer'});
21
23
  if (funcs.length == 0)
22
24
  return new DG.Widget(ui.label('Bio package is missing or out of date. Please install the latest version.'));
25
+
26
+ funcs = DG.Func.find({package: 'Helm', name: 'getMonomerLib'});
27
+ if (funcs.length == 0)
28
+ return new DG.Widget(ui.label('Helm package is missing or out of date. Please install the latest version.'));
29
+
23
30
  let tempCol = null;
24
31
  let scaledDf: DG.DataFrame;
25
32
  let newScaledColName: string;
@@ -85,7 +92,7 @@ export async function analyzePeptidesWidget(currentDf: DG.DataFrame, col: DG.Col
85
92
 
86
93
  export async function startAnalysis(
87
94
  activityColumn: DG.Column<number> | null, alignedSeqCol: DG.Column<string>, currentDf: DG.DataFrame,
88
- scaledDf: DG.DataFrame, newScaledColName: string, dgPackage?: DG.Package): Promise<PeptidesModel | null> {
95
+ scaledDf: DG.DataFrame, newScaledColName: string): Promise<PeptidesModel | null> {
89
96
  const progress = DG.TaskBarProgressIndicator.create('Loading SAR...');
90
97
  let model = null;
91
98
  if (activityColumn?.type === DG.TYPE.FLOAT) {
@@ -104,14 +111,15 @@ export async function startAnalysis(
104
111
  newDf.tags[C.COLUMNS_NAMES.ACTIVITY_SCALED] = newScaledColName;
105
112
  // newDf.tags[C.PEPTIDES_ANALYSIS] = 'true';
106
113
 
107
- const alignedSeqColUnits = alignedSeqCol.getTag(DG.TAGS.UNITS);
108
114
  let monomerType = 'HELM_AA';
109
- if (alignedSeqColUnits == 'HELM') {
115
+ if (alignedSeqCol.getTag(DG.TAGS.UNITS).toLowerCase() == 'helm') {
110
116
  const sampleSeq = alignedSeqCol.get(0)!;
111
117
  monomerType = sampleSeq.startsWith('PEPTIDE') ? 'HELM_AA' : 'HELM_BASE';
112
118
  } else {
113
- monomerType = alignedSeqColUnits.split(':')[2] == 'PT' ? 'HELM_AA' : 'HELM_BASE';
119
+ const alphabet = alignedSeqCol.tags[C.TAGS.ALPHABET];
120
+ monomerType = alphabet == 'DNA' || alphabet == 'RNA' ? 'HELM_BASE' : 'HELM_AA';
114
121
  }
122
+
115
123
  newDf.setTag('monomerType', monomerType);
116
124
 
117
125
  model = await PeptidesModel.getInstance(newDf);
@@ -5,7 +5,7 @@ import {StringDictionary} from '@datagrok-libraries/utils/src/type-declarations'
5
5
  import $ from 'cash-dom';
6
6
 
7
7
  import * as C from '../utils/constants';
8
- import {getStats, Stats} from '../utils/filtering-statistics';
8
+ import {getStats, Stats} from '../utils/statistics';
9
9
  import {PeptidesModel} from '../model';
10
10
 
11
11
  const allConst = 'All';
@@ -21,7 +21,7 @@ export function getDistributionWidget(table: DG.DataFrame, model: PeptidesModel)
21
21
  let otherStr = '';
22
22
  const useSelectedStr = model.isPeptideSpaceChangingBitset;
23
23
 
24
- const updateDistributionHost = () => {
24
+ const updateDistributionHost = (): void => {
25
25
  model.splitByPos = splitByPosition.value!;
26
26
  model.splitByAAR = splitByAAR.value!;
27
27
  const res: HTMLDivElement[] = [];
@@ -104,31 +104,32 @@ export function getDistributionWidget(table: DG.DataFrame, model: PeptidesModel)
104
104
  } else {
105
105
  const splitCol = table.col(C.COLUMNS_NAMES.SPLIT_COL);
106
106
  if (!splitCol)
107
- return new DG.Widget(ui.divText('No distribution'));
108
-
109
- otherStr = '';
110
- if (useSelectedStr) {
111
- aarStr = 'Selected';
112
- otherStr = otherConst;
113
- } else if (positionsLen) {
114
- aarStr = '';
115
- for (const position of positions)
116
- aarStr += `${position}: {${selectionObject[position].join(', ')}}; `;
117
- aarStr = aarStr.slice(0, aarStr.length - 2);
118
- otherStr = otherConst;
119
- }
107
+ res.push(ui.divText('No distribution'));
108
+ else {
109
+ otherStr = '';
110
+ if (useSelectedStr) {
111
+ aarStr = 'Selected';
112
+ otherStr = otherConst;
113
+ } else if (positionsLen) {
114
+ aarStr = '';
115
+ for (const position of positions)
116
+ aarStr += `${position}: {${selectionObject[position].join(', ')}}; `;
117
+ aarStr = aarStr.slice(0, aarStr.length - 2);
118
+ otherStr = otherConst;
119
+ }
120
120
 
121
- const distributionTable = DG.DataFrame.fromColumns([activityScaledCol, splitCol]);
122
- const stats = getStats(activityScaledCol.getRawData(), table.selection);
123
- const distributionRoot = getDistributionAndStats(distributionTable, stats, aarStr, otherStr);
124
- $(distributionRoot).addClass('d4-flex-col');
121
+ const distributionTable = DG.DataFrame.fromColumns([activityScaledCol, splitCol]);
122
+ const stats = getStats(activityScaledCol.getRawData(), table.selection);
123
+ const distributionRoot = getDistributionAndStats(distributionTable, stats, aarStr, otherStr);
124
+ $(distributionRoot).addClass('d4-flex-col');
125
125
 
126
- res.push(distributionRoot);
126
+ res.push(distributionRoot);
127
+ }
127
128
  }
128
129
  $(distributionHost).empty().append(res);
129
130
  };
130
131
 
131
- const setDefaultProperties = (input: DG.InputBase) => {
132
+ const setDefaultProperties = (input: DG.InputBase): void => {
132
133
  input.enabled = positionsLen != 0;
133
134
  $(input.root).find('.ui-input-editor').css('margin', '0px');
134
135
  $(input.root).find('.ui-input-description').css('padding', '0px');
@@ -2,10 +2,11 @@ import * as ui from 'datagrok-api/ui';
2
2
  import * as grok from 'datagrok-api/grok';
3
3
  import * as DG from 'datagrok-api/dg';
4
4
 
5
+ import {splitAlignedSequences} from '@datagrok-libraries/bio/src/utils/splitter';
6
+
5
7
  import $ from 'cash-dom';
6
8
  import '../styles.css';
7
9
  import {PeptidesModel} from '../model';
8
- import {splitAlignedPeptides} from '../utils/misc';
9
10
 
10
11
  /** Manual sequence alignment widget.
11
12
  *
@@ -19,7 +20,7 @@ export function manualAlignmentWidget(alignedSequenceCol: DG.Column<string>, cur
19
20
  const applyChangesBtn = ui.button('Apply', async () => {
20
21
  const newSequence = sequenceInput.value;
21
22
  const affectedRowIndex = currentDf.currentRowIdx;
22
- const splitSequence = splitAlignedPeptides(DG.Column.fromStrings('splitSequence', [newSequence]));
23
+ const splitSequence = splitAlignedSequences(DG.Column.fromStrings('splitSequence', [newSequence]));
23
24
 
24
25
  alignedSequenceCol.set(affectedRowIndex, newSequence);
25
26
  for (const part of splitSequence.columns) {
@@ -5,13 +5,13 @@ import * as type from '../utils/types';
5
5
  import {PeptidesModel} from '../model';
6
6
  import {getSeparator} from '../utils/misc';
7
7
 
8
- export function substitutionsWidget(table: DG.DataFrame, model: PeptidesModel): DG.Widget {
8
+ export function mutationCliffsWidget(table: DG.DataFrame, model: PeptidesModel): DG.Widget {
9
9
  const substInfo = model.substitutionsInfo;
10
10
  const currentCell = model.currentSelection;
11
11
  const positions = Object.keys(currentCell);
12
12
 
13
13
  if (!positions.length)
14
- return new DG.Widget(ui.label('No substitution table generated'));
14
+ return new DG.Widget(ui.label('No mutations table generated'));
15
15
 
16
16
  const substitutionsArray: string[] = [];
17
17
  const deltaArray: number[] = [];
@@ -49,18 +49,19 @@ export function substitutionsWidget(table: DG.DataFrame, model: PeptidesModel):
49
49
  }
50
50
 
51
51
  if (!substitutionsArray.length)
52
- return new DG.Widget(ui.label('No substitution table generated'));
52
+ return new DG.Widget(ui.label('No mutations table generated'));
53
53
 
54
- const substCol = DG.Column.fromStrings('Substiutions', substitutionsArray);
54
+ const substCol = DG.Column.fromStrings('Mutation', substitutionsArray);
55
55
  substCol.semType = C.SEM_TYPES.MACROMOLECULE_DIFFERENCE;
56
56
  substCol.tags[C.TAGS.SEPARATOR] = getSeparator(alignedSeqCol);
57
57
  substCol.tags[DG.TAGS.UNITS] = alignedSeqCol.tags[DG.TAGS.UNITS];
58
+ substCol.tags[DG.TAGS.CELL_RENDERER] = 'MacromoleculeDifference';
58
59
  const toColName = '~to';
59
60
  const hiddenSubstToAarCol = DG.Column.fromStrings(toColName, substitutedToArray);
60
61
  const substTable =
61
62
  DG.DataFrame.fromColumns([substCol, DG.Column.fromList('double', 'Delta', deltaArray), hiddenSubstToAarCol]);
62
63
 
63
- const aminoToInput = ui.stringInput('Substituted to:', '', () => {
64
+ const aminoToInput = ui.stringInput('Mutated to:', '', () => {
64
65
  const substitutedToAar = aminoToInput.stringValue;
65
66
  if (substitutedToAar != '')
66
67
  substTable.filter.init((idx) => hiddenSubstToAarCol.get(idx) === substitutedToAar);