@datagrok/peptides 0.8.13 → 1.0.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.
Files changed (39) hide show
  1. package/.eslintrc.json +5 -2
  2. package/dist/package-test.js +1268 -1766
  3. package/dist/package.js +1097 -1622
  4. package/dist/vendors-node_modules_datagrok-libraries_ml_src_workers_dimensionality-reducer_js.js +120 -62
  5. package/package.json +13 -17
  6. package/package.png +0 -0
  7. package/src/model.ts +504 -448
  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 +25 -151
  16. package/src/utils/chem-palette.ts +3 -14
  17. package/src/utils/constants.ts +5 -0
  18. package/src/utils/filtering-statistics.ts +2 -2
  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 +12 -9
  23. package/src/utils/types.ts +5 -2
  24. package/src/viewers/peptide-space-viewer.ts +67 -39
  25. package/src/viewers/sar-viewer.ts +34 -37
  26. package/src/viewers/stacked-barchart-viewer.ts +38 -61
  27. package/src/widgets/analyze-peptides.ts +53 -75
  28. package/src/widgets/distribution.ts +34 -18
  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 +8 -13
  33. package/{test-Peptides-f8114def7953-4bf59d70.html → test-Peptides-69a4761f6044-40ac3a0c.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,44 +1,39 @@
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';
10
9
 
11
- /**
12
- * Peptide analysis widget.
10
+ /** Peptide analysis widget.
13
11
  *
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
- */
12
+ * @param {DG.DataFrame} currentDf Working table
13
+ * @param {DG.Column} col Aligned sequence column
14
+ * @return {Promise<DG.Widget>} Widget containing peptide analysis */
21
15
  export async function analyzePeptidesWidget(currentDf: DG.DataFrame, col: DG.Column): Promise<DG.Widget> {
22
16
  let tempCol = null;
23
- let tempDf: DG.DataFrame;
17
+ let scaledDf: DG.DataFrame;
24
18
  let newScaledColName: string;
19
+ const separator = getSeparator(col);
20
+ col.tags[C.TAGS.SEPARATOR] ??= separator;
25
21
 
26
22
  for (const column of currentDf.columns.numerical)
27
23
  tempCol = column.type === DG.TYPE.FLOAT ? column : null;
28
24
 
29
- const defaultColumn: DG.Column = currentDf.col('activity') || currentDf.col('IC50') || tempCol;
25
+ const defaultColumn: DG.Column<number> | null = currentDf.col('activity') || currentDf.col('IC50') || tempCol;
30
26
  const histogramHost = ui.div([], {id: 'pep-hist-host'});
31
27
 
32
28
  const activityScalingMethod = ui.choiceInput(
33
29
  'Scaling', 'none', ['none', 'lg', '-lg'],
34
- async (currentMethod: string) => {
35
- const currentActivityCol = activityColumnChoice.value.name;
36
-
30
+ async (currentMethod: string): Promise<void> => {
31
+ const currentActivityCol = activityColumnChoice.value?.name;
37
32
 
38
- [tempDf, newScaledColName] = await PeptidesController.scaleActivity(
33
+ [scaledDf, newScaledColName] = await PeptidesModel.scaleActivity(
39
34
  currentMethod, currentDf, currentActivityCol, true);
40
35
 
41
- const hist = tempDf.plot.histogram({
36
+ const hist = scaledDf.plot.histogram({
42
37
  filteringEnabled: false,
43
38
  valueColumnName: C.COLUMNS_NAMES.ACTIVITY_SCALED,
44
39
  legendVisibility: 'Never',
@@ -46,83 +41,66 @@ export async function analyzePeptidesWidget(currentDf: DG.DataFrame, col: DG.Col
46
41
  showColumnSelector: false,
47
42
  showRangeSlider: false,
48
43
  showBinSelector: false,
49
- // bins: b,
50
44
  });
51
45
  histogramHost.lastChild?.remove();
52
46
  histogramHost.appendChild(hist.root);
53
47
  });
54
48
  activityScalingMethod.setTooltip('Function to apply for each value in activity column');
55
49
 
56
- const activityScalingMethodState = function(_: any) {
57
- activityScalingMethod.enabled =
58
- activityColumnChoice.value && DG.Stats.fromColumn(activityColumnChoice.value, currentDf.filter).min > 0;
50
+ const activityScalingMethodState = (_: any): void => {
51
+ activityScalingMethod.enabled = (activityColumnChoice.value ?? false) &&
52
+ DG.Stats.fromColumn(activityColumnChoice.value!, currentDf.filter).min > 0;
59
53
  activityScalingMethod.fireChanged();
60
54
  };
61
- const activityColumnChoice = ui.columnInput(
62
- 'Activity',
63
- currentDf,
64
- defaultColumn,
65
- activityScalingMethodState,
66
- );
55
+ const activityColumnChoice = ui.columnInput('Activity', currentDf, defaultColumn, activityScalingMethodState);
67
56
  activityColumnChoice.fireChanged();
68
57
  activityScalingMethod.fireChanged();
69
58
 
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';
59
+ const inputsList = [activityColumnChoice, activityScalingMethod];
90
60
 
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();
61
+ const startBtn = ui.button('Launch SAR', async () => {
62
+ await startAnalysis(activityColumnChoice.value, col, currentDf, scaledDf, newScaledColName);
96
63
  });
97
64
  startBtn.style.alignSelf = 'center';
98
65
 
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');
66
+ const viewer = await currentDf.plot.fromType('WebLogo');
67
+ viewer.root.style.setProperty('height', '130px');
117
68
 
118
69
  return new DG.Widget(
119
70
  ui.divV([
120
71
  viewer.root,
121
72
  ui.splitH([
122
- ui.splitV([ui.inputs([activityColumnChoice, activityScalingMethod]), startBtn]),
73
+ ui.splitV([ui.inputs(inputsList), startBtn]),
123
74
  histogramHost,
124
75
  ], {style: {height: 'unset'}}),
125
- // histogramHost,
126
76
  ]),
127
77
  );
128
78
  }
79
+
80
+ export async function startAnalysis(
81
+ activityColumn: DG.Column<number> | null, alignedSeqCol: DG.Column<string>, currentDf: DG.DataFrame,
82
+ scaledDf: DG.DataFrame, newScaledColName: string, dgPackage?: DG.Package): Promise<PeptidesModel | null> {
83
+ const progress = DG.TaskBarProgressIndicator.create('Loading SAR...');
84
+ let model = null;
85
+ if (activityColumn?.type === DG.TYPE.FLOAT) {
86
+ const activityColumnName: string = activityColumn.name;
87
+
88
+ //prepare new DF
89
+ const newDf = currentDf.clone(currentDf.filter, [alignedSeqCol.name, activityColumnName]);
90
+ const activityCol = newDf.getCol(activityColumnName);
91
+ activityCol.name = C.COLUMNS_NAMES.ACTIVITY;
92
+ activityCol.semType = C.SEM_TYPES.ACTIVITY;
93
+ newDf.getCol(alignedSeqCol.name).name = C.COLUMNS_NAMES.ALIGNED_SEQUENCE;
94
+ const activityScaledCol = scaledDf.getCol(C.COLUMNS_NAMES.ACTIVITY_SCALED);
95
+ activityScaledCol.semType = C.SEM_TYPES.ACTIVITY_SCALED;
96
+ newDf.columns.add(activityScaledCol);
97
+ newDf.name = 'Peptides analysis';
98
+ newDf.tags[C.COLUMNS_NAMES.ACTIVITY_SCALED] = newScaledColName;
99
+ // newDf.tags[C.PEPTIDES_ANALYSIS] = 'true';
100
+
101
+ model = await PeptidesModel.getInstance(newDf, dgPackage ?? _package);
102
+ } else
103
+ grok.shell.error('The activity column must be of floating point number type!');
104
+ progress.close();
105
+ return model;
106
+ }
@@ -4,10 +4,10 @@ import * as DG from 'datagrok-api/dg';
4
4
  import * as C from '../utils/constants';
5
5
  import {StringDictionary} from '@datagrok-libraries/utils/src/type-declarations';
6
6
  import {FilteringStatistics} from '../utils/filtering-statistics';
7
+ import * as type from '../utils/types';
7
8
 
8
- export function getDistributionPlot(df: DG.DataFrame, valueCol: string, splitCol: string) {
9
+ export function getDistributionPlot(df: DG.DataFrame, valueCol: string, splitCol: string): DG.Viewer {
9
10
  return df.plot.histogram({
10
- // const hist = originalDf.plot.histogram({
11
11
  filteringEnabled: false,
12
12
  valueColumnName: valueCol,
13
13
  splitColumnName: splitCol,
@@ -18,33 +18,49 @@ export function getDistributionPlot(df: DG.DataFrame, valueCol: string, splitCol
18
18
  });
19
19
  }
20
20
 
21
+ const allLabel = 'All';
22
+
21
23
  export function getDistributionWidget(table: DG.DataFrame): DG.Widget {
22
- // const labelStr = this.multipleFilter.filterLabel;
23
24
  const splitCol = table.col(C.COLUMNS_NAMES.SPLIT_COL);
24
- if (!splitCol)
25
+ const selectionObject: type.SelectionObject = JSON.parse(table.tags[C.TAGS.SELECTION]);
26
+ if (!splitCol || !selectionObject)
25
27
  return new DG.Widget(ui.divText('No distribution'));
26
- let [aarStr, otherStr] = splitCol.categories;
27
- if (typeof otherStr === 'undefined')
28
- [aarStr, otherStr] = [otherStr, aarStr];
29
- // const currentColor = DG.Color.toHtml(DG.Color.orange);
30
- // const otherColor = DG.Color.toHtml(DG.Color.blue);
31
- const currentColor = DG.Color.toHtml(DG.Color.getCategoryColor(splitCol, aarStr));
32
- const otherColor = DG.Color.toHtml(DG.Color.getCategoryColor(splitCol, otherStr));
28
+
29
+ const positions = Object.keys(selectionObject);
30
+ let currentColor = DG.Color.toHtml(DG.Color.blue);
31
+ const otherColor = DG.Color.toHtml(DG.Color.blue);
32
+ let aarStr = allLabel;
33
+ let otherStr = '';
34
+
35
+ if (positions.length) {
36
+ aarStr = '';
37
+
38
+ for (const position of positions) {
39
+ aarStr += `${position}: {`;
40
+
41
+ for (const aar of selectionObject[position])
42
+ aarStr += `${aar}, `;
43
+
44
+ aarStr = aarStr.slice(0, aarStr.length - 2);
45
+ aarStr += '}; ';
46
+ }
47
+ aarStr = aarStr.slice(0, aarStr.length - 2);
48
+ otherStr = 'Other';
49
+ currentColor = DG.Color.toHtml(DG.Color.orange);
50
+ }
33
51
 
34
52
  const currentLabel = ui.label(aarStr, {style: {color: currentColor}});
35
53
  const otherLabel = ui.label(otherStr, {style: {color: otherColor}});
36
54
  const elements: (HTMLLabelElement | HTMLElement)[] = [currentLabel, otherLabel];
37
55
 
38
- const getContent = () => {
39
- // const processedDf =
40
- // table.clone(null, [C.COLUMNS_NAMES.ACTIVITY_SCALED, C.COLUMNS_NAMES.SPLIT_COL]);
41
- const hist = getDistributionPlot(table, C.COLUMNS_NAMES.ACTIVITY_SCALED, C.COLUMNS_NAMES.SPLIT_COL).root;
42
-
56
+ const getContent = (): HTMLDivElement => {
57
+ const valueColName = table.columns.bySemType(C.SEM_TYPES.ACTIVITY_SCALED)!.name;
58
+ const hist = getDistributionPlot(table, valueColName, C.COLUMNS_NAMES.SPLIT_COL).root;
43
59
  hist.style.width = 'auto';
44
60
  elements.push(hist);
45
-
46
61
  const stats = (table.temp[C.STATS] as FilteringStatistics).result;
47
- if (stats) {
62
+
63
+ if (stats && aarStr != allLabel) {
48
64
  const tableMap: StringDictionary = {
49
65
  'Statistics:': '',
50
66
  'Count': stats.count.toString(),
@@ -3,25 +3,22 @@ import * as grok from 'datagrok-api/grok';
3
3
  import * as DG from 'datagrok-api/dg';
4
4
 
5
5
  import $ from 'cash-dom';
6
- // import {splitAlignedPeptides} from '../utils/split-aligned';
7
6
  import '../styles.css';
8
- import {PeptidesController} from '../peptides';
7
+ import {PeptidesModel} from '../model';
9
8
 
10
- /**
11
- * Manual sequence alignment widget.
9
+ /** Manual sequence alignment widget.
12
10
  *
13
- * @param {DG.Column} alignedSequenceCol Aligned sequence column.
14
- * @param {DG.DataFrame} currentDf Working table.
15
- * @return {DG.Widget} Widget for manual sequence alignment.
16
- */
17
- export function manualAlignmentWidget(alignedSequenceCol: DG.Column, currentDf: DG.DataFrame) {
11
+ * @param {DG.Column} alignedSequenceCol Aligned sequence column
12
+ * @param {DG.DataFrame} currentDf Working table
13
+ * @return {DG.Widget} Widget for manual sequence alignment */
14
+ export function manualAlignmentWidget(alignedSequenceCol: DG.Column<string>, currentDf: DG.DataFrame): DG.Widget {
18
15
  const sequenceInput = ui.textInput('', alignedSequenceCol.get(currentDf.currentRowIdx));
19
16
  $(sequenceInput.root).addClass('pep-textinput');
20
17
 
21
18
  const applyChangesBtn = ui.button('Apply', async () => {
22
19
  const newSequence = sequenceInput.value;
23
20
  const affectedRowIndex = currentDf.currentRowIdx;
24
- const [splitSequence] = PeptidesController.splitAlignedPeptides(
21
+ const [splitSequence] = PeptidesModel.splitAlignedPeptides(
25
22
  DG.Column.fromStrings('splitSequence', [newSequence]), false);
26
23
 
27
24
  alignedSequenceCol.set(affectedRowIndex, newSequence);
@@ -33,8 +30,7 @@ export function manualAlignmentWidget(alignedSequenceCol: DG.Column, currentDf:
33
30
  grok.shell.o = null;
34
31
  grok.shell.o = temp;
35
32
 
36
- const peptidesController = await PeptidesController.getInstance(currentDf);
37
- peptidesController.init(currentDf);
33
+ const peptidesController = await PeptidesModel.getInstance(currentDf);
38
34
  peptidesController.updateDefault();
39
35
  });
40
36
 
@@ -1,8 +1,8 @@
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 {ChemPalette} from '../utils/chem-palette';
5
- import {PeptidesController} from '../peptides';
4
+ import * as C from '../utils/constants';
5
+ import {PeptidesModel} from '../model';
6
6
 
7
7
  /**
8
8
  * 3D representation widget of peptide molecule.
@@ -11,40 +11,63 @@ import {PeptidesController} from '../peptides';
11
11
  * @param {string} pep Peptide string.
12
12
  * @return {Promise<DG.Widget>} Widget.
13
13
  */
14
- export async function peptideMoleculeWidget(pep: string): Promise<DG.Widget> {
14
+ export async function peptideMoleculeWidget(pep: string, currentTable: DG.DataFrame): Promise<DG.Widget> {
15
15
  const pi = DG.TaskBarProgressIndicator.create('Creating NGL view');
16
+ const separator = currentTable.columns.bySemType(C.SEM_TYPES.ALIGNED_SEQUENCE)!.tags[C.TAGS.SEPARATOR];
16
17
 
17
- const smiles = getMolecule(pep);
18
- if (smiles == '')
19
- return new DG.Widget(ui.divH([]));
18
+ let widgetHost;
19
+ let smiles = '';
20
+ let molfileStr = '';
21
+ try {
22
+ try {
23
+ const params = {table: currentTable};
24
+ const result = await grok.functions.call('Customerextensions:getPeptideStructure', params) as string[];
25
+ if (result.length !== 0) {
26
+ smiles = result[0];
27
+ molfileStr = result[1];
28
+ throw new Error(`Found structure in DB`);
29
+ }
20
30
 
31
+ smiles = getMolecule(pep, separator);
32
+ if (smiles == '')
33
+ throw new Error('Couldn\'t get smiles');
21
34
 
22
- let molfileStr = (await grok.functions.call('Peptides:SmiTo3D', {smiles}));
35
+ molfileStr = (await grok.functions.call('Peptides:SmiTo3D', {smiles})) as string;
36
+ } catch (e) {
37
+ console.warn(e);
38
+ }
23
39
 
24
- molfileStr = molfileStr.replaceAll('\\n', '\n'); ;
25
- const stringBlob = new Blob([molfileStr], {type: 'text/plain'});
26
- const nglHost = ui.div([], {classes: 'd4-ngl-viewer', id: 'ngl-3d-host'});
40
+ try {
41
+ molfileStr = molfileStr.replaceAll('\\n', '\n');
42
+ const stringBlob = new Blob([molfileStr], {type: 'text/plain'});
43
+ const nglHost = ui.div([], {classes: 'd4-ngl-viewer', id: 'ngl-3d-host'});
27
44
 
28
- //@ts-ignore
29
- const stage = new NGL.Stage(nglHost, {backgroundColor: 'white'});
30
- //@ts-ignore
31
- stage.loadFile(stringBlob, {ext: 'sdf'}).then(function(comp: NGL.StructureComponent) {
32
- stage.setSize(300, 300);
33
- comp.addRepresentation('ball+stick');
34
- comp.autoView();
35
- });
36
- const sketch = grok.chem.svgMol(smiles);
37
- const panel = ui.divH([sketch]);
45
+ //@ts-ignore
46
+ const stage = new NGL.Stage(nglHost, {backgroundColor: 'white'});
47
+ //@ts-ignore
48
+ stage.loadFile(stringBlob, {ext: 'sdf'}).then(function(comp: NGL.StructureComponent) {
49
+ stage.setSize(300, 300);
50
+ comp.addRepresentation('ball+stick');
51
+ comp.autoView();
52
+ });
53
+ const sketch = grok.chem.svgMol(molfileStr);
54
+ const panel = ui.divH([sketch]);
38
55
 
56
+ widgetHost = ui.div([panel, nglHost]);
57
+ } catch (e) {
58
+ widgetHost = ui.divText('Couldn\'t get peptide structure');
59
+ }
60
+ } catch (e) {
61
+ widgetHost = ui.divText('Couldn\'t get peptide structure');
62
+ }
39
63
  pi.close();
40
-
41
- return new DG.Widget(ui.div([panel, nglHost]));
64
+ return new DG.Widget(widgetHost);
42
65
  }
43
66
 
44
- export function getMolecule(pep: string): string {
45
- const split = pep.split('-');
67
+ export function getMolecule(pep: string, separator: string): string {
68
+ const split = pep.split(separator);
46
69
  const mols = [];
47
- const chemPalette = PeptidesController.chemPalette;
70
+ const chemPalette = PeptidesModel.chemPalette;
48
71
  for (let i = 1; i < split.length - 1; i++) {
49
72
  if (split[i] in chemPalette.AASmiles) {
50
73
  const aar = chemPalette.AASmiles[split[i]];
@@ -1,73 +1,74 @@
1
1
  import * as ui from 'datagrok-api/ui';
2
2
  import * as DG from 'datagrok-api/dg';
3
- import { PeptidesController } from '../peptides';
3
+ import * as C from '../utils/constants';
4
+ import * as type from '../utils/types';
5
+ import {PeptidesModel} from '../model';
4
6
 
5
- export async function substitutionsWidget(table: DG.DataFrame): Promise<DG.Widget> {
6
- const controller = await PeptidesController.getInstance(table);
7
- controller.init(table);
8
- const substTable = controller.getSubstitutions();
7
+ export function substitutionsWidget(table: DG.DataFrame, model: PeptidesModel): DG.Widget {
8
+ const substInfo = model.substitutionsInfo;
9
+ const currentCell = model.currentSelection;
10
+ const positions = Object.keys(currentCell);
9
11
 
10
- if (!substTable)
12
+ if (!positions.length)
11
13
  return new DG.Widget(ui.label('No substitution table generated'));
12
14
 
13
- const dfRowCount = substTable.rowCount;
14
- const aminoInputFrom = ui.stringInput('from', '');
15
- const aminoInputTo = ui.stringInput('to', '');
16
- const fromToMap: {[key: string]: DG.BitSet} = {};
17
- let aminoFrom = '';
18
- let aminoTo = '';
19
- const initialCol: DG.Column = substTable.getCol('Initial');
20
- const substitutedCol: DG.Column = substTable.getCol('Substituted');
15
+ const substitutionsArray: string[] = [];
16
+ const deltaArray: number[] = [];
17
+ const substitutedToArray: string[] = [];
18
+ const alignedSeqCol = table.columns.bySemType(C.SEM_TYPES.ALIGNED_SEQUENCE)!;
19
+ const activityScaledCol = table.columns.bySemType(C.SEM_TYPES.ACTIVITY_SCALED)!;
20
+ const seenIndexes = new Map<number, number[]>();
21
21
 
22
- initialCol.semType = 'alignedSequenceDifference';
23
- initialCol.name = 'Substitution';
24
- // substTable.columns.remove('Substituted');
25
- // const substCol = table.getCol('Substitution');
22
+ for (const pos of positions) {
23
+ for (const aar of currentCell[pos]) {
24
+ const substitutionsMap = substInfo.get(aar)?.get(pos) as Map<number, type.UTypedArray> | undefined;
25
+ if (typeof substitutionsMap === 'undefined')
26
+ continue;
26
27
 
27
- for (let i = 0; i < dfRowCount; ++i) {
28
- // const [from, to] = substCol!.get(i).split('#');
29
- const from = initialCol.get(i);
30
- const to = substitutedCol.get(i);
31
- const aminosFrom: [] = from.split('-');
32
- const aminosTo: [] = to.split('-');
28
+ const posCol = table.getCol(pos);
29
+ for (const [referenceIdx, indexArray] of substitutionsMap.entries()) {
30
+ const forbiddentIndexes = seenIndexes.has(referenceIdx) ? seenIndexes.get(referenceIdx)! : [];
31
+ const baseSequence = alignedSeqCol.get(referenceIdx);
32
+ const baseActivity = activityScaledCol.get(referenceIdx);
33
33
 
34
- for (let j = 0; j < aminosFrom.length; ++j) {
35
- if (aminosFrom[j] != aminosTo[j]) {
36
- const idx = `${getAmino(aminosFrom[j])}#${getAmino(aminosTo[j])}`;
34
+ for (const subIdx of indexArray) {
35
+ if (forbiddentIndexes.includes(subIdx))
36
+ continue;
37
37
 
38
- if (!(idx in fromToMap))
39
- fromToMap[idx] = DG.BitSet.create(dfRowCount);
40
- fromToMap[idx].set(i, true);
38
+ if (!seenIndexes.has(subIdx))
39
+ seenIndexes.set(subIdx, []);
40
+
41
+ seenIndexes.get(subIdx)!.push(referenceIdx);
42
+ substitutionsArray.push(`${baseSequence}#${alignedSeqCol.get(subIdx)}`);
43
+ deltaArray.push(baseActivity - activityScaledCol.get(subIdx));
44
+ substitutedToArray.push(posCol.get(subIdx));
45
+ }
41
46
  }
42
47
  }
43
48
  }
44
49
 
45
- for (let i = 0; i < initialCol.length; ++i) {
46
- const sequenceDifference = `${initialCol.get(i)}#${substitutedCol.get(i)}`;
47
- initialCol.set(i, sequenceDifference);
48
- }
50
+ if (!substitutionsArray.length)
51
+ return new DG.Widget(ui.label('No substitution table generated'));
49
52
 
50
- aminoInputFrom.onInput(() => {
51
- aminoFrom = getAmino(aminoInputFrom.value);
52
- const fromKey = `${aminoFrom}#${aminoTo}`;
53
- if (fromKey in fromToMap)
54
- substTable.selection.copyFrom(fromToMap[fromKey]);
55
- });
53
+ const substCol = DG.Column.fromStrings('Substiutions', substitutionsArray);
54
+ substCol.semType = C.SEM_TYPES.ALIGNED_SEQUENCE_DIFFERENCE;
55
+ const toColName = '~to';
56
+ const hiddenSubstToAarCol = DG.Column.fromStrings(toColName, substitutedToArray);
57
+ const substTable =
58
+ DG.DataFrame.fromColumns([substCol, DG.Column.fromList('double', 'Delta', deltaArray), hiddenSubstToAarCol]);
56
59
 
57
- aminoInputTo.onInput(() => {
58
- aminoTo = getAmino(aminoInputTo.value);
59
- const toKey = `${aminoFrom}#${aminoTo}`;
60
- if (toKey in fromToMap)
61
- substTable.selection.copyFrom(fromToMap[toKey]);
60
+ const aminoToInput = ui.stringInput('Substituted to:', '', () => {
61
+ const substitutedToAar = aminoToInput.stringValue;
62
+ if (substitutedToAar != '')
63
+ substTable.filter.init((idx) => hiddenSubstToAarCol.get(idx) === substitutedToAar);
64
+ else
65
+ substTable.filter.setAll(true);
62
66
  });
63
67
 
64
68
  const grid = substTable.plot.grid();
65
69
  grid.props.allowEdit = false;
66
- grid.root.style.width = 'auto';
67
- grid.root.style.height = '150px';
68
- return new DG.Widget(ui.divV([aminoInputFrom.root, aminoInputTo.root, grid.root]));
69
- }
70
-
71
- function getAmino(amino: string): string {
72
- return amino === '' ? '-' : amino;
70
+ const gridRoot = grid.root;
71
+ gridRoot.style.width = 'auto';
72
+ gridRoot.style.height = '150px';
73
+ return new DG.Widget(ui.divV([aminoToInput.root, gridRoot]));
73
74
  }
@@ -1,6 +1,5 @@
1
1
  import {DimensionalityReducer, KnownMethods} from '@datagrok-libraries/ml/src/reduce-dimensionality';
2
2
  import {KnownMetrics} from '@datagrok-libraries/ml/src/typed-metrics';
3
- import {Coordinates} from '@datagrok-libraries/utils/src/type-declarations';
4
3
 
5
4
  /**
6
5
  * Worker thread receiving data function.
@@ -8,23 +7,19 @@ import {Coordinates} from '@datagrok-libraries/utils/src/type-declarations';
8
7
  * @param {any[]} columnData Samples to process.
9
8
  * @param {string} method Embedding method.
10
9
  * @param {string} measure Distance metric.
11
- * @param {number} cyclesCount Number of cycles to repeat.
12
- * @return {Coordinates} Embedding.
10
+ * @param {any} options Options to pass to algorithm.
11
+ * @return {any} Embedding (and distance matrix where applicable).
13
12
  */
14
- function onMessage(columnData: any[], method: KnownMethods, measure: KnownMetrics, cyclesCount: number): Coordinates {
15
- const reducer = new DimensionalityReducer(
16
- columnData,
17
- method,
18
- measure,
19
- {cycles: cyclesCount},
20
- );
13
+ function onMessage(columnData: any[], method: KnownMethods, measure: KnownMetrics, options: any): any {
14
+ const reducer = new DimensionalityReducer(columnData, method, measure, options);
21
15
  return reducer.transform(true);
22
16
  }
23
17
 
24
- self.onmessage = ({data: {columnData, method, measure, cyclesCount}}) => {
25
- const embedding = onMessage(columnData, method, measure, cyclesCount);
18
+ self.onmessage = ({data: {columnData, method, measure, options}}): void => {
19
+ const embedding = onMessage(columnData, method, measure, options);
26
20
  self.postMessage({
27
- embedding: embedding,
21
+ distance: embedding.distance,
22
+ embedding: embedding.embedding,
28
23
  });
29
24
  };
30
25
 
@@ -1,4 +1,4 @@
1
- <html><head><meta charset="utf-8"/><title>Peptides Test Report. Datagrok version datagrok/datagrok:latest SHA=f8114def7953. Commit 4bf59d70.</title><style type="text/css">html,
1
+ <html><head><meta charset="utf-8"/><title>Peptides Test Report. Datagrok version datagrok/datagrok:latest SHA=69a4761f6044. Commit 40ac3a0c.</title><style type="text/css">html,
2
2
  body {
3
3
  font-family: Arial, Helvetica, sans-serif;
4
4
  font-size: 1rem;
@@ -229,7 +229,7 @@ header {
229
229
  font-size: 1rem;
230
230
  padding: 0 0.5rem;
231
231
  }
232
- </style></head><body><div id="jesthtml-content"><header><h1 id="title">Peptides Test Report. Datagrok version datagrok/datagrok:latest SHA=f8114def7953. Commit 4bf59d70.</h1></header><div id="metadata-container"><div id="timestamp">Started: 2022-05-08 20:15:31</div><div id="summary"><div id="suite-summary"><div class="summary-total">Suites (1)</div><div class="summary-passed summary-empty">0 passed</div><div class="summary-failed">1 failed</div><div class="summary-pending summary-empty">0 pending</div></div><div id="test-summary"><div class="summary-total">Tests (1)</div><div class="summary-passed summary-empty">0 passed</div><div class="summary-failed">1 failed</div><div class="summary-pending summary-empty">0 pending</div></div></div></div><div id="suite-1" class="suite-container"><div class="suite-info"><div class="suite-path">/home/runner/work/public/public/packages/Peptides/src/__jest__/remote.test.ts</div><div class="suite-time warn">117.567s</div></div><div class="suite-tests"><div class="test-result failed"><div class="test-info"><div class="test-suitename"> </div><div class="test-title">TEST</div><div class="test-status">failed</div><div class="test-duration">100.001s</div></div><div class="failureMessages"> <pre class="failureMsg">Error: thrown: "Exceeded timeout of 100000 ms for a test.
232
+ </style></head><body><div id="jesthtml-content"><header><h1 id="title">Peptides Test Report. Datagrok version datagrok/datagrok:latest SHA=69a4761f6044. Commit 40ac3a0c.</h1></header><div id="metadata-container"><div id="timestamp">Started: 2022-07-01 16:42:11</div><div id="summary"><div id="suite-summary"><div class="summary-total">Suites (1)</div><div class="summary-passed summary-empty">0 passed</div><div class="summary-failed">1 failed</div><div class="summary-pending summary-empty">0 pending</div></div><div id="test-summary"><div class="summary-total">Tests (1)</div><div class="summary-passed summary-empty">0 passed</div><div class="summary-failed">1 failed</div><div class="summary-pending summary-empty">0 pending</div></div></div></div><div id="suite-1" class="suite-container"><div class="suite-info"><div class="suite-path">/home/runner/work/public/public/packages/Peptides/src/__jest__/remote.test.ts</div><div class="suite-time warn">112.158s</div></div><div class="suite-tests"><div class="test-result failed"><div class="test-info"><div class="test-suitename"> </div><div class="test-title">TEST</div><div class="test-status">failed</div><div class="test-duration">100.002s</div></div><div class="failureMessages"> <pre class="failureMsg">Error: thrown: "Exceeded timeout of 100000 ms for a test.
233
233
  Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."
234
234
  at Object.&lt;anonymous&gt; (/home/runner/work/public/public/packages/Peptides/src/__jest__/remote.test.ts:22:1)
235
235
  at Runtime._execModule (/home/runner/work/public/public/packages/Peptides/node_modules/jest-runtime/build/index.js:1646:24)