@datagrok/peptides 0.5.6 → 0.8.4
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/detectors.js +1 -1
- package/files/aligned.csv +3 -648
- package/files/aligned_2.csv +3 -10275
- package/package.json +26 -15
- package/src/describe.ts +207 -103
- package/src/{viewers/model.ts → model.ts} +1 -1
- package/src/package-test.ts +18 -0
- package/src/package.ts +35 -23
- package/src/peptides.ts +78 -5
- package/src/semantics.ts +5 -0
- package/src/styles.css +46 -0
- package/src/tests/peptide-space-test.ts +40 -0
- package/src/tests/peptides-tests.ts +84 -0
- package/src/tests/utils.ts +87 -0
- package/src/utils/chem-palette.ts +2 -2
- package/src/utils/multiple-sequence-alignment.ts +89 -0
- package/src/utils/peptide-similarity-space.ts +18 -35
- package/src/viewers/sar-viewer.ts +204 -193
- package/src/viewers/stacked-barchart-viewer.ts +0 -69
- package/src/viewers/subst-viewer.ts +276 -0
- package/src/widgets/analyze-peptides.ts +15 -5
- package/src/widgets/manual-alignment.ts +8 -7
- package/src/widgets/peptide-molecule.ts +21 -12
- package/src/workers/dimensionality-reducer.ts +2 -2
- package/webpack.config.js +20 -2
- package/src/utils/correlation-analysis.ts +0 -204
- package/src/viewers/spiral-plot.ts +0 -97
package/src/peptides.ts
CHANGED
|
@@ -2,6 +2,8 @@ import * as ui from 'datagrok-api/ui';
|
|
|
2
2
|
import * as DG from 'datagrok-api/dg';
|
|
3
3
|
import {createPeptideSimilaritySpaceViewer} from './utils/peptide-similarity-space';
|
|
4
4
|
import {addViewerToHeader} from './viewers/stacked-barchart-viewer';
|
|
5
|
+
import {model} from './model';
|
|
6
|
+
// import $ from 'cash-dom';
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* Peptides controller class.
|
|
@@ -10,6 +12,12 @@ import {addViewerToHeader} from './viewers/stacked-barchart-viewer';
|
|
|
10
12
|
* @class Peptides
|
|
11
13
|
*/
|
|
12
14
|
export class Peptides {
|
|
15
|
+
private static _model = model;
|
|
16
|
+
|
|
17
|
+
static async recalculate() {
|
|
18
|
+
await Peptides._model.updateDefault();
|
|
19
|
+
}
|
|
20
|
+
|
|
13
21
|
/**
|
|
14
22
|
* Class initializer
|
|
15
23
|
*
|
|
@@ -27,7 +35,6 @@ export class Peptides {
|
|
|
27
35
|
currentDf: DG.DataFrame,
|
|
28
36
|
options: {[key: string]: string},
|
|
29
37
|
col: DG.Column,
|
|
30
|
-
activityColumnChoice: string,
|
|
31
38
|
) {
|
|
32
39
|
for (let i = 0; i < tableGrid.columns.length; i++) {
|
|
33
40
|
const aarCol = tableGrid.columns.byIndex(i);
|
|
@@ -40,13 +47,23 @@ export class Peptides {
|
|
|
40
47
|
}
|
|
41
48
|
}
|
|
42
49
|
|
|
50
|
+
const initialFiter = currentDf.filter.clone();
|
|
43
51
|
const originalDfColumns = (currentDf.columns as DG.ColumnList).names();
|
|
52
|
+
const originalDfName = currentDf.name;
|
|
53
|
+
|
|
54
|
+
// const substViewer = view.addViewer(
|
|
55
|
+
// 'substitution-analysis-viewer', {'activityColumnName': options['activityColumnName']},
|
|
56
|
+
// );
|
|
57
|
+
// const substNode = view.dockManager.dock(substViewer, DG.DOCK_TYPE.RIGHT, null, 'Substitution Analysis');
|
|
58
|
+
|
|
59
|
+
// const layout1 = view.saveLayout();
|
|
60
|
+
// view.dockManager.close(substNode);
|
|
44
61
|
|
|
45
62
|
const sarViewer = view.addViewer('peptide-sar-viewer', options);
|
|
46
63
|
const sarNode = view.dockManager.dock(sarViewer, DG.DOCK_TYPE.DOWN, null, 'SAR Viewer');
|
|
47
64
|
|
|
48
65
|
const sarViewerVertical = view.addViewer('peptide-sar-viewer-vertical');
|
|
49
|
-
view.dockManager.dock(sarViewerVertical, DG.DOCK_TYPE.RIGHT, sarNode, 'SAR Vertical Viewer');
|
|
66
|
+
const sarVNode = view.dockManager.dock(sarViewerVertical, DG.DOCK_TYPE.RIGHT, sarNode, 'SAR Vertical Viewer');
|
|
50
67
|
|
|
51
68
|
const peptideSpaceViewer = await createPeptideSimilaritySpaceViewer(
|
|
52
69
|
currentDf,
|
|
@@ -55,12 +72,17 @@ export class Peptides {
|
|
|
55
72
|
'Levenshtein',
|
|
56
73
|
100,
|
|
57
74
|
view,
|
|
58
|
-
`${activityColumnChoice}Scaled`,
|
|
75
|
+
`${options['activityColumnChoice']}Scaled`,
|
|
59
76
|
);
|
|
60
|
-
view.dockManager.dock(peptideSpaceViewer, DG.DOCK_TYPE.LEFT, sarNode, 'Peptide Space Viewer', 0.3);
|
|
77
|
+
const psNode = view.dockManager.dock(peptideSpaceViewer, DG.DOCK_TYPE.LEFT, sarNode, 'Peptide Space Viewer', 0.3);
|
|
78
|
+
|
|
79
|
+
const layout2 = view.saveLayout();
|
|
80
|
+
|
|
81
|
+
const nodeList = [sarNode, sarVNode, psNode];
|
|
61
82
|
|
|
62
83
|
const StackedBarchartProm = currentDf.plot.fromType('StackedBarChartAA');
|
|
63
84
|
addViewerToHeader(tableGrid, StackedBarchartProm);
|
|
85
|
+
tableGrid.props.allowEdit = false;
|
|
64
86
|
|
|
65
87
|
const hideIcon = ui.iconFA('window-close', () => { //undo?, times?
|
|
66
88
|
const viewers = [];
|
|
@@ -83,11 +105,62 @@ export class Peptides {
|
|
|
83
105
|
|
|
84
106
|
tableGrid.setOptions({'colHeaderHeight': 20});
|
|
85
107
|
tableGrid.columns.setVisible(originalDfColumns);
|
|
108
|
+
tableGrid.props.allowEdit = true;
|
|
109
|
+
currentDf.name = originalDfName;
|
|
86
110
|
|
|
87
111
|
view.setRibbonPanels(ribbonPanels);
|
|
88
112
|
}, 'Close viewers and restore dataframe');
|
|
89
113
|
|
|
114
|
+
let isSA = false;
|
|
115
|
+
//TODO: fix layouts
|
|
116
|
+
// const switchViewers = ui.iconFA('toggle-on', () => {
|
|
117
|
+
// if (isSA) {
|
|
118
|
+
// view.loadLayout(layout1);
|
|
119
|
+
// $(switchViewers).removeClass('fa-toggle-off');
|
|
120
|
+
// $(switchViewers).addClass('fa-toggle-on');
|
|
121
|
+
// } else {
|
|
122
|
+
// view.loadLayout(layout2);
|
|
123
|
+
// $(switchViewers).removeClass('fa-toggle-on');
|
|
124
|
+
// $(switchViewers).addClass('fa-toggle-off');
|
|
125
|
+
// }
|
|
126
|
+
// isSA = !isSA;
|
|
127
|
+
// });
|
|
128
|
+
const switchViewers = ui.iconFA('toggle-on', async () => {
|
|
129
|
+
currentDf.filter.copyFrom(initialFiter);
|
|
130
|
+
currentDf.selection.setAll(false);
|
|
131
|
+
nodeList.forEach((node) => view.dockManager.close(node));
|
|
132
|
+
nodeList.length = 0;
|
|
133
|
+
if (isSA) {
|
|
134
|
+
const sarViewer = view.addViewer('peptide-sar-viewer', options);
|
|
135
|
+
const sarNode = view.dockManager.dock(sarViewer, DG.DOCK_TYPE.DOWN, null, 'SAR Viewer');
|
|
136
|
+
|
|
137
|
+
const sarViewerVertical = view.addViewer('peptide-sar-viewer-vertical');
|
|
138
|
+
const sarVNode = view.dockManager.dock(sarViewerVertical, DG.DOCK_TYPE.RIGHT, sarNode, 'SAR Vertical Viewer');
|
|
139
|
+
|
|
140
|
+
const peptideSpaceViewer = await createPeptideSimilaritySpaceViewer(
|
|
141
|
+
currentDf, col, 't-SNE', 'Levenshtein', 100, view, `${options['activityColumnChoice']}Scaled`);
|
|
142
|
+
const psNode = view.dockManager.dock(
|
|
143
|
+
peptideSpaceViewer, DG.DOCK_TYPE.LEFT, sarNode, 'Peptide Space Viewer', 0.3);
|
|
144
|
+
|
|
145
|
+
nodeList.push(sarNode);
|
|
146
|
+
nodeList.push(sarVNode);
|
|
147
|
+
nodeList.push(psNode);
|
|
148
|
+
|
|
149
|
+
$(switchViewers).removeClass('fa-toggle-off');
|
|
150
|
+
$(switchViewers).addClass('fa-toggle-on');
|
|
151
|
+
} else {
|
|
152
|
+
const substViewer = view.addViewer(
|
|
153
|
+
'substitution-analysis-viewer', {'activityColumnName': options['activityColumnName']},
|
|
154
|
+
);
|
|
155
|
+
nodeList.push(view.dockManager.dock(substViewer, DG.DOCK_TYPE.RIGHT, null, 'Substitution Analysis'));
|
|
156
|
+
$(switchViewers).removeClass('fa-toggle-on');
|
|
157
|
+
$(switchViewers).addClass('fa-toggle-off');
|
|
158
|
+
}
|
|
159
|
+
isSA = !isSA;
|
|
160
|
+
});
|
|
161
|
+
|
|
90
162
|
const ribbonPanels = view.getRibbonPanels();
|
|
91
|
-
view.setRibbonPanels([[hideIcon]]);
|
|
163
|
+
view.setRibbonPanels([[hideIcon, switchViewers]]);
|
|
164
|
+
// view.setRibbonPanels([[hideIcon]]);
|
|
92
165
|
}
|
|
93
166
|
}
|
package/src/semantics.ts
ADDED
package/src/styles.css
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
.pep-textarea-box {
|
|
2
|
+
position: relative;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.pep-textarea-box:hover .pep-snippet-editor-icon {
|
|
6
|
+
visibility: visible;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.pep-snippet-editor-icon {
|
|
10
|
+
position: absolute;
|
|
11
|
+
top: 5px;
|
|
12
|
+
visibility: hidden;
|
|
13
|
+
margin: 5px;
|
|
14
|
+
z-index: 1;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.pep-reset-icon {
|
|
18
|
+
right: 10px;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.pep-snippet-editor-icon i {
|
|
22
|
+
font-size: 13px;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.pep-snippet-editor-icon:hover {
|
|
26
|
+
background-color: var(--steel-1);
|
|
27
|
+
border-radius: 2px;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.pep-snippet-inline-icon i {
|
|
31
|
+
font-size: 13px;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.pep-textinput {
|
|
35
|
+
height: 50px;
|
|
36
|
+
overflow: hidden;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
#pep-hist-host #center {
|
|
40
|
+
height: 131px;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
#pep-hist-host > #root {
|
|
44
|
+
height: unset;
|
|
45
|
+
width: 100%;
|
|
46
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import {category, test} from '@datagrok-libraries/utils/src/test';
|
|
2
|
+
import {
|
|
3
|
+
_testViewerIsDrawing,
|
|
4
|
+
_testDimensionalityReducer,
|
|
5
|
+
_testPeptideSimilaritySpaceViewer,
|
|
6
|
+
} from './utils';
|
|
7
|
+
import {DimensionalityReducer} from '@datagrok-libraries/ml/src/reduce-dimensionality';
|
|
8
|
+
import {cleanAlignedSequencesColumn} from '../utils/peptide-similarity-space';
|
|
9
|
+
|
|
10
|
+
import * as DG from 'datagrok-api/dg';
|
|
11
|
+
import * as grok from 'datagrok-api/grok';
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
category('peptides', async () => {
|
|
15
|
+
const table = await grok.data.files.openTable('Demo:TestJobs:Files:DemoFiles/bio/peptides.csv');
|
|
16
|
+
const view = grok.shell.v as DG.TableView;
|
|
17
|
+
|
|
18
|
+
test('PeptideSimilaritySpaceWidget.is_drawing', async () => {
|
|
19
|
+
await _testViewerIsDrawing(table, view);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const alignedSequencesColumn = table.getCol('AlignedSequence');
|
|
23
|
+
const columnData = cleanAlignedSequencesColumn(alignedSequencesColumn);
|
|
24
|
+
|
|
25
|
+
for (const method of DimensionalityReducer.availableMethods) {
|
|
26
|
+
for (const measure of DimensionalityReducer.availableMetrics) {
|
|
27
|
+
test(`DimensinalityReducer.${method}.${measure}.is_numeric`, async () => {
|
|
28
|
+
await _testDimensionalityReducer(columnData, method, measure);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
for (const method of DimensionalityReducer.availableMethods) {
|
|
34
|
+
for (const measure of DimensionalityReducer.availableMetrics) {
|
|
35
|
+
test(`peptides.PeptideSimilaritySpaceViewer.${method}.${measure}.is_proper`, async () => {
|
|
36
|
+
await _testPeptideSimilaritySpaceViewer(table, alignedSequencesColumn, method, measure, 100);//, view);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
});
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import {after, before, category, expect, test} from "@datagrok-libraries/utils/src/test";
|
|
2
|
+
import {splitAlignedPeptides} from "../utils/split-aligned";
|
|
3
|
+
import * as DG from "datagrok-api/dg";
|
|
4
|
+
import * as grok from "datagrok-api/grok";
|
|
5
|
+
import * as ui from "datagrok-api/ui";
|
|
6
|
+
import { Peptides } from "../peptides";
|
|
7
|
+
import { describe } from "../describe";
|
|
8
|
+
import { analyzePeptidesWidget } from "../widgets/analyze-peptides";
|
|
9
|
+
import { manualAlignmentWidget } from "../widgets/manual-alignment";
|
|
10
|
+
import { peptideMoleculeWidget } from "../widgets/peptide-molecule";
|
|
11
|
+
|
|
12
|
+
export let _package = new DG.Package();
|
|
13
|
+
|
|
14
|
+
category('peptides', async () => {
|
|
15
|
+
let peptidesDf: DG.DataFrame;
|
|
16
|
+
let options: {[key: string]: string};
|
|
17
|
+
let peptidesGrid: DG.Grid;
|
|
18
|
+
let asCol: DG.Column;
|
|
19
|
+
let pepView: DG.TableView;
|
|
20
|
+
|
|
21
|
+
before(async () => {
|
|
22
|
+
// peptidesDf = DG.DataFrame.fromCsv(await _package.files.readAsText('aligned.csv'));
|
|
23
|
+
const csv = `ID,AlignedSequence,IC50
|
|
24
|
+
1,NH2--A-Q-T-T-Y-K-N-Y-R-R-N-L-L--COOH,4.6411368455908086e-4
|
|
25
|
+
2,NH2-M-A-N-T-T-Y-K-N-Y-R-N-N-L-L--COOH,0.003327324930165897
|
|
26
|
+
3,NH2--A-N-T-T-Y-K-C-Y-R-R-N-L-L--COOH,3.0748148478921324e-4
|
|
27
|
+
4,NH2--A-N-T-T-Y-K-F-Y-R-R-N-L-L--COOH,0.0015532837750281958
|
|
28
|
+
5,NH2--A-V-T-T-Y-K-N-Y-R-R-N-L-L--COOH,6.549885174778741e-4
|
|
29
|
+
6,NH2--A-N-T-T-Y-K-N-Y-R-R-N-L-L--COOH,0.00213298315038382
|
|
30
|
+
7,NH2--A-N-T-T-Y-K-N-Y-R-F-N-L-L--COOH,0.002171297321903189
|
|
31
|
+
8,NH2--A-N-T-T-Y-K-N-Y-R-R-N-H-L--COOH,0.002060711496394637
|
|
32
|
+
9,NH2-M-A-N-T-T-Y-K-N-Y-R-R-N-L-L--COOH,0.0016058870359321516
|
|
33
|
+
10,NH2--A-N-T-T-Y-K-N-Y-R-N-N-L-L--COOH,0.00212911675087592
|
|
34
|
+
11,NH2--A-N-T-T-Y-K-N-Y-R-R-N-L-L--COOH,0.002736311013579287
|
|
35
|
+
12,NH2--A-N-T-T-Y-K-N-Y-R-R-N-L-L--COOH,5.673074652436946e-5
|
|
36
|
+
13,NH2-C-A-N-T-T-Y-K-N-Y-R-R-N-L-L--COOH,0.0032881139376902814
|
|
37
|
+
14,NH2--A-N-T-T-Y-K-N-Y-R-H-N-L-L--COOH,0.0012828163841736553
|
|
38
|
+
15,NH2-Y-A-N-T-T-Y-K-N-Y-R-D-N-L-L--COOH,7.186983807098166e-4
|
|
39
|
+
16,NH2-M-A-N-T-T-Y-K-N-Y-R-N-N-L-L--COOH,0.00659708587488309
|
|
40
|
+
17,NH2-P-A-N-T-T-Y-K-N-Y-R-G-N-L-L--COOH,3.7620528849324097e-4
|
|
41
|
+
18,NH2-Y-A-N-T--Y-K-N-Y-R-S-N-L-L--COOH,6.812868474160967e-4
|
|
42
|
+
19,NH2--A-N-T-T-Y-K-N-Y-R-S-N-L-L--COOH,0.0010148578953195436`;
|
|
43
|
+
peptidesDf = DG.DataFrame.fromCsv(csv);
|
|
44
|
+
options = {
|
|
45
|
+
'activityColumnName': 'IC50',
|
|
46
|
+
'scaling': '-lg',
|
|
47
|
+
};
|
|
48
|
+
peptidesGrid = peptidesDf.plot.grid();
|
|
49
|
+
asCol = peptidesDf.getCol('AlignedSequence');
|
|
50
|
+
pepView = grok.shell.addTableView(peptidesDf);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test('utils.split-sequence', async () => {
|
|
54
|
+
splitAlignedPeptides(peptidesDf.getCol('AlignedSequence'));
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test('describe', async () => {
|
|
58
|
+
await describe(
|
|
59
|
+
peptidesDf, options['activityColumnName'], options['scaling'], peptidesGrid, true,
|
|
60
|
+
DG.BitSet.create(peptidesDf.rowCount, (i) => i % 2 === 0), true);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test('Peptides-class', async () => {
|
|
64
|
+
const peptides = new Peptides();
|
|
65
|
+
peptides.init(peptidesGrid, pepView, peptidesDf, options, asCol);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('widgets.analyze-peptides', async () => {
|
|
69
|
+
await analyzePeptidesWidget(asCol, pepView, peptidesGrid, peptidesDf);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test('widgets.manual-alignment', async () => {
|
|
73
|
+
manualAlignmentWidget(asCol, peptidesDf);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test('widgets.peptide-molecule', async () => {
|
|
77
|
+
await peptideMoleculeWidget('NH2--A-N-T-T-Y-K-N-Y-R-S-N-L-L--COOH');
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
after(async () => {
|
|
81
|
+
pepView.close();
|
|
82
|
+
grok.shell.closeTable(peptidesDf);
|
|
83
|
+
})
|
|
84
|
+
});
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import * as DG from 'datagrok-api/dg';
|
|
2
|
+
|
|
3
|
+
import {expect} from '@datagrok-libraries/utils/src/test';
|
|
4
|
+
import {PeptideSimilaritySpaceWidget, createPeptideSimilaritySpaceViewer} from '../utils/peptide-similarity-space';
|
|
5
|
+
import {
|
|
6
|
+
createDimensinalityReducingWorker,
|
|
7
|
+
} from '@datagrok-libraries/ml/src/workers/dimensionality-reducing-worker-creator';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Tests if peptide space viewer is drawing without exceptions.
|
|
11
|
+
*
|
|
12
|
+
* @param {DG.DataFrame} table Demo table.
|
|
13
|
+
* @param {DG.TableView} view Demo view.
|
|
14
|
+
*/
|
|
15
|
+
export async function _testViewerIsDrawing(table: DG.DataFrame, view: DG.TableView) {
|
|
16
|
+
let noException = true;
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
const widget = new PeptideSimilaritySpaceWidget(table.getCol('AlignedSequence'), view);
|
|
20
|
+
await widget.draw();
|
|
21
|
+
} catch (error) {
|
|
22
|
+
noException = false;
|
|
23
|
+
}
|
|
24
|
+
expect(noException, true);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Tests if dimensionality reducer works for both the method and the measure chosen.
|
|
29
|
+
*
|
|
30
|
+
* @param {Array<string>} columnData Strings to process.
|
|
31
|
+
* @param {string} method Embedding method.
|
|
32
|
+
* @param {string} measure Measure to apply to a pair of strings.
|
|
33
|
+
*/
|
|
34
|
+
export async function _testDimensionalityReducer(columnData: Array<string>, method: string, measure: string) {
|
|
35
|
+
const cyclesCount = 100;
|
|
36
|
+
const embcols = await createDimensinalityReducingWorker(columnData, method, measure, cyclesCount);
|
|
37
|
+
const [X, Y] = embcols as Array<Float32Array>;
|
|
38
|
+
|
|
39
|
+
expect(X.every((v) => v !== null && v !== NaN), true);
|
|
40
|
+
expect(Y.every((v) => v !== null && v !== NaN), true);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Tests if PeptideSimilaritySpaceViewer works for both the method and the measure chosen.
|
|
45
|
+
*
|
|
46
|
+
* @export
|
|
47
|
+
* @param {DG.DataFrame} table Table.
|
|
48
|
+
* @param {DG.Column} alignedSequencesColumn Aligned sequences column.
|
|
49
|
+
* @param {string} method Embedding method.
|
|
50
|
+
* @param {string} measure Strings similarity measure.
|
|
51
|
+
* @param {number} cyclesCount Number of embedding iterations.
|
|
52
|
+
* @param {(DG.TableView | null)} view Viewer to show graphics on.
|
|
53
|
+
* @param {(string | null)} [activityColumnName] Name of column with activity.
|
|
54
|
+
*/
|
|
55
|
+
export async function _testPeptideSimilaritySpaceViewer(
|
|
56
|
+
table: DG.DataFrame,
|
|
57
|
+
alignedSequencesColumn: DG.Column,
|
|
58
|
+
method: string,
|
|
59
|
+
measure: string,
|
|
60
|
+
cyclesCount: number,
|
|
61
|
+
//view: DG.TableView | null,
|
|
62
|
+
//activityColumnName?: string | null,
|
|
63
|
+
) {
|
|
64
|
+
const viewer = await createPeptideSimilaritySpaceViewer(
|
|
65
|
+
table,
|
|
66
|
+
alignedSequencesColumn,
|
|
67
|
+
method,
|
|
68
|
+
measure,
|
|
69
|
+
cyclesCount,
|
|
70
|
+
null, // view,
|
|
71
|
+
// activityColumnName,
|
|
72
|
+
);
|
|
73
|
+
const df = viewer.dataFrame;
|
|
74
|
+
let noException = true;
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
const axesNames = ['~X', '~Y', '~MW'];
|
|
78
|
+
const axes = axesNames.map((v) => df?.getCol(v).getRawData() as Float32Array);
|
|
79
|
+
|
|
80
|
+
for (const ax of axes) {
|
|
81
|
+
expect(ax.every((v) => v !== null && v !== NaN), true);
|
|
82
|
+
}
|
|
83
|
+
} catch (error) {
|
|
84
|
+
noException = false;
|
|
85
|
+
}
|
|
86
|
+
expect(noException, true);
|
|
87
|
+
}
|
|
@@ -56,7 +56,7 @@ export class ChemPalette {
|
|
|
56
56
|
/**
|
|
57
57
|
* Get color for the provided amino acid residue.
|
|
58
58
|
* @param {string} c Amino acid residue string.
|
|
59
|
-
* @
|
|
59
|
+
* @return {string} Color.
|
|
60
60
|
*/
|
|
61
61
|
getColor(c: string): string {
|
|
62
62
|
const [color] = this.getColorPivot(c);
|
|
@@ -66,7 +66,7 @@ export class ChemPalette {
|
|
|
66
66
|
/**
|
|
67
67
|
* Get color for the provided amino acid residue pivot
|
|
68
68
|
* @param {string} [c=''] Amino acid residue string.
|
|
69
|
-
* @
|
|
69
|
+
* @return {[string, string, number]}
|
|
70
70
|
*/
|
|
71
71
|
getColorAAPivot(c: string = ''): [string, string, number] {
|
|
72
72
|
if (c.length == 1 || c[1] == '(') {
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import * as DG from 'datagrok-api/dg';
|
|
2
|
+
|
|
3
|
+
//@ts-ignore
|
|
4
|
+
import Aioli from '@biowasm/aioli';
|
|
5
|
+
|
|
6
|
+
import {AlignedSequenceEncoder} from '@datagrok-libraries/bio/src/sequence-encoder';
|
|
7
|
+
//@ts-ignore
|
|
8
|
+
import {SEMTYPE} from '../semantics';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Converts array of sequences into simple fasta string.
|
|
12
|
+
*
|
|
13
|
+
* @param {string[]} sequences Input list of sequences.
|
|
14
|
+
* @return {string} Fasta-formatted string.
|
|
15
|
+
*/
|
|
16
|
+
function _stringsToFasta(sequences: string[]): string {
|
|
17
|
+
return sequences.reduce((a, v, i) => a + `>sample${i + 1}\n${v}\n`, '');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Extracts array of sequences from simple fasta string.
|
|
22
|
+
*
|
|
23
|
+
* @param {string} fasta Fasta-formatted string.
|
|
24
|
+
* @return {string[]} Output list of sequences.
|
|
25
|
+
*/
|
|
26
|
+
function _fastaToStrings(fasta: string): string[] {
|
|
27
|
+
return fasta.replace(/>sample\d+(\r\n|\r|\n)/g, '').split('\n');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Converts aligned sequence to semantic type format.
|
|
32
|
+
*
|
|
33
|
+
* @param {string} seq Source sequence.
|
|
34
|
+
* @return {string} Formatted sequence.
|
|
35
|
+
*/
|
|
36
|
+
function _castAligned(seq: string): string {
|
|
37
|
+
let delimited = '';
|
|
38
|
+
|
|
39
|
+
for (let i = 0; i < seq.length; ++i) {
|
|
40
|
+
const char = seq[i];
|
|
41
|
+
delimited += char == '-' ? char : `-${char}`;
|
|
42
|
+
}
|
|
43
|
+
return `NH2${delimited}-COOH`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Formats a batch of sequences to correspond the semantic type.
|
|
48
|
+
*
|
|
49
|
+
* @param {string[]} alignment List of aligned sequences.
|
|
50
|
+
* @return {string[]} Formatted sequences.
|
|
51
|
+
*/
|
|
52
|
+
function _stringsToAligned(alignment: string[]): string[] {
|
|
53
|
+
const nItems = alignment.length;
|
|
54
|
+
const aligned = new Array<string>(nItems);
|
|
55
|
+
|
|
56
|
+
for (let i = 0; i < nItems; ++i) {
|
|
57
|
+
aligned[i] = _castAligned(alignment[i]);
|
|
58
|
+
}
|
|
59
|
+
return aligned;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Runs Aioli environment with kalign tool.
|
|
64
|
+
*
|
|
65
|
+
* @param {DG.Column} col Column with sequences.
|
|
66
|
+
* @param {boolean} isAligned Whether the column is aligned.
|
|
67
|
+
* @return {Promise<DG.Column>} Aligned sequences.
|
|
68
|
+
*/
|
|
69
|
+
export async function runKalign(col: DG.Column, isAligned = false) : Promise<DG.Column> {
|
|
70
|
+
let sequences = col.toList();
|
|
71
|
+
|
|
72
|
+
if (isAligned) {
|
|
73
|
+
sequences = sequences.map((v: string, _) => AlignedSequenceEncoder.clean(v).replace(/\-/g, ''));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const fasta = _stringsToFasta(sequences);
|
|
77
|
+
|
|
78
|
+
const CLI = await new Aioli('kalign/3.3.1');
|
|
79
|
+
await CLI.fs.writeFile('input.fa', fasta);
|
|
80
|
+
const output = await CLI.exec(`kalign input.fa -f fasta -o result.fasta`);
|
|
81
|
+
const buf = await CLI.cat('result.fasta');
|
|
82
|
+
|
|
83
|
+
console.warn(output);
|
|
84
|
+
|
|
85
|
+
const aligned = _fastaToStrings(buf).slice(0, sequences.length);
|
|
86
|
+
const alignedCol = DG.Column.fromStrings(`(${col.name})msa`, _stringsToAligned(aligned));
|
|
87
|
+
alignedCol.semType = SEMTYPE.ALIGNED;
|
|
88
|
+
return alignedCol;
|
|
89
|
+
}
|
|
@@ -3,40 +3,14 @@ import * as ui from 'datagrok-api/ui';
|
|
|
3
3
|
import * as DG from 'datagrok-api/dg';
|
|
4
4
|
|
|
5
5
|
import {getSequenceMolecularWeight} from './molecular-measure';
|
|
6
|
-
import {AlignedSequenceEncoder} from '@datagrok-libraries/
|
|
7
|
-
import {DimensionalityReducer} from '@datagrok-libraries/
|
|
8
|
-
import {
|
|
6
|
+
import {AlignedSequenceEncoder} from '@datagrok-libraries/bio/src/sequence-encoder';
|
|
7
|
+
import {DimensionalityReducer} from '@datagrok-libraries/ml/src/reduce-dimensionality';
|
|
8
|
+
import {
|
|
9
|
+
createDimensinalityReducingWorker,
|
|
10
|
+
} from '@datagrok-libraries/ml/src/workers/dimensionality-reducing-worker-creator';
|
|
11
|
+
import {StringMeasure} from '@datagrok-libraries/ml/src/string-measure';
|
|
9
12
|
import {Coordinates} from '@datagrok-libraries/utils/src/type-declarations';
|
|
10
13
|
|
|
11
|
-
/**
|
|
12
|
-
* A worker to perform dimensionality reduction.
|
|
13
|
-
*
|
|
14
|
-
* @param {any[]} columnData The data to process.
|
|
15
|
-
* @param {string} method A method of dimensionality reduction.
|
|
16
|
-
* @param {string} measure A distance metrics.
|
|
17
|
-
* @param {number} cyclesCount Number of iterations to run.
|
|
18
|
-
* @return {Promise<unknown>} Resulting embedding.
|
|
19
|
-
*/
|
|
20
|
-
function createDimensinalityReducingWorker(
|
|
21
|
-
columnData: any[],
|
|
22
|
-
method: string,
|
|
23
|
-
measure: string,
|
|
24
|
-
cyclesCount: number,
|
|
25
|
-
): Promise<unknown> {
|
|
26
|
-
return new Promise(function(resolve) {
|
|
27
|
-
const worker = new Worker(new URL('../workers/dimensionality-reducer.ts', import.meta.url));
|
|
28
|
-
worker.postMessage({
|
|
29
|
-
columnData: columnData,
|
|
30
|
-
method: method,
|
|
31
|
-
measure: measure,
|
|
32
|
-
cyclesCount: cyclesCount,
|
|
33
|
-
});
|
|
34
|
-
worker.onmessage = ({data: {embedding}}) => {
|
|
35
|
-
resolve(embedding);
|
|
36
|
-
};
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
|
|
40
14
|
/**
|
|
41
15
|
* Finds a column with an activity.
|
|
42
16
|
*
|
|
@@ -53,6 +27,17 @@ function inferActivityColumnsName(table: DG.DataFrame): string | null {
|
|
|
53
27
|
return null;
|
|
54
28
|
}
|
|
55
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Cast an aligned sequences column to clean sequences.
|
|
32
|
+
*
|
|
33
|
+
* @export
|
|
34
|
+
* @param {DG.Column} col Column to process.
|
|
35
|
+
* @return {Array<string>} Clean sequences array.
|
|
36
|
+
*/
|
|
37
|
+
export function cleanAlignedSequencesColumn(col: DG.Column): Array<string> {
|
|
38
|
+
return col.toList().map((v, _) => AlignedSequenceEncoder.clean(v));
|
|
39
|
+
}
|
|
40
|
+
|
|
56
41
|
/**
|
|
57
42
|
* Creates scatter plot with sequences embeded.
|
|
58
43
|
*
|
|
@@ -75,7 +60,6 @@ export async function createPeptideSimilaritySpaceViewer(
|
|
|
75
60
|
cyclesCount: number,
|
|
76
61
|
view: DG.TableView | null,
|
|
77
62
|
activityColumnName?: string | null,
|
|
78
|
-
zoom: boolean = false,
|
|
79
63
|
): Promise<DG.ScatterPlotViewer> {
|
|
80
64
|
const pi = DG.TaskBarProgressIndicator.create('Creating embedding.');
|
|
81
65
|
|
|
@@ -157,7 +141,7 @@ export class PeptideSimilaritySpaceWidget {
|
|
|
157
141
|
*/
|
|
158
142
|
constructor(alignedSequencesColumn: DG.Column, view: DG.TableView) {
|
|
159
143
|
this.availableMethods = DimensionalityReducer.availableMethods;
|
|
160
|
-
this.availableMetrics =
|
|
144
|
+
this.availableMetrics = StringMeasure.availableMeasures;
|
|
161
145
|
this.method = this.availableMethods[0];
|
|
162
146
|
this.metrics = this.availableMetrics[0];
|
|
163
147
|
this.currentDf = alignedSequencesColumn.dataFrame;
|
|
@@ -181,7 +165,6 @@ export class PeptideSimilaritySpaceWidget {
|
|
|
181
165
|
this.cycles,
|
|
182
166
|
null,
|
|
183
167
|
null,
|
|
184
|
-
true,
|
|
185
168
|
);
|
|
186
169
|
viewer.root.style.width = 'auto';
|
|
187
170
|
return viewer;
|