@datagrok/peptides 0.6.1 → 0.8.6
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 +12 -2
- package/detectors.js +1 -1
- package/files/aligned_2.csv +1 -1
- package/package.json +27 -18
- package/setup.sh +15 -0
- package/src/describe.ts +219 -123
- package/src/{viewers/model.ts → model.ts} +1 -1
- package/src/monomer-library.ts +187 -0
- package/src/package-test.ts +18 -0
- package/src/package.ts +45 -19
- package/src/peptides.ts +68 -37
- package/src/semantics.ts +5 -0
- package/src/styles.css +9 -0
- package/src/tests/peptide-space-test.ts +40 -0
- package/src/tests/peptides-tests.ts +120 -0
- package/src/tests/utils.ts +86 -0
- package/src/utils/cell-renderer.ts +27 -26
- package/src/utils/chem-palette.ts +5 -6
- package/src/utils/molecular-measure.ts +3 -4
- package/src/utils/multiple-sequence-alignment.ts +89 -0
- package/src/utils/peptide-similarity-space.ts +22 -41
- package/src/utils/split-aligned.ts +6 -6
- package/src/viewers/logo-viewer.ts +10 -12
- package/src/viewers/sar-viewer.ts +191 -182
- package/src/viewers/stacked-barchart-viewer.ts +21 -95
- package/src/viewers/subst-viewer.ts +10 -10
- package/src/widgets/analyze-peptides.ts +16 -7
- package/src/widgets/manual-alignment.ts +7 -4
- package/src/widgets/peptide-molecule.ts +21 -13
- package/src/workers/dimensionality-reducer.ts +2 -2
- package/tsconfig.json +1 -1
- package/webpack.config.js +16 -2
- package/src/utils/correlation-analysis.ts +0 -204
- package/src/viewers/spiral-plot.ts +0 -97
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import * as ui from 'datagrok-api/ui';
|
|
2
|
+
import * as DG from 'datagrok-api/dg';
|
|
3
|
+
import * as grok from 'datagrok-api/grok';
|
|
4
|
+
|
|
5
|
+
/** HELM associated sdf libraries with monomer processing*/
|
|
6
|
+
export class MonomerLibrary {
|
|
7
|
+
private monomerFields: string[] = ['molecule', 'MonomerType', 'MonomerNaturalAnalogCode', 'MonomerName', 'MonomerCode', 'MonomerCaps', 'BranchMonomer'];
|
|
8
|
+
private library: {
|
|
9
|
+
[name: string]: {
|
|
10
|
+
mol: string,
|
|
11
|
+
type: string,
|
|
12
|
+
analogueCode: string,
|
|
13
|
+
linkages: { [link: string]: { atomNumber: number, type: string } }
|
|
14
|
+
}
|
|
15
|
+
} = {};
|
|
16
|
+
private monomers: string[] = [];
|
|
17
|
+
|
|
18
|
+
constructor(sdf: string) {
|
|
19
|
+
//sdf = sdf.replaceAll('\n\[', '\[');
|
|
20
|
+
const sdfReader = new SDFReader();
|
|
21
|
+
const data = sdfReader.get_colls(sdf);
|
|
22
|
+
this.monomerFields.forEach((f) => {
|
|
23
|
+
if (!(f in data))
|
|
24
|
+
throw `Monomer library was not compiled: ${f} field is absent in provided file`;
|
|
25
|
+
|
|
26
|
+
if (data[f].length != data.molecule.length)
|
|
27
|
+
throw `Monomer library was not compiled: ${f} field is not presented for each monomer`;
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
for (let i = 0; i < data.molecule.length; i++) {
|
|
31
|
+
const linkData = this.getLinkData(data.molecule[i], data.MonomerCaps[i], data.MonomerName[i]);
|
|
32
|
+
const entry = {
|
|
33
|
+
mol: data.molecule[i],
|
|
34
|
+
type: 'Peptide',
|
|
35
|
+
code: data.MonomerCode[i],
|
|
36
|
+
analogueCode: data.MonomerNaturalAnalogCode[i],
|
|
37
|
+
linkages: linkData,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const name = data.MonomerCode[i] !== '.' ? data.MonomerCode[i] : data.MonomerName[i];
|
|
41
|
+
this.library[name] = entry;
|
|
42
|
+
this.monomers.push(data.MonomerName[i]);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** getting full monomer information from monomer library*/
|
|
47
|
+
public getMonomerEntry(name: string) {
|
|
48
|
+
if (!this.monomers.includes(name))
|
|
49
|
+
throw `Monomer library do not contain ${name} monomer`;
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
return this.library[name];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** getting mol as string for monomer*/
|
|
56
|
+
public getMonomerMol(name: string) {
|
|
57
|
+
if (!this.monomers.includes(name))
|
|
58
|
+
throw `Monomer library do not contain ${name} monomer`;
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
const entry = this.library[name];
|
|
62
|
+
let monomerMol = entry.mol.replace(/M RGP .+\n/, '');
|
|
63
|
+
|
|
64
|
+
//order matters
|
|
65
|
+
const links = Object.keys(entry.linkages);
|
|
66
|
+
for (let i = 0; i < links.length; i++)
|
|
67
|
+
monomerMol = monomerMol.replace('R#', entry.linkages[links[i]].type + ' ');
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
return monomerMol;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** getting the list of the minomers available in library*/
|
|
74
|
+
get monomerNames() {
|
|
75
|
+
return this.monomers;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
private getLinkData(mol: string, caps: string, name: string) {
|
|
79
|
+
const rawData = mol.match(/M RGP .+/);
|
|
80
|
+
if (rawData === null)
|
|
81
|
+
throw `Monomer library was not compiled: ${name} entry has no RGP`;
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
const types: { [code: string]: string } = {};
|
|
85
|
+
caps.split('\n')?.forEach((e) => {
|
|
86
|
+
types[e.match(/\d+/)![0]] = e.match(/(?<=\])\w+/)![0];
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const data = rawData![0].replace('M RGP ', '').split(/\s+/);
|
|
90
|
+
const res: { [link: string]: { atomNumber: number, type: string } } = {};
|
|
91
|
+
for (let i = 0; i < parseInt(data[0]); i++) {
|
|
92
|
+
const code = parseInt(data[2 * i + 2]);
|
|
93
|
+
let type = '';
|
|
94
|
+
switch (code) {
|
|
95
|
+
case 1:
|
|
96
|
+
type = 'N-terminal';
|
|
97
|
+
break;
|
|
98
|
+
case 2:
|
|
99
|
+
type = 'C-terminal';
|
|
100
|
+
break;
|
|
101
|
+
case 3:
|
|
102
|
+
type = 'branch';
|
|
103
|
+
break;
|
|
104
|
+
default:
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
res[type] = {atomNumber: parseInt(data[2 * i + 1]), type: types[code]};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return res;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
//TODO: merge with Chem version
|
|
115
|
+
class SDFReader {
|
|
116
|
+
dataColls: { [_: string]: any };
|
|
117
|
+
|
|
118
|
+
constructor() {
|
|
119
|
+
this.dataColls = {'molecule': []};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
get_colls(content: string) {
|
|
123
|
+
this.read(content);
|
|
124
|
+
return this.dataColls;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
read(content: string) {
|
|
128
|
+
content = content.replaceAll('\r', ''); //equalize old and new sdf standards
|
|
129
|
+
let startIndex = content.indexOf('$$$$', 0);
|
|
130
|
+
this.parse(content, 0, startIndex, (name: string, val: any) => { // TODO: type
|
|
131
|
+
this.dataColls[name] = [];
|
|
132
|
+
this.dataColls[name].push(val);
|
|
133
|
+
});
|
|
134
|
+
startIndex += 5;
|
|
135
|
+
while (startIndex > -1 && startIndex < content.length)
|
|
136
|
+
startIndex = this.readNext(content, startIndex);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
readNext(content: string, startIndex: number) {
|
|
140
|
+
const nextStartIndex = content.indexOf('$$$$', startIndex);
|
|
141
|
+
if (nextStartIndex === -1)
|
|
142
|
+
return -1;
|
|
143
|
+
else {
|
|
144
|
+
this.parse(content, startIndex, nextStartIndex,
|
|
145
|
+
(name: string, val: number) => this.dataColls[name].push(val));
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (nextStartIndex > -1)
|
|
149
|
+
return nextStartIndex + 5;
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
return nextStartIndex;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
parse(content: string, start: number, end: number, handler: any) {
|
|
156
|
+
const molEnd = +content.indexOf('M END\n', start) + 7;
|
|
157
|
+
let localEnd = start;
|
|
158
|
+
this.dataColls['molecule'].push(content.substr(start, molEnd - start));
|
|
159
|
+
|
|
160
|
+
start = molEnd;
|
|
161
|
+
while (localEnd < end) {
|
|
162
|
+
start = content.indexOf('> <', localEnd);
|
|
163
|
+
if (start === -1)
|
|
164
|
+
return;
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
start += 3;
|
|
168
|
+
localEnd = content.indexOf('>\n', start);
|
|
169
|
+
if (localEnd === -1)
|
|
170
|
+
return;
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
const propertyName = content.substring(start, localEnd);
|
|
174
|
+
start = localEnd + 2;
|
|
175
|
+
|
|
176
|
+
localEnd = content.indexOf('\n', start);
|
|
177
|
+
if (localEnd === -1)
|
|
178
|
+
localEnd = end;
|
|
179
|
+
else if (content[localEnd + 1] != '\n')
|
|
180
|
+
localEnd = content.indexOf('\n', ++localEnd);
|
|
181
|
+
;
|
|
182
|
+
|
|
183
|
+
handler(propertyName, content.substring(start, localEnd));
|
|
184
|
+
localEnd += 2;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as DG from 'datagrok-api/dg';
|
|
2
|
+
|
|
3
|
+
import {runTests} from '@datagrok-libraries/utils/src/test';
|
|
4
|
+
|
|
5
|
+
import './tests/peptide-space-test';
|
|
6
|
+
import './tests/peptides-tests';
|
|
7
|
+
|
|
8
|
+
export const _package = new DG.Package();
|
|
9
|
+
|
|
10
|
+
//name: test
|
|
11
|
+
//input: string category {optional: true}
|
|
12
|
+
//input: string test {optional: true}
|
|
13
|
+
//output: dataframe result
|
|
14
|
+
//top-menu: Tools | Dev | JS API Tests
|
|
15
|
+
export async function test(category: string, test: string): Promise<DG.DataFrame> {
|
|
16
|
+
const data = await runTests({category, test});
|
|
17
|
+
return DG.DataFrame.fromObjects(data)!;
|
|
18
|
+
}
|
package/src/package.ts
CHANGED
|
@@ -14,9 +14,9 @@ import {analyzePeptidesWidget} from './widgets/analyze-peptides';
|
|
|
14
14
|
import {PeptideSimilaritySpaceWidget} from './utils/peptide-similarity-space';
|
|
15
15
|
import {manualAlignmentWidget} from './widgets/manual-alignment';
|
|
16
16
|
import {SARViewer, SARViewerVertical} from './viewers/sar-viewer';
|
|
17
|
-
import {peptideMoleculeWidget} from './widgets/peptide-molecule';
|
|
18
|
-
import {SpiralPlot} from './viewers/spiral-plot';
|
|
17
|
+
import {peptideMoleculeWidget, getMolecule} from './widgets/peptide-molecule';
|
|
19
18
|
import {SubstViewer} from './viewers/subst-viewer';
|
|
19
|
+
import {runKalign} from './utils/multiple-sequence-alignment';
|
|
20
20
|
|
|
21
21
|
export const _package = new DG.Package();
|
|
22
22
|
let tableGrid: DG.Grid;
|
|
@@ -38,9 +38,9 @@ async function main(chosenFile: string) {
|
|
|
38
38
|
pi.close();
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
//name: Peptides
|
|
41
|
+
//name: Peptides
|
|
42
42
|
//tags: app
|
|
43
|
-
export function Peptides() {
|
|
43
|
+
export async function Peptides() {
|
|
44
44
|
const wikiLink = ui.link('wiki', 'https://github.com/datagrok-ai/public/blob/master/help/domains/bio/peptides.md');
|
|
45
45
|
const textLink = ui.inlineText(['For more details, see our ', wikiLink, '.']);
|
|
46
46
|
|
|
@@ -73,8 +73,8 @@ export function Peptides() {
|
|
|
73
73
|
appDescription,
|
|
74
74
|
ui.info([textLink]),
|
|
75
75
|
ui.divH([
|
|
76
|
-
ui.button('
|
|
77
|
-
ui.button('
|
|
76
|
+
ui.button('Simple demo', () => main('aligned.csv'), ''),
|
|
77
|
+
ui.button('Complex demo', () => main('aligned_2.csv'), ''),
|
|
78
78
|
]),
|
|
79
79
|
]);
|
|
80
80
|
}
|
|
@@ -84,9 +84,9 @@ export function Peptides() {
|
|
|
84
84
|
//input: column col {semType: alignedSequence}
|
|
85
85
|
//output: widget result
|
|
86
86
|
export async function peptidesPanel(col: DG.Column): Promise<DG.Widget> {
|
|
87
|
-
if (col.getTag('isAnalysisApplicable') === 'false')
|
|
87
|
+
if (col.getTag('isAnalysisApplicable') === 'false')
|
|
88
88
|
return new DG.Widget(ui.divText('Analysis is not applicable'));
|
|
89
|
-
|
|
89
|
+
|
|
90
90
|
view = (grok.shell.v as DG.TableView);
|
|
91
91
|
tableGrid = view.grid;
|
|
92
92
|
currentDf = col.dataFrame;
|
|
@@ -136,6 +136,15 @@ export async function peptideMolecule(peptide: string): Promise<DG.Widget> {
|
|
|
136
136
|
return await peptideMoleculeWidget(peptide);
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
//name: Peptide Molecule
|
|
140
|
+
//tags: panel, widgets
|
|
141
|
+
//input: string aar {semType: aminoAcids}
|
|
142
|
+
//output: widget result
|
|
143
|
+
export async function peptideMolecule2(aar: string): Promise<DG.Widget> {
|
|
144
|
+
const peptide = alignedSequenceCol.get(currentDf.currentRowIdx);
|
|
145
|
+
return await peptideMolecule(peptide);
|
|
146
|
+
}
|
|
147
|
+
|
|
139
148
|
//name: StackedBarChartAA
|
|
140
149
|
//tags: viewer
|
|
141
150
|
//output: viewer result
|
|
@@ -171,6 +180,7 @@ export function logov() {
|
|
|
171
180
|
//input: string monomer {semType: aminoAcids}
|
|
172
181
|
//output: widget result
|
|
173
182
|
export function manualAlignment(monomer: string) {
|
|
183
|
+
//TODO: recalculate Molfile and Molecule panels on sequence update
|
|
174
184
|
return manualAlignmentWidget(alignedSequenceCol, currentDf);
|
|
175
185
|
}
|
|
176
186
|
|
|
@@ -183,15 +193,31 @@ export async function peptideSpacePanel(col: DG.Column): Promise<DG.Widget> {
|
|
|
183
193
|
return await widget.draw();
|
|
184
194
|
}
|
|
185
195
|
|
|
186
|
-
//name:
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
//
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
196
|
+
//name: Molfile
|
|
197
|
+
//tags: panel, widgets
|
|
198
|
+
//input: string peptide { semType: alignedSequence }
|
|
199
|
+
//output: widget result
|
|
200
|
+
export async function peptideMolfile(peptide: string): Promise<DG.Widget> {
|
|
201
|
+
const smiles = getMolecule(peptide);
|
|
202
|
+
return await grok.functions.call('Chem:molfile', {'smiles': smiles});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
//name: Molfile
|
|
206
|
+
//tags: panel, widgets
|
|
207
|
+
//input: string aar { semType: aminoAcids }
|
|
208
|
+
//output: widget result
|
|
209
|
+
export async function peptideMolfile2(aar: string): Promise<DG.Widget> {
|
|
210
|
+
const peptide = alignedSequenceCol.get(currentDf.currentRowIdx);
|
|
211
|
+
return await peptideMolfile(peptide);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
//name: Multiple sequence alignment
|
|
215
|
+
//tags: panel
|
|
216
|
+
//input: column col {semType: alignedSequence}
|
|
217
|
+
//output: dataframe result
|
|
218
|
+
export async function multipleSequenceAlignment(col: DG.Column): Promise<DG.DataFrame> {
|
|
219
|
+
const msaCol = await runKalign(col, true);
|
|
220
|
+
const table = col.dataFrame;
|
|
221
|
+
table.columns.add(msaCol);
|
|
222
|
+
return table;
|
|
197
223
|
}
|
package/src/peptides.ts
CHANGED
|
@@ -2,6 +2,7 @@ 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';
|
|
5
6
|
// import $ from 'cash-dom';
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -11,6 +12,12 @@ import {addViewerToHeader} from './viewers/stacked-barchart-viewer';
|
|
|
11
12
|
* @class Peptides
|
|
12
13
|
*/
|
|
13
14
|
export class Peptides {
|
|
15
|
+
private static _model = model;
|
|
16
|
+
|
|
17
|
+
static async recalculate() {
|
|
18
|
+
await Peptides._model.updateDefault();
|
|
19
|
+
}
|
|
20
|
+
|
|
14
21
|
/**
|
|
15
22
|
* Class initializer
|
|
16
23
|
*
|
|
@@ -28,7 +35,6 @@ export class Peptides {
|
|
|
28
35
|
currentDf: DG.DataFrame,
|
|
29
36
|
options: {[key: string]: string},
|
|
30
37
|
col: DG.Column,
|
|
31
|
-
activityColumnChoice: string,
|
|
32
38
|
) {
|
|
33
39
|
for (let i = 0; i < tableGrid.columns.length; i++) {
|
|
34
40
|
const aarCol = tableGrid.columns.byIndex(i);
|
|
@@ -41,18 +47,26 @@ export class Peptides {
|
|
|
41
47
|
}
|
|
42
48
|
}
|
|
43
49
|
|
|
50
|
+
const initialFiter = currentDf.filter.clone();
|
|
44
51
|
const originalDfColumns = (currentDf.columns as DG.ColumnList).names();
|
|
45
52
|
const originalDfName = currentDf.name;
|
|
46
53
|
|
|
47
|
-
const substViewer = view.addViewer(
|
|
48
|
-
|
|
49
|
-
);
|
|
50
|
-
view.dockManager.dock(substViewer, DG.DOCK_TYPE.RIGHT, null, 'Substitution Analysis');
|
|
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);
|
|
61
|
+
|
|
62
|
+
const helpUrl = '/help/domains/bio/peptides.md';
|
|
51
63
|
|
|
52
64
|
const sarViewer = view.addViewer('peptide-sar-viewer', options);
|
|
65
|
+
sarViewer.helpUrl = helpUrl;
|
|
53
66
|
const sarNode = view.dockManager.dock(sarViewer, DG.DOCK_TYPE.DOWN, null, 'SAR Viewer');
|
|
54
67
|
|
|
55
68
|
const sarViewerVertical = view.addViewer('peptide-sar-viewer-vertical');
|
|
69
|
+
sarViewerVertical.helpUrl = helpUrl;
|
|
56
70
|
const sarVNode = view.dockManager.dock(sarViewerVertical, DG.DOCK_TYPE.RIGHT, sarNode, 'SAR Vertical Viewer');
|
|
57
71
|
|
|
58
72
|
const peptideSpaceViewer = await createPeptideSimilaritySpaceViewer(
|
|
@@ -62,11 +76,13 @@ export class Peptides {
|
|
|
62
76
|
'Levenshtein',
|
|
63
77
|
100,
|
|
64
78
|
view,
|
|
65
|
-
`${activityColumnChoice}Scaled`,
|
|
79
|
+
`${options['activityColumnChoice']}Scaled`,
|
|
66
80
|
);
|
|
67
81
|
const psNode = view.dockManager.dock(peptideSpaceViewer, DG.DOCK_TYPE.LEFT, sarNode, 'Peptide Space Viewer', 0.3);
|
|
68
|
-
|
|
69
|
-
|
|
82
|
+
|
|
83
|
+
const layout2 = view.saveLayout();
|
|
84
|
+
|
|
85
|
+
const nodeList = [sarNode, sarVNode, psNode];
|
|
70
86
|
|
|
71
87
|
const StackedBarchartProm = currentDf.plot.fromType('StackedBarChartAA');
|
|
72
88
|
addViewerToHeader(tableGrid, StackedBarchartProm);
|
|
@@ -75,17 +91,15 @@ export class Peptides {
|
|
|
75
91
|
const hideIcon = ui.iconFA('window-close', () => { //undo?, times?
|
|
76
92
|
const viewers = [];
|
|
77
93
|
for (const viewer of view.viewers) {
|
|
78
|
-
if (viewer.type !== DG.VIEWER.GRID)
|
|
94
|
+
if (viewer.type !== DG.VIEWER.GRID)
|
|
79
95
|
viewers.push(viewer);
|
|
80
|
-
}
|
|
81
96
|
}
|
|
82
97
|
viewers.forEach((v) => v.close());
|
|
83
98
|
|
|
84
99
|
const cols = (currentDf.columns as DG.ColumnList);
|
|
85
100
|
for (const colName of cols.names()) {
|
|
86
|
-
if (!originalDfColumns.includes(colName))
|
|
101
|
+
if (!originalDfColumns.includes(colName))
|
|
87
102
|
cols.remove(colName);
|
|
88
|
-
}
|
|
89
103
|
}
|
|
90
104
|
|
|
91
105
|
currentDf.selection.setAll(false);
|
|
@@ -99,42 +113,59 @@ export class Peptides {
|
|
|
99
113
|
view.setRibbonPanels(ribbonPanels);
|
|
100
114
|
}, 'Close viewers and restore dataframe');
|
|
101
115
|
|
|
102
|
-
|
|
103
|
-
//
|
|
104
|
-
// let isSA = false;
|
|
105
|
-
// let viewLayout1: DG.ViewLayout | null = null;
|
|
106
|
-
// let viewLayout2: DG.ViewLayout | null = null;
|
|
116
|
+
let isSA = false;
|
|
117
|
+
//TODO: fix layouts
|
|
107
118
|
// const switchViewers = ui.iconFA('toggle-on', () => {
|
|
108
119
|
// if (isSA) {
|
|
109
|
-
//
|
|
110
|
-
// // view.dockManager.close(substNode!);
|
|
111
|
-
// substViewer?.close();
|
|
112
|
-
|
|
113
|
-
// view.loadLayout(viewLayout1!);
|
|
114
|
-
|
|
120
|
+
// view.loadLayout(layout1);
|
|
115
121
|
// $(switchViewers).removeClass('fa-toggle-off');
|
|
116
122
|
// $(switchViewers).addClass('fa-toggle-on');
|
|
117
123
|
// } else {
|
|
118
|
-
//
|
|
119
|
-
// // sarDockNodes.forEach((node) => view.dockManager.close(node));
|
|
120
|
-
// sarViewers.forEach((v) => v.close());
|
|
121
|
-
|
|
122
|
-
// if (viewLayout2 === null) {
|
|
123
|
-
// substViewer = view.addViewer(
|
|
124
|
-
// 'substitution-analysis-viewer', {'activityColumnName': options['activityColumnName']},
|
|
125
|
-
// );
|
|
126
|
-
// substNode = view.dockManager.dock(substViewer, DG.DOCK_TYPE.DOWN, null, 'Substitution Analysis');
|
|
127
|
-
// } else {
|
|
128
|
-
// view.loadLayout(viewLayout2);
|
|
129
|
-
// }
|
|
130
|
-
|
|
124
|
+
// view.loadLayout(layout2);
|
|
131
125
|
// $(switchViewers).removeClass('fa-toggle-on');
|
|
132
126
|
// $(switchViewers).addClass('fa-toggle-off');
|
|
133
127
|
// }
|
|
134
128
|
// isSA = !isSA;
|
|
135
129
|
// });
|
|
130
|
+
const switchViewers = ui.iconFA('toggle-on', async () => {
|
|
131
|
+
currentDf.filter.copyFrom(initialFiter);
|
|
132
|
+
currentDf.selection.setAll(false);
|
|
133
|
+
nodeList.forEach((node) => view.dockManager.close(node));
|
|
134
|
+
nodeList.length = 0;
|
|
135
|
+
if (isSA) {
|
|
136
|
+
const sarViewer = view.addViewer('peptide-sar-viewer', options);
|
|
137
|
+
sarViewer.helpUrl = helpUrl;
|
|
138
|
+
const sarNode = view.dockManager.dock(sarViewer, DG.DOCK_TYPE.DOWN, null, 'SAR Viewer');
|
|
139
|
+
|
|
140
|
+
const sarViewerVertical = view.addViewer('peptide-sar-viewer-vertical');
|
|
141
|
+
sarViewerVertical.helpUrl = helpUrl;
|
|
142
|
+
const sarVNode = view.dockManager.dock(sarViewerVertical, DG.DOCK_TYPE.RIGHT, sarNode, 'SAR Vertical Viewer');
|
|
143
|
+
|
|
144
|
+
const peptideSpaceViewer = await createPeptideSimilaritySpaceViewer(
|
|
145
|
+
currentDf, col, 't-SNE', 'Levenshtein', 100, view, `${options['activityColumnChoice']}Scaled`);
|
|
146
|
+
const psNode = view.dockManager.dock(
|
|
147
|
+
peptideSpaceViewer, DG.DOCK_TYPE.LEFT, sarNode, 'Peptide Space Viewer', 0.3);
|
|
148
|
+
|
|
149
|
+
nodeList.push(sarNode);
|
|
150
|
+
nodeList.push(sarVNode);
|
|
151
|
+
nodeList.push(psNode);
|
|
152
|
+
|
|
153
|
+
$(switchViewers).removeClass('fa-toggle-off');
|
|
154
|
+
$(switchViewers).addClass('fa-toggle-on');
|
|
155
|
+
} else {
|
|
156
|
+
const substViewer = view.addViewer(
|
|
157
|
+
'substitution-analysis-viewer', {'activityColumnName': options['activityColumnName']},
|
|
158
|
+
);
|
|
159
|
+
substViewer.helpUrl = helpUrl;
|
|
160
|
+
nodeList.push(view.dockManager.dock(substViewer, DG.DOCK_TYPE.DOWN, null, 'Substitution Analysis'));
|
|
161
|
+
$(switchViewers).removeClass('fa-toggle-on');
|
|
162
|
+
$(switchViewers).addClass('fa-toggle-off');
|
|
163
|
+
}
|
|
164
|
+
isSA = !isSA;
|
|
165
|
+
});
|
|
136
166
|
|
|
137
167
|
const ribbonPanels = view.getRibbonPanels();
|
|
138
|
-
view.setRibbonPanels([[hideIcon]]);
|
|
168
|
+
view.setRibbonPanels([[hideIcon, switchViewers]]);
|
|
169
|
+
// view.setRibbonPanels([[hideIcon]]);
|
|
139
170
|
}
|
|
140
171
|
}
|
package/src/semantics.ts
ADDED
package/src/styles.css
CHANGED
|
@@ -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,120 @@
|
|
|
1
|
+
import {after, before, category, 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 {Peptides} from '../peptides';
|
|
6
|
+
import {describe} from '../describe';
|
|
7
|
+
import {analyzePeptidesWidget} from '../widgets/analyze-peptides';
|
|
8
|
+
import {manualAlignmentWidget} from '../widgets/manual-alignment';
|
|
9
|
+
import {peptideMoleculeWidget} from '../widgets/peptide-molecule';
|
|
10
|
+
import * as P from '../package';
|
|
11
|
+
|
|
12
|
+
// 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 P._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
|
+
asCol = peptidesDf.getCol('AlignedSequence');
|
|
49
|
+
pepView = grok.shell.addTableView(peptidesDf);
|
|
50
|
+
peptidesGrid = pepView.grid;
|
|
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('panel.peptides', async () => {
|
|
69
|
+
await P.peptidesPanel(asCol);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test('widgets.analyze-peptides', async () => {
|
|
73
|
+
await analyzePeptidesWidget(asCol, pepView, peptidesGrid, peptidesDf);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test('widgets.manual-alignment', async () => {
|
|
77
|
+
manualAlignmentWidget(asCol, peptidesDf);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test('widgets.peptide-molecule', async () => {
|
|
81
|
+
await peptideMoleculeWidget('NH2--A-N-T-T-Y-K-N-Y-R-S-N-L-L--COOH');
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
test('widgets.molfile', async () => {
|
|
85
|
+
await P.peptideMolfile2('');
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test('renderers.aligned-sequence-cell', async () => {
|
|
89
|
+
P.alignedSequenceCellRenderer();
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test('renderers.amino-acids-cell', async () => {
|
|
93
|
+
P.aminoAcidsCellRenderer();
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('viewers.logo-viewer', async () => {
|
|
97
|
+
P.logov();
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test('viewers.sar-viewer', async () => {
|
|
101
|
+
P.sar();
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test('viewers.sar-vertical-viewer', async () => {
|
|
105
|
+
P.sarVertical();
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
test('viewers.stacked-barchart-viewer', async () => {
|
|
109
|
+
P.stackedBarChart();
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test('viewers.subst-viewer', async () => {
|
|
113
|
+
P.subst();
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
after(async () => {
|
|
117
|
+
pepView.close();
|
|
118
|
+
grok.shell.closeTable(peptidesDf);
|
|
119
|
+
});
|
|
120
|
+
});
|