@datagrok/bio 2.5.0 → 2.6.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/detectors.js +23 -5
- package/dist/package-test.js +1 -1
- package/dist/package-test.js.map +1 -1
- package/dist/package.js +1 -1
- package/dist/package.js.map +1 -1
- package/package.json +3 -3
- package/src/package-test.ts +1 -3
- package/src/tests/WebLogo-positions-test.ts +10 -14
- package/src/tests/detectors-benchmark-tests.ts +9 -9
- package/src/tests/detectors-tests.ts +30 -0
- package/src/tests/msa-tests.ts +4 -4
- package/src/tests/renderers-test.ts +26 -44
- package/src/tests/similarity-diversity-tests.ts +35 -52
- package/src/tests/splitters-test.ts +16 -6
- package/src/tests/utils/sequences-generators.ts +7 -3
- package/src/tests/viewers.ts +3 -7
- package/src/utils/cell-renderer.ts +13 -8
- package/src/utils/convert.ts +0 -2
- package/src/viewers/web-logo-viewer.ts +35 -32
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"name": "Leonid Stolbov",
|
|
6
6
|
"email": "lstolbov@datagrok.ai"
|
|
7
7
|
},
|
|
8
|
-
"version": "2.
|
|
8
|
+
"version": "2.6.1",
|
|
9
9
|
"description": "Bioinformatics support (import/export of sequences, conversion, visualization, analysis). [See more](https://github.com/datagrok-ai/public/blob/master/packages/Bio/README.md) for details.",
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@biowasm/aioli": "^3.1.0",
|
|
25
|
-
"@datagrok-libraries/bio": "^5.33.
|
|
25
|
+
"@datagrok-libraries/bio": "^5.33.2",
|
|
26
26
|
"@datagrok-libraries/chem-meta": "^1.0.1",
|
|
27
27
|
"@datagrok-libraries/ml": "^6.3.39",
|
|
28
28
|
"@datagrok-libraries/tutorials": "^1.3.2",
|
|
29
|
-
"@datagrok-libraries/utils": "^4.0.
|
|
29
|
+
"@datagrok-libraries/utils": "^4.0.17",
|
|
30
30
|
"cash-dom": "^8.0.0",
|
|
31
31
|
"css-loader": "^6.7.3",
|
|
32
32
|
"datagrok-api": "^1.13.3",
|
package/src/package-test.ts
CHANGED
|
@@ -8,9 +8,7 @@ import './tests/detectors-tests';
|
|
|
8
8
|
import './tests/detectors-weak-and-likely-tests';
|
|
9
9
|
import './tests/detectors-benchmark-tests';
|
|
10
10
|
import './tests/msa-tests';
|
|
11
|
-
|
|
12
|
-
import './tests/splitters-test'; //Unhandled exceptions.exceptions : Cannot read properties of null (reading 'f')
|
|
13
|
-
|
|
11
|
+
import './tests/splitters-test';
|
|
14
12
|
import './tests/monomer-libraries-tests';
|
|
15
13
|
import './tests/renderers-test';
|
|
16
14
|
import './tests/renderers-monomer-placer';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as grok from 'datagrok-api/grok';
|
|
2
2
|
import * as DG from 'datagrok-api/dg';
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import {ALPHABET, NOTATION,
|
|
4
|
+
import {category, expect, expectArray, test, awaitCheck, delay} from '@datagrok-libraries/utils/src/test';
|
|
5
|
+
import {ALPHABET, NOTATION, TAGS as bioTAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
6
6
|
import {
|
|
7
7
|
countForMonomerAtPosition,
|
|
8
8
|
PositionInfo as PI,
|
|
@@ -19,14 +19,6 @@ ATC-G-TTGC--
|
|
|
19
19
|
-TC-GCTTGC--
|
|
20
20
|
-TC-GCTTGC--`;
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
before(async () => {
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
after(async () => {
|
|
27
|
-
// Closing opened views causes the error 'Cannot read properties of null (reading 'f')'
|
|
28
|
-
});
|
|
29
|
-
|
|
30
22
|
test('allPositions', async () => {
|
|
31
23
|
const df: DG.DataFrame = DG.DataFrame.fromCsv(csvDf1);
|
|
32
24
|
const tv: DG.TableView = grok.shell.addTableView(df);
|
|
@@ -40,6 +32,7 @@ ATC-G-TTGC--
|
|
|
40
32
|
const wlViewer: WebLogoViewer = (await df.plot.fromType('WebLogo')) as WebLogoViewer;
|
|
41
33
|
tv.dockManager.dock(wlViewer.root, DG.DOCK_TYPE.DOWN);
|
|
42
34
|
|
|
35
|
+
await awaitCheck(() => wlViewer.Length > 0, 'WebLogo.Length is zero', 100);
|
|
43
36
|
const positions: PI[] = wlViewer['positions'];
|
|
44
37
|
|
|
45
38
|
const resAllDf1: PI[] = [
|
|
@@ -64,7 +57,7 @@ ATC-G-TTGC--
|
|
|
64
57
|
for (const m of positions[i].getMonomers())
|
|
65
58
|
expect(positions[i].getFreq(m).count, resAllDf1[i].getFreq(m).count);
|
|
66
59
|
}
|
|
67
|
-
}
|
|
60
|
+
});
|
|
68
61
|
|
|
69
62
|
test('positions with shrinkEmptyTail option true (filtered)', async () => {
|
|
70
63
|
const csvDf2 = `seq
|
|
@@ -91,6 +84,7 @@ ATC-G-TTGC--
|
|
|
91
84
|
{'shrinkEmptyTail': true})) as WebLogoViewer;
|
|
92
85
|
tv.dockManager.dock(wlViewer.root, DG.DOCK_TYPE.DOWN);
|
|
93
86
|
|
|
87
|
+
await awaitCheck(() => wlViewer.Length > 0, 'WebLogo.Length is zero', 100);
|
|
94
88
|
const positions: PI[] = wlViewer['positions'];
|
|
95
89
|
|
|
96
90
|
const resAllDf1: PI[] = [
|
|
@@ -112,7 +106,7 @@ ATC-G-TTGC--
|
|
|
112
106
|
for (const m of positions[i].getMonomers())
|
|
113
107
|
expect(positions[i].getFreq(m).count, resAllDf1[i].getFreq(m).count);
|
|
114
108
|
}
|
|
115
|
-
}
|
|
109
|
+
});
|
|
116
110
|
|
|
117
111
|
test('positions with skipEmptyPositions option', async () => {
|
|
118
112
|
const df: DG.DataFrame = DG.DataFrame.fromCsv(csvDf1);
|
|
@@ -128,6 +122,7 @@ ATC-G-TTGC--
|
|
|
128
122
|
{'skipEmptyPositions': true})) as WebLogoViewer;
|
|
129
123
|
tv.dockManager.dock(wlViewer.root, DG.DOCK_TYPE.DOWN);
|
|
130
124
|
|
|
125
|
+
await awaitCheck(() => wlViewer.Length > 0, 'WebLogo.Length is zero');
|
|
131
126
|
const resPosList: PI[] = wlViewer['positions'];
|
|
132
127
|
|
|
133
128
|
const tgtPosList: PI[] = [
|
|
@@ -148,7 +143,7 @@ ATC-G-TTGC--
|
|
|
148
143
|
const tgtPos = tgtPosList[posI];
|
|
149
144
|
expectPositionInfo(resPos, tgtPos);
|
|
150
145
|
}
|
|
151
|
-
}
|
|
146
|
+
});
|
|
152
147
|
|
|
153
148
|
test('count sequences for monomer at position', async () => {
|
|
154
149
|
const df: DG.DataFrame = buildDfWithSeqCol(csvDf1, NOTATION.FASTA, ALPHABET.DNA, 'SEQ.MSA');
|
|
@@ -163,6 +158,7 @@ ATC-G-TTGC--
|
|
|
163
158
|
})) as WebLogoViewer;
|
|
164
159
|
tv.dockManager.dock(wlViewer.root, DG.DOCK_TYPE.DOWN);
|
|
165
160
|
|
|
161
|
+
await awaitCheck(() => wlViewer.Length > 0, 'WebLogo.Length is zero', 100);
|
|
166
162
|
const resPosList: PI[] = wlViewer['positions'];
|
|
167
163
|
const tgtPosList: PI[] = [
|
|
168
164
|
new PI(2, '3', {'C': new PMI(5)}),
|
|
@@ -182,7 +178,7 @@ ATC-G-TTGC--
|
|
|
182
178
|
const uh = UnitsHandler.getOrCreate(seqCol);
|
|
183
179
|
const countAt1 = countForMonomerAtPosition(df, uh, df.filter, 'G', atPI1);
|
|
184
180
|
expect(countAt1, 5);
|
|
185
|
-
}
|
|
181
|
+
});
|
|
186
182
|
});
|
|
187
183
|
|
|
188
184
|
function expectPositionInfo(actualPos: PI, expectedPos: PI): void {
|
|
@@ -21,19 +21,19 @@ category('detectorsBenchmark', () => {
|
|
|
21
21
|
// -- fasta --
|
|
22
22
|
|
|
23
23
|
test('fastaDnaShorts50Few50', async () => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
await detectMacromoleculeBenchmark(10, NOTATION.FASTA, ALPHABET.DNA, 50, 50);
|
|
25
|
+
},
|
|
26
|
+
{skipReason: '#1192'});
|
|
27
27
|
|
|
28
28
|
test('fastaDnaShorts50Many1E6', async () => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
await detectMacromoleculeBenchmark(10, NOTATION.FASTA, ALPHABET.DNA, 50, 1E6);
|
|
30
|
+
},
|
|
31
|
+
{skipReason: '#1192'});
|
|
32
32
|
|
|
33
33
|
test('fastaDnaLong1e6Few50', async () => {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
await detectMacromoleculeBenchmark(10, NOTATION.FASTA, ALPHABET.DNA, 1E6, 50);
|
|
35
|
+
},
|
|
36
|
+
{skipReason: '#1192'});
|
|
37
37
|
|
|
38
38
|
// -- separator --
|
|
39
39
|
|
|
@@ -225,6 +225,11 @@ MWRSWY-CKHP`;
|
|
|
225
225
|
await _testPos(readCsv(csvTests.fastaPt1), 'seq',
|
|
226
226
|
NOTATION.FASTA, ALIGNMENT.SEQ, ALPHABET.PT, 20, false);
|
|
227
227
|
});
|
|
228
|
+
test('FastaPtGaps', () => _testPosList(['FW-PH-EYY', 'FYNRQWYV-', 'FKP-Q-SEYV'],
|
|
229
|
+
NOTATION.FASTA, ALIGNMENT.SEQ, ALPHABET.PT, 20, false));
|
|
230
|
+
test('FastaPtGapsMsa', () => _testPosList(['FW-PH-EYY', 'FYNRQWYV-', 'FKP-Q-SEY'],
|
|
231
|
+
NOTATION.FASTA, ALIGNMENT.SEQ_MSA, ALPHABET.PT, 20, false));
|
|
232
|
+
|
|
228
233
|
test('FastaUn', async () => {
|
|
229
234
|
await _testPos(readCsv(csvTests.fastaUn), 'seq',
|
|
230
235
|
NOTATION.FASTA, ALIGNMENT.SEQ_MSA, ALPHABET.UN, 12, true);
|
|
@@ -387,6 +392,31 @@ export async function _testNeg(readDf: DfReaderFunc, colName: string) {
|
|
|
387
392
|
}
|
|
388
393
|
}
|
|
389
394
|
|
|
395
|
+
export async function _testPosList(list: string[], units: NOTATION,
|
|
396
|
+
aligned: ALIGNMENT, alphabet: ALPHABET, alphabetSize: number, alphabetIsMultichar: boolean,
|
|
397
|
+
separator: string | null = null
|
|
398
|
+
): Promise<void> {
|
|
399
|
+
const col: DG.Column = DG.Column.fromList(DG.TYPE.STRING, 'seq', list);
|
|
400
|
+
const semType: string = await grok.functions.call('Bio:detectMacromolecule', {col: col});
|
|
401
|
+
if (semType)
|
|
402
|
+
col.semType = semType;
|
|
403
|
+
|
|
404
|
+
expect(col.semType, DG.SEMTYPE.MACROMOLECULE);
|
|
405
|
+
expect(col.getTag(DG.TAGS.UNITS), units);
|
|
406
|
+
expect(col.getTag(bioTAGS.aligned), aligned);
|
|
407
|
+
expect(col.getTag(bioTAGS.alphabet), alphabet);
|
|
408
|
+
if (separator)
|
|
409
|
+
expect(col.getTag(bioTAGS.separator), separator);
|
|
410
|
+
|
|
411
|
+
const uh = UnitsHandler.getOrCreate(col);
|
|
412
|
+
expect(uh.getAlphabetSize(), alphabetSize);
|
|
413
|
+
expect(uh.getAlphabetIsMultichar(), alphabetIsMultichar);
|
|
414
|
+
if (!uh.isHelm()) {
|
|
415
|
+
expect(uh.aligned, aligned);
|
|
416
|
+
expect(uh.alphabet, alphabet);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
390
420
|
export async function _testPos(
|
|
391
421
|
readDf: DfReaderFunc, colName: string, units: string,
|
|
392
422
|
aligned: string | null, alphabet: string | null, alphabetSize: number, alphabetIsMultichar: boolean,
|
package/src/tests/msa-tests.ts
CHANGED
|
@@ -73,11 +73,11 @@ MWRSWYCKHPMWRSWYCKHPMWRSWYCKHPMWRSWYCKHPMWRSWYCKHPMWRSWYCKHPMWRSWYCKHPMWRSWYCKHP
|
|
|
73
73
|
|
|
74
74
|
test('isCorrect', async () => {
|
|
75
75
|
await _testMsaIsCorrect(fromCsv, toCsv);
|
|
76
|
-
}
|
|
76
|
+
});
|
|
77
77
|
|
|
78
78
|
test('isCorrectLong', async () => {
|
|
79
79
|
await _testMsaIsCorrect(longFromCsv, longToCsv);
|
|
80
|
-
}
|
|
80
|
+
});
|
|
81
81
|
|
|
82
82
|
test('isCorrectHelm', async () => {
|
|
83
83
|
await awaitContainerStart();
|
|
@@ -93,13 +93,13 @@ MWRSWYCKHPMWRSWYCKHPMWRSWYCKHPMWRSWYCKHPMWRSWYCKHPMWRSWYCKHPMWRSWYCKHPMWRSWYCKHP
|
|
|
93
93
|
await _testMSAOnColumn(
|
|
94
94
|
SeparatorFromCsv, SeparatorToCsv, NOTATION.SEPARATOR, NOTATION.FASTA, ALPHABET.PT,
|
|
95
95
|
);
|
|
96
|
-
}
|
|
96
|
+
});
|
|
97
97
|
|
|
98
98
|
test('isCorrectSeparatorLong', async () => {
|
|
99
99
|
await _testMSAOnColumn(
|
|
100
100
|
SeparatorLongFromCsv, SeparatorLongToCsv, NOTATION.SEPARATOR, NOTATION.FASTA, ALPHABET.PT,
|
|
101
101
|
);
|
|
102
|
-
}
|
|
102
|
+
});
|
|
103
103
|
});
|
|
104
104
|
|
|
105
105
|
async function _testMsaIsCorrect(srcCsv: string, tgtCsv: string): Promise<void> {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as grok from 'datagrok-api/grok';
|
|
2
2
|
import * as DG from 'datagrok-api/dg';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {category, expect, test, awaitCheck, delay} from '@datagrok-libraries/utils/src/test';
|
|
5
5
|
|
|
6
6
|
import {importFasta} from '../package';
|
|
7
7
|
import {convertDo} from '../utils/convert';
|
|
@@ -12,54 +12,40 @@ import {UnitsHandler} from '@datagrok-libraries/bio/src/utils/units-handler';
|
|
|
12
12
|
import {multipleSequenceAlignmentUI} from '../utils/multiple-sequence-alignment-ui';
|
|
13
13
|
|
|
14
14
|
category('renderers', () => {
|
|
15
|
-
let tvList: DG.TableView[];
|
|
16
|
-
let dfList: DG.DataFrame[];
|
|
17
|
-
|
|
18
|
-
before(async () => {
|
|
19
|
-
tvList = [];
|
|
20
|
-
dfList = [];
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
after(async () => {
|
|
24
|
-
// Closing viewes and data frames leads to exception
|
|
25
|
-
// dfList.forEach((df: DG.DataFrame) => { grok.shell.closeTable(df); });
|
|
26
|
-
// tvList.forEach((tv: DG.TableView) => tv.close());
|
|
27
|
-
});
|
|
28
|
-
|
|
29
15
|
test('long sequence performance ', async () => {
|
|
30
|
-
performanceTest(generateLongSequence, 'Long sequences');
|
|
31
|
-
}
|
|
16
|
+
await performanceTest(generateLongSequence, 'Long sequences');
|
|
17
|
+
});
|
|
32
18
|
|
|
33
19
|
test('many sequence performance', async () => {
|
|
34
|
-
performanceTest(generateManySequences, 'Many sequences');
|
|
35
|
-
}
|
|
20
|
+
await performanceTest(generateManySequences, 'Many sequences');
|
|
21
|
+
});
|
|
36
22
|
test('many sequence performance', async () => {
|
|
37
|
-
performanceTest(generateManySequences, 'Many sequences');
|
|
38
|
-
}
|
|
23
|
+
await performanceTest(generateManySequences, 'Many sequences');
|
|
24
|
+
});
|
|
39
25
|
|
|
40
26
|
test('rendererMacromoleculeFasta', async () => {
|
|
41
27
|
await _rendererMacromoleculeFasta();
|
|
42
|
-
}
|
|
28
|
+
});
|
|
43
29
|
|
|
44
30
|
test('rendererMacromoleculeSeparator', async () => {
|
|
45
31
|
await _rendererMacromoleculeSeparator();
|
|
46
|
-
}
|
|
32
|
+
});
|
|
47
33
|
|
|
48
34
|
test('rendererMacromoleculeDifference', async () => {
|
|
49
35
|
await _rendererMacromoleculeDifference();
|
|
50
|
-
}
|
|
36
|
+
});
|
|
51
37
|
|
|
52
38
|
test('afterMsa', async () => {
|
|
53
39
|
await _testAfterMsa();
|
|
54
|
-
}
|
|
40
|
+
});
|
|
55
41
|
|
|
56
42
|
test('afterConvert', async () => {
|
|
57
43
|
await _testAfterConvert();
|
|
58
|
-
}
|
|
44
|
+
});
|
|
59
45
|
|
|
60
46
|
test('selectRendererBySemType', async () => {
|
|
61
47
|
await _selectRendererBySemType();
|
|
62
|
-
}
|
|
48
|
+
});
|
|
63
49
|
|
|
64
50
|
test('setRendererManually', async () => {
|
|
65
51
|
await _setRendererManually();
|
|
@@ -78,8 +64,8 @@ category('renderers', () => {
|
|
|
78
64
|
// call to calculate 'cell.renderer' tag
|
|
79
65
|
await grok.data.detectSemanticTypes(df);
|
|
80
66
|
|
|
81
|
-
|
|
82
|
-
|
|
67
|
+
await awaitCheck(() => { return tv.grid.dataFrame != df; },
|
|
68
|
+
'View grid has wrong data frame', 100);
|
|
83
69
|
|
|
84
70
|
const resCellRenderer = seqCol.getTag(DG.TAGS.CELL_RENDERER);
|
|
85
71
|
expect(resCellRenderer, 'sequence');
|
|
@@ -98,8 +84,8 @@ category('renderers', () => {
|
|
|
98
84
|
// call to calculate 'cell.renderer' tag
|
|
99
85
|
await grok.data.detectSemanticTypes(df);
|
|
100
86
|
|
|
101
|
-
|
|
102
|
-
|
|
87
|
+
await awaitCheck(() => { return tv.grid.dataFrame != df; },
|
|
88
|
+
'View grid has wrong data frame', 100);
|
|
103
89
|
|
|
104
90
|
const resCellRenderer = seqCol.getTag(DG.TAGS.CELL_RENDERER);
|
|
105
91
|
expect(resCellRenderer, 'sequence');
|
|
@@ -120,8 +106,8 @@ category('renderers', () => {
|
|
|
120
106
|
// call to calculate 'cell.renderer' tag
|
|
121
107
|
await grok.data.detectSemanticTypes(df);
|
|
122
108
|
|
|
123
|
-
|
|
124
|
-
|
|
109
|
+
await awaitCheck(() => { return tv.grid.dataFrame != df; },
|
|
110
|
+
'View grid has wrong data frame', 100);
|
|
125
111
|
|
|
126
112
|
const resCellRenderer = seqDiffCol.getTag(DG.TAGS.CELL_RENDERER);
|
|
127
113
|
expect(resCellRenderer, C.SEM_TYPES.MACROMOLECULE_DIFFERENCE);
|
|
@@ -141,6 +127,8 @@ category('renderers', () => {
|
|
|
141
127
|
await grok.data.detectSemanticTypes(df);
|
|
142
128
|
|
|
143
129
|
console.log('Bio: tests/renderers/afterMsa, table view');
|
|
130
|
+
await awaitCheck(() => { return tv.grid.dataFrame != df; },
|
|
131
|
+
'View grid has wrong data frame', 100);
|
|
144
132
|
|
|
145
133
|
console.log('Bio: tests/renderers/afterMsa, src before test ' +
|
|
146
134
|
`semType="${srcSeqCol!.semType}", units="${srcSeqCol!.getTag(DG.TAGS.UNITS)}", ` +
|
|
@@ -153,6 +141,8 @@ category('renderers', () => {
|
|
|
153
141
|
|
|
154
142
|
const msaSeqCol = await multipleSequenceAlignmentUI({col: srcSeqCol});
|
|
155
143
|
tv.grid.invalidate();
|
|
144
|
+
await awaitCheck(() => { return tv.grid.dataFrame != df; },
|
|
145
|
+
'View grid has wrong data frame', 100);
|
|
156
146
|
|
|
157
147
|
expect(msaSeqCol.semType, DG.SEMTYPE.MACROMOLECULE);
|
|
158
148
|
expect(msaSeqCol.getTag(DG.TAGS.UNITS), NOTATION.FASTA);
|
|
@@ -162,9 +152,6 @@ category('renderers', () => {
|
|
|
162
152
|
|
|
163
153
|
// check newColumn with UnitsHandler constructor
|
|
164
154
|
const _uh: UnitsHandler = UnitsHandler.getOrCreate(msaSeqCol);
|
|
165
|
-
|
|
166
|
-
dfList.push(df);
|
|
167
|
-
tvList.push(tv);
|
|
168
155
|
}
|
|
169
156
|
|
|
170
157
|
async function _testAfterConvert() {
|
|
@@ -180,10 +167,9 @@ category('renderers', () => {
|
|
|
180
167
|
// call to calculate 'cell.renderer' tag
|
|
181
168
|
await grok.data.detectSemanticTypes(df);
|
|
182
169
|
|
|
183
|
-
tvList.push(tv);
|
|
184
|
-
dfList.push(df);
|
|
185
|
-
|
|
186
170
|
const tgtCol: DG.Column = await convertDo(srcCol, NOTATION.SEPARATOR, '/');
|
|
171
|
+
await awaitCheck(() => { return tv.grid.dataFrame != df; },
|
|
172
|
+
'View grid has wrong data frame', 100);
|
|
187
173
|
|
|
188
174
|
const resCellRenderer = tgtCol.getTag(DG.TAGS.CELL_RENDERER);
|
|
189
175
|
expect(resCellRenderer, 'sequence');
|
|
@@ -206,8 +192,6 @@ category('renderers', () => {
|
|
|
206
192
|
seqDiffCol.semType = C.SEM_TYPES.MACROMOLECULE_DIFFERENCE;
|
|
207
193
|
const df = DG.DataFrame.fromColumns([seqDiffCol]);
|
|
208
194
|
const tv = grok.shell.addTableView(df);
|
|
209
|
-
dfList.push(df);
|
|
210
|
-
tvList.push(tv);
|
|
211
195
|
|
|
212
196
|
await delay(100);
|
|
213
197
|
const renderer = seqDiffCol.getTag(DG.TAGS.CELL_RENDERER);
|
|
@@ -234,10 +218,8 @@ category('renderers', () => {
|
|
|
234
218
|
const df = DG.DataFrame.fromColumns([seqDiffCol]);
|
|
235
219
|
await grok.data.detectSemanticTypes(df);
|
|
236
220
|
const tv = grok.shell.addTableView(df);
|
|
237
|
-
|
|
238
|
-
tvList.push(tv);
|
|
221
|
+
await awaitCheck(() => document.querySelector('canvas') !== null, 'cannot load table', 3000);
|
|
239
222
|
|
|
240
|
-
await delay(100);
|
|
241
223
|
const resCellRenderer = seqDiffCol.getTag(DG.TAGS.CELL_RENDERER);
|
|
242
224
|
if (resCellRenderer !== tgtCellRenderer) { // this is value of MacromoleculeDifferenceCR.cellType
|
|
243
225
|
throw new Error(`Tag 'cell.renderer' has been manually set to '${tgtCellRenderer}' for column ` +
|
|
@@ -1,18 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {category, test, expect, awaitCheck} from '@datagrok-libraries/utils/src/test';
|
|
2
2
|
import * as DG from 'datagrok-api/dg';
|
|
3
3
|
import {createTableView} from './utils';
|
|
4
4
|
import * as grok from 'datagrok-api/grok';
|
|
5
5
|
import {SequenceSimilarityViewer} from '../analysis/sequence-similarity-viewer';
|
|
6
6
|
|
|
7
7
|
category('similarity/diversity', async () => {
|
|
8
|
-
before(async () => {
|
|
9
|
-
// grok.shell.closeAll();
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
after(async () => {
|
|
13
|
-
grok.shell.closeAll();
|
|
14
|
-
});
|
|
15
|
-
|
|
16
8
|
test('similaritySearchViewer', async () => {
|
|
17
9
|
await _testSimilaritySearchViewer();
|
|
18
10
|
});
|
|
@@ -23,51 +15,43 @@ category('similarity/diversity', async () => {
|
|
|
23
15
|
});
|
|
24
16
|
|
|
25
17
|
async function _testSimilaritySearchViewer() {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
} finally {
|
|
51
|
-
grok.shell.closeAll();
|
|
52
|
-
}
|
|
18
|
+
const molecules = await createTableView('tests/sample_MSA_data.csv');
|
|
19
|
+
const viewer = molecules.addViewer('Sequence Similarity Search');
|
|
20
|
+
await awaitCheck(() => getSearchViewer(viewer, 'Sequence Similarity Search') !== undefined,
|
|
21
|
+
'Sequence Similarity Search has not been created', 5000);
|
|
22
|
+
const similaritySearchViewer: SequenceSimilarityViewer = getSearchViewer(viewer, 'Sequence Similarity Search');
|
|
23
|
+
await awaitCheck(() => similaritySearchViewer.root.getElementsByClassName('d4-grid').length !== 0,
|
|
24
|
+
'Sequence Similarity Search has not been created', 5000);
|
|
25
|
+
expect(similaritySearchViewer.fingerprint, 'Morgan');
|
|
26
|
+
expect(similaritySearchViewer.distanceMetric, 'Tanimoto');
|
|
27
|
+
expect(similaritySearchViewer.scores!.get(0), DG.FLOAT_NULL);
|
|
28
|
+
expect(similaritySearchViewer.idxs!.get(0), 0);
|
|
29
|
+
expect(similaritySearchViewer.molCol!.get(0),
|
|
30
|
+
'D-Tyr_Et/Tyr_ab-dehydroMe/dV/E/N/D-Orn/D-aThr//Phe_4Me');
|
|
31
|
+
expect(similaritySearchViewer.scores!.get(1), 0.4722222089767456);
|
|
32
|
+
expect(similaritySearchViewer.idxs!.get(1), 11);
|
|
33
|
+
expect(similaritySearchViewer.molCol!.get(1),
|
|
34
|
+
'meI/hHis//Aca/meM/Tyr_ab-dehydroMe/dV/E/N/D-Orn/D-aThr//Phe_4Me');
|
|
35
|
+
molecules.dataFrame.currentRowIdx = 1;
|
|
36
|
+
await awaitCheck(() => similaritySearchViewer.targetMoleculeIdx === 1,
|
|
37
|
+
'Target molecule has not been changed', 5000);
|
|
38
|
+
await awaitCheck(() => similaritySearchViewer.molCol!.get(0) ===
|
|
39
|
+
'meI/hHis/Aca/Cys_SEt/T/dK/Thr_PO3H2/Aca/Tyr_PO3H2/D-Chg/dV/Phe_ab-dehydro/N/D-Orn/D-aThr//Phe_4Me',
|
|
40
|
+
'Incorrect first similar molecule', 5000);
|
|
53
41
|
}
|
|
54
42
|
|
|
55
43
|
async function _testDiversitySearchViewer() {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
expect(diversitySearchviewer.renderMolIds.length > 0, true);
|
|
68
|
-
} finally {
|
|
69
|
-
grok.shell.closeAll();
|
|
70
|
-
}
|
|
44
|
+
const molecules = await createTableView('tests/sample_MSA_data.csv');
|
|
45
|
+
const viewer = molecules.addViewer('Sequence Diversity Search');
|
|
46
|
+
await awaitCheck(() => getSearchViewer(viewer, 'Sequence Diversity Search') !== undefined,
|
|
47
|
+
'Sequence Diversity Search has not been created', 5000);
|
|
48
|
+
const diversitySearchviewer = getSearchViewer(viewer, 'Sequence Diversity Search');
|
|
49
|
+
await awaitCheck(() => diversitySearchviewer.root.getElementsByClassName('d4-grid').length !== 0,
|
|
50
|
+
'Sequence Diversity Search has not been created', 5000);
|
|
51
|
+
expect(diversitySearchviewer.fingerprint, 'Morgan');
|
|
52
|
+
expect(diversitySearchviewer.distanceMetric, 'Tanimoto');
|
|
53
|
+
expect(diversitySearchviewer.initialized, true);
|
|
54
|
+
expect(diversitySearchviewer.renderMolIds.length > 0, true);
|
|
71
55
|
}
|
|
72
56
|
|
|
73
57
|
function getSearchViewer(viewer: DG.Viewer, name: string) {
|
|
@@ -77,4 +61,3 @@ function getSearchViewer(viewer: DG.Viewer, name: string) {
|
|
|
77
61
|
return v;
|
|
78
62
|
}
|
|
79
63
|
}
|
|
80
|
-
|
|
@@ -2,7 +2,16 @@ 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
4
|
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
after,
|
|
7
|
+
before,
|
|
8
|
+
category,
|
|
9
|
+
test,
|
|
10
|
+
expect,
|
|
11
|
+
expectArray,
|
|
12
|
+
delay,
|
|
13
|
+
awaitCheck
|
|
14
|
+
} from '@datagrok-libraries/utils/src/test';
|
|
6
15
|
import * as C from '../utils/constants';
|
|
7
16
|
import {_package, getHelmMonomers} from '../package';
|
|
8
17
|
import {TAGS as bioTAGS, splitterAsFasta, splitterAsHelm} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
@@ -80,13 +89,14 @@ category('splitters', async () => {
|
|
|
80
89
|
|
|
81
90
|
const newDf = await splitToMonomersUI(df, seqCol);
|
|
82
91
|
expect(newDf.columns.names().includes('17'), true);
|
|
92
|
+
// call to calculate 'cell.renderer' tag
|
|
93
|
+
await grok.data.detectSemanticTypes(newDf);
|
|
83
94
|
|
|
84
95
|
// TODO: Check cell.renderer for columns of monomers
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}, {skipReason: 'GROK-13300'});
|
|
96
|
+
const tv: DG.TableView = grok.shell.addTableView(newDf);
|
|
97
|
+
await awaitCheck(() => { return tv.grid.dataFrame != df; },
|
|
98
|
+
'View grid has wrong data frame', 100);
|
|
99
|
+
});
|
|
90
100
|
|
|
91
101
|
test('getHelmMonomers', async () => {
|
|
92
102
|
const df: DG.DataFrame = DG.DataFrame.fromCsv(
|
|
@@ -2,6 +2,7 @@ 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
4
|
import {ALIGNMENT, ALPHABET, NOTATION, TAGS as bioTAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
5
|
+
import {awaitCheck} from '@datagrok-libraries/utils/src/test';
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
export function generateManySequences(): DG.Column[] {
|
|
@@ -23,13 +24,16 @@ export function generateLongSequence(): DG.Column[] {
|
|
|
23
24
|
return columns;
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
export function performanceTest(generateFunc: () => DG.Column[], testName: string) {
|
|
27
|
+
export async function performanceTest(generateFunc: () => DG.Column[], testName: string) {
|
|
27
28
|
const columns = generateFunc();
|
|
28
29
|
const df: DG.DataFrame = DG.DataFrame.fromColumns(columns);
|
|
29
|
-
grok.data.detectSemanticTypes(df);
|
|
30
|
+
await grok.data.detectSemanticTypes(df);
|
|
30
31
|
const startTime: number = Date.now();
|
|
31
32
|
const col: DG.Column = df.columns.byName('MSA');
|
|
32
|
-
grok.shell.addTableView(df);
|
|
33
|
+
const view: DG.TableView = grok.shell.addTableView(df);
|
|
34
|
+
|
|
35
|
+
await awaitCheck(() => { return view.grid.dataFrame !== df; },
|
|
36
|
+
'View grid has wrong data frame ', 100);
|
|
33
37
|
|
|
34
38
|
const endTime: number = Date.now();
|
|
35
39
|
const elapsedTime: number = endTime - startTime;
|
package/src/tests/viewers.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as DG from 'datagrok-api/dg';
|
|
|
2
2
|
import * as grok from 'datagrok-api/grok';
|
|
3
3
|
//import * as ui from 'datagrok-api/ui';
|
|
4
4
|
|
|
5
|
-
import {category,
|
|
5
|
+
import {category, test, testViewer} from '@datagrok-libraries/utils/src/test';
|
|
6
6
|
import {readDataframe} from './utils';
|
|
7
7
|
|
|
8
8
|
|
|
@@ -11,11 +11,7 @@ category('viewers', () => {
|
|
|
11
11
|
for (const v of viewers) {
|
|
12
12
|
test(v, async () => {
|
|
13
13
|
const df = await readDataframe('data/sample_FASTA_DNA.csv');
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
tv.addViewer(v);
|
|
17
|
-
await delay(2000);
|
|
18
|
-
// await testViewer(v, df, {detectSemanticTypes: true});
|
|
19
|
-
});
|
|
14
|
+
await testViewer(v, df, {detectSemanticTypes: true});
|
|
15
|
+
}, v === 'Sequence Similarity Search' ? {skipReason: 'GROK-13162'} : undefined);
|
|
20
16
|
}
|
|
21
17
|
});
|
|
@@ -88,11 +88,16 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
88
88
|
if (left !== null && left < seqMonList.length) {
|
|
89
89
|
const monomerSymbol: string = seqMonList[left];
|
|
90
90
|
const tooltipElements: HTMLElement[] = [ui.div(monomerSymbol)];
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
const
|
|
95
|
-
|
|
91
|
+
if (seqColTemp._monomerStructureMap[monomerSymbol]) {
|
|
92
|
+
tooltipElements.push(seqColTemp._monomerStructureMap[monomerSymbol]);
|
|
93
|
+
} else {
|
|
94
|
+
const monomer = seqColTemp.getMonomer(monomerSymbol);
|
|
95
|
+
if (monomer) {
|
|
96
|
+
const options = {autoCrop: true, autoCropMargin: 0, suppressChiralText: true};
|
|
97
|
+
const monomerSVG = grok.chem.svgMol(monomer.smiles, undefined, undefined, options);
|
|
98
|
+
tooltipElements.push(monomerSVG);
|
|
99
|
+
seqColTemp._monomerStructureMap[monomerSymbol] = monomerSVG;
|
|
100
|
+
}
|
|
96
101
|
}
|
|
97
102
|
ui.tooltip.show(ui.divV(tooltipElements), e.x + 16, e.y + 16);
|
|
98
103
|
} else {
|
|
@@ -122,7 +127,7 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
122
127
|
|
|
123
128
|
// TODO: Store temp data to GridColumn
|
|
124
129
|
// Now the renderer requires data frame table Column underlying GridColumn
|
|
125
|
-
const
|
|
130
|
+
const grid = gridCell.grid;
|
|
126
131
|
const tableCol: DG.Column = gridCell.cell.column;
|
|
127
132
|
const tableColTemp: TempType = tableCol.temp;
|
|
128
133
|
|
|
@@ -135,7 +140,7 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
135
140
|
|
|
136
141
|
let seqColTemp: MonomerPlacer = tableCol.temp[tempTAGS.bioSeqCol];
|
|
137
142
|
if (!seqColTemp) {
|
|
138
|
-
seqColTemp = new MonomerPlacer(
|
|
143
|
+
seqColTemp = new MonomerPlacer(grid, tableCol,
|
|
139
144
|
() => {
|
|
140
145
|
const uh = UnitsHandler.getOrCreate(tableCol);
|
|
141
146
|
return {
|
|
@@ -236,7 +241,7 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
236
241
|
/*x1 = */
|
|
237
242
|
printLeftOrCentered(x + this.padding, y, w, h,
|
|
238
243
|
g, amino, color, 0, true, 1.0, separator, last, drawStyle,
|
|
239
|
-
maxLengthWordsSum, index, gridCell, referenceSequence, maxLengthOfMonomer);
|
|
244
|
+
maxLengthWordsSum, index, gridCell, referenceSequence, maxLengthOfMonomer, seqColTemp._monomerLengthMap);
|
|
240
245
|
if (minDistanceRenderer > w) break;
|
|
241
246
|
}
|
|
242
247
|
} catch (err: any) {
|