@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.
@@ -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/samples/peptides_complex_msa.csv',
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/samples/testDemog.csv',
123
- 'testHelmCsv': 'System:AppData/Bio/samples/testHelm.csv',
124
- 'testIdCsv': 'System:AppData/Bio/samples/id.csv',
125
- 'testSmilesCsv': 'System:AppData/Bio/samples/testSmiles.csv',
126
- 'testSmiles2Csv': 'System:AppData/Bio/samples/testSmiles2.csv',
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 "./constants";
1
+ import * as C from './constants';
2
2
  import * as DG from 'datagrok-api/dg';
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";
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 = 'rgb(100,100,100)';
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
- case 'PT':
16
- return AminoacidsPalettes.GrokGroups;
17
- case 'NT':
18
- return NucleotidesPalettes.Chromatogram
19
- // other
20
- default:
21
- return UnknownSeqPalettes.Color;
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
- amino.length > 1 &&
28
- index != 0 &&
29
- index != subParts.length - 1);
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
- x: number, y: number, w: number, h: number,
59
- g: CanvasRenderingContext2D, s: string, color = undefinedColor,
60
- pivot: number = 0, left = false, hideMod = false, transparencyRate: number = 1.0,
61
- separator: string = '', last:boolean = false): number {
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
- let colorPart = s.substring(0);
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 name(): string {return 'macromoleculeSequence';}
96
-
97
- get cellType(): string {return C.SEM_TYPES.Macro_Molecule;}
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
- g: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, gridCell: DG.GridCell,
117
- cellStyle: DG.GridCellStyle,
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
- let host = ui.div([], { style: { width: `${w}px`, height: `${h}px`}});
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
- var canvas = new JSDraw2.Editor(host, { width: w, height: h, skin: "w8", viewonly: true });
129
- var formula = canvas.getFormula(true);
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
- var molWeight = Math.round(canvas.getMolWeight() * 100) / 100;
135
- var coef = Math.round(canvas.getExtinctionCoefficient(true) * 100) / 100;
136
- var molfile = canvas.getMolfile();
137
- var result = formula + ', ' + molWeight + ', ' + coef + ', ' + molfile;
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] = gridCell.cell.column.getTag(DG.TAGS.UNITS).split(":");
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') );// splitter,
159
+ const splitterFunc: SplitterFunc = WebLogo.getSplitter(units, gridCell.cell.column.getTag('separator'));
158
160
 
159
- const subParts:string[] = splitterFunc(cell.value);
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, false, 1.0, separator, last);
172
+ x1 = printLeftOrCentered(x1, y, w, h, g, amino, color, 0, true, 1.0, separator, last);
173
173
  });
174
174
 
175
175
  g.restore();
@@ -4,7 +4,6 @@ import * as DG from 'datagrok-api/dg';
4
4
  import Aioli from '@biowasm/aioli';
5
5
 
6
6
  import {AlignedSequenceEncoder} from '@datagrok-libraries/bio/src/sequence-encoder';
7
- import * as C from './constants';
8
7
 
9
8
  /**
10
9
  * Converts array of sequences into simple fasta string.
@@ -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 determineSourceNotation(): NOTATION {
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 = 'Macromolecule';
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
- * Convert a Macromolecule column from FASTA to HELM
133
- *
134
- * @param {string} fastaGapSymbol Optional fasta gap symbol
135
- * @param {string} helmGapSymbol Optional helm gap symbol
136
- * @return {DG.Column} A new column in HELM notation
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 fastaPolymer = this.sourceColumn.get(idx);
162
- const fastaMonomersArray = splitterAsFasta(fastaPolymer);
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 < fastaMonomersArray.length; i++) {
166
- if (fastaMonomersArray[i] === fastaGapSymbol) {
167
- // TODO: verify the correctness of gap symbols handling
168
- helmArray.push(helmGapSymbol);
169
- } else {
170
- const dot = firstIteration ? '' : '.';
171
- const item = [dot, leftWrapper, fastaMonomersArray[i], rightWrapper];
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
- // if (separator === null)
214
- // separator = this.determineSeparator();
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._sourceColumn);
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.convertFastaToHelm();
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
- this._sourceUnits = this._sourceColumn.tags[DG.TAGS.UNITS];
325
- this._sourceNotation = this.determineSourceNotation();
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 95c6fae9.</title><style type="text/css">html,
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 95c6fae9.</h1></header><div id="metadata-container"><div id="timestamp">Started: 2022-07-12 11:55:44</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">112.789s</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.002s</div></div><div class="failureMessages"> <pre class="failureMsg">Error: thrown: "Exceeded timeout of 100000 ms for a test.
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.&lt;anonymous&gt; (/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)