@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
package/src/monomer-library.ts
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
|
+
export type MonomerEntry = {
|
|
2
|
+
mol: string,
|
|
3
|
+
type: string,
|
|
4
|
+
analogueCode: string,
|
|
5
|
+
linkages: { [link: string]: { atomNumber: number, type: string } }
|
|
6
|
+
};
|
|
7
|
+
export type MonomerEntries = {[name: string]: MonomerEntry};
|
|
8
|
+
export type LinkData = { [link: string]: { atomNumber: number, type: string } };
|
|
9
|
+
|
|
1
10
|
/** HELM associated sdf libraries with monomer processing*/
|
|
2
11
|
export class MonomerLibrary {
|
|
3
|
-
|
|
12
|
+
static libName = 'monomerLibrary';
|
|
4
13
|
|
|
5
14
|
private monomerFields: string[] = [
|
|
6
15
|
'molecule', 'MonomerType', 'MonomerNaturalAnalogCode', 'MonomerName', 'MonomerCode', 'MonomerCaps', 'BranchMonomer',
|
|
7
16
|
];
|
|
8
17
|
|
|
9
|
-
private library: {
|
|
10
|
-
[name: string]: {
|
|
11
|
-
mol: string,
|
|
12
|
-
type: string,
|
|
13
|
-
analogueCode: string,
|
|
14
|
-
linkages: { [link: string]: { atomNumber: number, type: string } }
|
|
15
|
-
}
|
|
16
|
-
} = {};
|
|
18
|
+
private library: MonomerEntries = {};
|
|
17
19
|
|
|
18
20
|
private monomers: string[] = [];
|
|
19
21
|
|
|
@@ -45,16 +47,15 @@ export class MonomerLibrary {
|
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
/** getting full monomer information from monomer library*/
|
|
48
|
-
public getMonomerEntry(name: string) {
|
|
50
|
+
public getMonomerEntry(name: string): MonomerEntry {
|
|
49
51
|
if (!this.monomers.includes(name))
|
|
50
52
|
throw new Error(`Monomer library do not contain ${name} monomer`);
|
|
51
53
|
|
|
52
|
-
|
|
53
54
|
return this.library[name];
|
|
54
55
|
}
|
|
55
56
|
|
|
56
57
|
/** getting mol as string for monomer*/
|
|
57
|
-
public getMonomerMol(name: string) {
|
|
58
|
+
public getMonomerMol(name: string): string {
|
|
58
59
|
if (!this.monomers.includes(name))
|
|
59
60
|
throw new Error(`Monomer library do not contain ${name} monomer`);
|
|
60
61
|
|
|
@@ -64,35 +65,34 @@ export class MonomerLibrary {
|
|
|
64
65
|
|
|
65
66
|
//order matters
|
|
66
67
|
const links = Object.keys(entry.linkages);
|
|
67
|
-
for (
|
|
68
|
-
monomerMol = monomerMol.replace('R#', entry.linkages[
|
|
68
|
+
for (const link of links)
|
|
69
|
+
monomerMol = monomerMol.replace('R#', entry.linkages[link].type + ' ');
|
|
69
70
|
|
|
70
71
|
|
|
71
72
|
return monomerMol;
|
|
72
73
|
}
|
|
73
74
|
|
|
74
75
|
/** getting the list of the minomers available in library*/
|
|
75
|
-
get monomerNames() {
|
|
76
|
+
get monomerNames(): string[] {
|
|
76
77
|
return this.monomers;
|
|
77
78
|
}
|
|
78
79
|
|
|
79
80
|
static get id(): string {
|
|
80
|
-
return MonomerLibrary.
|
|
81
|
+
return MonomerLibrary.libName;
|
|
81
82
|
}
|
|
82
83
|
|
|
83
|
-
private getLinkData(mol: string, caps: string, name: string) {
|
|
84
|
+
private getLinkData(mol: string, caps: string, name: string): LinkData {
|
|
84
85
|
const rawData = mol.match(/M RGP .+/);
|
|
85
86
|
if (rawData === null)
|
|
86
87
|
throw new Error(`Monomer library was not compiled: ${name} entry has no RGP`);
|
|
87
88
|
|
|
88
|
-
|
|
89
89
|
const types: { [code: string]: string } = {};
|
|
90
90
|
caps.split('\n')?.forEach((e) => {
|
|
91
91
|
types[e.match(/\d+/)![0]] = e.match(/(?<=\])\w+/)![0];
|
|
92
92
|
});
|
|
93
93
|
|
|
94
|
-
const data = rawData
|
|
95
|
-
const res:
|
|
94
|
+
const data = rawData[0].replace('M RGP ', '').split(/\s+/);
|
|
95
|
+
const res: LinkData = {};
|
|
96
96
|
for (let i = 0; i < parseInt(data[0]); i++) {
|
|
97
97
|
const code = parseInt(data[2 * i + 2]);
|
|
98
98
|
let type = '';
|
|
@@ -118,21 +118,21 @@ export class MonomerLibrary {
|
|
|
118
118
|
|
|
119
119
|
//TODO: merge with Chem version
|
|
120
120
|
class SDFReader {
|
|
121
|
-
dataColls: { [_: string]:
|
|
121
|
+
dataColls: { [_: string]: string [] };
|
|
122
122
|
|
|
123
123
|
constructor() {
|
|
124
124
|
this.dataColls = {'molecule': []};
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
getColls(content: string) {
|
|
127
|
+
getColls(content: string): { [_: string]: string[] } {
|
|
128
128
|
this.read(content);
|
|
129
129
|
return this.dataColls;
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
read(content: string) {
|
|
132
|
+
read(content: string): void {
|
|
133
133
|
content = content.replaceAll('\r', ''); //equalize old and new sdf standards
|
|
134
134
|
let startIndex = content.indexOf('$$$$', 0);
|
|
135
|
-
this.parse(content, 0, startIndex, (name: string, val:
|
|
135
|
+
this.parse(content, 0, startIndex, (name: string, val: string): void => { // TODO: type
|
|
136
136
|
this.dataColls[name] = [];
|
|
137
137
|
this.dataColls[name].push(val);
|
|
138
138
|
});
|
|
@@ -141,13 +141,15 @@ class SDFReader {
|
|
|
141
141
|
startIndex = this.readNext(content, startIndex);
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
-
readNext(content: string, startIndex: number) {
|
|
144
|
+
readNext(content: string, startIndex: number): number {
|
|
145
145
|
const nextStartIndex = content.indexOf('$$$$', startIndex);
|
|
146
146
|
if (nextStartIndex === -1)
|
|
147
147
|
return -1;
|
|
148
148
|
else {
|
|
149
149
|
this.parse(content, startIndex, nextStartIndex,
|
|
150
|
-
(name: string, val:
|
|
150
|
+
(name: string, val: string): void => {
|
|
151
|
+
this.dataColls[name].push(val);
|
|
152
|
+
});
|
|
151
153
|
}
|
|
152
154
|
|
|
153
155
|
if (nextStartIndex > -1)
|
|
@@ -157,10 +159,10 @@ class SDFReader {
|
|
|
157
159
|
return nextStartIndex;
|
|
158
160
|
}
|
|
159
161
|
|
|
160
|
-
parse(content: string, start: number, end: number, handler:
|
|
162
|
+
parse(content: string, start: number, end: number, handler: (name: string, val: string) => void): void {
|
|
161
163
|
const molEnd = +content.indexOf('M END\n', start) + 7;
|
|
162
164
|
let localEnd = start;
|
|
163
|
-
this.dataColls['molecule'].push(content.
|
|
165
|
+
this.dataColls['molecule'].push(content.substring(start, molEnd));
|
|
164
166
|
|
|
165
167
|
start = molEnd;
|
|
166
168
|
while (localEnd < end) {
|
|
@@ -182,8 +184,7 @@ class SDFReader {
|
|
|
182
184
|
if (localEnd === -1)
|
|
183
185
|
localEnd = end;
|
|
184
186
|
else if (content[localEnd + 1] != '\n')
|
|
185
|
-
localEnd = content.indexOf('\n',
|
|
186
|
-
;
|
|
187
|
+
localEnd = content.indexOf('\n', localEnd + 1);
|
|
187
188
|
|
|
188
189
|
handler(propertyName, content.substring(start, localEnd));
|
|
189
190
|
localEnd += 2;
|
package/src/package-test.ts
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
import * as DG from 'datagrok-api/dg';
|
|
2
|
-
|
|
3
2
|
import {runTests, tests} from '@datagrok-libraries/utils/src/test';
|
|
4
3
|
|
|
4
|
+
import './tests/core';
|
|
5
5
|
import './tests/peptide-space-test';
|
|
6
|
-
import './tests/peptides-tests';
|
|
7
6
|
import './tests/msa-tests';
|
|
8
7
|
|
|
9
|
-
export const
|
|
8
|
+
export const _package = new DG.Package();
|
|
10
9
|
export {tests};
|
|
11
10
|
|
|
12
11
|
//name: test
|
|
13
12
|
//input: string category {optional: true}
|
|
14
|
-
//input: string
|
|
13
|
+
//input: string test {optional: true}
|
|
15
14
|
//output: dataframe result
|
|
16
15
|
//top-menu: Tools | Dev | JS API Tests
|
|
17
|
-
export async function test(category: string,
|
|
18
|
-
const data = await runTests({category, test:
|
|
16
|
+
export async function test(category: string, test: string): Promise<DG.DataFrame> {
|
|
17
|
+
const data = await runTests({category, test: test});
|
|
19
18
|
return DG.DataFrame.fromObjects(data)!;
|
|
20
19
|
}
|
package/src/package.ts
CHANGED
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
AlignedSequenceDifferenceCellRenderer,
|
|
11
11
|
AminoAcidsCellRenderer,
|
|
12
12
|
} from './utils/cell-renderer';
|
|
13
|
-
import {Logo} from './viewers/logo-viewer';
|
|
14
13
|
import {StackedBarChart} from './viewers/stacked-barchart-viewer';
|
|
15
14
|
|
|
16
15
|
import {analyzePeptidesWidget} from './widgets/analyze-peptides';
|
|
@@ -19,24 +18,19 @@ import {manualAlignmentWidget} from './widgets/manual-alignment';
|
|
|
19
18
|
import {SARViewer, SARViewerVertical} from './viewers/sar-viewer';
|
|
20
19
|
import {peptideMoleculeWidget, getMolecule} from './widgets/peptide-molecule';
|
|
21
20
|
import {runKalign, testMSAEnoughMemory} from './utils/multiple-sequence-alignment';
|
|
22
|
-
import {substitutionsWidget} from './widgets/subst-table';
|
|
23
21
|
import {msaWidget} from './widgets/multiple-sequence-alignment';
|
|
24
|
-
import {getDistributionWidget} from './widgets/distribution';
|
|
25
22
|
import {PeptideSpaceViewer} from './viewers/peptide-space-viewer';
|
|
26
23
|
|
|
27
24
|
export const _package = new DG.Package();
|
|
28
|
-
let currentGrid: DG.Grid;
|
|
29
25
|
let currentTable: DG.DataFrame;
|
|
30
26
|
let alignedSequenceColumn: DG.Column;
|
|
31
|
-
let currentView: DG.TableView;
|
|
32
27
|
|
|
33
|
-
async function main(chosenFile: string) {
|
|
28
|
+
async function main(chosenFile: string): Promise<void> {
|
|
34
29
|
const pi = DG.TaskBarProgressIndicator.create('Loading Peptides');
|
|
35
30
|
const path = _package.webRoot + 'files/' + chosenFile;
|
|
36
|
-
const peptides =
|
|
31
|
+
const peptides = await grok.data.loadTable(path);
|
|
37
32
|
peptides.name = 'Peptides';
|
|
38
33
|
const view = grok.shell.addTableView(peptides);
|
|
39
|
-
currentGrid = view.grid;
|
|
40
34
|
view.name = 'PeptidesView';
|
|
41
35
|
grok.shell.windows.showProperties = true;
|
|
42
36
|
|
|
@@ -45,7 +39,7 @@ async function main(chosenFile: string) {
|
|
|
45
39
|
|
|
46
40
|
//name: Peptides
|
|
47
41
|
//tags: app
|
|
48
|
-
export async function Peptides() {
|
|
42
|
+
export async function Peptides(): Promise<void> {
|
|
49
43
|
const wikiLink = ui.link('wiki', 'https://github.com/datagrok-ai/public/blob/master/help/domains/bio/peptides.md');
|
|
50
44
|
const textLink = ui.inlineText(['For more details, see our ', wikiLink, '.']);
|
|
51
45
|
|
|
@@ -93,8 +87,7 @@ export async function peptidesPanel(col: DG.Column): Promise<DG.Widget> {
|
|
|
93
87
|
if (!(col.temp['isAnalysisApplicable'] ?? true))
|
|
94
88
|
return new DG.Widget(ui.divText('Analysis is not applicable'));
|
|
95
89
|
|
|
96
|
-
[
|
|
97
|
-
getOrDefine(undefined, undefined, col.dataFrame, col);
|
|
90
|
+
[currentTable, alignedSequenceColumn] = getOrDefine(col.dataFrame, col);
|
|
98
91
|
return analyzePeptidesWidget(currentTable, alignedSequenceColumn);
|
|
99
92
|
}
|
|
100
93
|
|
|
@@ -137,16 +130,16 @@ export async function stackedBarchartWidget(col: DG.Column): Promise<DG.Widget>
|
|
|
137
130
|
//input: string peptide {semType: alignedSequence}
|
|
138
131
|
//output: widget result
|
|
139
132
|
export async function peptideMolecule(peptide: string): Promise<DG.Widget> {
|
|
140
|
-
|
|
133
|
+
[currentTable, alignedSequenceColumn] = getOrDefine();
|
|
134
|
+
return peptideMoleculeWidget(peptide, currentTable);
|
|
141
135
|
}
|
|
142
136
|
|
|
143
137
|
//name: Peptide Molecule
|
|
144
138
|
//tags: panel, widgets
|
|
145
|
-
//input: string
|
|
139
|
+
//input: string _aar {semType: aminoAcids}
|
|
146
140
|
//output: widget result
|
|
147
|
-
export async function peptideMolecule2(
|
|
148
|
-
[
|
|
149
|
-
getOrDefine();
|
|
141
|
+
export async function peptideMolecule2(_aar: string): Promise<DG.Widget> {
|
|
142
|
+
[currentTable, alignedSequenceColumn] = getOrDefine();
|
|
150
143
|
const peptide = alignedSequenceColumn.get(currentTable.currentRowIdx);
|
|
151
144
|
return peptideMolecule(peptide);
|
|
152
145
|
}
|
|
@@ -159,35 +152,27 @@ export function stackedBarChart(): DG.JsViewer {
|
|
|
159
152
|
}
|
|
160
153
|
|
|
161
154
|
//name: alignedSequenceCellRenderer
|
|
162
|
-
//tags: cellRenderer
|
|
163
|
-
//meta
|
|
155
|
+
//tags: cellRenderer
|
|
156
|
+
//meta.cellType: alignedSequence
|
|
164
157
|
//output: grid_cell_renderer result
|
|
165
|
-
export function alignedSequenceCellRenderer() {
|
|
158
|
+
export function alignedSequenceCellRenderer(): AlignedSequenceCellRenderer {
|
|
166
159
|
return new AlignedSequenceCellRenderer();
|
|
167
160
|
}
|
|
168
161
|
|
|
169
162
|
//name: aminoAcidsCellRenderer
|
|
170
|
-
//tags: cellRenderer
|
|
171
|
-
//meta
|
|
163
|
+
//tags: cellRenderer
|
|
164
|
+
//meta.cellType: aminoAcids
|
|
172
165
|
//output: grid_cell_renderer result
|
|
173
|
-
export function aminoAcidsCellRenderer() {
|
|
166
|
+
export function aminoAcidsCellRenderer(): AminoAcidsCellRenderer {
|
|
174
167
|
return new AminoAcidsCellRenderer();
|
|
175
168
|
}
|
|
176
169
|
|
|
177
|
-
//name: peptide-logo-viewer
|
|
178
|
-
//tags: viewer, panel
|
|
179
|
-
//output: viewer result
|
|
180
|
-
export function logov() {
|
|
181
|
-
return new Logo();
|
|
182
|
-
}
|
|
183
|
-
|
|
184
170
|
//name: Manual Alignment
|
|
185
171
|
//tags: panel, widgets
|
|
186
|
-
//input: string
|
|
172
|
+
//input: string _monomer {semType: aminoAcids}
|
|
187
173
|
//output: widget result
|
|
188
|
-
export function manualAlignment(
|
|
189
|
-
[
|
|
190
|
-
getOrDefine();
|
|
174
|
+
export function manualAlignment(_monomer: string): DG.Widget {
|
|
175
|
+
[currentTable, alignedSequenceColumn] = getOrDefine();
|
|
191
176
|
//TODO: recalculate Molfile and Molecule panels on sequence update
|
|
192
177
|
return manualAlignmentWidget(alignedSequenceColumn, currentTable);
|
|
193
178
|
}
|
|
@@ -197,9 +182,8 @@ export function manualAlignment(monomer: string) {
|
|
|
197
182
|
//input: column col {semType: alignedSequence}
|
|
198
183
|
//output: widget result
|
|
199
184
|
export async function peptideSpacePanel(col: DG.Column): Promise<DG.Widget> {
|
|
200
|
-
[
|
|
201
|
-
|
|
202
|
-
const widget = new PeptideSimilaritySpaceWidget(col, currentView);
|
|
185
|
+
[currentTable, alignedSequenceColumn] = getOrDefine(col.dataFrame, col);
|
|
186
|
+
const widget = new PeptideSimilaritySpaceWidget(col, grok.shell.v as DG.TableView);
|
|
203
187
|
return widget.draw();
|
|
204
188
|
}
|
|
205
189
|
|
|
@@ -208,17 +192,17 @@ export async function peptideSpacePanel(col: DG.Column): Promise<DG.Widget> {
|
|
|
208
192
|
//input: string peptide { semType: alignedSequence }
|
|
209
193
|
//output: widget result
|
|
210
194
|
export async function peptideMolfile(peptide: string): Promise<DG.Widget> {
|
|
211
|
-
|
|
212
|
-
|
|
195
|
+
[currentTable, alignedSequenceColumn] = getOrDefine();
|
|
196
|
+
const smiles = getMolecule(peptide, alignedSequenceColumn.tags[C.TAGS.SEPARATOR]);
|
|
197
|
+
return grok.functions.call('Chem:molfile', {'smiles': smiles}) as Promise<DG.Widget>;
|
|
213
198
|
}
|
|
214
199
|
|
|
215
200
|
//name: Molfile
|
|
216
201
|
//tags: panel, widgets
|
|
217
|
-
//input: string
|
|
202
|
+
//input: string _aar { semType: aminoAcids }
|
|
218
203
|
//output: widget result
|
|
219
|
-
export async function peptideMolfile2(
|
|
220
|
-
[
|
|
221
|
-
getOrDefine();
|
|
204
|
+
export async function peptideMolfile2(_aar: string): Promise<DG.Widget> {
|
|
205
|
+
[currentTable, alignedSequenceColumn] = getOrDefine();
|
|
222
206
|
const peptide = alignedSequenceColumn.get(currentTable.currentRowIdx);
|
|
223
207
|
return peptideMolfile(peptide);
|
|
224
208
|
}
|
|
@@ -242,51 +226,49 @@ export async function multipleSequenceAlignmentAny(table: DG.DataFrame, col: DG.
|
|
|
242
226
|
}
|
|
243
227
|
|
|
244
228
|
//name: Test multiple sequence alignment for any column
|
|
245
|
-
//input: dataframe
|
|
229
|
+
//input: dataframe _table
|
|
246
230
|
//input: column col
|
|
247
231
|
//output: column result
|
|
248
|
-
export async function runTestMSAEnoughMemory(
|
|
232
|
+
export async function runTestMSAEnoughMemory(_table: DG.DataFrame, col: DG.Column<string>): Promise<DG.Column<string>> {
|
|
249
233
|
await testMSAEnoughMemory(col);
|
|
250
234
|
return col;
|
|
251
235
|
}
|
|
252
236
|
|
|
253
|
-
//name:
|
|
237
|
+
//name: Get Peptides Structure
|
|
254
238
|
//tags: panel, widgets
|
|
255
|
-
//input:
|
|
256
|
-
//output: widget result
|
|
257
|
-
export async function peptideSubstitution(table: DG.DataFrame): Promise<DG.Widget> {
|
|
258
|
-
if (!table.temp[C.PEPTIDES_ANALYSIS])
|
|
259
|
-
return new DG.Widget(ui.divText('This widget is only applicable for peptides analysis'));
|
|
260
|
-
return substitutionsWidget(table);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
//name: Distribution
|
|
264
|
-
//tags: panel, widgets
|
|
265
|
-
//input: dataframe table {semType: viewerTable}
|
|
239
|
+
//input: column col {semType: alignedSequence}
|
|
266
240
|
//output: widget result
|
|
267
|
-
export function
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
241
|
+
export function getPeptidesStructure(col: DG.Column): DG.Widget {
|
|
242
|
+
const getButtonTooltip = 'Retrieves peptides structure from customer database by special id column';
|
|
243
|
+
const getButton = ui.button('Get structure', async () => {
|
|
244
|
+
const progress = DG.TaskBarProgressIndicator.create('Getting structure...');
|
|
245
|
+
try {
|
|
246
|
+
const params = {peptidesTable: col.dataFrame};
|
|
247
|
+
const result = await grok.functions.call('Customerextensions:getPeptidesStructure', params);
|
|
248
|
+
const text = result ? 'Structure retreived' : 'Structure retreivial is not possible';
|
|
249
|
+
grok.shell.info(text);
|
|
250
|
+
} catch (e) {
|
|
251
|
+
console.warn(e);
|
|
252
|
+
} finally {
|
|
253
|
+
progress.close();
|
|
254
|
+
}
|
|
255
|
+
}, getButtonTooltip);
|
|
256
|
+
return new DG.Widget(getButton);
|
|
271
257
|
}
|
|
272
258
|
|
|
273
259
|
//name: alignedSequenceDifferenceCellRenderer
|
|
274
|
-
//tags: cellRenderer
|
|
275
|
-
//meta
|
|
260
|
+
//tags: cellRenderer
|
|
261
|
+
//meta.cellType: alignedSequenceDifference
|
|
276
262
|
//output: grid_cell_renderer result
|
|
277
|
-
export function alignedSequenceDifferenceCellRenderer() {
|
|
263
|
+
export function alignedSequenceDifferenceCellRenderer(): AlignedSequenceDifferenceCellRenderer {
|
|
278
264
|
return new AlignedSequenceDifferenceCellRenderer();
|
|
279
265
|
}
|
|
280
266
|
|
|
281
|
-
function getOrDefine(
|
|
282
|
-
view?: DG.TableView, grid?: DG.Grid, dataframe?: DG.DataFrame, column?: DG.Column | null,
|
|
283
|
-
): [DG.TableView, DG.Grid, DG.DataFrame, DG.Column] {
|
|
284
|
-
view ??= (grok.shell.v as DG.TableView);
|
|
285
|
-
grid ??= view.grid;
|
|
267
|
+
function getOrDefine(dataframe?: DG.DataFrame, column?: DG.Column | null): [DG.DataFrame, DG.Column] {
|
|
286
268
|
dataframe ??= grok.shell.t;
|
|
287
|
-
column ??=
|
|
269
|
+
column ??= dataframe.columns.bySemType(C.SEM_TYPES.ALIGNED_SEQUENCE);
|
|
288
270
|
if (column === null)
|
|
289
271
|
throw new Error('Table does not contain aligned sequence columns');
|
|
290
272
|
|
|
291
|
-
return [
|
|
273
|
+
return [dataframe, column];
|
|
292
274
|
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import * as grok from 'datagrok-api/grok';
|
|
2
|
+
import * as DG from 'datagrok-api/dg';
|
|
3
|
+
|
|
4
|
+
import {category, test, expect} from '@datagrok-libraries/utils/src/test';
|
|
5
|
+
|
|
6
|
+
import {_package} from '../package-test';
|
|
7
|
+
import {startAnalysis} from '../widgets/analyze-peptides';
|
|
8
|
+
import {PeptidesModel} from '../model';
|
|
9
|
+
import * as C from '../utils/constants';
|
|
10
|
+
|
|
11
|
+
category('Core', () => {
|
|
12
|
+
let simpleTable: DG.DataFrame;
|
|
13
|
+
let simpleActivityCol: DG.Column<number>;
|
|
14
|
+
let simpleAlignedSeqCol: DG.Column<string>;
|
|
15
|
+
let simpleScaledDf: DG.DataFrame;
|
|
16
|
+
let simpleScaledColName: string;
|
|
17
|
+
|
|
18
|
+
let complexTable: DG.DataFrame;
|
|
19
|
+
let complexActivityCol: DG.Column<number>;
|
|
20
|
+
let complexAlignedSeqCol: DG.Column<string>;
|
|
21
|
+
let complexScaledDf: DG.DataFrame;
|
|
22
|
+
let complexScaledColName: string;
|
|
23
|
+
const alignedSeuqnceCol = 'AlignedSequence';
|
|
24
|
+
|
|
25
|
+
let model: PeptidesModel | null = null;
|
|
26
|
+
|
|
27
|
+
test('Start analysis: simple', async () => {
|
|
28
|
+
const simpleActivityColName = 'IC50';
|
|
29
|
+
simpleTable = DG.DataFrame.fromCsv(await _package.files.readAsText('aligned.csv'));
|
|
30
|
+
simpleActivityCol = simpleTable.getCol(simpleActivityColName);
|
|
31
|
+
simpleAlignedSeqCol = simpleTable.getCol(alignedSeuqnceCol);
|
|
32
|
+
simpleAlignedSeqCol.semType = C.SEM_TYPES.ALIGNED_SEQUENCE;
|
|
33
|
+
[simpleScaledDf, simpleScaledColName] =
|
|
34
|
+
await PeptidesModel.scaleActivity('-lg', simpleTable, simpleActivityColName, true);
|
|
35
|
+
|
|
36
|
+
model = await startAnalysis(
|
|
37
|
+
simpleActivityCol, simpleAlignedSeqCol, simpleTable, simpleScaledDf, simpleScaledColName, _package);
|
|
38
|
+
expect(model instanceof PeptidesModel, true);
|
|
39
|
+
|
|
40
|
+
if (model != null) {
|
|
41
|
+
model.currentSelection = {'11': ['D']};
|
|
42
|
+
grok.shell.closeTable(model._dataFrame);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('Start analysis: сomplex', async () => {
|
|
47
|
+
const measureCategory = 'interleukin 23 receptor_h_wt_DC_HEK293_SPR_biotin_BIND Dose Response (Kd (uM):koff)';
|
|
48
|
+
const complexActivityColName = 'Value';
|
|
49
|
+
complexTable = DG.DataFrame.fromCsv(await _package.files.readAsText('aligned_2.csv'));
|
|
50
|
+
const measuredCol: DG.Column<string> = complexTable.getCol('Measured');
|
|
51
|
+
complexTable.filter.init((idx) => measuredCol.get(idx) == measureCategory);
|
|
52
|
+
complexActivityCol = complexTable.getCol(complexActivityColName);
|
|
53
|
+
complexAlignedSeqCol = complexTable.getCol(alignedSeuqnceCol);
|
|
54
|
+
complexAlignedSeqCol.semType = C.SEM_TYPES.ALIGNED_SEQUENCE;
|
|
55
|
+
[complexScaledDf, complexScaledColName] =
|
|
56
|
+
await PeptidesModel.scaleActivity('-lg', complexTable, complexActivityColName, true);
|
|
57
|
+
|
|
58
|
+
model = await startAnalysis(
|
|
59
|
+
complexActivityCol, complexAlignedSeqCol, complexTable, complexScaledDf, complexScaledColName, _package);
|
|
60
|
+
expect(model instanceof PeptidesModel, true);
|
|
61
|
+
|
|
62
|
+
if (model != null) {
|
|
63
|
+
model.currentSelection = {'13': ['-']};
|
|
64
|
+
grok.shell.closeTable(model._dataFrame);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
});
|
package/src/tests/msa-tests.ts
CHANGED
|
@@ -12,16 +12,16 @@ export const _package = new DG.Package();
|
|
|
12
12
|
|
|
13
13
|
let table: DG.DataFrame;
|
|
14
14
|
|
|
15
|
-
category('
|
|
15
|
+
category('MSA', async () => {
|
|
16
16
|
//table = await grok.data.files.openTable('Demo:Files/bio/peptides.csv');
|
|
17
17
|
table = DG.DataFrame.fromCsv(aligned1);
|
|
18
18
|
const alignedSequencesColumn = table.getCol('AlignedSequence');
|
|
19
19
|
|
|
20
|
-
test('
|
|
20
|
+
test('test_table.is_not_empty', async () => {
|
|
21
21
|
_testTableIsNotEmpty(table);
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
-
test('
|
|
24
|
+
test('is_correct', async () => {
|
|
25
25
|
_testMSAIsCorrect(alignedSequencesColumn);
|
|
26
26
|
});
|
|
27
27
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {/*before, after, */category, test} from '@datagrok-libraries/utils/src/test';
|
|
1
|
+
import {/*before, after, */after, category, test} from '@datagrok-libraries/utils/src/test';
|
|
2
2
|
import {
|
|
3
3
|
_testViewerIsDrawing,
|
|
4
4
|
_testDimensionalityReducer,
|
|
@@ -12,66 +12,86 @@ import {aligned1} from './test-data';
|
|
|
12
12
|
import * as DG from 'datagrok-api/dg';
|
|
13
13
|
import * as grok from 'datagrok-api/grok';
|
|
14
14
|
import {StringMetrics} from '@datagrok-libraries/ml/src/typed-metrics';
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
import {computeWeights} from '../viewers/peptide-space-viewer';
|
|
16
|
+
import {_package} from '../package-test';
|
|
17
17
|
|
|
18
18
|
let table: DG.DataFrame;
|
|
19
19
|
let view: DG.TableView;
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
//'/home/www/data/dev/packages/data/peptides/aligned.csv');
|
|
23
|
-
//console.log(table);
|
|
24
|
-
//const table = await grok.data.files.openTable('Demo:Files/bio/peptides.csv');
|
|
25
|
-
|
|
26
|
-
category('peptides', async () => {
|
|
27
|
-
/*before(async () => {
|
|
28
|
-
console.log(['before']);
|
|
29
|
-
// const text = await _package.files.readAsText('aligned.csv');
|
|
30
|
-
// console.log([text]);
|
|
31
|
-
// table = DG.DataFrame.fromCsv(text);
|
|
32
|
-
|
|
33
|
-
// const path = `${_package.webRoot}files/aligned.csv`;
|
|
34
|
-
// console.log([path]);
|
|
35
|
-
// table = await grok.data.loadTable(path);
|
|
36
|
-
// console.log([table]);
|
|
37
|
-
|
|
38
|
-
table = await grok.data.files.openTable('Demo:Files/bio/peptides.csv');
|
|
39
|
-
view = grok.shell.addTableView(table);
|
|
40
|
-
});*/
|
|
41
|
-
|
|
42
|
-
//table = await grok.data.files.openTable('Demo:Files/bio/peptides.csv');
|
|
21
|
+
category('Peptide space', async () => {
|
|
43
22
|
table = DG.DataFrame.fromCsv(aligned1);
|
|
44
|
-
view = grok.shell.addTableView(table);
|
|
45
23
|
|
|
46
|
-
test('
|
|
24
|
+
test('test_table.is_not_empty', async () => {
|
|
47
25
|
_testTableIsNotEmpty(table);
|
|
48
26
|
});
|
|
49
27
|
|
|
50
|
-
test('
|
|
28
|
+
test('PeptideSimilaritySpaceWidget.is_drawing', async () => {
|
|
29
|
+
view = grok.shell.addTableView(table);
|
|
51
30
|
await _testViewerIsDrawing(table, view);
|
|
52
31
|
});
|
|
53
32
|
|
|
54
33
|
const alignedSequencesColumn = table.getCol('AlignedSequence');
|
|
55
|
-
const columnData = cleanAlignedSequencesColumn(alignedSequencesColumn);
|
|
56
34
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
35
|
+
test('test_deminsionality_reducer', async () => {
|
|
36
|
+
const columnData = cleanAlignedSequencesColumn(alignedSequencesColumn);
|
|
37
|
+
for (const method of DimensionalityReducer.availableMethods) {
|
|
38
|
+
for (const measure of DimensionalityReducer.availableMetricsByType('String')) {
|
|
39
|
+
test(`peptide_space.DimensinalityReducer.${method}.${measure}.is_numeric`, async () => {
|
|
40
|
+
await _testDimensionalityReducer(columnData, method as StringMetrics, measure);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
62
43
|
}
|
|
63
|
-
}
|
|
44
|
+
});
|
|
64
45
|
|
|
65
|
-
|
|
66
|
-
for (const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
46
|
+
test('test_peptide_similarity_space_viewer', async () => {
|
|
47
|
+
for (const method of DimensionalityReducer.availableMethods) {
|
|
48
|
+
for (const measure of DimensionalityReducer.availableMetricsByType('String')) {
|
|
49
|
+
test(`peptide_space.PeptideSimilaritySpaceViewer.${method}.${measure}.is_proper`, async () => {
|
|
50
|
+
await _testPeptideSimilaritySpaceViewer(table, alignedSequencesColumn, method, measure, 100);//, view);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
70
53
|
}
|
|
71
|
-
}
|
|
54
|
+
});
|
|
72
55
|
|
|
73
|
-
|
|
74
|
-
view
|
|
75
|
-
|
|
76
|
-
|
|
56
|
+
after(async () => {
|
|
57
|
+
view?.close();
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
category('Peptide Space Performance', () => {
|
|
62
|
+
test('test_compute_weights_performance', async () => {
|
|
63
|
+
const table = DG.DataFrame.fromCsv(await _package.files.readAsText('peptides_large.csv'));
|
|
64
|
+
const results: {[key: string]: {[key: string]: {[key: string]: number}}} = {};
|
|
65
|
+
const slice_volumes = [1, 2, 3, 4, 5, 7, 10];
|
|
66
|
+
const methods = DimensionalityReducer.availableMethods;
|
|
67
|
+
const metrics = DimensionalityReducer.availableMetricsByType('String');
|
|
68
|
+
const total_runs = slice_volumes.length * methods.length * metrics.length;
|
|
69
|
+
console.log('Started Peptide Space Performance benchmark...');
|
|
70
|
+
|
|
71
|
+
let run = 0;
|
|
72
|
+
for (const slice of slice_volumes) {
|
|
73
|
+
const bitset = DG.BitSet.create(table.rowCount, (i) => i < slice * 1000);
|
|
74
|
+
const table_slice = table.clone(bitset);
|
|
75
|
+
const col = table_slice.getCol('sequence');
|
|
76
|
+
const methodObj: {[key: string]: {[key: string]: number}} = {};
|
|
77
|
+
|
|
78
|
+
for (const method of methods) {
|
|
79
|
+
const measureObj: {[key: string]: number} = {};
|
|
80
|
+
|
|
81
|
+
for (const metric of metrics) {
|
|
82
|
+
console.log(`Run ${run++}/${total_runs}`);
|
|
83
|
+
|
|
84
|
+
const start = new Date();
|
|
85
|
+
await computeWeights(table_slice, method, metric, 100, col);
|
|
86
|
+
const stop = new Date();
|
|
87
|
+
|
|
88
|
+
measureObj[metric] = stop.getTime() - start.getTime();
|
|
89
|
+
}
|
|
90
|
+
methodObj[method] = measureObj;
|
|
91
|
+
}
|
|
92
|
+
results[`${slice}k`] = methodObj;
|
|
93
|
+
}
|
|
94
|
+
console.log('Peptide Space Performance benchmark finished...');
|
|
95
|
+
console.log(results);
|
|
96
|
+
});
|
|
77
97
|
});
|