@datagrok/bio 1.1.0 → 1.3.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/detectors.js +200 -1
- package/dist/package-test.js +3839 -3576
- package/dist/package.js +3445 -3131
- package/package.json +2 -2
- package/src/package-test.ts +7 -4
- package/src/package.ts +9 -0
- package/src/tests/{Palettes.test.ts → Palettes-test.ts} +2 -2
- package/src/tests/WebLogo-test.ts +127 -0
- package/src/tests/detectors-test.ts +135 -0
- package/src/viewers/vd-regions-viewer.ts +274 -0
- package/{test-Bio-3109311545e4-04060aee.html → test-Bio-ea88b3c1054c-d589d38a.html} +2 -2
- package/src/tests/WebLogo.test.ts +0 -132
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@datagrok/bio",
|
|
3
3
|
"beta": false,
|
|
4
4
|
"friendlyName": "Bio",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.3.0",
|
|
6
6
|
"description": "Bio is a [package](https://datagrok.ai/help/develop/develop#packages) for the [Datagrok](https://datagrok.ai) platform",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"directory": "packages/Bio"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@datagrok-libraries/bio": "^2.1.
|
|
13
|
+
"@datagrok-libraries/bio": "^2.1.1",
|
|
14
14
|
"@datagrok-libraries/utils": "^0.4.2",
|
|
15
15
|
"cash-dom": "latest",
|
|
16
16
|
"datagrok-api": "^1.3.5",
|
package/src/package-test.ts
CHANGED
|
@@ -2,17 +2,20 @@ import * as DG from 'datagrok-api/dg';
|
|
|
2
2
|
|
|
3
3
|
import {runTests, tests} from '@datagrok-libraries/utils/src/test';
|
|
4
4
|
|
|
5
|
-
import './tests/WebLogo
|
|
5
|
+
import './tests/WebLogo-test';
|
|
6
|
+
import './tests/Palettes-test';
|
|
7
|
+
import './tests/detectors-test';
|
|
6
8
|
|
|
7
9
|
export const _packageTest = new DG.Package();
|
|
8
10
|
export {tests};
|
|
9
11
|
|
|
12
|
+
/** For the 'test' function argument names are fixed as 'category' and 'test' because of way it is called. */
|
|
10
13
|
//name: test
|
|
11
14
|
//input: string category {optional: true}
|
|
12
|
-
//input: string
|
|
15
|
+
//input: string test {optional: true}
|
|
13
16
|
//output: dataframe result
|
|
14
17
|
//top-menu: Tools | Dev | JS API Tests
|
|
15
|
-
export async function test(category: string,
|
|
16
|
-
const data = await runTests({category, test
|
|
18
|
+
export async function test(category: string, test: string): Promise<DG.DataFrame> {
|
|
19
|
+
const data = await runTests({category, test});
|
|
17
20
|
return DG.DataFrame.fromObjects(data)!;
|
|
18
21
|
}
|
package/src/package.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {SequenceAlignment, Aligned} from './seq_align';
|
|
|
7
7
|
export const _package = new DG.Package();
|
|
8
8
|
|
|
9
9
|
import {WebLogo} from '@datagrok-libraries/bio/src/viewers/web-logo';
|
|
10
|
+
import {VdRegionsViewer} from './viewers/vd-regions-viewer';
|
|
10
11
|
|
|
11
12
|
//name: sequenceAlignment
|
|
12
13
|
//input: string alignType {choices: ['Local alignment', 'Global alignment']}
|
|
@@ -29,3 +30,11 @@ export function sequenceAlignment(alignType: string, alignTable: string, gap: nu
|
|
|
29
30
|
export function webLogoViewer() {
|
|
30
31
|
return new WebLogo();
|
|
31
32
|
}
|
|
33
|
+
|
|
34
|
+
//name: VdRegions
|
|
35
|
+
//description: V-Domain regions viewer
|
|
36
|
+
//tags: viewer, panel
|
|
37
|
+
//output: viewer result
|
|
38
|
+
export function vdRegionViewer() {
|
|
39
|
+
return new VdRegionsViewer();
|
|
40
|
+
}
|
|
@@ -7,6 +7,6 @@ import * as DG from 'datagrok-api/dg';
|
|
|
7
7
|
import {_testPaletteN, _testPaletteAA} from '@datagrok-libraries/bio/src/tests/palettes.test';
|
|
8
8
|
|
|
9
9
|
category('Palettes', () => {
|
|
10
|
-
test('testPaletteN', async () => { _testPaletteN(); });
|
|
11
|
-
test('testPaletteAA', async () => { _testPaletteAA(); });
|
|
10
|
+
test('testPaletteN', async () => { await _testPaletteN(); });
|
|
11
|
+
test('testPaletteAA', async () => { await _testPaletteAA(); });
|
|
12
12
|
});
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import {after, before, category, test, expect, expectObject} from '@datagrok-libraries/utils/src/test';
|
|
2
|
+
|
|
3
|
+
import * as grok from 'datagrok-api/grok';
|
|
4
|
+
import * as ui from 'datagrok-api/ui';
|
|
5
|
+
import * as DG from 'datagrok-api/dg';
|
|
6
|
+
|
|
7
|
+
import {Nucleotides, NucleotidesPalettes} from '@datagrok-libraries/bio/src/nucleotides';
|
|
8
|
+
import {Aminoacids, AminoacidsPalettes} from '@datagrok-libraries/bio/src/aminoacids';
|
|
9
|
+
import {WebLogo} from '@datagrok-libraries/bio/src/viewers/web-logo';
|
|
10
|
+
import {SeqPalette} from '@datagrok-libraries/bio/src/seq-palettes';
|
|
11
|
+
import {UnknownSeqPalette} from '@datagrok-libraries/bio/src/unknown';
|
|
12
|
+
|
|
13
|
+
category('WebLogo', () => {
|
|
14
|
+
const csvDfN1: string = `seq
|
|
15
|
+
ACGTCT
|
|
16
|
+
CAGTGT
|
|
17
|
+
TTCAAC
|
|
18
|
+
`;
|
|
19
|
+
|
|
20
|
+
/** 2 - is an error monomer
|
|
21
|
+
* This sequence set should be classified as nucleotides sequences.
|
|
22
|
+
* Small error, not similar to amino acids.
|
|
23
|
+
*/
|
|
24
|
+
const csvDfN1e: string = `seq
|
|
25
|
+
ACGTAT
|
|
26
|
+
CAGTTG
|
|
27
|
+
TTCG2C
|
|
28
|
+
`;
|
|
29
|
+
|
|
30
|
+
/** Pure amino acids sequence */
|
|
31
|
+
const csvDfAA1: string = `seq
|
|
32
|
+
FWPHEYV
|
|
33
|
+
YNRQWYV
|
|
34
|
+
MKPSEYV
|
|
35
|
+
`;
|
|
36
|
+
|
|
37
|
+
/** A - alanine, G - glycine, T -= threonine, C - cysteine, W - tryptophan
|
|
38
|
+
* This sequence set should be detected as amino acids more than nucleotides.
|
|
39
|
+
*/
|
|
40
|
+
const csvDfAA2: string = `seq
|
|
41
|
+
AGTCAT
|
|
42
|
+
AGTCGC
|
|
43
|
+
AGTCATW
|
|
44
|
+
`;
|
|
45
|
+
|
|
46
|
+
/** This sequence set should be recognized as unknown. */
|
|
47
|
+
const csvDfX: string = `seq
|
|
48
|
+
XZJ{}2
|
|
49
|
+
5Z4733
|
|
50
|
+
3Z6></
|
|
51
|
+
675687
|
|
52
|
+
`;
|
|
53
|
+
|
|
54
|
+
// anonymous functions specified in test() registering must return Promise<any>
|
|
55
|
+
test('testGetAlphabetSimilarity', async () => { await _testGetAlphabetSimilarity(); });
|
|
56
|
+
|
|
57
|
+
test('testPickupPaletteN1', async () => { await _testPickupPaletteN1(csvDfN1); });
|
|
58
|
+
test('testPickupPaletteN1e', async () => { await _testPickupPaletteN1e(csvDfN1e); });
|
|
59
|
+
test('testPickupPaletteAA1', async () => { await _testPickupPaletteAA1(csvDfAA1); });
|
|
60
|
+
test('testPickupPaletteX', async () => { await _testPickupPaletteX(csvDfX); });
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
export async function _testGetAlphabetFreqs(dfN1: DG.DataFrame) {
|
|
65
|
+
const seqCol: DG.Column = dfN1.col('seq')!;
|
|
66
|
+
const mFreq = WebLogo.getAlphabetFreqs(seqCol);
|
|
67
|
+
|
|
68
|
+
expectObject(mFreq, {
|
|
69
|
+
'A': 4,
|
|
70
|
+
'C': 5,
|
|
71
|
+
'G': 3,
|
|
72
|
+
'T': 6
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export async function _testGetAlphabetSimilarity() {
|
|
77
|
+
const freq: { [m: string]: number } = {
|
|
78
|
+
'A': 2041,
|
|
79
|
+
'C': 3015,
|
|
80
|
+
'G': 3015,
|
|
81
|
+
'T': 2048,
|
|
82
|
+
'-': 1000
|
|
83
|
+
};
|
|
84
|
+
const alphabet: Set<string> = new Set(Object.keys(Nucleotides.Names));
|
|
85
|
+
const res = WebLogo.getAlphabetSimilarity(freq, alphabet);
|
|
86
|
+
|
|
87
|
+
expect(res > 0.6, true);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export async function _testPickupPaletteN1(csvDfN1: string) {
|
|
91
|
+
const df: DG.DataFrame = DG.DataFrame.fromCsv(csvDfN1);
|
|
92
|
+
const col: DG.Column = df.col('seq')!;
|
|
93
|
+
const cp = WebLogo.pickUpPalette(col);
|
|
94
|
+
|
|
95
|
+
expect(cp instanceof NucleotidesPalettes, true);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export async function _testPickupPaletteN1e(csvDfN1e: string) {
|
|
99
|
+
const df: DG.DataFrame = DG.DataFrame.fromCsv(csvDfN1e);
|
|
100
|
+
const col: DG.Column = df.col('seq')!;
|
|
101
|
+
const cp = WebLogo.pickUpPalette(col);
|
|
102
|
+
|
|
103
|
+
expect(cp instanceof NucleotidesPalettes, true);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export async function _testPickupPaletteAA1(csvDfAA1: string) {
|
|
107
|
+
const df: DG.DataFrame = DG.DataFrame.fromCsv(csvDfAA1);
|
|
108
|
+
const col: DG.Column = df.col('seq')!;
|
|
109
|
+
const cp = WebLogo.pickUpPalette(col);
|
|
110
|
+
|
|
111
|
+
expect(cp instanceof AminoacidsPalettes, true);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export async function _testPickupPaletteX(csvDfX: string) {
|
|
115
|
+
const df: DG.DataFrame = DG.DataFrame.fromCsv(csvDfX);
|
|
116
|
+
const col: DG.Column = df.col('seq')!;
|
|
117
|
+
const cp = WebLogo.pickUpPalette(col);
|
|
118
|
+
|
|
119
|
+
expect(cp instanceof UnknownSeqPalette, true);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export async function _testPickupPaletteAA2(dfAA2: DG.DataFrame) {
|
|
123
|
+
const seqCol: DG.Column = dfAA2.col('seq')!;
|
|
124
|
+
const cp = WebLogo.pickUpPalette(seqCol);
|
|
125
|
+
|
|
126
|
+
expect(cp instanceof AminoacidsPalettes, true);
|
|
127
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import {after, before, category, test, expect, expectObject} from '@datagrok-libraries/utils/src/test';
|
|
2
|
+
|
|
3
|
+
import * as grok from 'datagrok-api/grok';
|
|
4
|
+
import * as ui from 'datagrok-api/ui';
|
|
5
|
+
import * as DG from 'datagrok-api/dg';
|
|
6
|
+
|
|
7
|
+
category('detectors', () => {
|
|
8
|
+
const csvDfN1: string = `seq
|
|
9
|
+
ACGTC
|
|
10
|
+
CAGTGT
|
|
11
|
+
TTCAAC
|
|
12
|
+
`;
|
|
13
|
+
|
|
14
|
+
/** Pure amino acids sequence */
|
|
15
|
+
const csvDfAA1: string = `seq
|
|
16
|
+
FWPHEY
|
|
17
|
+
YNRQWYV
|
|
18
|
+
MKPSEYV
|
|
19
|
+
`;
|
|
20
|
+
|
|
21
|
+
const csvDfSepNt: string = `seq
|
|
22
|
+
A*C*G*T*C
|
|
23
|
+
C*A*G*T*G*T
|
|
24
|
+
T*T*C*A*A*C
|
|
25
|
+
`;
|
|
26
|
+
|
|
27
|
+
const csvDfSepPt: string = `seq
|
|
28
|
+
F-W-P-H-E-Y
|
|
29
|
+
Y-N-R-Q-W-Y-V
|
|
30
|
+
M-K-P-S-E-Y-V
|
|
31
|
+
`;
|
|
32
|
+
|
|
33
|
+
const csvDfSepUn1: string = `seq
|
|
34
|
+
abc-dfgg-abc1-cfr3-rty-wert
|
|
35
|
+
rut12-her2-rty-wert-abc-abc1-dfgg
|
|
36
|
+
rut12-rty-her2-abc-cfr3-wert-rut12
|
|
37
|
+
`;
|
|
38
|
+
|
|
39
|
+
const csvDfSepUn2: string = `seq
|
|
40
|
+
abc/dfgg/abc1/cfr3/rty/wert
|
|
41
|
+
rut12/her2/rty/wert//abc/abc1/dfgg
|
|
42
|
+
rut12/rty/her2/abc/cfr3//wert/rut12
|
|
43
|
+
`;
|
|
44
|
+
|
|
45
|
+
const csvDfSepMsaN1: string = `seq
|
|
46
|
+
A-C--G-T--C-T
|
|
47
|
+
C-A-C--T--G-T
|
|
48
|
+
A-C-C-G-T-A-C-T
|
|
49
|
+
`;
|
|
50
|
+
|
|
51
|
+
const csvDfMsaN1: string = `seq
|
|
52
|
+
AC-GT-CT
|
|
53
|
+
CAC-T-GT
|
|
54
|
+
ACCGTACT
|
|
55
|
+
`;
|
|
56
|
+
|
|
57
|
+
const csvDfMsaAA1: string = `seq
|
|
58
|
+
FWR-WYV-KHP
|
|
59
|
+
YNR-WYV-KHP
|
|
60
|
+
MWRSWY-CKHP
|
|
61
|
+
`;
|
|
62
|
+
|
|
63
|
+
test('testDetectorsN1', async () => { await _testDetectorsN1(csvDfN1); });
|
|
64
|
+
test('testDetectorsAA1', async () => { await _testDetectorsAA1(csvDfAA1); });
|
|
65
|
+
test('testDetectorsMsaN1', async () => { await _testDetectorsMsaN1(csvDfMsaN1); });
|
|
66
|
+
test('testDetectorsMsaAA1', async () => { await _testDetectorsMsaAA1(csvDfMsaAA1); });
|
|
67
|
+
|
|
68
|
+
test('testDetectorsSepUn1', async () => { await _testDetectorsSepUn1(csvDfSepUn1); });
|
|
69
|
+
test('testDetectorsSepUn2', async () => { await _testDetectorsSepUn2(csvDfSepUn2); });
|
|
70
|
+
|
|
71
|
+
test('testDetectorsSepMsaN1', async () => { await _testDetectorsSepMsaN1(csvDfSepMsaN1); });
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
export async function _testDetectorsN1(csvDfN1: string) {
|
|
75
|
+
const dfN1: DG.DataFrame = DG.DataFrame.fromCsv(csvDfN1);
|
|
76
|
+
await grok.data.detectSemanticTypes(dfN1);
|
|
77
|
+
|
|
78
|
+
const col: DG.Column = dfN1.col('seq')!;
|
|
79
|
+
expect(col.semType, 'MACROMOLECULE');
|
|
80
|
+
expect(col.getTag(DG.TAGS.UNITS), 'fasta:SEQ:NT');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export async function _testDetectorsAA1(csvDfAA1: string) {
|
|
84
|
+
const dfAA1: DG.DataFrame = DG.DataFrame.fromCsv(csvDfAA1);
|
|
85
|
+
await grok.data.detectSemanticTypes(dfAA1);
|
|
86
|
+
|
|
87
|
+
const col: DG.Column = dfAA1.col('seq')!;
|
|
88
|
+
expect(col.semType, 'MACROMOLECULE');
|
|
89
|
+
expect(col.getTag(DG.TAGS.UNITS), 'fasta:SEQ:PT');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export async function _testDetectorsMsaN1(csvDfMsaN1: string) {
|
|
93
|
+
const dfMsaN1: DG.DataFrame = DG.DataFrame.fromCsv(csvDfMsaN1);
|
|
94
|
+
await grok.data.detectSemanticTypes(dfMsaN1);
|
|
95
|
+
|
|
96
|
+
const col: DG.Column = dfMsaN1.col('seq')!;
|
|
97
|
+
expect(col.semType, 'MACROMOLECULE');
|
|
98
|
+
expect(col.getTag(DG.TAGS.UNITS), 'fasta:SEQ.MSA:NT');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export async function _testDetectorsMsaAA1(csvDfMsaAA1: string) {
|
|
102
|
+
const dfMsaAA1: DG.DataFrame = DG.DataFrame.fromCsv(csvDfMsaAA1);
|
|
103
|
+
await grok.data.detectSemanticTypes(dfMsaAA1);
|
|
104
|
+
|
|
105
|
+
const col: DG.Column = dfMsaAA1.col('seq')!;
|
|
106
|
+
expect(col.semType, 'MACROMOLECULE');
|
|
107
|
+
expect(col.getTag(DG.TAGS.UNITS), 'fasta:SEQ.MSA:PT');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export async function _testDetectorsSepUn1(csvDfSepUn1: string) {
|
|
111
|
+
const dfSepUn1: DG.DataFrame = DG.DataFrame.fromCsv(csvDfSepUn1);
|
|
112
|
+
await grok.data.detectSemanticTypes(dfSepUn1);
|
|
113
|
+
|
|
114
|
+
const col: DG.Column = dfSepUn1.col('seq')!;
|
|
115
|
+
expect(col.semType, 'MACROMOLECULE');
|
|
116
|
+
expect(col.getTag(DG.TAGS.UNITS), 'separator:SEQ:UN');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export async function _testDetectorsSepUn2(csvDfSepUn2: string) {
|
|
120
|
+
const dfSepUn2: DG.DataFrame = DG.DataFrame.fromCsv(csvDfSepUn2);
|
|
121
|
+
await grok.data.detectSemanticTypes(dfSepUn2);
|
|
122
|
+
|
|
123
|
+
const col: DG.Column = dfSepUn2.col('seq')!;
|
|
124
|
+
expect(col.semType, 'MACROMOLECULE');
|
|
125
|
+
expect(col.getTag(DG.TAGS.UNITS), 'separator:SEQ:UN');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export async function _testDetectorsSepMsaN1(csvDfSepMsaN1: string) {
|
|
129
|
+
const dfSepMsaN1: DG.DataFrame = DG.DataFrame.fromCsv(csvDfSepMsaN1);
|
|
130
|
+
await grok.data.detectSemanticTypes(dfSepMsaN1);
|
|
131
|
+
|
|
132
|
+
const col: DG.Column = dfSepMsaN1.col('seq')!;
|
|
133
|
+
expect(col.semType, 'MACROMOLECULE');
|
|
134
|
+
expect(col.getTag(DG.TAGS.UNITS), 'separator:SEQ.MSA:NT');
|
|
135
|
+
}
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import * as ui from 'datagrok-api/ui';
|
|
2
|
+
import * as grok from 'datagrok-api/grok';
|
|
3
|
+
import * as DG from 'datagrok-api/dg';
|
|
4
|
+
|
|
5
|
+
import {VdRegionType, VdRegion} from '@datagrok-libraries/bio/src/vd-regions';
|
|
6
|
+
import {WebLogo} from '@datagrok-libraries/bio/src/viewers/web-logo';
|
|
7
|
+
|
|
8
|
+
const vrt = VdRegionType;
|
|
9
|
+
|
|
10
|
+
// Positions of regions for numbering schemes
|
|
11
|
+
// http://www.bioinf.org.uk/abs/info.html
|
|
12
|
+
|
|
13
|
+
// const imgtRegions: VdRegion[] = [
|
|
14
|
+
// new VdRegion(vrt.FR, 'FR1', 'Light', 1, '1', '26'),
|
|
15
|
+
// new VdRegion(vrt.FR, 'FR1', 'Heavy', 1, '1', '26'),
|
|
16
|
+
//
|
|
17
|
+
// new VdRegion(vrt.CDR, 'CDR1', 'Light', 2, '27', '38'), // 27-32
|
|
18
|
+
// new VdRegion(vrt.CDR, 'CDR1', 'Heavy', 2, '27', '38'), // 27-32
|
|
19
|
+
//
|
|
20
|
+
// new VdRegion(vrt.FR, 'FR2', 'Light', 3, '39', '55'),
|
|
21
|
+
// new VdRegion(vrt.FR, 'FR2', 'Heavy', 3, '39', '55'),
|
|
22
|
+
//
|
|
23
|
+
// new VdRegion(vrt.CDR, 'CDR2', 'Light', 4, '56', '65'),
|
|
24
|
+
// new VdRegion(vrt.CDR, 'CDR2', 'Heavy', 4, '56', '65'),
|
|
25
|
+
//
|
|
26
|
+
// new VdRegion(vrt.FR, 'FR3', 'Light', 5, '66', '104'),
|
|
27
|
+
// new VdRegion(vrt.FR, 'FR3', 'Heavy', 5, '66', '104'),
|
|
28
|
+
//
|
|
29
|
+
// new VdRegion(vrt.CDR, 'CDR3', 'Light', 6, '105', '117'),
|
|
30
|
+
// new VdRegion(vrt.CDR, 'CDR3', 'Heavy', 6, '105', '117'),
|
|
31
|
+
//
|
|
32
|
+
// new VdRegion(vrt.FR, 'FR4', 'Light', 7, '118', null/*127*/),
|
|
33
|
+
// new VdRegion(vrt.FR, 'FR4', 'Heavy', 7, '118', null/*128*/),
|
|
34
|
+
// ];
|
|
35
|
+
|
|
36
|
+
/** Viewer with tabs based on description of chain regions.
|
|
37
|
+
* Used to define regions of an immunoglobulin LC.
|
|
38
|
+
*/
|
|
39
|
+
export class VdRegionsViewer extends DG.JsViewer {
|
|
40
|
+
// private regionsDf: DG.DataFrame;
|
|
41
|
+
private regionsFg: DG.FilterGroup | null = null;
|
|
42
|
+
// private regionsTV: DG.TableView;
|
|
43
|
+
private regionsRoot: HTMLElement | null = null;
|
|
44
|
+
|
|
45
|
+
private isOpened: boolean = false;
|
|
46
|
+
private panelNode: DG.DockNode | null = null;
|
|
47
|
+
|
|
48
|
+
public regions: VdRegion[] = [];
|
|
49
|
+
public regionTypes: string[];
|
|
50
|
+
public chains: string[];
|
|
51
|
+
public sequenceColumnNamePostfix: string;
|
|
52
|
+
|
|
53
|
+
public get df(): DG.DataFrame {
|
|
54
|
+
return this.dataFrame;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// TODO: .onTableAttached is not calling on dataFrame set, onPropertyChanged also not calling
|
|
58
|
+
public async setDf(value: DG.DataFrame, regions: VdRegion[]) {
|
|
59
|
+
console.debug('VdRegionsViewer.setDf()');
|
|
60
|
+
await this.destroyView();
|
|
61
|
+
this.regions = regions;
|
|
62
|
+
this.dataFrame = value;
|
|
63
|
+
await this.buildView();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
constructor() {
|
|
67
|
+
super();
|
|
68
|
+
|
|
69
|
+
// To prevent ambiguous numbering scheme in MLB
|
|
70
|
+
this.regionTypes = this.stringList('regionTypes', [vrt.CDR],
|
|
71
|
+
{choices: Object.values(vrt).filter((t) => t != vrt.Unknown)});
|
|
72
|
+
this.chains = this.stringList('chains', ['Heavy', 'Light'],
|
|
73
|
+
{choices: ['Heavy', 'Light']});
|
|
74
|
+
this.sequenceColumnNamePostfix = this.string('sequenceColumnNamePostfix', 'chain sequence');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
public async init() {
|
|
78
|
+
//#region regionsDF with filter
|
|
79
|
+
// this.regionsDf = DG.DataFrame.fromObjects(this.regions);
|
|
80
|
+
// this.regionsDf.rows.filter((row) => row.name == 'CDR1');
|
|
81
|
+
// // To available options /
|
|
82
|
+
// this.regionsFg = (await this.regionsDf.plot.fromType(DG.VIEWER.FILTERS, {
|
|
83
|
+
// // columnNames: ['name',],
|
|
84
|
+
// showFilterCountsIndication: false,
|
|
85
|
+
// showHeader: false,
|
|
86
|
+
// showSearchBox: false,
|
|
87
|
+
// filters: [
|
|
88
|
+
// {type: DG.FILTER_TYPE.CATEGORICAL, column: 'type', label: 'Region name', showHistogram: false},
|
|
89
|
+
// {type: DG.FILTER_TYPE.CATEGORICAL, column: 'name', label: 'Region type', showHistogram: false},
|
|
90
|
+
// ],
|
|
91
|
+
// title: 'Regions filter',
|
|
92
|
+
// showTitle: true,
|
|
93
|
+
// description: 'Filter for regions of multiple alignment by IMGT nomenclature',
|
|
94
|
+
// someProperty: 'Hello',
|
|
95
|
+
// })) as DG.FilterGroup;
|
|
96
|
+
|
|
97
|
+
//#endregion regionsDF with filter
|
|
98
|
+
|
|
99
|
+
// this.mlbView.dockManager.dock(this.regionsFg.root, DG.DOCK_TYPE.LEFT, rootNode, 'Filter regions', 0.2);
|
|
100
|
+
|
|
101
|
+
this.subs.push(ui.onSizeChanged(this.root).subscribe(this.rootOnSizeChanged.bind(this)));
|
|
102
|
+
// rxjs.fromEvent(this.root, 'mousemove').subscribe(this.onMouseMoveRoot.bind(this));
|
|
103
|
+
this.root.addEventListener('mousemove', this.onMouseMoveRoot.bind(this));
|
|
104
|
+
|
|
105
|
+
await this.buildView();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
public override async onTableAttached() {
|
|
109
|
+
await this.init();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
public override async onPropertyChanged(property: DG.Property | null) {
|
|
113
|
+
super.onPropertyChanged(property);
|
|
114
|
+
if (property) {
|
|
115
|
+
switch (property.name) {
|
|
116
|
+
case 'regionTypes':
|
|
117
|
+
break;
|
|
118
|
+
case 'chains':
|
|
119
|
+
break;
|
|
120
|
+
case 'sequenceColumnNamePostfix':
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
public async reset() {
|
|
128
|
+
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
public async open(mlbView: DG.TableView) {
|
|
132
|
+
if (!this.isOpened) {
|
|
133
|
+
this.isOpened = true;
|
|
134
|
+
this.panelNode = mlbView.dockManager.dock(this.root, DG.DOCK_TYPE.TOP, null, 'Regions', 0.2);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
public async show(mlbView: DG.TableView) {
|
|
139
|
+
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// #region -- Handle controls' events --
|
|
143
|
+
|
|
144
|
+
private resizing: boolean = false;
|
|
145
|
+
|
|
146
|
+
private rootOnSizeChanged(args: any): void {
|
|
147
|
+
this.calcSize();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// #endregion
|
|
151
|
+
|
|
152
|
+
//#region -- View --
|
|
153
|
+
private host: HTMLElement | null = null;
|
|
154
|
+
private mainLayout: HTMLTableElement | null = null;
|
|
155
|
+
private logos: { [chain: string]: WebLogo }[] = [];
|
|
156
|
+
|
|
157
|
+
private async destroyView(): Promise<void> {
|
|
158
|
+
// TODO: Unsubscribe from and remove all view elements
|
|
159
|
+
console.debug(`VdRegionsViewer.destroyView( mainLayout = ${!this.mainLayout ? 'none' : 'value'} )`);
|
|
160
|
+
if (this.mainLayout != null) {
|
|
161
|
+
// this.root.removeChild(this.host);
|
|
162
|
+
this.mainLayout.remove();
|
|
163
|
+
this.host!.remove();
|
|
164
|
+
this.host = null;
|
|
165
|
+
this.mainLayout = null;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
private async buildView(): Promise<void> {
|
|
170
|
+
console.debug('VdRegionsViewer.buildView() start');
|
|
171
|
+
|
|
172
|
+
const colNames: { [chain: string]: string } = Object.assign({},
|
|
173
|
+
...this.chains.map((chain) => ({[chain]: `${chain} ${this.sequenceColumnNamePostfix}`})));
|
|
174
|
+
|
|
175
|
+
const regionsFiltered: VdRegion[] = this.regions.filter((r: VdRegion) => this.regionTypes.includes(r.type));
|
|
176
|
+
|
|
177
|
+
const orderList: number[] = Array.from(new Set(regionsFiltered.map((r) => r.order))).sort();
|
|
178
|
+
|
|
179
|
+
this.logos = [];
|
|
180
|
+
|
|
181
|
+
for (let orderI = 0; orderI < orderList.length; orderI++) {
|
|
182
|
+
const regionChains: { [chain: string]: WebLogo } = {};
|
|
183
|
+
for (const chain of this.chains) {
|
|
184
|
+
const region: VdRegion | undefined = regionsFiltered
|
|
185
|
+
.find((r) => r.order == orderList[orderI] && r.chain == chain);
|
|
186
|
+
regionChains[chain] = (await this.dataFrame.plot.fromType('WebLogo', {
|
|
187
|
+
sequenceColumnName: colNames[chain],
|
|
188
|
+
startPositionName: region!.positionStartName,
|
|
189
|
+
endPositionName: region!.positionEndName,
|
|
190
|
+
fixWidth: true,
|
|
191
|
+
})) as unknown as WebLogo;
|
|
192
|
+
}
|
|
193
|
+
// WebLogo creation fires onRootSizeChanged event even before control being added to this.logos
|
|
194
|
+
this.logos[orderI] = regionChains;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// ui.tableFromMap()
|
|
198
|
+
// DG.HtmlTable.create()
|
|
199
|
+
this.mainLayout = ui.table(
|
|
200
|
+
this.chains,
|
|
201
|
+
(chain) => {
|
|
202
|
+
const elements = [
|
|
203
|
+
// This is chain label
|
|
204
|
+
...(orderList.length > 0 ? [ui.div(chain, {
|
|
205
|
+
style: {
|
|
206
|
+
transform: 'rotate(-90deg)',
|
|
207
|
+
font: '12px Roboto, Roboto Local, sans-serif',
|
|
208
|
+
textAlign: 'center',
|
|
209
|
+
width: '16px',
|
|
210
|
+
marginTop: '24px',
|
|
211
|
+
marginLeft: '6px',
|
|
212
|
+
}
|
|
213
|
+
})] : []),
|
|
214
|
+
// List with controls for regions
|
|
215
|
+
...[...Array(orderList.length).keys()].map((orderI) => {
|
|
216
|
+
const wl: WebLogo = this.logos[orderI][chain];
|
|
217
|
+
wl.root.style.height = '100%';
|
|
218
|
+
|
|
219
|
+
const resDiv = ui.div([wl.root]/*`${chain} ${regionsFiltered[rI]}`*/, {
|
|
220
|
+
style: {
|
|
221
|
+
// height: '100%',
|
|
222
|
+
marginTop: '4px',
|
|
223
|
+
marginBottom: '4px',
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
return resDiv;
|
|
228
|
+
})];
|
|
229
|
+
return elements;
|
|
230
|
+
},
|
|
231
|
+
['', ...[...Array(orderList.length).keys()].map(
|
|
232
|
+
(orderI: number) => regionsFiltered.find(
|
|
233
|
+
(r: VdRegion) => r.order == orderList[orderI] && r.chain == this.chains[0]
|
|
234
|
+
)!.name || 'Name')]
|
|
235
|
+
);
|
|
236
|
+
this.mainLayout.className = 'mlb-vd-regions-viewer-table2';
|
|
237
|
+
// this.mainLayout.style.background = '#EEEEFF';
|
|
238
|
+
// this.mainLayout.style.height = '100%';
|
|
239
|
+
// this.mainLayout.style.border = '1px solid black';
|
|
240
|
+
|
|
241
|
+
const color: string = `#ffbb${Math.ceil(Math.random() * 255).toString(16)}`;
|
|
242
|
+
this.host = ui.box(this.mainLayout,
|
|
243
|
+
{/*style: {backgroundColor: color}*/});
|
|
244
|
+
this.root.appendChild(this.host);
|
|
245
|
+
this.root.style.overflowX = 'auto';
|
|
246
|
+
|
|
247
|
+
this.calcSize();
|
|
248
|
+
|
|
249
|
+
console.debug('VdRegionsViewer.buildView() end');
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
private calcSize() {
|
|
253
|
+
const logoHeight = (this.root.clientHeight - 54) / this.chains.length;
|
|
254
|
+
|
|
255
|
+
const maxHeight: number = Math.min(logoHeight,
|
|
256
|
+
Math.max(...this.logos.map((wlDict) =>
|
|
257
|
+
Math.max(...Object.values(wlDict).map((wl) => wl.maxHeight))))
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
for (let orderI = 0; orderI < this.logos.length; orderI++) {
|
|
261
|
+
for (let chainI = 0; chainI < this.chains.length; chainI++) {
|
|
262
|
+
const chain: string = this.chains[chainI];
|
|
263
|
+
this.logos[orderI][chain].root.style.height = `${maxHeight}px`;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
//#endregion -- View --
|
|
269
|
+
|
|
270
|
+
private onMouseMoveRoot(e: MouseEvent) {
|
|
271
|
+
// ui.tooltip.show('text', e.x + 8, e.y + 8,);
|
|
272
|
+
// console.log(`onMouseMoveRoot.( x: ${e.x}, y: ${e.y} )`);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<html><head><meta charset="utf-8"/><title>Bio Test Report. Datagrok version datagrok/datagrok:latest SHA=
|
|
1
|
+
<html><head><meta charset="utf-8"/><title>Bio Test Report. Datagrok version datagrok/datagrok:latest SHA=ea88b3c1054c. Commit d589d38a.</title><style type="text/css">html,
|
|
2
2
|
body {
|
|
3
3
|
font-family: Arial, Helvetica, sans-serif;
|
|
4
4
|
font-size: 1rem;
|
|
@@ -229,7 +229,7 @@ header {
|
|
|
229
229
|
font-size: 1rem;
|
|
230
230
|
padding: 0 0.5rem;
|
|
231
231
|
}
|
|
232
|
-
</style></head><body><div id="jesthtml-content"><header><h1 id="title">Bio Test Report. Datagrok version datagrok/datagrok:latest SHA=
|
|
232
|
+
</style></head><body><div id="jesthtml-content"><header><h1 id="title">Bio Test Report. Datagrok version datagrok/datagrok:latest SHA=ea88b3c1054c. Commit d589d38a.</h1></header><div id="metadata-container"><div id="timestamp">Started: 2022-06-28 11:54:32</div><div id="summary"><div id="suite-summary"><div class="summary-total">Suites (1)</div><div class="summary-passed">1 passed</div><div class="summary-failed summary-empty">0 failed</div><div class="summary-pending summary-empty">0 pending</div></div><div id="test-summary"><div class="summary-total">Tests (1)</div><div class="summary-passed">1 passed</div><div class="summary-failed summary-empty">0 failed</div><div class="summary-pending summary-empty">0 pending</div></div></div></div><div id="suite-1" class="suite-container"><div class="suite-info"><div class="suite-path">/home/runner/work/public/public/packages/Bio/src/__jest__/remote.test.ts</div><div class="suite-time warn">40.832s</div></div><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename"> </div><div class="test-title">TEST</div><div class="test-status">passed</div><div class="test-duration">28.874s</div></div></div></div><div class="suite-consolelog"><div class="suite-consolelog-header">Console Log</div><div class="suite-consolelog-item"><pre class="suite-consolelog-item-origin"> at Object.<anonymous> (/home/runner/work/public/public/packages/Bio/src/__jest__/test-node.ts:63:11)
|
|
233
233
|
at Generator.next (<anonymous>)
|
|
234
234
|
at fulfilled (/home/runner/work/public/public/packages/Bio/src/__jest__/test-node.ts:28:58)
|
|
235
235
|
at processTicksAndRejections (internal/process/task_queues.js:97:5)</pre><pre class="suite-consolelog-item-message">Using web root: http://localhost:8080</pre></div><div class="suite-consolelog-item"><pre class="suite-consolelog-item-origin"> at /home/runner/work/public/public/packages/Bio/src/__jest__/remote.test.ts:24:11
|