@datagrok/bio 2.1.10 → 2.1.12

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.
Files changed (34) hide show
  1. package/.eslintrc.json +1 -0
  2. package/detectors.js +5 -4
  3. package/dist/package-test.js +2182 -57664
  4. package/dist/package.js +1773 -57252
  5. package/dist/vendors-node_modules_datagrok-libraries_ml_src_workers_dimensionality-reducer_js.js +301 -250
  6. package/package.json +10 -12
  7. package/src/analysis/sequence-activity-cliffs.ts +5 -5
  8. package/src/analysis/sequence-diversity-viewer.ts +3 -2
  9. package/src/analysis/sequence-search-base-viewer.ts +2 -1
  10. package/src/analysis/sequence-similarity-viewer.ts +2 -2
  11. package/src/calculations/monomerLevelMols.ts +3 -3
  12. package/src/package.ts +28 -25
  13. package/src/substructure-search/substructure-search.ts +9 -9
  14. package/src/tests/Palettes-test.ts +9 -9
  15. package/src/tests/WebLogo-positions-test.ts +64 -57
  16. package/src/tests/bio-tests.ts +31 -21
  17. package/src/tests/checkInputColumn-tests.ts +17 -17
  18. package/src/tests/converters-test.ts +30 -30
  19. package/src/tests/detectors-benchmark-tests.ts +15 -16
  20. package/src/tests/detectors-tests.ts +31 -24
  21. package/src/tests/fasta-export-tests.ts +2 -3
  22. package/src/tests/renderers-test.ts +17 -15
  23. package/src/tests/splitters-test.ts +3 -3
  24. package/src/tests/utils/sequences-generators.ts +7 -7
  25. package/src/utils/cell-renderer.ts +33 -24
  26. package/src/utils/convert.ts +10 -10
  27. package/src/utils/multiple-sequence-alignment.ts +6 -7
  28. package/src/utils/save-as-fasta.ts +8 -8
  29. package/src/viewers/vd-regions-viewer.ts +15 -14
  30. package/tsconfig.json +1 -1
  31. package/jest.config.js +0 -33
  32. package/src/__jest__/remote.test.ts +0 -77
  33. package/src/__jest__/test-node.ts +0 -98
  34. package/test-Bio-62cc009524f3-e7a922ae.html +0 -392
@@ -1,6 +1,5 @@
1
1
  import * as grok from 'datagrok-api/grok';
2
2
  import * as DG from 'datagrok-api/dg';
3
- import * as bio from '@datagrok-libraries/bio';
4
3
 
5
4
  import {after, before, category, delay, expect, test} from '@datagrok-libraries/utils/src/test';
6
5
 
@@ -9,6 +8,7 @@ import {convertDo} from '../utils/convert';
9
8
  import {SEM_TYPES, TAGS} from '../utils/constants';
10
9
  import {generateLongSequence, generateManySequences, performanceTest} from './utils/sequences-generators';
11
10
  import {errorToConsole} from '@datagrok-libraries/utils/src/to-console';
11
+ import {ALIGNMENT, ALPHABET, NOTATION, TAGS as bioTAGS, UnitsHandler} from '@datagrok-libraries/bio';
12
12
 
