@datagrok/peptides 0.8.14 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +5 -2
- package/dist/package-test.js +1451 -2252
- package/dist/package.js +1277 -2105
- package/dist/vendors-node_modules_datagrok-libraries_ml_src_workers_dimensionality-reducer_js.js +9 -25
- package/package.json +10 -14
- package/package.png +0 -0
- package/src/model.ts +565 -599
- 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 +86 -151
- package/src/utils/chem-palette.ts +3 -14
- package/src/utils/constants.ts +7 -0
- package/src/utils/filtering-statistics.ts +21 -53
- 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 +11 -8
- package/src/utils/types.ts +5 -2
- package/src/viewers/peptide-space-viewer.ts +66 -40
- package/src/viewers/sar-viewer.ts +35 -38
- package/src/viewers/stacked-barchart-viewer.ts +42 -83
- package/src/widgets/analyze-peptides.ts +64 -76
- package/src/widgets/distribution.ts +172 -47
- 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 +2 -7
- package/{test-Peptides-2f94f62b59a8-c6d7c434.html → test-Peptides-34f75e5127b8-4210edfc.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,61 +1,186 @@
|
|
|
1
1
|
import * as ui from 'datagrok-api/ui';
|
|
2
2
|
import * as DG from 'datagrok-api/dg';
|
|
3
3
|
|
|
4
|
-
import * as C from '../utils/constants';
|
|
5
4
|
import {StringDictionary} from '@datagrok-libraries/utils/src/type-declarations';
|
|
6
|
-
import
|
|
5
|
+
import $ from 'cash-dom';
|
|
6
|
+
|
|
7
|
+
import * as C from '../utils/constants';
|
|
8
|
+
import {getStats, Stats} from '../utils/filtering-statistics';
|
|
9
|
+
import {PeptidesModel} from '../model';
|
|
10
|
+
|
|
11
|
+
const allConst = 'All';
|
|
12
|
+
const otherConst = 'Other';
|
|
13
|
+
|
|
14
|
+
export function getDistributionWidget(table: DG.DataFrame, model: PeptidesModel): DG.Widget {
|
|
15
|
+
const activityScaledCol = table.columns.bySemType(C.SEM_TYPES.ACTIVITY_SCALED)!;
|
|
16
|
+
const rowCount = activityScaledCol.length;
|
|
17
|
+
const selectionObject = model.currentSelection;
|
|
18
|
+
const positions = Object.keys(selectionObject);
|
|
19
|
+
const positionsLen = positions.length;
|
|
20
|
+
let aarStr = allConst;
|
|
21
|
+
let otherStr = '';
|
|
22
|
+
const useSelectedStr = model.isPeptideSpaceChangingBitset;
|
|
23
|
+
|
|
24
|
+
const updateDistributionHost = () => {
|
|
25
|
+
model.splitByPos = splitByPosition.value!;
|
|
26
|
+
model.splitByAAR = splitByAAR.value!;
|
|
27
|
+
const res: HTMLDivElement[] = [];
|
|
28
|
+
if (splitByPosition.value && splitByAAR.value) {
|
|
29
|
+
otherStr = otherConst;
|
|
30
|
+
for (const position of positions) {
|
|
31
|
+
const posCol = table.getCol(position);
|
|
32
|
+
for (const aar of selectionObject[position]) {
|
|
33
|
+
aarStr = `${position} : ${aar}`;
|
|
34
|
+
const splitCol = DG.Column.bool(C.COLUMNS_NAMES.SPLIT_COL, rowCount).init((i) => posCol.get(i) == aar);
|
|
35
|
+
|
|
36
|
+
const distributionTable = DG.DataFrame.fromColumns([activityScaledCol, splitCol]);
|
|
37
|
+
const currentStatsDf = model.statsDf.rows.match({Pos: position, AAR: aar}).toDataFrame();
|
|
38
|
+
const stats: Stats = {
|
|
39
|
+
count: currentStatsDf.get(C.COLUMNS_NAMES.COUNT, 0),
|
|
40
|
+
ratio: currentStatsDf.get(C.COLUMNS_NAMES.RATIO, 0),
|
|
41
|
+
pValue: currentStatsDf.get(C.COLUMNS_NAMES.P_VALUE, 0),
|
|
42
|
+
meanDifference: currentStatsDf.get(C.COLUMNS_NAMES.MEAN_DIFFERENCE, 0),
|
|
43
|
+
};
|
|
44
|
+
const distributionRoot = getDistributionAndStats(distributionTable, stats, aarStr, otherStr, true);
|
|
45
|
+
$(distributionRoot).addClass('d4-flex-col');
|
|
46
|
+
|
|
47
|
+
res.push(distributionRoot);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
} else if (splitByPosition.value) {
|
|
51
|
+
otherStr = otherConst;
|
|
52
|
+
const activityScaledData = activityScaledCol.getRawData();
|
|
53
|
+
for (const position of positions) {
|
|
54
|
+
const posCol = table.getCol(position);
|
|
55
|
+
const aarList = selectionObject[position];
|
|
56
|
+
aarStr = `${position}: {${aarList.join(', ')}}`;
|
|
57
|
+
|
|
58
|
+
const mask = DG.BitSet.create(rowCount, (i) => aarList.includes(posCol.get(i)));
|
|
59
|
+
const stats = getStats(activityScaledData, mask);
|
|
60
|
+
const splitCol = DG.Column.fromBitSet(C.COLUMNS_NAMES.SPLIT_COL, mask);
|
|
61
|
+
const distributionTable = DG.DataFrame.fromColumns([activityScaledCol, splitCol]);
|
|
62
|
+
const distributionRoot = getDistributionAndStats(distributionTable, stats, aarStr, otherStr, true);
|
|
63
|
+
$(distributionRoot).addClass('d4-flex-col');
|
|
64
|
+
|
|
65
|
+
res.push(distributionRoot);
|
|
66
|
+
}
|
|
67
|
+
} else if (splitByAAR.value) {
|
|
68
|
+
const reversedSelectionObject: {[aar: string]: string[]} = {};
|
|
69
|
+
const aars = [];
|
|
70
|
+
for (const position of positions) {
|
|
71
|
+
for (const aar of selectionObject[position]) {
|
|
72
|
+
if (!reversedSelectionObject.hasOwnProperty(aar)) {
|
|
73
|
+
reversedSelectionObject[aar] = [position];
|
|
74
|
+
aars.push(aar);
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (!reversedSelectionObject[aar].includes(position))
|
|
78
|
+
reversedSelectionObject[aar].push(position);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
otherStr = otherConst;
|
|
83
|
+
const activityScaledData = activityScaledCol.getRawData();
|
|
84
|
+
for (const aar of aars) {
|
|
85
|
+
const posList = reversedSelectionObject[aar];
|
|
86
|
+
aarStr = `${aar}: {${posList.join(', ')}}`;
|
|
87
|
+
|
|
88
|
+
const mask = DG.BitSet.create(rowCount, (i) => {
|
|
89
|
+
const currentRow = table.row(i);
|
|
90
|
+
for (const position of posList) {
|
|
91
|
+
if (currentRow.get(position) == aar)
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
return false;
|
|
95
|
+
});
|
|
96
|
+
const stats = getStats(activityScaledData, mask);
|
|
97
|
+
const splitCol = DG.Column.fromBitSet(C.COLUMNS_NAMES.SPLIT_COL, mask);
|
|
98
|
+
const distributionTable = DG.DataFrame.fromColumns([activityScaledCol, splitCol]);
|
|
99
|
+
const distributionRoot = getDistributionAndStats(distributionTable, stats, aarStr, otherStr, true);
|
|
100
|
+
$(distributionRoot).addClass('d4-flex-col');
|
|
101
|
+
|
|
102
|
+
res.push(distributionRoot);
|
|
103
|
+
}
|
|
104
|
+
} else {
|
|
105
|
+
const splitCol = table.col(C.COLUMNS_NAMES.SPLIT_COL);
|
|
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
|
+
}
|
|
7
120
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
+
|
|
126
|
+
res.push(distributionRoot);
|
|
127
|
+
}
|
|
128
|
+
$(distributionHost).empty().append(res);
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const setDefaultProperties = (input: DG.InputBase) => {
|
|
132
|
+
input.enabled = positionsLen != 0;
|
|
133
|
+
$(input.root).find('.ui-input-editor').css('margin', '0px');
|
|
134
|
+
$(input.root).find('.ui-input-bool-deco').css('left', '-35px').css('margin-right', '-35px');
|
|
135
|
+
$(input.root).find('.ui-input-description').css('padding', '0px');
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const splitByPosition = ui.boolInput('', model.splitByPos, updateDistributionHost);
|
|
139
|
+
splitByPosition.addPostfix('Split by position');
|
|
140
|
+
setDefaultProperties(splitByPosition);
|
|
141
|
+
$(splitByPosition.root).css('margin-right', '10px');
|
|
142
|
+
const splitByAAR = ui.boolInput('', model.splitByAAR, updateDistributionHost);
|
|
143
|
+
splitByAAR.addPostfix('Split by monomer');
|
|
144
|
+
setDefaultProperties(splitByAAR);
|
|
145
|
+
|
|
146
|
+
const controlsHost = ui.divH([splitByPosition.root, splitByAAR.root]);
|
|
147
|
+
const distributionHost = ui.div([], 'd4-flex-wrap');
|
|
148
|
+
splitByAAR.fireChanged();
|
|
149
|
+
|
|
150
|
+
return new DG.Widget(ui.divV([controlsHost, distributionHost]));
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function getDistributionAndStats(
|
|
154
|
+
table: DG.DataFrame, stats: Stats, thisLabel: string, otherLabel: string = '', isTooltip: boolean = false,
|
|
155
|
+
): HTMLDivElement {
|
|
156
|
+
const labels = ui.divV([
|
|
157
|
+
ui.label(thisLabel, {style: {color: DG.Color.toHtml(otherLabel == '' ? DG.Color.blue : DG.Color.orange)}}),
|
|
158
|
+
ui.label(otherLabel, {style: {color: DG.Color.toHtml(DG.Color.blue)}})]);
|
|
159
|
+
|
|
160
|
+
const histRoot = table.plot.histogram({
|
|
11
161
|
filteringEnabled: false,
|
|
12
|
-
valueColumnName:
|
|
13
|
-
splitColumnName:
|
|
162
|
+
valueColumnName: table.columns.bySemType(C.SEM_TYPES.ACTIVITY_SCALED)?.name,
|
|
163
|
+
splitColumnName: C.COLUMNS_NAMES.SPLIT_COL,
|
|
14
164
|
legendVisibility: 'Never',
|
|
15
165
|
showXAxis: true,
|
|
16
166
|
showColumnSelector: false,
|
|
17
167
|
showRangeSlider: false,
|
|
18
|
-
|
|
19
|
-
|
|
168
|
+
showBinSelector: !isTooltip,
|
|
169
|
+
backColor: isTooltip ? '#fdffe5' : '#fffff',
|
|
170
|
+
}).root;
|
|
171
|
+
histRoot.style.width = 'auto';
|
|
20
172
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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));
|
|
33
|
-
|
|
34
|
-
const currentLabel = ui.label(aarStr, {style: {color: currentColor}});
|
|
35
|
-
const otherLabel = ui.label(otherStr, {style: {color: otherColor}});
|
|
36
|
-
const elements: (HTMLLabelElement | HTMLElement)[] = [currentLabel, otherLabel];
|
|
37
|
-
|
|
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
|
-
|
|
43
|
-
hist.style.width = 'auto';
|
|
44
|
-
elements.push(hist);
|
|
45
|
-
|
|
46
|
-
const stats = (table.temp[C.STATS] as FilteringStatistics).result;
|
|
47
|
-
if (stats) {
|
|
48
|
-
const tableMap: StringDictionary = {
|
|
49
|
-
'Statistics:': '',
|
|
50
|
-
'Count': stats.count.toString(),
|
|
51
|
-
'p-value': stats.pValue < 0.01 ? '<0.01' : stats.pValue.toFixed(2),
|
|
52
|
-
'Mean difference': stats.meanDifference.toFixed(2),
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
elements.push(ui.tableFromMap(tableMap));
|
|
56
|
-
}
|
|
57
|
-
return ui.divV(elements);
|
|
173
|
+
const tableMap: StringDictionary = {
|
|
174
|
+
'Statistics:': '',
|
|
175
|
+
'Count': stats.count.toString(),
|
|
176
|
+
'Ratio': stats.ratio.toFixed(2),
|
|
177
|
+
'p-value': stats.pValue < 0.01 ? '<0.01' : stats.pValue.toFixed(2),
|
|
178
|
+
'Mean difference': stats.meanDifference.toFixed(2),
|
|
58
179
|
};
|
|
59
180
|
|
|
60
|
-
|
|
181
|
+
const result = ui.divV([labels, histRoot, ui.tableFromMap(tableMap)]);
|
|
182
|
+
result.style.minWidth = '200px';
|
|
183
|
+
if (isTooltip)
|
|
184
|
+
histRoot.style.maxHeight = '150px';
|
|
185
|
+
return result;
|
|
61
186
|
}
|
|
@@ -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
|
}
|
|
@@ -11,16 +11,11 @@ import {KnownMetrics} from '@datagrok-libraries/ml/src/typed-metrics';
|
|
|
11
11
|
* @return {any} Embedding (and distance matrix where applicable).
|
|
12
12
|
*/
|
|
13
13
|
function onMessage(columnData: any[], method: KnownMethods, measure: KnownMetrics, options: any): any {
|
|
14
|
-
const reducer = new DimensionalityReducer(
|
|
15
|
-
columnData,
|
|
16
|
-
method,
|
|
17
|
-
measure,
|
|
18
|
-
options,
|
|
19
|
-
);
|
|
14
|
+
const reducer = new DimensionalityReducer(columnData, method, measure, options);
|
|
20
15
|
return reducer.transform(true);
|
|
21
16
|
}
|
|
22
17
|
|
|
23
|
-
self.onmessage = ({data: {columnData, method, measure, options}}) => {
|
|
18
|
+
self.onmessage = ({data: {columnData, method, measure, options}}): void => {
|
|
24
19
|
const embedding = onMessage(columnData, method, measure, options);
|
|
25
20
|
self.postMessage({
|
|
26
21
|
distance: embedding.distance,
|
package/{test-Peptides-2f94f62b59a8-c6d7c434.html → test-Peptides-34f75e5127b8-4210edfc.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=34f75e5127b8. Commit 4210edfc.</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=34f75e5127b8. Commit 4210edfc.</h1></header><div id="metadata-container"><div id="timestamp">Started: 2022-07-08 12:49:24</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">113.293s</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.003s</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)
|