@datagrok/bio 1.6.0 → 1.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/detectors.js +1 -1
- package/dist/package-test.js +147 -123
- package/dist/package.js +104 -117
- package/files/samples/sample_FASTA_DNA.csv +101 -0
- package/files/samples/sample_FASTA_PT.csv +101 -0
- package/files/samples/sample_FASTA_RNA.csv +101 -0
- package/files/{samples → tests}/peptides_complex_msa.csv +0 -0
- package/files/{samples → tests}/peptides_simple_msa.csv +0 -0
- package/files/{samples/testSmiles.csv → tests/sar-small.csv} +0 -0
- package/files/{samples → tests}/testDemog.csv +0 -0
- package/files/{samples → tests}/testHelm.csv +0 -0
- package/files/{samples → tests}/testId.csv +0 -0
- package/files/tests/testSmiles.csv +201 -0
- package/files/{samples → tests}/testSmiles2.csv +0 -0
- package/package.json +2 -2
- package/scripts/generate_fasta_csv_for_alphabets.R +70 -0
- package/src/package.ts +19 -1
- package/src/tests/convert-test.ts +41 -0
- package/src/tests/detectors-test.ts +12 -6
- package/src/utils/cell-renderer.ts +48 -48
- package/src/utils/multiple-sequence-alignment.ts +0 -1
- package/src/utils/notation-converter.ts +51 -98
- package/{test-Bio-34f75e5127b8-95c6fae9.html → test-Bio-34f75e5127b8-ac96da52.html} +2 -2
|
@@ -22,6 +22,10 @@ category('converters', () => {
|
|
|
22
22
|
fastaRna = 'fastaRna',
|
|
23
23
|
separatorRna = 'separatorRna',
|
|
24
24
|
helmRna = 'helmRna',
|
|
25
|
+
|
|
26
|
+
fastaGaps = 'fastaGaps',
|
|
27
|
+
separatorGaps = 'separatorGaps',
|
|
28
|
+
helmGaps = 'helmGaps'
|
|
25
29
|
}
|
|
26
30
|
|
|
27
31
|
const _csvTxts: { [key: string]: string } = {
|
|
@@ -69,6 +73,24 @@ U*U*C*A*A*C
|
|
|
69
73
|
RNA1{R(A)P.R(C)P.R(G)P.R(U)P.R(C)P}$$$
|
|
70
74
|
RNA1{R(C)P.R(A)P.R(G)P.R(U)P.R(G)P.R(U)P}$$$
|
|
71
75
|
RNA1{R(U)P.R(U)P.R(C)P.R(A)P.R(A)P.R(C)P}$$$
|
|
76
|
+
`,
|
|
77
|
+
|
|
78
|
+
fastaGaps: `seq
|
|
79
|
+
FW-PH-EY
|
|
80
|
+
-YNRQWYV-
|
|
81
|
+
MKP---SEYV
|
|
82
|
+
`,
|
|
83
|
+
|
|
84
|
+
separatorGaps: `seq
|
|
85
|
+
F/W//P/H//E/Y
|
|
86
|
+
//Y/N/R/Q/W/Y/V//
|
|
87
|
+
M/K/P////S/E/Y/V
|
|
88
|
+
`,
|
|
89
|
+
|
|
90
|
+
helmGaps: `seq
|
|
91
|
+
PEPTIDE1{F.W.*.P.H.*.E.Y}$$$
|
|
92
|
+
PEPTIDE1{*.Y.N.R.Q.W.Y.V.*}$$$
|
|
93
|
+
PEPTIDE1{M.K.P.*.*.*.S.E.Y.V}$$$
|
|
72
94
|
`,
|
|
73
95
|
};
|
|
74
96
|
|
|
@@ -110,6 +132,7 @@ RNA1{R(U)P.R(U)P.R(C)P.R(A)P.R(A)P.R(C)P}$$$
|
|
|
110
132
|
expectArray(resCol.toList(), tgtCol.toList());
|
|
111
133
|
}
|
|
112
134
|
|
|
135
|
+
// FASTA tests
|
|
113
136
|
test('testFastaPtToSeparator', async () => {
|
|
114
137
|
await _testConvert(Samples.fastaPt, converter(NOTATION.SEPARATOR, '-'), Samples.separatorPt);
|
|
115
138
|
});
|
|
@@ -130,6 +153,15 @@ RNA1{R(U)P.R(U)P.R(C)P.R(A)P.R(A)P.R(C)P}$$$
|
|
|
130
153
|
await _testConvert(Samples.fastaRna, converter(NOTATION.HELM), Samples.helmRna);
|
|
131
154
|
});
|
|
132
155
|
|
|
156
|
+
test('testFastaGapsToSeparator', async () => {
|
|
157
|
+
await _testConvert(Samples.fastaGaps, converter(NOTATION.SEPARATOR, '/'), Samples.separatorGaps);
|
|
158
|
+
});
|
|
159
|
+
test('testFastaGapsToHelm', async () => {
|
|
160
|
+
await _testConvert(Samples.fastaGaps, converter(NOTATION.SEPARATOR), Samples.helmGaps);
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
// SEPARATOR tests
|
|
133
165
|
test('testSeparatorPtToFasta', async () => {
|
|
134
166
|
await _testConvert(Samples.separatorPt, converter(NOTATION.FASTA), Samples.fastaPt);
|
|
135
167
|
});
|
|
@@ -149,4 +181,13 @@ RNA1{R(U)P.R(U)P.R(C)P.R(A)P.R(A)P.R(C)P}$$$
|
|
|
149
181
|
test('testSeparatorRnaToHelm', async () => {
|
|
150
182
|
await _testConvert(Samples.separatorRna, converter(NOTATION.HELM), Samples.helmRna);
|
|
151
183
|
});
|
|
184
|
+
test('testSeparatorGapsToFasta', async () => {
|
|
185
|
+
await _testConvert(Samples.separatorGaps, converter(NOTATION.FASTA), Samples.fastaGaps);
|
|
186
|
+
});
|
|
187
|
+
test('testSeparatorGapsToHelm', async () => {
|
|
188
|
+
await _testConvert(Samples.separatorGaps, converter(NOTATION.HELM), Samples.helmGaps);
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
// HELM tests: TODO
|
|
152
193
|
});
|
|
@@ -104,6 +104,7 @@ MWRSWY-CKHP
|
|
|
104
104
|
peptidesComplex = 'peptidesComplex',
|
|
105
105
|
fastaCsv = 'fastaCsv',
|
|
106
106
|
fastaFasta = 'fastaFasta',
|
|
107
|
+
fastaPtCsv = 'fastaPtCsv',
|
|
107
108
|
msaComplex = 'msaComplex',
|
|
108
109
|
helmCsv = 'helmCsv',
|
|
109
110
|
testDemogCsv = 'testDemogCsv',
|
|
@@ -114,16 +115,17 @@ MWRSWY-CKHP
|
|
|
114
115
|
}
|
|
115
116
|
|
|
116
117
|
const samples: { [key: string]: string } = {
|
|
117
|
-
'peptidesComplex': 'System:AppData/Bio/
|
|
118
|
+
'peptidesComplex': 'System:AppData/Bio/tests/peptides_complex_msa.csv',
|
|
118
119
|
'fastaCsv': 'System:AppData/Bio/samples/sample_FASTA.csv',
|
|
119
120
|
'fastaFasta': 'System:AppData/Bio/samples/sample_FASTA.fasta',
|
|
121
|
+
'fastaPtCsv': 'System:AppData/Bio/samples/sample_FASTA_PT.csv',
|
|
120
122
|
'msaComplex': 'System:AppData/Bio/samples/sample_MSA.csv',
|
|
121
123
|
'helmCsv': 'System:AppData/Bio/samples/sample_HELM.csv',
|
|
122
|
-
'testDemogCsv': 'System:AppData/Bio/
|
|
123
|
-
'testHelmCsv': 'System:AppData/Bio/
|
|
124
|
-
'testIdCsv': 'System:AppData/Bio/
|
|
125
|
-
'testSmilesCsv': 'System:AppData/Bio/
|
|
126
|
-
'testSmiles2Csv': 'System:AppData/Bio/
|
|
124
|
+
'testDemogCsv': 'System:AppData/Bio/tests/testDemog.csv',
|
|
125
|
+
'testHelmCsv': 'System:AppData/Bio/tests/testHelm.csv',
|
|
126
|
+
'testIdCsv': 'System:AppData/Bio/tests/id.csv',
|
|
127
|
+
'testSmilesCsv': 'System:AppData/Bio/tests/testSmiles.csv',
|
|
128
|
+
'testSmiles2Csv': 'System:AppData/Bio/tests/testSmiles2.csv',
|
|
127
129
|
};
|
|
128
130
|
|
|
129
131
|
const _samplesDfs: { [key: string]: Promise<DG.DataFrame> } = {};
|
|
@@ -294,6 +296,10 @@ MWRSWY-CKHP
|
|
|
294
296
|
test('samplesTestSmiles2NegativeSmiles', async () => {
|
|
295
297
|
await _testNeg(readSamples(Samples.testSmiles2Csv), 'SMILES');
|
|
296
298
|
});
|
|
299
|
+
|
|
300
|
+
test('samplesFastaPtPosSequence', async () => {
|
|
301
|
+
await (_testPos(readSamples(Samples.fastaPtCsv), 'sequence', 'fasta:SEQ:PT'));
|
|
302
|
+
});
|
|
297
303
|
});
|
|
298
304
|
|
|
299
305
|
export async function _testNeg(readDf: DfReaderFunc, colName: string) {
|
|
@@ -1,32 +1,36 @@
|
|
|
1
|
-
import * as C from
|
|
1
|
+
import * as C from './constants';
|
|
2
2
|
import * as DG from 'datagrok-api/dg';
|
|
3
|
-
import {AminoacidsPalettes} from
|
|
4
|
-
import {NucleotidesPalettes} from
|
|
5
|
-
import {UnknownSeqPalettes} from
|
|
6
|
-
import {SplitterFunc, WebLogo} from
|
|
7
|
-
import {SeqPalette} from
|
|
3
|
+
import {AminoacidsPalettes} from '@datagrok-libraries/bio/src/aminoacids';
|
|
4
|
+
import {NucleotidesPalettes} from '@datagrok-libraries/bio/src/nucleotides';
|
|
5
|
+
import {UnknownSeqPalettes} from '@datagrok-libraries/bio/src/unknown';
|
|
6
|
+
import {SplitterFunc, WebLogo} from '@datagrok-libraries/bio/src/viewers/web-logo';
|
|
7
|
+
import {SeqPalette} from '@datagrok-libraries/bio/src/seq-palettes';
|
|
8
8
|
import * as ui from 'datagrok-api/ui';
|
|
9
9
|
|
|
10
10
|
const lru = new DG.LruCache<any, any>();
|
|
11
|
-
const undefinedColor =
|
|
11
|
+
const undefinedColor = 'rgb(100,100,100)';
|
|
12
12
|
|
|
13
|
-
function getPalleteByType(paletteType: string): SeqPalette
|
|
13
|
+
function getPalleteByType(paletteType: string): SeqPalette {
|
|
14
14
|
switch (paletteType) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
case 'PT':
|
|
16
|
+
return AminoacidsPalettes.GrokGroups;
|
|
17
|
+
case 'NT':
|
|
18
|
+
return NucleotidesPalettes.Chromatogram;
|
|
19
|
+
case 'DNA':
|
|
20
|
+
return NucleotidesPalettes.Chromatogram;
|
|
21
|
+
case 'RNA':
|
|
22
|
+
return NucleotidesPalettes.Chromatogram;
|
|
23
|
+
// other
|
|
24
|
+
default:
|
|
25
|
+
return UnknownSeqPalettes.Color;
|
|
22
26
|
}
|
|
23
27
|
}
|
|
24
28
|
|
|
25
29
|
export function processSequence(subParts: string[]): [string[], boolean] {
|
|
26
30
|
const simplified = !subParts.some((amino, index) =>
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
31
|
+
amino.length > 1 &&
|
|
32
|
+
index != 0 &&
|
|
33
|
+
index != subParts.length - 1);
|
|
30
34
|
|
|
31
35
|
const text: string[] = [];
|
|
32
36
|
const gap = simplified ? '' : ' ';
|
|
@@ -38,6 +42,7 @@ export function processSequence(subParts: string[]): [string[], boolean] {
|
|
|
38
42
|
});
|
|
39
43
|
return [text, simplified];
|
|
40
44
|
}
|
|
45
|
+
|
|
41
46
|
/**
|
|
42
47
|
* A function that prints a string aligned to left or centered.
|
|
43
48
|
*
|
|
@@ -50,17 +55,18 @@ export function processSequence(subParts: string[]): [string[], boolean] {
|
|
|
50
55
|
* @param {string} [color=undefinedColor] String color.
|
|
51
56
|
* @param {number} [pivot=0] Pirvot.
|
|
52
57
|
* @param {boolean} [left=false] Is left aligned.
|
|
53
|
-
* @param {boolean} [hideMod=false] Hide amino acid redidue modifications.
|
|
54
58
|
* @param {number} [transparencyRate=0.0] Transparency rate where 1.0 is fully transparent
|
|
59
|
+
* @param {string} [separator=''] Is separator for sequence.
|
|
60
|
+
* @param {boolean} [last=false] Is checker if element last or not.
|
|
55
61
|
* @return {number} x coordinate to start printing at.
|
|
56
62
|
*/
|
|
57
63
|
function printLeftOrCentered(
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
64
|
+
x: number, y: number, w: number, h: number,
|
|
65
|
+
g: CanvasRenderingContext2D, s: string, color = undefinedColor,
|
|
66
|
+
pivot: number = 0, left = false, transparencyRate: number = 1.0,
|
|
67
|
+
separator: string = '', last: boolean = false): number {
|
|
62
68
|
g.textAlign = 'start';
|
|
63
|
-
|
|
69
|
+
const colorPart = s.substring(0);
|
|
64
70
|
let grayPart = separator;
|
|
65
71
|
if (last) {
|
|
66
72
|
grayPart = '';
|
|
@@ -91,14 +97,10 @@ function printLeftOrCentered(
|
|
|
91
97
|
}
|
|
92
98
|
|
|
93
99
|
export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
94
|
-
|
|
95
|
-
get
|
|
96
|
-
|
|
97
|
-
get
|
|
98
|
-
|
|
99
|
-
get defaultHeight(): number {return 30;}
|
|
100
|
-
|
|
101
|
-
get defaultWidth(): number {return 230;}
|
|
100
|
+
get name(): string { return 'macromoleculeSequence'; }
|
|
101
|
+
get cellType(): string { return C.SEM_TYPES.Macro_Molecule; }
|
|
102
|
+
get defaultHeight(): number { return 30; }
|
|
103
|
+
get defaultWidth(): number { return 230; }
|
|
102
104
|
|
|
103
105
|
/**
|
|
104
106
|
* Cell renderer function.
|
|
@@ -113,32 +115,32 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
113
115
|
* @memberof AlignedSequenceCellRenderer
|
|
114
116
|
*/
|
|
115
117
|
render(
|
|
116
|
-
|
|
117
|
-
|
|
118
|
+
g: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, gridCell: DG.GridCell,
|
|
119
|
+
cellStyle: DG.GridCellStyle
|
|
118
120
|
): void {
|
|
119
|
-
const grid = gridCell.grid;
|
|
121
|
+
const grid = gridCell.gridRow !== -1 ? gridCell.grid : undefined;
|
|
120
122
|
const cell = gridCell.cell;
|
|
121
123
|
const tag = gridCell.cell.column.getTag(DG.TAGS.UNITS);
|
|
122
124
|
if (tag === 'HELM') {
|
|
123
|
-
|
|
125
|
+
const host = ui.div([], {style: {width: `${w}px`, height: `${h}px`}});
|
|
124
126
|
host.setAttribute('dataformat', 'helm');
|
|
125
127
|
host.setAttribute('data', gridCell.cell.value);
|
|
126
128
|
gridCell.element = host;
|
|
127
129
|
//@ts-ignore
|
|
128
|
-
|
|
129
|
-
|
|
130
|
+
const canvas = new JSDraw2.Editor(host, {width: w, height: h, skin: 'w8', viewonly: true});
|
|
131
|
+
const formula = canvas.getFormula(true);
|
|
130
132
|
if (!formula) {
|
|
131
133
|
gridCell.element = ui.divText(gridCell.cell.value, {style: {color: 'red'}});
|
|
132
134
|
} else {
|
|
133
135
|
gridCell.element = host;
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
136
|
+
const molWeight = Math.round(canvas.getMolWeight() * 100) / 100;
|
|
137
|
+
const coef = Math.round(canvas.getExtinctionCoefficient(true) * 100) / 100;
|
|
138
|
+
const molfile = canvas.getMolfile();
|
|
139
|
+
const result = formula + ', ' + molWeight + ', ' + coef + ', ' + molfile;
|
|
138
140
|
lru.set(gridCell.cell.value, result);
|
|
139
141
|
}
|
|
140
142
|
} else {
|
|
141
|
-
const [type, subtype, paletteType] =
|
|
143
|
+
const [type, subtype, paletteType] = gridCell.cell.column.getTag(DG.TAGS.UNITS).split(':');
|
|
142
144
|
w = grid ? Math.min(grid.canvas.width - x, w) : g.canvas.width - x;
|
|
143
145
|
g.save();
|
|
144
146
|
g.beginPath();
|
|
@@ -154,12 +156,10 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
154
156
|
const palette = getPalleteByType(paletteType);
|
|
155
157
|
|
|
156
158
|
const separator = gridCell.cell.column.getTag('separator') ?? '';
|
|
157
|
-
const splitterFunc: SplitterFunc = WebLogo.getSplitter(units, gridCell.cell.column.getTag('separator')
|
|
159
|
+
const splitterFunc: SplitterFunc = WebLogo.getSplitter(units, gridCell.cell.column.getTag('separator'));
|
|
158
160
|
|
|
159
|
-
const subParts:string[] =
|
|
161
|
+
const subParts: string[] = splitterFunc(cell.value);
|
|
160
162
|
// console.log(subParts);
|
|
161
|
-
|
|
162
|
-
const textSize = g.measureText(subParts.join(''));
|
|
163
163
|
let x1 = x;
|
|
164
164
|
let color = undefinedColor;
|
|
165
165
|
subParts.forEach((amino, index) => {
|
|
@@ -169,7 +169,7 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
169
169
|
if (index === subParts.length - 1) {
|
|
170
170
|
last = true;
|
|
171
171
|
}
|
|
172
|
-
x1 = printLeftOrCentered(x1, y, w, h, g, amino, color, 0, true,
|
|
172
|
+
x1 = printLeftOrCentered(x1, y, w, h, g, amino, color, 0, true, 1.0, separator, last);
|
|
173
173
|
});
|
|
174
174
|
|
|
175
175
|
g.restore();
|
|
@@ -13,6 +13,12 @@ export class NotationConverter {
|
|
|
13
13
|
private _sourceColumn: DG.Column; // the column to be converted
|
|
14
14
|
private _sourceUnits: string; // units, of the form fasta:SEQ:NT, etc.
|
|
15
15
|
private _sourceNotation: NOTATION; // current notation (without :SEQ:NT, etc.)
|
|
16
|
+
private _defaultGapSymbol: string;
|
|
17
|
+
private _defaultGapSymbolsDict = {
|
|
18
|
+
helm: '*',
|
|
19
|
+
separator: '',
|
|
20
|
+
fasta: '-',
|
|
21
|
+
};
|
|
16
22
|
|
|
17
23
|
private get sourceUnits(): string { return this._sourceUnits; }
|
|
18
24
|
|
|
@@ -20,6 +26,16 @@ export class NotationConverter {
|
|
|
20
26
|
|
|
21
27
|
public get sourceNotation(): NOTATION { return this._sourceNotation; }
|
|
22
28
|
|
|
29
|
+
public get defaultGapSymbol(): string { return this._defaultGapSymbol; }
|
|
30
|
+
|
|
31
|
+
public get separator(): string {
|
|
32
|
+
const separator = this.sourceColumn.getTag('separator');
|
|
33
|
+
if (separator !== null)
|
|
34
|
+
return separator;
|
|
35
|
+
else
|
|
36
|
+
throw new Error('Separator not set');
|
|
37
|
+
}
|
|
38
|
+
|
|
23
39
|
public isFasta(): boolean { return this.sourceNotation === NOTATION.FASTA; }
|
|
24
40
|
|
|
25
41
|
public isSeparator(): boolean { return this.sourceNotation === NOTATION.SEPARATOR; }
|
|
@@ -42,34 +58,15 @@ export class NotationConverter {
|
|
|
42
58
|
/**
|
|
43
59
|
* @return {NOTATION} Notation associated with the units type
|
|
44
60
|
*/
|
|
45
|
-
private
|
|
61
|
+
private getSourceNotation(): NOTATION {
|
|
46
62
|
if (this.sourceUnits.toLowerCase().startsWith('fasta'))
|
|
47
63
|
return NOTATION.FASTA;
|
|
48
64
|
else if (this.sourceUnits.toLowerCase().startsWith('separator'))
|
|
49
65
|
return NOTATION.SEPARATOR;
|
|
50
|
-
else
|
|
51
|
-
// TODO: handle possible exceptions
|
|
66
|
+
else if (this.sourceUnits.toLowerCase().startsWith('helm'))
|
|
52
67
|
return NOTATION.HELM;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Determine the separator used in SEPARATOR column
|
|
57
|
-
*
|
|
58
|
-
* @return {string} The detected separator
|
|
59
|
-
*/
|
|
60
|
-
private determineSeparator(): string {
|
|
61
|
-
// TODO: figure out how to determine the separator efficiently
|
|
62
|
-
const col = this.sourceColumn;
|
|
63
|
-
let i = 0;
|
|
64
|
-
const re = /[^a-z]/;
|
|
65
|
-
while (i < col.length) {
|
|
66
|
-
const molecule = col.get(i);
|
|
67
|
-
const foundSeparator = molecule.toLowerCase().match(re);
|
|
68
|
-
if (foundSeparator)
|
|
69
|
-
return foundSeparator[0];
|
|
70
|
-
i++;
|
|
71
|
-
}
|
|
72
|
-
throw new Error('No separators found');
|
|
68
|
+
else
|
|
69
|
+
throw new Error('The column has units that do not correspond to any notation');
|
|
73
70
|
}
|
|
74
71
|
|
|
75
72
|
/**
|
|
@@ -86,7 +83,7 @@ export class NotationConverter {
|
|
|
86
83
|
const newColName = col.dataFrame.columns.getUnusedName(name);
|
|
87
84
|
// dummy code
|
|
88
85
|
const newColumn = DG.Column.fromList('string', newColName, new Array(len).fill(''));
|
|
89
|
-
newColumn.semType =
|
|
86
|
+
newColumn.semType = DG.SEMTYPE.MACROMOLECULE;
|
|
90
87
|
newColumn.setTag(
|
|
91
88
|
DG.TAGS.UNITS,
|
|
92
89
|
this.sourceUnits.replace(
|
|
@@ -98,6 +95,7 @@ export class NotationConverter {
|
|
|
98
95
|
if (this.toFasta(targetNotation)) {
|
|
99
96
|
newColumn.setTag(
|
|
100
97
|
DG.TAGS.CELL_RENDERER,
|
|
98
|
+
// TODO: replace by the enumeration value
|
|
101
99
|
'Macromolecule');
|
|
102
100
|
}
|
|
103
101
|
return newColumn;
|
|
@@ -128,19 +126,12 @@ export class NotationConverter {
|
|
|
128
126
|
return newColumn;
|
|
129
127
|
}
|
|
130
128
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
*/
|
|
138
|
-
private convertFastaToHelm(
|
|
139
|
-
fastaGapSymbol: string = '-',
|
|
140
|
-
helmGapSymbol: string = '*'
|
|
141
|
-
): DG.Column {
|
|
142
|
-
// a function splitting FASTA sequence into an array of monomers
|
|
143
|
-
const splitterAsFasta = WebLogo.splitterAsFasta;
|
|
129
|
+
private convertToHelm(sourceGapSymbol: string | null = null) {
|
|
130
|
+
if (sourceGapSymbol === null)
|
|
131
|
+
sourceGapSymbol = this.defaultGapSymbol;
|
|
132
|
+
// A function splitting a sequence into an array of monomers according to
|
|
133
|
+
// its notation
|
|
134
|
+
const splitter = WebLogo.getSplitterForColumn(this.sourceColumn);
|
|
144
135
|
|
|
145
136
|
const prefix = (this.isDna()) ? 'DNA1{' :
|
|
146
137
|
(this.isRna()) ? 'RNA1{' :
|
|
@@ -158,19 +149,17 @@ export class NotationConverter {
|
|
|
158
149
|
const newColumn = this.getNewColumn(NOTATION.HELM);
|
|
159
150
|
// assign the values to the empty column
|
|
160
151
|
newColumn.init((idx: number) => {
|
|
161
|
-
const
|
|
162
|
-
const
|
|
152
|
+
const sourcePolymer = this.sourceColumn.get(idx);
|
|
153
|
+
const sourceMonomersArray = splitter(sourcePolymer);
|
|
163
154
|
const helmArray = [prefix];
|
|
164
155
|
let firstIteration = true;
|
|
165
|
-
for (let i = 0; i <
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
helmArray.push(item.join(''));
|
|
173
|
-
}
|
|
156
|
+
for (let i = 0; i < sourceMonomersArray.length; i++) {
|
|
157
|
+
const dot = firstIteration ? '' : '.';
|
|
158
|
+
let token = sourceMonomersArray[i];
|
|
159
|
+
if (token === sourceGapSymbol)
|
|
160
|
+
token = this._defaultGapSymbolsDict.helm;
|
|
161
|
+
const item = [dot, leftWrapper, token, rightWrapper];
|
|
162
|
+
helmArray.push(item.join(''));
|
|
174
163
|
firstIteration = false;
|
|
175
164
|
}
|
|
176
165
|
helmArray.push(postfix);
|
|
@@ -210,12 +199,12 @@ export class NotationConverter {
|
|
|
210
199
|
// conversion
|
|
211
200
|
// * consider automatic determining the separator
|
|
212
201
|
|
|
213
|
-
|
|
214
|
-
|
|
202
|
+
if (separator === null)
|
|
203
|
+
separator = this.separator;
|
|
215
204
|
|
|
216
205
|
// a function splitting FASTA sequence into an array of monomers
|
|
217
206
|
//const splitterAsSeparator = WebLogo.getSplitterWithSeparator(separator);
|
|
218
|
-
const splitter = WebLogo.getSplitterForColumn(this.
|
|
207
|
+
const splitter = WebLogo.getSplitterForColumn(this.sourceColumn);
|
|
219
208
|
|
|
220
209
|
const newColumn = this.getNewColumn(NOTATION.FASTA);
|
|
221
210
|
// assign the values to the empty column
|
|
@@ -241,47 +230,6 @@ export class NotationConverter {
|
|
|
241
230
|
return newColumn;
|
|
242
231
|
}
|
|
243
232
|
|
|
244
|
-
private convertSeparatorToHelm(fastaGapSymbol: string = '-', helmGapSymbol: string = '*'): DG.Column {
|
|
245
|
-
// a function splitting FASTA sequence into an array of monomers
|
|
246
|
-
const splitter = WebLogo.getSplitterForColumn(this._sourceColumn);
|
|
247
|
-
|
|
248
|
-
const prefix = (this.isDna()) ? 'DNA1{' :
|
|
249
|
-
(this.isRna()) ? 'RNA1{' :
|
|
250
|
-
(this.isPeptide()) ? 'PEPTIDE1{' :
|
|
251
|
-
'Unknown'; // this case should be handled as exceptional
|
|
252
|
-
|
|
253
|
-
if (prefix === 'Unknown')
|
|
254
|
-
throw new Error('Neither peptide, nor nucleotide');
|
|
255
|
-
|
|
256
|
-
const postfix = '}$$$';
|
|
257
|
-
const leftWrapper = (this.isDna()) ? 'D(' :
|
|
258
|
-
(this.isRna()) ? 'R(' : ''; // no wrapper for peptides
|
|
259
|
-
const rightWrapper = (this.isDna() || this.isRna()) ? ')P' : ''; // no wrapper for peptides
|
|
260
|
-
|
|
261
|
-
const newColumn = this.getNewColumn(NOTATION.HELM);
|
|
262
|
-
// assign the values to the empty column
|
|
263
|
-
newColumn.init((idx: number) => {
|
|
264
|
-
const fastaPolymer = this.sourceColumn.get(idx);
|
|
265
|
-
const fastaMonomersArray = splitter(fastaPolymer);
|
|
266
|
-
const helmArray = [prefix];
|
|
267
|
-
let firstIteration = true;
|
|
268
|
-
for (let i = 0; i < fastaMonomersArray.length; i++) {
|
|
269
|
-
if (fastaMonomersArray[i] === fastaGapSymbol) {
|
|
270
|
-
// TODO: verify the correctness of gap symbols handling
|
|
271
|
-
helmArray.push(helmGapSymbol);
|
|
272
|
-
} else {
|
|
273
|
-
const dot = firstIteration ? '' : '.';
|
|
274
|
-
const item = [dot, leftWrapper, fastaMonomersArray[i], rightWrapper];
|
|
275
|
-
helmArray.push(item.join(''));
|
|
276
|
-
}
|
|
277
|
-
firstIteration = false;
|
|
278
|
-
}
|
|
279
|
-
helmArray.push(postfix);
|
|
280
|
-
return helmArray.join('');
|
|
281
|
-
});
|
|
282
|
-
return newColumn;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
233
|
private convertHelmToFasta(): DG.Column {
|
|
286
234
|
// TODO: implementation
|
|
287
235
|
return this.getNewColumn(NOTATION.FASTA);
|
|
@@ -307,12 +255,10 @@ export class NotationConverter {
|
|
|
307
255
|
|
|
308
256
|
if (this.isFasta() && this.toSeparator(targetNotation) && tgtSeparator !== null)
|
|
309
257
|
return this.convertFastaToSeparator(tgtSeparator);
|
|
310
|
-
else if (this.isFasta() && this.toHelm(targetNotation))
|
|
311
|
-
return this.
|
|
258
|
+
else if ((this.isFasta() || this.isSeparator()) && this.toHelm(targetNotation))
|
|
259
|
+
return this.convertToHelm();
|
|
312
260
|
else if (this.isSeparator() && this.toFasta(targetNotation))
|
|
313
261
|
return this.convertSeparatorToFasta(tgtSeparator!);
|
|
314
|
-
else if (this.isSeparator() && this.toHelm(targetNotation))
|
|
315
|
-
return this.convertSeparatorToHelm();
|
|
316
262
|
else if (this.isHelm() && this.toFasta(targetNotation))
|
|
317
263
|
return this.convertHelmToFasta();
|
|
318
264
|
else
|
|
@@ -321,7 +267,14 @@ export class NotationConverter {
|
|
|
321
267
|
|
|
322
268
|
public constructor(col: DG.Column) {
|
|
323
269
|
this._sourceColumn = col;
|
|
324
|
-
|
|
325
|
-
|
|
270
|
+
const units = this._sourceColumn.tags[DG.TAGS.UNITS];
|
|
271
|
+
if (units !== null)
|
|
272
|
+
this._sourceUnits = units;
|
|
273
|
+
else
|
|
274
|
+
throw new Error('Units are not specified in column');
|
|
275
|
+
this._sourceNotation = this.getSourceNotation();
|
|
276
|
+
this._defaultGapSymbol = (this.isFasta()) ? this._defaultGapSymbolsDict.fasta :
|
|
277
|
+
(this.isHelm()) ? this._defaultGapSymbolsDict.helm :
|
|
278
|
+
this._defaultGapSymbolsDict.separator;
|
|
326
279
|
}
|
|
327
280
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<html><head><meta charset="utf-8"/><title>Bio Test Report. Datagrok version datagrok/datagrok:latest SHA=34f75e5127b8. Commit
|
|
1
|
+
<html><head><meta charset="utf-8"/><title>Bio Test Report. Datagrok version datagrok/datagrok:latest SHA=34f75e5127b8. Commit ac96da52.</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=34f75e5127b8. Commit
|
|
232
|
+
</style></head><body><div id="jesthtml-content"><header><h1 id="title">Bio Test Report. Datagrok version datagrok/datagrok:latest SHA=34f75e5127b8. Commit ac96da52.</h1></header><div id="metadata-container"><div id="timestamp">Started: 2022-07-13 09:24:48</div><div id="summary"><div id="suite-summary"><div class="summary-total">Suites (1)</div><div class="summary-passed summary-empty">0 passed</div><div class="summary-failed">1 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 summary-empty">0 passed</div><div class="summary-failed">1 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">110.354s</div></div><div class="suite-tests"><div class="test-result failed"><div class="test-info"><div class="test-suitename"> </div><div class="test-title">TEST</div><div class="test-status">failed</div><div class="test-duration">100.001s</div></div><div class="failureMessages"> <pre class="failureMsg">Error: thrown: "Exceeded timeout of 100000 ms for a test.
|
|
233
233
|
Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."
|
|
234
234
|
at Object.<anonymous> (/home/runner/work/public/public/packages/Bio/src/__jest__/remote.test.ts:22:1)
|
|
235
235
|
at Runtime._execModule (/home/runner/work/public/public/packages/Bio/node_modules/jest-runtime/build/index.js:1646:24)
|