13
13
  category('renderers', () => {
14
14
  let tvList: DG.TableView[];
@@ -103,7 +103,7 @@ category('renderers', () => {
103
103
  async function _rendererMacromoleculeDifference() {
104
104
  const seqDiffCol: DG.Column = DG.Column.fromStrings('SequencesDiff',
105
105
  ['meI/hHis/Aca/N/T/dK/Thr_PO3H2/Aca#D-Tyr_Et/Tyr_ab-dehydroMe/meN/E/N/dV']);
106
- seqDiffCol.tags[DG.TAGS.UNITS] = bio.NOTATION.SEPARATOR;
106
+ seqDiffCol.tags[DG.TAGS.UNITS] = NOTATION.SEPARATOR;
107
107
  seqDiffCol.tags[TAGS.SEPARATOR] = '/';
108
108
  seqDiffCol.semType = SEM_TYPES.MACROMOLECULE_DIFFERENCE;
109
109
  const df = DG.DataFrame.fromColumns([seqDiffCol]);
@@ -138,22 +138,22 @@ category('renderers', () => {
138
138
  `semType="${srcSeqCol!.semType}", units="${srcSeqCol!.getTag(DG.TAGS.UNITS)}", ` +
139
139
  `cell.renderer="${srcSeqCol!.getTag(DG.TAGS.CELL_RENDERER)}"`);
140
140
  expect(srcSeqCol.semType, DG.SEMTYPE.MACROMOLECULE);
141
- expect(srcSeqCol.getTag(DG.TAGS.UNITS), bio.NOTATION.FASTA);
142
- expect(srcSeqCol.getTag(bio.TAGS.aligned), bio.ALIGNMENT.SEQ);
143
- expect(srcSeqCol.getTag(bio.TAGS.alphabet), bio.ALPHABET.PT);
141
+ expect(srcSeqCol.getTag(DG.TAGS.UNITS), NOTATION.FASTA);
142
+ expect(srcSeqCol.getTag(bioTAGS.aligned), ALIGNMENT.SEQ);
143
+ expect(srcSeqCol.getTag(bioTAGS.alphabet), ALPHABET.PT);
144
144
  expect(srcSeqCol.getTag(DG.TAGS.CELL_RENDERER), 'sequence');
145
145
 
146
146
  const msaSeqCol: DG.Column = (await multipleSequenceAlignmentAny(df, srcSeqCol!))!;
147
147
  tv.grid.invalidate();
148
148
 
149
149
  expect(msaSeqCol.semType, DG.SEMTYPE.MACROMOLECULE);
150
- expect(msaSeqCol.getTag(DG.TAGS.UNITS), bio.NOTATION.FASTA);
151
- expect(msaSeqCol.getTag(bio.TAGS.aligned), bio.ALIGNMENT.SEQ_MSA);
152
- expect(msaSeqCol.getTag(bio.TAGS.alphabet), bio.ALPHABET.PT);
150
+ expect(msaSeqCol.getTag(DG.TAGS.UNITS), NOTATION.FASTA);
151
+ expect(msaSeqCol.getTag(bioTAGS.aligned), ALIGNMENT.SEQ_MSA);
152
+ expect(msaSeqCol.getTag(bioTAGS.alphabet), ALPHABET.PT);
153
153
  expect(msaSeqCol.getTag(DG.TAGS.CELL_RENDERER), 'sequence');
154
154
 
155
155
  // check newColumn with UnitsHandler constructor
156
- const uh: bio.UnitsHandler = new bio.UnitsHandler(msaSeqCol);
156
+ const uh: UnitsHandler = new UnitsHandler(msaSeqCol);
157
157
 
158
158
  dfList.push(df);
159
159
  tvList.push(tv);
@@ -175,13 +175,13 @@ category('renderers', () => {
175
175
  tvList.push(tv);
176
176
  dfList.push(df);
177
177
 
178
- const tgtCol: DG.Column = await convertDo(srcCol, bio.NOTATION.SEPARATOR, '/');
178
+ const tgtCol: DG.Column = await convertDo(srcCol, NOTATION.SEPARATOR, '/');
179
179
 
180
180
  const resCellRenderer = tgtCol.getTag(DG.TAGS.CELL_RENDERER);
181
181
  expect(resCellRenderer, 'sequence');
182
182
 
183
183
  // check tgtCol with UnitsHandler constructor
184
- const uh: bio.UnitsHandler = new bio.UnitsHandler(tgtCol);
184
+ const uh: UnitsHandler = new UnitsHandler(tgtCol);
185
185
  }
186
186
 
187
187
  async function _selectRendererBySemType() {
@@ -190,7 +190,7 @@ category('renderers', () => {
190
190
  /**/
191
191
  const seqDiffCol: DG.Column = DG.Column.fromStrings('SequencesDiff',
192
192
  ['meI/hHis/Aca/N/T/dK/Thr_PO3H2/Aca#D-Tyr_Et/Tyr_ab-dehydroMe/meN/E/N/dV']);
193
- seqDiffCol.tags[DG.TAGS.UNITS] = bio.NOTATION.SEPARATOR;
193
+ seqDiffCol.tags[DG.TAGS.UNITS] = NOTATION.SEPARATOR;
194
194
  seqDiffCol.tags[TAGS.SEPARATOR] = '/';
195
195
  seqDiffCol.semType = SEM_TYPES.MACROMOLECULE_DIFFERENCE;
196
196
  const df = DG.DataFrame.fromColumns([seqDiffCol]);
@@ -200,10 +200,11 @@ category('renderers', () => {
200
200
 
201
201
  await delay(100);
202
202
  const renderer = seqDiffCol.getTag(DG.TAGS.CELL_RENDERER);
203
- if (renderer !== 'MacromoleculeDifference') // this is value of MacromoleculeDifferenceCR.cellType
203
+ if (renderer !== 'MacromoleculeDifference') { // this is value of MacromoleculeDifferenceCR.cellType
204
204
  throw new Error(`Units 'separator', separator '/' and semType 'MacromoleculeDifference' ` +
205
205
  `have been manually set on column but after df was added as table, ` +
206
206
  `view renderer has set to '${renderer}' instead of correct 'MacromoleculeDifference'.`);
207
+ }
207
208
  }
208
209
 
209
210
  /** GROK-11212 Do not overwrite / recalculate 'cell.renderer' tag that has been set programmatically
@@ -211,7 +212,7 @@ category('renderers', () => {
211
212
  async function _setRendererManually() {
212
213
  const seqDiffCol: DG.Column = DG.Column.fromStrings('SequencesDiff',
213
214
  ['meI/hHis/Aca/N/T/dK/Thr_PO3H2/Aca#D-Tyr_Et/Tyr_ab-dehydroMe/meN/E/N/dV']);
214
- seqDiffCol.tags[DG.TAGS.UNITS] = bio.NOTATION.SEPARATOR;
215
+ seqDiffCol.tags[DG.TAGS.UNITS] = NOTATION.SEPARATOR;
215
216
  seqDiffCol.tags[TAGS.SEPARATOR] = '/';
216
217
  seqDiffCol.semType = SEM_TYPES.MACROMOLECULE;
217
218
  const tgtCellRenderer = 'MacromoleculeDifference';
@@ -224,9 +225,10 @@ category('renderers', () => {
224
225
 
225
226
  await delay(100);
226
227
  const resCellRenderer = seqDiffCol.getTag(DG.TAGS.CELL_RENDERER);
227
- if (resCellRenderer !== tgtCellRenderer) // this is value of MacromoleculeDifferenceCR.cellType
228
+ if (resCellRenderer !== tgtCellRenderer) { // this is value of MacromoleculeDifferenceCR.cellType
228
229
  throw new Error(`Tag 'cell.renderer' has been manually set to '${tgtCellRenderer}' for column ` +
229
230
  `but after df was added as table, tag 'cell.renderer' has reset to '${resCellRenderer}' ` +
230
231
  `instead of manual '${tgtCellRenderer}'.`);
232
+ }
231
233
  }
232
234
  });
@@ -1,12 +1,12 @@
1
1
  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
- import * as bio from '@datagrok-libraries/bio';
5
4
 
6
5
  import {after, before, category, test, expect, expectArray, expectObject} from '@datagrok-libraries/utils/src/test';
7
6
  import * as C from '../utils/constants';
8
7
  import {splitToMonomers, _package, getHelmMonomers} from '../package';
9
8
  import {errorToConsole} from '@datagrok-libraries/utils/src/to-console';
9
+ import {splitterAsFasta, splitterAsHelm} from '@datagrok-libraries/bio';
10
10
 
11
11
 
12
12
  category('splitters', () => {
@@ -122,13 +122,13 @@ PEPTIDE1{hHis.Aca.Cys_SEt}$$$,5.72388
122
122
  });
123
123
 
124
124
  export async function _testFastaSplitter(src: string, tgt: string[]) {
125
- const res: string[] = bio.splitterAsFasta(src);
125
+ const res: string[] = splitterAsFasta(src);
126
126
  console.debug(`Bio: tests: splitters: src=${JSON.stringify(src)}, res=${JSON.stringify(res)} .`);
127
127
  expectArray(res, tgt);
128
128
  }
129
129
 
130
130
  export async function _testHelmSplitter(src: string, tgt: string[]) {
131
- const res: string[] = bio.splitterAsHelm(src);
131
+ const res: string[] = splitterAsHelm(src);
132
132
  console.debug(`Bio: tests: splitters: src=${JSON.stringify(src)}, res=${JSON.stringify(res)} .`);
133
133
  expectArray(res, tgt);
134
134
  }
@@ -1,18 +1,18 @@
1
1
  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
- import * as bio from '@datagrok-libraries/bio';
4
+ import {ALIGNMENT, ALPHABET, NOTATION, TAGS as bioTAGS} from '@datagrok-libraries/bio';
5
5
 
6
6
 
7
7
  export function generateManySequences(): DG.Column[] {
8
- let columns: DG.Column[] = [];
8
+ const columns: DG.Column[] = [];
9
9
  columns.push(DG.Column.fromList('string', 'MSA', new Array(10 ** 6).fill('meI/hHis/Aca/N/T/dE/Thr_PO3H2/Aca/D-Tyr_Et/Tyr_ab-dehydroMe/dV/E/N/D-Orn/D-aThr//Phe_4Me')));
10
10
  columns.push(DG.Column.fromList('string', 'Activity', new Array(10 ** 6).fill('5.30751')));
11
11
  return columns;
12
12
  }
13
13
 
14
14
  export function generateLongSequence(): DG.Column[] {
15
- let columns: DG.Column[] = [];
15
+ const columns: DG.Column[] = [];
16
16
  const longSequence = `meI/hHis/Aca/N/T/dE/Thr_PO3H2/Aca/D-Tyr_Et/Tyr_ab-dehydroMe/dV/E/N/D-Orn/D-aThr`.repeat(10 ** 5);
17
17
  columns.push(DG.Column.fromList('string', 'MSA', new Array(10 ** 2).fill(longSequence)));
18
18
  columns.push(DG.Column.fromList('string', 'Activity', new Array(10 ** 2).fill('7.30751')));
@@ -21,10 +21,10 @@ export function generateLongSequence(): DG.Column[] {
21
21
 
22
22
  export function setTagsMacromolecule(col: DG.Column) {
23
23
  col.semType = DG.SEMTYPE.MACROMOLECULE;
24
- col.setTag(DG.TAGS.UNITS, bio.NOTATION.SEPARATOR);
25
- col.setTag(bio.TAGS.aligned, bio.ALIGNMENT.SEQ_MSA);
26
- col.setTag(bio.TAGS.alphabet, bio.ALPHABET.UN);
27
- col.setTag(bio.TAGS.separator, '/');
24
+ col.setTag(DG.TAGS.UNITS, NOTATION.SEPARATOR);
25
+ col.setTag(bioTAGS.aligned, ALIGNMENT.SEQ_MSA);
26
+ col.setTag(bioTAGS.alphabet, ALPHABET.UN);
27
+ col.setTag(bioTAGS.separator, '/');
28
28
  return col;
29
29
  }
30
30
 
@@ -3,11 +3,20 @@ import * as DG from 'datagrok-api/dg';
3
3
  import * as ui from 'datagrok-api/ui';
4
4
 
5
5
  import {printLeftOrCentered, DrawStyle} from '@datagrok-libraries/bio/src/utils/cell-renderer';
6
- import * as bio from '@datagrok-libraries/bio';
7
6
  import * as C from './constants';
7
+ import {
8
+ ALIGNMENT,
9
+ getPaletteByType,
10
+ getSplitter,
11
+ monomerToShort,
12
+ SeqPalette,
13
+ SplitterFunc,
14
+ TAGS as bioTAGS,
15
+ UnknownSeqPalettes
16
+ } from '@datagrok-libraries/bio';
8
17
 
9
18
  const undefinedColor = 'rgb(100,100,100)';
10
- const monomerToShortFunction: (amino: string, maxLengthOfMonomer: number) => string = bio.monomerToShort;
19
+ const monomerToShortFunction: (amino: string, maxLengthOfMonomer: number) => string = monomerToShort;
11
20
 
12
21
  function getUpdatedWidth(grid: DG.Grid | null, g: CanvasRenderingContext2D, x: number, w: number): number {
13
22
  return grid ? Math.min(grid.canvas.width - x, w) : g.canvas.width - x;
@@ -46,7 +55,7 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
46
55
  }
47
56
 
48
57
  onMouseMove(gridCell: DG.GridCell, e: MouseEvent): void {
49
- if (gridCell.cell.column.getTag(bio.TAGS.aligned) !== bio.ALIGNMENT.SEQ_MSA)
58
+ if (gridCell.cell.column.getTag(bioTAGS.aligned) !== ALIGNMENT.SEQ_MSA)
50
59
  return;
51
60
 
52
61
  const maxLengthWordsSum = gridCell.cell.column.temp['bio-sum-maxLengthWords'];
@@ -74,7 +83,7 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
74
83
  }
75
84
  left = (argsX >= maxLengthWordsSum[left]) ? left + 1 : left;
76
85
  const separator = gridCell.cell.column.getTag('separator') ?? '';
77
- const splitterFunc: bio.SplitterFunc = bio.getSplitter('separator', separator);
86
+ const splitterFunc: SplitterFunc = getSplitter('separator', separator);
78
87
  const subParts: string[] = splitterFunc(gridCell.cell.value);
79
88
  (((subParts[left]?.length ?? 0) > 0)) ?
80
89
  ui.tooltip.show(ui.div(subParts[left]), e.x + 16, e.y + 16) : ui.tooltip.hide();
@@ -95,7 +104,7 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
95
104
  render(
96
105
  g: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, gridCell: DG.GridCell,
97
106
  cellStyle: DG.GridCellStyle
98
- ): void {
107
+ ) {
99
108
  const grid = gridCell.gridRow !== -1 ? gridCell.grid : null;
100
109
  const cell = gridCell.cell;
101
110
  const paletteType = gridCell.cell.column.getTag(C.TAGS.ALPHABET);
@@ -111,11 +120,11 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
111
120
  //TODO: can this be replaced/merged with splitSequence?
112
121
  const units = gridCell.cell.column.getTag(DG.TAGS.UNITS);
113
122
 
114
- const palette = bio.getPaletteByType(paletteType);
123
+ const palette = getPaletteByType(paletteType);
115
124
 
116
125
  const separator = gridCell.cell.column.getTag('separator') ?? '';
117
126
  const splitLimit = gridCell.bounds.width / 5;
118
- const splitterFunc: bio.SplitterFunc = bio.getSplitter(units, separator, splitLimit);
127
+ const splitterFunc: SplitterFunc = getSplitter(units, separator, splitLimit);
119
128
  const referenceSequence: string[] = splitterFunc(((gridCell.cell.column?.temp['reference-sequence'] != null) && (gridCell.cell.column?.temp['reference-sequence'] != ''))
120
129
  ? gridCell.cell.column.temp['reference-sequence'] : gridCell.cell.column.temp['current-word'] ?? '');
121
130
  const monomerWidth = (gridCell.cell.column?.temp['monomer-width'] != null) ? gridCell.cell.column.temp['monomer-width'] : 'short';
@@ -146,7 +155,7 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
146
155
  });
147
156
  samples += 1;
148
157
  }
149
- let minLength = 3 * 7;
158
+ const minLength = 3 * 7;
150
159
  for (let i = 0; i <= maxIndex; i++) {
151
160
  if (maxLengthWords[i] < minLength) {
152
161
  maxLengthWords[i] = minLength;
@@ -168,15 +177,15 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
168
177
  const subParts: string[] = splitterFunc(cell.value);
169
178
  let x1 = x;
170
179
  let color = undefinedColor;
171
- let drawStyle = bio.DrawStyle.classic;
180
+ let drawStyle = DrawStyle.classic;
172
181
  if (gridCell.cell.column.getTag('aligned').includes('MSA') && gridCell.cell.column.getTag('units') === 'separator')
173
- drawStyle = bio.DrawStyle.MSA;
182
+ drawStyle = DrawStyle.MSA;
174
183
 
175
184
  subParts.every((amino, index) => {
176
185
  color = palette.get(amino);
177
186
  g.fillStyle = undefinedColor;
178
- let last = index === subParts.length - 1;
179
- x1 = bio.printLeftOrCentered(x1, y, w, h, g, amino, color, 0, true, 1.0, separator, last, drawStyle, maxLengthWords, index, gridCell, referenceSequence, maxLengthOfMonomer);
187
+ const last = index === subParts.length - 1;
188
+ x1 = printLeftOrCentered(x1, y, w, h, g, amino, color, 0, true, 1.0, separator, last, drawStyle, maxLengthWords, index, gridCell, referenceSequence, maxLengthOfMonomer);
180
189
  return x1 - minDistanceRenderer - gridCell.gridColumn.left + (gridCell.gridColumn.left - gridCell.bounds.x) <= gridCell.bounds.width;
181
190
  });
182
191
 
@@ -212,14 +221,14 @@ export class MonomerCellRenderer extends DG.GridCellRenderer {
212
221
  g.textBaseline = 'middle';
213
222
  g.textAlign = 'center';
214
223
 
215
- const palette = bio.getPaletteByType(gridCell.cell.column.getTag(C.TAGS.ALPHABET));
224
+ const palette = getPaletteByType(gridCell.cell.column.getTag(C.TAGS.ALPHABET));
216
225
  const s: string = gridCell.cell.value;
217
226
  if (!s)
218
227
  return;
219
228
  const color = palette.get(s);
220
229
 
221
230
  g.fillStyle = color;
222
- g.fillText(s, x + (w / 2), y + (h / 2), w);
231
+ g.fillText(monomerToShort(s, 3), x + (w / 2), y + (h / 2), w);
223
232
  }
224
233
  }
225
234
 
@@ -255,7 +264,7 @@ export class MacromoleculeDifferenceCellRenderer extends DG.GridCellRenderer {
255
264
  w = getUpdatedWidth(grid, g, x, w);
256
265
  //TODO: can this be replaced/merged with splitSequence?
257
266
  const [s1, s2] = s.split('#');
258
- const splitter = bio.getSplitter(units, separator);
267
+ const splitter = getSplitter(units, separator);
259
268
  const subParts1 = splitter(s1);
260
269
  const subParts2 = splitter(s2);
261
270
  drawMoleculeDifferenceOnCanvas(g, x, y, w, h, subParts1, subParts2, units);
@@ -272,8 +281,8 @@ export function drawMoleculeDifferenceOnCanvas(
272
281
  subParts2: string [],
273
282
  units: string,
274
283
  fullStringLength?: boolean,
275
- molDifferences?: { [key: number]: HTMLCanvasElement }) {
276
-
284
+ molDifferences?: { [key: number]: HTMLCanvasElement }
285
+ ): void {
277
286
  if (subParts1.length !== subParts2.length) {
278
287
  const emptyMonomersArray = new Array<string>(Math.abs(subParts1.length - subParts2.length)).fill('');
279
288
  subParts1.length > subParts2.length ?
@@ -297,9 +306,9 @@ export function drawMoleculeDifferenceOnCanvas(
297
306
  g.font = '12px monospace';
298
307
  g.textBaseline = 'top';
299
308
 
300
- let palette: bio.SeqPalette = bio.UnknownSeqPalettes.Color;
309
+ let palette: SeqPalette = UnknownSeqPalettes.Color;
301
310
  if (units != 'HELM')
302
- palette = bio.getPaletteByType(units.substring(units.length - 2));
311
+ palette = getPaletteByType(units.substring(units.length - 2));
303
312
 
304
313
  const vShift = 7;
305
314
  for (let i = 0; i < subParts1.length; i++) {
@@ -309,12 +318,12 @@ export function drawMoleculeDifferenceOnCanvas(
309
318
 
310
319
  if (amino1 != amino2) {
311
320
  const color2 = palette.get(amino2);
312
- const subX0 = bio.printLeftOrCentered(updatedX, updatedY - vShift, w, h, g, amino1, color1, 0, true);
313
- const subX1 = bio.printLeftOrCentered(updatedX, updatedY + vShift, w, h, g, amino2, color2, 0, true);
321
+ const subX0 = printLeftOrCentered(updatedX, updatedY - vShift, w, h, g, amino1, color1, 0, true);
322
+ const subX1 = printLeftOrCentered(updatedX, updatedY + vShift, w, h, g, amino2, color2, 0, true);
314
323
  updatedX = Math.max(subX1, subX0);
315
324
  if (molDifferences)
316
325
  molDifferences[i] = createDifferenceCanvas(amino1, amino2, color1, color2, updatedY, vShift, h);
317
- } else { updatedX = bio.printLeftOrCentered(updatedX, updatedY, w, h, g, amino1, color1, 0, true, 0.5); }
326
+ } else { updatedX = printLeftOrCentered(updatedX, updatedY, w, h, g, amino1, color1, 0, true, 0.5); }
318
327
  updatedX += 4;
319
328
  }
320
329
  g.restore();
@@ -338,7 +347,7 @@ function createDifferenceCanvas(
338
347
  canvas.width = width + 4;
339
348
  context.font = '12px monospace';
340
349
  context.textBaseline = 'top';
341
- bio.printLeftOrCentered(0, y - shift, width, h, context, amino1, color1, 0, true);
342
- bio.printLeftOrCentered(0, y + shift, width, h, context, amino2, color2, 0, true);
350
+ printLeftOrCentered(0, y - shift, width, h, context, amino1, color1, 0, true);
351
+ printLeftOrCentered(0, y + shift, width, h, context, amino2, color2, 0, true);
343
352
  return canvas;
344
353
  }
@@ -1,10 +1,10 @@
1
1
  import * as DG from 'datagrok-api/dg';
2
2
  import * as ui from 'datagrok-api/ui';
3
3
  import * as grok from 'datagrok-api/grok';
4
- import * as bio from '@datagrok-libraries/bio';
5
4
 
6
5
  import $ from 'cash-dom';
7
6
  import {Subscription} from 'rxjs';
7
+ import {NOTATION, NotationConverter} from '@datagrok-libraries/bio';
8
8
 
9
9
 
10
10
  let convertDialog: DG.Dialog | null = null;
@@ -16,13 +16,13 @@ let convertDialogSubs: Subscription[] = [];
16
16
  * @param {DG.column} col Column with 'Macromolecule' semantic type
17
17
  */
18
18
  export function convert(col: DG.Column): void {
19
- const converter = new bio.NotationConverter(col);
20
- const currentNotation: bio.NOTATION = converter.notation;
19
+ const converter = new NotationConverter(col);
20
+ const currentNotation: NOTATION = converter.notation;
21
21
  //TODO: read all notations
22
22
  const notations = [
23
- bio.NOTATION.FASTA,
24
- bio.NOTATION.SEPARATOR,
25
- bio.NOTATION.HELM
23
+ NOTATION.FASTA,
24
+ NOTATION.SEPARATOR,
25
+ NOTATION.HELM
26
26
  ];
27
27
  const separatorArray = ['-', '.', '/'];
28
28
  const filteredNotations = notations.filter((e) => e !== currentNotation);
@@ -32,7 +32,7 @@ export function convert(col: DG.Column): void {
32
32
 
33
33
  // hide the separator input for non-SEPARATOR target notations
34
34
  const toggleSeparator = () => {
35
- if (targetNotationInput.value !== bio.NOTATION.SEPARATOR)
35
+ if (targetNotationInput.value !== NOTATION.SEPARATOR)
36
36
  $(separatorInput.root).hide();
37
37
  else
38
38
  $(separatorInput.root).show();
@@ -63,7 +63,7 @@ export function convert(col: DG.Column): void {
63
63
  separatorInput.root
64
64
  ]))
65
65
  .onOK(async () => {
66
- const targetNotation = targetNotationInput.value as bio.NOTATION;
66
+ const targetNotation = targetNotationInput.value as NOTATION;
67
67
  const separator: string | null = separatorInput.value;
68
68
 
69
69
  await convertDo(col, targetNotation, separator);
@@ -80,9 +80,9 @@ export function convert(col: DG.Column): void {
80
80
 
81
81
  /** Creates a new column with converted sequences and detects its semantic type */
82
82
  export async function convertDo(
83
- srcCol: DG.Column, targetNotation: bio.NOTATION, separator: string | null
83
+ srcCol: DG.Column, targetNotation: NOTATION, separator: string | null
84
84
  ): Promise<DG.Column> {
85
- const converter = new bio.NotationConverter(srcCol);
85
+ const converter = new NotationConverter(srcCol);
86
86
  const newColumn = converter.convert(targetNotation, separator);
87
87
  srcCol.dataFrame.columns.add(newColumn);
88
88
 
@@ -2,10 +2,9 @@
2
2
  import * as grok from 'datagrok-api/grok';
3
3
  import * as ui from 'datagrok-api/ui';
4
4
  import * as DG from 'datagrok-api/dg';
5
- import * as bio from '@datagrok-libraries/bio';
6
5
 
7
6
  import {FastaFileHandler} from '@datagrok-libraries/bio/src/utils/fasta-handler';
8
-
7
+ import {TAGS as bioTAGS} from '@datagrok-libraries/bio';
9
8
  //@ts-ignore
10
9
  import Aioli from '@biowasm/aioli';
11
10
 
@@ -39,7 +38,7 @@ export async function runKalign(srcCol: DG.Column, isAligned = false, unUsedName
39
38
  const fasta = _stringsToFasta(sequences);
40
39
  const CLI = await new Aioli([
41
40
  'base/1.0.0',
42
- {tool: 'kalign', version: '3.3.1', reinit: true,}
41
+ {tool: 'kalign', version: '3.3.1', reinit: true}
43
42
  ]);
44
43
 
45
44
  console.log(['fasta.length =', fasta.length]);
@@ -59,14 +58,14 @@ export async function runKalign(srcCol: DG.Column, isAligned = false, unUsedName
59
58
  // units
60
59
  const srcUnits = srcCol.getTag(DG.TAGS.UNITS);
61
60
  //aligned
62
- const srcAligned = srcCol.getTag(bio.TAGS.aligned);
61
+ const srcAligned = srcCol.getTag(bioTAGS.aligned);
63
62
  const tgtAligned = srcAligned + '.MSA';
64
63
  //alphabet
65
- const srcAlphabet = srcCol.getTag(bio.TAGS.alphabet);
64
+ const srcAlphabet = srcCol.getTag(bioTAGS.alphabet);
66
65
 
67
66
  tgtCol.setTag(DG.TAGS.UNITS, srcUnits);
68
- tgtCol.setTag(bio.TAGS.aligned, tgtAligned);
69
- tgtCol.setTag(bio.TAGS.alphabet, srcAlphabet);
67
+ tgtCol.setTag(bioTAGS.aligned, tgtAligned);
68
+ tgtCol.setTag(bioTAGS.alphabet, srcAlphabet);
70
69
  tgtCol.semType = DG.SEMTYPE.MACROMOLECULE;
71
70
  return tgtCol;
72
71
  }
@@ -1,16 +1,16 @@
1
1
  import * as DG from 'datagrok-api/dg';
2
2
  import * as ui from 'datagrok-api/ui';
3
3
  import * as grok from 'datagrok-api/grok';
4
- import * as bio from '@datagrok-libraries/bio';
5
4
 
6
5
  import wu from 'wu';
6
+ import {splitterAsFasta, SplitterFunc, UnitsHandler} from '@datagrok-libraries/bio';
7
7
 
8
8
  const FASTA_LINE_WIDTH = 60;
9
9
 
10
10
  /** Shows dialog to select id columns list and seq column, builds and downloads FASTA content */
11
11
  export function saveAsFastaUI() {
12
12
  // Use grid for column order adjusted by user
13
- let grid: DG.Grid = grok.shell.tv.grid;
13
+ const grid: DG.Grid = grok.shell.tv.grid;
14
14
 
15
15
  const idGColList: DG.GridColumn[] = wu.count(0).take(grid.columns.length)
16
16
  .map((colI: number) => grid.columns.byIndex(colI)!)
@@ -27,7 +27,7 @@ export function saveAsFastaUI() {
27
27
  .filter((gc: DG.GridColumn) => {
28
28
  const col: DG.Column | null = gc.column;
29
29
  if (col && col.semType === DG.SEMTYPE.MACROMOLECULE) {
30
- const uh = new bio.UnitsHandler(col);
30
+ const uh = new UnitsHandler(col);
31
31
  return uh.isFasta();
32
32
  }
33
33
  return false;
@@ -39,7 +39,7 @@ export function saveAsFastaUI() {
39
39
 
40
40
  const lineWidthInput = ui.intInput('FASTA line width', FASTA_LINE_WIDTH);
41
41
 
42
- ui.dialog({title: 'Save as FASTA',})
42
+ ui.dialog({title: 'Save as FASTA'})
43
43
  .add(ui.inputs([
44
44
  idGColListInput,
45
45
  seqColInput,
@@ -57,7 +57,7 @@ export function saveAsFastaUI() {
57
57
 
58
58
  const resFastaTxt: string = saveAsFastaDo(valueIdColList, valueSeqCol!, valueLineWidth);
59
59
 
60
- const aEl: HTMLAnchorElement = document.createElement('a',);
60
+ const aEl: HTMLAnchorElement = document.createElement('a');
61
61
  aEl.setAttribute('href', `data:text/plain;charset=utf-8,${encodeURIComponent(resFastaTxt)}`);
62
62
  aEl.setAttribute('download', `${grid.dataFrame.name}.fasta`);
63
63
  aEl.click();
@@ -69,7 +69,7 @@ export function saveAsFastaUI() {
69
69
  export function saveAsFastaDo(
70
70
  idColList: DG.Column[], seqCol: DG.Column, lineWidth: number = FASTA_LINE_WIDTH, lineSeparator: string = '\n'
71
71
  ): string {
72
- const splitter: bio.SplitterFunc = bio.splitterAsFasta;
72
+ const splitter: SplitterFunc = splitterAsFasta;
73
73
 
74
74
  const fastaLines: string[] = [];
75
75
 
@@ -91,7 +91,7 @@ export function saveAsFastaDo(
91
91
  }
92
92
 
93
93
  /* split sequence for monomers to prevent wrapping monomer partially */
94
- export function wrapSequence(seq: string, splitter: bio.SplitterFunc, lineWidth: number = FASTA_LINE_WIDTH): string[] {
94
+ export function wrapSequence(seq: string, splitter: SplitterFunc, lineWidth: number = FASTA_LINE_WIDTH): string[] {
95
95
  const seqMonomerList = splitter(seq);
96
96
  let seqPos: number = 0;
97
97
  const seqLength: number = seqMonomerList.length;
@@ -106,4 +106,4 @@ export function wrapSequence(seq: string, splitter: bio.SplitterFunc, lineWidth:
106
106
  }
107
107
 
108
108
  return seqLineList;
109
- }
109
+ }
@@ -1,9 +1,10 @@
1
1
  import * as ui from 'datagrok-api/ui';
2
2
  import * as grok from 'datagrok-api/grok';
3
3
  import * as DG from 'datagrok-api/dg';
4
- import * as bio from '@datagrok-libraries/bio';
5
4
 
6
- const vrt = bio.VdRegionType;
5
+ import {IVdRegionsViewer, PositionHeight, VdRegion, VdRegionType, WebLogoViewer} from '@datagrok-libraries/bio';
6
+
7
+ const vrt = VdRegionType;
7
8
 
8
9
  // Positions of regions for numbering schemes
9
10
  // http://www.bioinf.org.uk/abs/info.html
@@ -34,7 +35,7 @@ const vrt = bio.VdRegionType;
34
35
  /** Viewer with tabs based on description of chain regions.
35
36
  * Used to define regions of an immunoglobulin LC.
36
37
  */
37
- export class VdRegionsViewer extends DG.JsViewer implements bio.IVdRegionsViewer {
38
+ export class VdRegionsViewer extends DG.JsViewer implements IVdRegionsViewer {
38
39
  // private regionsDf: DG.DataFrame;
39
40
  private regionsFg: DG.FilterGroup | null = null;
40
41
  // private regionsTV: DG.TableView;
@@ -43,7 +44,7 @@ export class VdRegionsViewer extends DG.JsViewer implements bio.IVdRegionsViewer
43
44
  private isOpened: boolean = false;
44
45
  private panelNode: DG.DockNode | null = null;
45
46
 
46
- public regions: bio.VdRegion[] = [];
47
+ public regions: VdRegion[] = [];
47
48
  public regionTypes: string[];
48
49
  public chains: string[];
49
50
  public sequenceColumnNamePostfix: string;
@@ -58,7 +59,7 @@ export class VdRegionsViewer extends DG.JsViewer implements bio.IVdRegionsViewer
58
59
  }
59
60
 
60
61
  // TODO: .onTableAttached is not calling on dataFrame set, onPropertyChanged also not calling
61
- public async setDf(value: DG.DataFrame, regions: bio.VdRegion[]) {
62
+ public async setDf(value: DG.DataFrame, regions: VdRegion[]) {
62
63
  console.debug('VdRegionsViewer.setDf()');
63
64
  await this.destroyView();
64
65
  this.regions = regions;
@@ -78,8 +79,8 @@ export class VdRegionsViewer extends DG.JsViewer implements bio.IVdRegionsViewer
78
79
 
79
80
  this.skipEmptyPositions = this.bool('skipEmptyPositions', false);
80
81
  this.positionWidth = this.float('positionWidth', 16);
81
- this.positionHeight = this.string('positionHeight', bio.PositionHeight.Entropy,
82
- {choices: Object.keys(bio.PositionHeight)});
82
+ this.positionHeight = this.string('positionHeight', PositionHeight.Entropy,
83
+ {choices: Object.keys(PositionHeight)});
83
84
  }
84
85
 
85
86
  public async init() {
@@ -180,7 +181,7 @@ export class VdRegionsViewer extends DG.JsViewer implements bio.IVdRegionsViewer
180
181
  //#region -- View --
181
182
  private host: HTMLElement | null = null;
182
183
  private mainLayout: HTMLTableElement | null = null;
183
- private logos: { [chain: string]: bio.WebLogoViewer }[] = [];
184
+ private logos: { [chain: string]: WebLogoViewer }[] = [];
184
185
 
185
186
  private async destroyView(): Promise<void> {
186
187
  // TODO: Unsubscribe from and remove all view elements
@@ -200,16 +201,16 @@ export class VdRegionsViewer extends DG.JsViewer implements bio.IVdRegionsViewer
200
201
  const colNames: { [chain: string]: string } = Object.assign({},
201
202
  ...this.chains.map((chain) => ({[chain]: `${chain} ${this.sequenceColumnNamePostfix}`})));
202
203
 
203
- const regionsFiltered: bio.VdRegion[] = this.regions.filter((r: bio.VdRegion) => this.regionTypes.includes(r.type));
204
+ const regionsFiltered: VdRegion[] = this.regions.filter((r: VdRegion) => this.regionTypes.includes(r.type));
204
205
 
205
206
  const orderList: number[] = Array.from(new Set(regionsFiltered.map((r) => r.order))).sort();
206
207
 
207
208
  this.logos = [];
208
209
 
209
210
  for (let orderI = 0; orderI < orderList.length; orderI++) {
210
- const regionChains: { [chain: string]: bio.WebLogoViewer } = {};
211
+ const regionChains: { [chain: string]: WebLogoViewer } = {};
211
212
  for (const chain of this.chains) {
212
- const region: bio.VdRegion | undefined = regionsFiltered
213
+ const region: VdRegion | undefined = regionsFiltered
213
214
  .find((r) => r.order == orderList[orderI] && r.chain == chain);
214
215
  regionChains[chain] = (await this.dataFrame.plot.fromType('WebLogo', {
215
216
  sequenceColumnName: colNames[chain],
@@ -219,7 +220,7 @@ export class VdRegionsViewer extends DG.JsViewer implements bio.IVdRegionsViewer
219
220
  skipEmptyPositions: this.skipEmptyPositions,
220
221
  positionWidth: this.positionWidth,
221
222
  positionHeight: this.positionHeight,
222
- })) as unknown as bio.WebLogoViewer;
223
+ })) as unknown as WebLogoViewer;
223
224
  }
224
225
  // WebLogo creation fires onRootSizeChanged event even before control being added to this.logos
225
226
  this.logos[orderI] = regionChains;
@@ -244,7 +245,7 @@ export class VdRegionsViewer extends DG.JsViewer implements bio.IVdRegionsViewer
244
245
  })] : []),
245
246
  // List with controls for regions
246
247
  ...[...Array(orderList.length).keys()].map((orderI) => {
247
- const wl: bio.WebLogoViewer = this.logos[orderI][chain];
248
+ const wl: WebLogoViewer = this.logos[orderI][chain];
248
249
  wl.root.style.height = '100%';
249
250
 
250
251
  const resDiv = ui.div([wl.root]/*`${chain} ${regionsFiltered[rI]}`*/, {
@@ -261,7 +262,7 @@ export class VdRegionsViewer extends DG.JsViewer implements bio.IVdRegionsViewer
261
262
  },
262
263
  ['', ...[...Array(orderList.length).keys()].map(
263
264
  (orderI: number) => regionsFiltered.find(
264
- (r: bio.VdRegion) => r.order == orderList[orderI] && r.chain == this.chains[0]
265
+ (r: VdRegion) => r.order == orderList[orderI] && r.chain == this.chains[0]
265
266
  )!.name || 'Name')]
266
267
  );
267
268
  this.mainLayout.className = 'mlb-vd-regions-viewer-table2';
package/tsconfig.json CHANGED
@@ -6,7 +6,7 @@
6
6
  // "incremental": true, /* Enable incremental compilation */
7
7
  "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
8
8
  "module": "es2020", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
9
- "lib": ["es2020", "dom", "ES2021.String"], /* Specify library files to be included in the compilation. */
9
+ "lib": ["es2020", "dom", "ES2021.String"], /* Specify library files to be included in the compilation. */
10
10
  // "allowJs": true, /* Allow javascript files to be compiled. */
11
11
  // "checkJs": true, /* Report errors in .js files. */
12
12
  // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
package/jest.config.js DELETED
@@ -1,33 +0,0 @@
1
- module.exports = {
2
- 'roots': [
3
- '<rootDir>/src',
4
- ],
5
- 'testMatch': [
6
- '**/__jest__/**/*.test.+(ts|tsx)',
7
- ],
8
- moduleFileExtensions: [
9
- 'ts',
10
- 'js',
11
- ],
12
- 'transform': {
13
- '^.+\\.(ts|tsx)$': 'ts-jest',
14
- },
15
- transformIgnorePatterns: ['^.+\\.js$'],
16
- globals: {
17
- 'ts-jest': {
18
- 'tsconfig': {
19
- 'target': 'es6',
20
- 'module': 'es2020',
21
- },
22
- },
23
- },
24
- reporters: [
25
- 'default',
26
- [
27
- './node_modules/jest-html-reporter',
28
- {
29
- 'includeConsoleLog': true,
30
- },
31
- ],
32
- ],
33
- };