@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.
- package/.eslintrc.json +5 -2
- package/dist/package-test.js +1268 -1766
- package/dist/package.js +1097 -1622
- package/dist/vendors-node_modules_datagrok-libraries_ml_src_workers_dimensionality-reducer_js.js +120 -62
- package/package.json +13 -17
- package/package.png +0 -0
- package/src/model.ts +504 -448
- package/src/monomer-library.ts +31 -30
- package/src/package-test.ts +5 -6
- package/src/package.ts +52 -70
- package/src/tests/core.ts +67 -0
- package/src/tests/msa-tests.ts +3 -3
- package/src/tests/peptide-space-test.ts +65 -45
- package/src/tests/utils.ts +20 -50
- package/src/utils/cell-renderer.ts +25 -151
- package/src/utils/chem-palette.ts +3 -14
- package/src/utils/constants.ts +5 -0
- package/src/utils/filtering-statistics.ts +2 -2
- package/src/utils/misc.ts +29 -0
- package/src/utils/multiple-sequence-alignment.ts +5 -18
- package/src/utils/multivariate-analysis.ts +5 -8
- package/src/utils/peptide-similarity-space.ts +12 -9
- package/src/utils/types.ts +5 -2
- package/src/viewers/peptide-space-viewer.ts +67 -39
- package/src/viewers/sar-viewer.ts +34 -37
- package/src/viewers/stacked-barchart-viewer.ts +38 -61
- package/src/widgets/analyze-peptides.ts +53 -75
- package/src/widgets/distribution.ts +34 -18
- package/src/widgets/manual-alignment.ts +8 -12
- package/src/widgets/peptide-molecule.ts +48 -25
- package/src/widgets/subst-table.ts +53 -52
- package/src/workers/dimensionality-reducer.ts +8 -13
- package/{test-Peptides-f8114def7953-4bf59d70.html → test-Peptides-69a4761f6044-40ac3a0c.html} +2 -2
- package/src/peptides.ts +0 -327
- package/src/semantics.ts +0 -5
- package/src/tests/peptides-tests.ts +0 -60
- package/src/utils/SAR-multiple-filter.ts +0 -439
- package/src/utils/SAR-multiple-selection.ts +0 -177
- 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 {
|
|
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
|
-
* @
|
|
15
|
-
* @param {DG.Column} col Aligned sequence column
|
|
16
|
-
* @
|
|
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
|
|
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
|
|
36
|
-
|
|
30
|
+
async (currentMethod: string): Promise<void> => {
|
|
31
|
+
const currentActivityCol = activityColumnChoice.value?.name;
|
|
37
32
|
|
|
38
|
-
[
|
|
33
|
+
[scaledDf, newScaledColName] = await PeptidesModel.scaleActivity(
|
|
39
34
|
currentMethod, currentDf, currentActivityCol, true);
|
|
40
35
|
|
|
41
|
-
const hist =
|
|
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 =
|
|
57
|
-
activityScalingMethod.enabled =
|
|
58
|
-
|
|
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
|
|
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
|
-
|
|
92
|
-
|
|
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
|
-
|
|
100
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
|
|
40
|
-
|
|
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
|
-
|
|
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 {
|
|
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] =
|
|
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
|
|
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
|
-
|
|
5
|
-
import {
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
35
|
+
molfileStr = (await grok.functions.call('Peptides:SmiTo3D', {smiles})) as string;
|
|
36
|
+
} catch (e) {
|
|
37
|
+
console.warn(e);
|
|
38
|
+
}
|
|
23
39
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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 =
|
|
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
|
|
3
|
+
import * as C from '../utils/constants';
|
|
4
|
+
import * as type from '../utils/types';
|
|
5
|
+
import {PeptidesModel} from '../model';
|
|
4
6
|
|
|
5
|
-
export
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
const
|
|
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 (!
|
|
12
|
+
if (!positions.length)
|
|
11
13
|
return new DG.Widget(ui.label('No substitution table generated'));
|
|
12
14
|
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
for (const subIdx of indexArray) {
|
|
35
|
+
if (forbiddentIndexes.includes(subIdx))
|
|
36
|
+
continue;
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
initialCol.set(i, sequenceDifference);
|
|
48
|
-
}
|
|
50
|
+
if (!substitutionsArray.length)
|
|
51
|
+
return new DG.Widget(ui.label('No substitution table generated'));
|
|
49
52
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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
|
|
67
|
-
|
|
68
|
-
|
|
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 {
|
|
12
|
-
* @return {
|
|
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,
|
|
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,
|
|
25
|
-
const embedding = onMessage(columnData, method, measure,
|
|
18
|
+
self.onmessage = ({data: {columnData, method, measure, options}}): void => {
|
|
19
|
+
const embedding = onMessage(columnData, method, measure, options);
|
|
26
20
|
self.postMessage({
|
|
27
|
-
|
|
21
|
+
distance: embedding.distance,
|
|
22
|
+
embedding: embedding.embedding,
|
|
28
23
|
});
|
|
29
24
|
};
|
|
30
25
|
|
package/{test-Peptides-f8114def7953-4bf59d70.html → test-Peptides-69a4761f6044-40ac3a0c.html}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<html><head><meta charset="utf-8"/><title>Peptides Test Report. Datagrok version datagrok/datagrok:latest SHA=
|
|
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=
|
|
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.<anonymous> (/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)
|