@datagrok/bio 2.23.2 → 2.25.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.
Files changed (63) hide show
  1. package/.eslintrc.json +0 -2
  2. package/CHANGELOG.md +9 -0
  3. package/README.md +1 -1
  4. package/dist/455.js.map +1 -1
  5. package/dist/package-test.js +3 -3
  6. package/dist/package-test.js.map +1 -1
  7. package/dist/package.js +2 -2
  8. package/dist/package.js.map +1 -1
  9. package/files/samples/HELM_CHEMS.csv +11 -0
  10. package/package.json +2 -2
  11. package/src/analysis/sequence-space.ts +1 -1
  12. package/src/demo/bio03-atomic-level.ts +1 -1
  13. package/src/package-types.ts +2 -2
  14. package/src/package.ts +10 -4
  15. package/src/tests/activity-cliffs-tests.ts +2 -2
  16. package/src/tests/monomer-libraries-tests.ts +9 -7
  17. package/src/tests/renderers-monomer-placer-tests.ts +1 -1
  18. package/src/tests/scoring.ts +1 -1
  19. package/src/tests/seq-handler-get-helm-tests.ts +1 -1
  20. package/src/tests/splitters-test.ts +2 -2
  21. package/src/tests/substructure-filters-tests.ts +11 -11
  22. package/src/tests/to-atomic-level-tests.ts +2 -2
  23. package/src/tests/to-atomic-level-ui-tests.ts +13 -14
  24. package/src/utils/cell-renderer.ts +1 -1
  25. package/src/utils/get-region.ts +2 -2
  26. package/src/utils/helm-to-molfile/converter/const.ts +0 -1
  27. package/src/utils/helm-to-molfile/converter/converter.ts +4 -4
  28. package/src/utils/helm-to-molfile/converter/helm.ts +14 -6
  29. package/src/utils/helm-to-molfile/converter/mol-bonds.ts +2 -2
  30. package/src/utils/helm-to-molfile/converter/mol-wrapper.ts +2 -2
  31. package/src/utils/helm-to-molfile/converter/monomer-wrapper.ts +1 -1
  32. package/src/utils/helm-to-molfile/converter/polymer.ts +1 -1
  33. package/src/utils/helm-to-molfile/converter/r-group-handler.ts +2 -2
  34. package/src/utils/helm-to-molfile/utils.ts +3 -2
  35. package/src/utils/monomer-cell-renderer-base.ts +1 -2
  36. package/src/utils/monomer-lib/consts.ts +1 -6
  37. package/src/utils/monomer-lib/lib-manager.ts +239 -112
  38. package/src/utils/monomer-lib/library-file-manager/file-validator.ts +1 -1
  39. package/src/utils/monomer-lib/library-file-manager/monomers-lib-provider.ts +378 -0
  40. package/src/utils/monomer-lib/library-file-manager/ui.ts +120 -81
  41. package/src/utils/monomer-lib/monomer-colors.ts +37 -39
  42. package/src/utils/monomer-lib/monomer-lib-base.ts +34 -7
  43. package/src/utils/monomer-lib/monomer-lib.ts +7 -33
  44. package/src/utils/monomer-lib/monomer-manager/duplicate-monomer-manager.ts +3 -3
  45. package/src/utils/monomer-lib/monomer-manager/monomer-manager.ts +91 -82
  46. package/src/utils/monomer-lib/smiles2Monomer.ts +128 -0
  47. package/src/utils/monomer-lib/web-editor-monomer-dummy.ts +15 -1
  48. package/src/utils/monomer-lib/web-editor-monomer-of-library.ts +2 -1
  49. package/src/utils/multiple-sequence-alignment-ui.ts +1 -1
  50. package/src/utils/multiple-sequence-alignment.ts +1 -1
  51. package/src/utils/seq-helper/seq-handler.ts +26 -13
  52. package/src/utils/seq-helper/seq-helper.ts +1 -2
  53. package/src/utils/sequence-to-mol.ts +1 -1
  54. package/src/utils/ui-utils.ts +1 -1
  55. package/src/viewers/web-logo-viewer.ts +20 -9
  56. package/src/widgets/composition-analysis-widget.ts +1 -1
  57. package/src/widgets/sequence-scrolling-widget.ts +1 -2
  58. package/test-console-output-1.log +670 -721
  59. package/test-record-1.mp4 +0 -0
  60. package/src/utils/monomer-lib/library-file-manager/custom-monomer-lib-handlers.ts +0 -41
  61. package/src/utils/monomer-lib/library-file-manager/event-manager.ts +0 -93
  62. package/src/utils/monomer-lib/library-file-manager/file-manager.ts +0 -317
  63. package/src/utils/monomer-lib/monomer-set.ts +0 -61
@@ -6,11 +6,11 @@ import wu from 'wu';
6
6
 
7
7
  /* eslint-disable max-len */
8
8
  import {ALIGNMENT, ALPHABET, candidateAlphabets, getSplitterWithSeparator, NOTATION, positionSeparator, splitterAsFasta, splitterAsHelm, TAGS} from '@datagrok-libraries/bio/src/utils/macromolecule/index';
9
- import {INotationProvider, ISeqConnection, ISeqSplitted, SeqColStats, SplitterFunc,} from '@datagrok-libraries/bio/src/utils/macromolecule/types';
9
+ import {CandidateType, INotationProvider, ISeqConnection, ISeqSplitted, SeqColStats, SplitterFunc,} from '@datagrok-libraries/bio/src/utils/macromolecule/types';
10
10
  import {detectAlphabet, detectHelmAlphabet, splitterAsFastaSimple, StringListSeqSplitted} from '@datagrok-libraries/bio/src/utils/macromolecule/utils';
11
11
  import {mmDistanceFunctions, MmDistanceFunctionsNames} from '@datagrok-libraries/ml/src/macromolecule-distance-functions';
12
12
  import {mmDistanceFunctionType} from '@datagrok-libraries/ml/src/macromolecule-distance-functions/types';
13
- import {getMonomerLibHelper, IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
13
+ import {getMonomerLibHelper, IMonomerLibHelper} from '@datagrok-libraries/bio/src/types/monomer-library';
14
14
  import {HELM_POLYMER_TYPE, HELM_WRAPPERS_REGEXP, PHOSPHATE_SYMBOL} from '@datagrok-libraries/bio/src/utils/const';
15
15
  import {GAP_SYMBOL, GapOriginals} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
16
16
  import {CellRendererBackBase, GridCellRendererTemp} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
@@ -132,7 +132,7 @@ export class SeqHandler implements ISeqHandler {
132
132
  for (const seq of values) {
133
133
  const mSeq = !!seq ? splitter(seq) : [];
134
134
 
135
- if (firstLength === null)
135
+ if (firstLength == null)
136
136
  firstLength = mSeq.length;
137
137
  else if (mSeq.length !== firstLength)
138
138
  sameLength = false;
@@ -182,13 +182,13 @@ export class SeqHandler implements ISeqHandler {
182
182
  throw new Error('Alphabet is empty and not annotated.');
183
183
 
184
184
  let aligned = uh.column.getTag(TAGS.aligned);
185
- if (aligned === null) {
185
+ if (aligned == null) {
186
186
  aligned = uh.stats.sameLength ? ALIGNMENT.SEQ_MSA : ALIGNMENT.SEQ;
187
187
  uh.column.setTag(TAGS.aligned, aligned);
188
188
  }
189
189
 
190
190
  let alphabet = uh.column.getTag(TAGS.alphabet);
191
- if (alphabet === null) {
191
+ if (alphabet == null) {
192
192
  alphabet = detectAlphabet(uh.stats.freq, candidateAlphabets);
193
193
  uh.column.setTag(TAGS.alphabet, alphabet);
194
194
  }
@@ -200,8 +200,21 @@ export class SeqHandler implements ISeqHandler {
200
200
  }
201
201
  } else if (units === NOTATION.HELM) {
202
202
  let alphabet = uh.column.getTag(TAGS.alphabet);
203
- if (alphabet === null) {
204
- alphabet = detectHelmAlphabet(uh.stats.freq, candidateAlphabets, uh.defaultGapOriginal);
203
+ if (alphabet == null) {
204
+ // const cats = uh.column.categories;
205
+ // const splitter = uh.getSplitter();
206
+ // const samples = Array.from(new Set(
207
+ // wu.count(0).take(Math.min(100, cats.length)).map((_) => Math.floor(Math.random() * cats.length)).toArray())
208
+ // ).map((catIndex) => cats[catIndex]).filter((s) => (s?.length ?? 0) > 0).map((s) => splitter(s));
209
+ // // splitted helm has info about polymer types
210
+ // const polymerTypes = new Set<HELM_POLYMER_TYPE>();
211
+ // for (const ss of samples) {
212
+ // ss.graphInfo?.polymerTypes
213
+ // }
214
+ // increase the detection threshold for candidate alphabets
215
+ const modifiedCandidateAlphabets = candidateAlphabets.map((ca) => new CandidateType(ca.name, ca.alphabet, 0.9));
216
+
217
+ alphabet = detectHelmAlphabet(uh.stats.freq, modifiedCandidateAlphabets, uh.defaultGapOriginal);
205
218
  uh.column.setTag(TAGS.alphabet, alphabet);
206
219
  }
207
220
  }
@@ -219,7 +232,7 @@ export class SeqHandler implements ISeqHandler {
219
232
 
220
233
  public get separator(): string | undefined {
221
234
  const separator: string | undefined = this.column.getTag(TAGS.separator) ?? undefined;
222
- if (this.notation === NOTATION.SEPARATOR && separator === undefined)
235
+ if (this.notation === NOTATION.SEPARATOR && separator == undefined)
223
236
  throw new Error(`Separator is mandatory for column '${this.column.name}' of notation '${this.notation}'.`);
224
237
  return separator;
225
238
  }
@@ -314,7 +327,7 @@ export class SeqHandler implements ISeqHandler {
314
327
  const seq = this.column.get(rowIdx);
315
328
  return this.getSplitter(limit)(seq);
316
329
  } else {
317
- if (this.column.version !== this.columnVersion || this._splitted === null) {
330
+ if (this.column.version !== this.columnVersion || this._splitted == null) {
318
331
  this.columnVersion = this.column.version;
319
332
  this._splitted = new Array<WeakRef<ISeqSplitted>>(this.column.length);
320
333
  }
@@ -395,7 +408,7 @@ export class SeqHandler implements ISeqHandler {
395
408
  }
396
409
 
397
410
  public get stats(): SeqColStats {
398
- if (this._stats === null) {
411
+ if (this._stats == null) {
399
412
  const freq: { [m: string]: number } = {};
400
413
  let sameLength = true;
401
414
  let firstLength = null;
@@ -422,7 +435,7 @@ export class SeqHandler implements ISeqHandler {
422
435
 
423
436
  private _maxLength: number | null = null;
424
437
  public get maxLength(): number {
425
- if (this._maxLength === null) {
438
+ if (this._maxLength == null) {
426
439
  this._maxLength = this.column.length === 0 ? 0 :
427
440
  wu.count(0).take(this.column.length).map((rowIdx) => this.getSplitted(rowIdx).length).reduce((a, b) => a > b ? a : b, 0);
428
441
  }
@@ -431,7 +444,7 @@ export class SeqHandler implements ISeqHandler {
431
444
 
432
445
  private _posList: string[] | null = null;
433
446
  public get posList(): string[] {
434
- if (this._posList === null) {
447
+ if (this._posList == null) {
435
448
  const posListTxt = this.column.getTag(TAGS.positionNames);
436
449
  this._posList = posListTxt ? posListTxt.split(positionSeparator).map((p) => p.trim()) :
437
450
  wu.count(1).take(this.maxLength).map((pos) => pos.toString()).toArray();
@@ -606,7 +619,7 @@ export class SeqHandler implements ISeqHandler {
606
619
  }
607
620
 
608
621
  get splitter(): SplitterFunc {
609
- if (this._splitter === null)
622
+ if (this._splitter == null)
610
623
  this._splitter = this.getSplitter();
611
624
  return this._splitter;
612
625
  }
@@ -6,12 +6,11 @@ import wu from 'wu';
6
6
 
7
7
  import {ISeqHelper, ToAtomicLevelRes} from '@datagrok-libraries/bio/src/utils/seq-helper';
8
8
  import {RDModule, RDMol} from '@datagrok-libraries/chem-meta/src/rdkit-api';
9
- import {IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
10
9
  import {getHelmHelper, IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
11
10
  import {MolfileWithMap} from '@datagrok-libraries/bio/src/monomer-works/types';
12
11
  import {getMolColName} from '@datagrok-libraries/bio/src/monomer-works/utils';
13
12
  import {ChemTags} from '@datagrok-libraries/chem-meta/src/consts';
14
- import {IMonomerLibBase} from '@datagrok-libraries/bio/src/types/index';
13
+ import {IMonomerLibBase, IMonomerLibHelper} from '@datagrok-libraries/bio/src/types/monomer-library';
15
14
 
16
15
  import {HelmToMolfileConverter} from '../helm-to-molfile/converter';
17
16
  import {ISeqHandler} from '@datagrok-libraries/bio/src/utils/macromolecule/seq-handler';
@@ -3,7 +3,7 @@ import * as ui from 'datagrok-api/ui';
3
3
  import * as DG from 'datagrok-api/dg';
4
4
 
5
5
  import {_toAtomicLevel} from '@datagrok-libraries/bio/src/monomer-works/to-atomic-level';
6
- import {IMonomerLib} from '@datagrok-libraries/bio/src/types';
6
+ import {IMonomerLib} from '@datagrok-libraries/bio/src/types/monomer-library';
7
7
  import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
8
8
  import {getSeqHelper, ISeqHelper, ToAtomicLevelRes} from '@datagrok-libraries/bio/src/utils/seq-helper';
9
9
  import {RDModule} from '@datagrok-libraries/chem-meta/src/rdkit-api';
@@ -3,7 +3,7 @@ import * as DG from 'datagrok-api/dg';
3
3
 
4
4
  export function getMacromoleculeColumns(): DG.Column<string>[] {
5
5
  const columns = grok.shell.t.columns.bySemTypeAll(DG.SEMTYPE.MACROMOLECULE);
6
- if (columns === null) {
6
+ if (columns == null) {
7
7
  grok.shell.error('Current table does not contain macromolecules');
8
8
  return [];
9
9
  }
@@ -25,7 +25,7 @@ import {ISeqSplitted} from '@datagrok-libraries/bio/src/utils/macromolecule/type
25
25
  import {testEvent} from '@datagrok-libraries/utils/src/test';
26
26
  import {PromiseSyncer} from '@datagrok-libraries/bio/src/utils/syncer';
27
27
  import {GAP_SYMBOL} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
28
- import {IMonomerLibBase} from '@datagrok-libraries/bio/src/types/index';
28
+ import {IMonomerLibBase} from '@datagrok-libraries/bio/src/types/monomer-library';
29
29
  import {HelmType} from '@datagrok-libraries/bio/src/helm/types';
30
30
  import {undefinedColor} from '@datagrok-libraries/bio/src/utils/cell-renderer-monomer-placer';
31
31
 
@@ -34,6 +34,7 @@ import {AggFunc, getAgg} from '../utils/agg';
34
34
  import {_package, PackageFunctions} from '../package';
35
35
  import {numbersWithinMaxDiff} from './utils';
36
36
  import {buildCompositionTable} from '@datagrok-libraries/bio/src/utils/composition-table';
37
+ import {helmTypeToPolymerType} from '@datagrok-libraries/bio/src/monomer-works/monomer-works';
37
38
 
38
39
  declare global {
39
40
  interface HTMLCanvasElement {
@@ -212,14 +213,24 @@ export class PositionInfo {
212
213
  ) {
213
214
  for (const [monomer, pmInfo] of Object.entries(this._freqs)) {
214
215
  if (monomer !== GAP_SYMBOL) {
215
- const monomerTxt = monomerToShort(monomer, maxMonomerLetters);
216
+ // to handle explicit smiles based monomers in monomer lib
217
+ let monomerDisplayValue = monomer;
218
+
216
219
  const b = pmInfo.bounds!;
217
220
  const left = b.left;
218
221
 
219
222
  let color: string = undefinedColor;
220
- if (monomerLib)
221
- color = monomerLib.getMonomerTextColor(biotype, monomer)!;
222
-
223
+ if (monomerLib) {
224
+ try {
225
+ color = monomerLib.getMonomerTextColor(biotype, monomer)!;
226
+ const m = monomerLib.getMonomer(helmTypeToPolymerType(biotype), monomer);
227
+ if (m && m.symbol !== monomer) // for explicit smiles based monomers
228
+ monomerDisplayValue = m.symbol;
229
+ } catch (e) {
230
+ errorToConsole(e);
231
+ }
232
+ }
233
+ const monomerTxt = monomerToShort(monomerDisplayValue, maxMonomerLetters);
223
234
  g.resetTransform();
224
235
  g.strokeStyle = 'lightgray';
225
236
  g.lineWidth = 1;
@@ -949,7 +960,7 @@ export class WebLogoViewer extends DG.JsViewer implements IWebLogoViewer {
949
960
  return [null, null, null];
950
961
 
951
962
  const monomer: string | undefined = pi.getMonomerAt(calculatedX, p.y);
952
- if (monomer === undefined)
963
+ if (monomer == undefined)
953
964
  return [pi, null, null];
954
965
 
955
966
  return [pi, monomer, pi.getFreq(monomer)];
@@ -1262,7 +1273,7 @@ export class WebLogoViewer extends DG.JsViewer implements IWebLogoViewer {
1262
1273
  const [pi, monomer] = this.getMonomer(cursorP, dpr);
1263
1274
  const positionLabelHeight = this.showPositionLabels ? POSITION_LABELS_HEIGHT * dpr : 0;
1264
1275
 
1265
- if (pi !== null && monomer === null && 0 <= cursorP.y && cursorP.y <= positionLabelHeight) {
1276
+ if (pi !== null && monomer == null && 0 <= cursorP.y && cursorP.y <= positionLabelHeight) {
1266
1277
  // Position tooltip
1267
1278
 
1268
1279
  const tooltipRows = [ui.divText(`Position ${pi.label}`)];
@@ -1373,8 +1384,8 @@ function renderPositionLabels(g: CanvasRenderingContext2D,
1373
1384
  const pos = positions[jPos];
1374
1385
  const tm = g.measureText(pos.name);
1375
1386
  const textHeight = tm.actualBoundingBoxDescent - tm.actualBoundingBoxAscent;
1376
- maxPosNameWidth = maxPosNameWidth === null ? tm.width : Math.max(maxPosNameWidth, tm.width);
1377
- maxPosNameHeight = maxPosNameHeight === null ? textHeight : Math.max(maxPosNameHeight, textHeight);
1387
+ maxPosNameWidth = maxPosNameWidth == null ? tm.width : Math.max(maxPosNameWidth, tm.width);
1388
+ maxPosNameHeight = maxPosNameHeight == null ? textHeight : Math.max(maxPosNameHeight, textHeight);
1378
1389
  }
1379
1390
  const hScale = maxPosNameWidth! < (positionWidth * dpr - 2) ? 1 : (positionWidth * dpr - 2) / maxPosNameWidth!;
1380
1391
 
@@ -6,7 +6,7 @@ import wu from 'wu';
6
6
 
7
7
  import {TAGS as bioTAGS, ALPHABET} from '@datagrok-libraries/bio/src/utils/macromolecule';
8
8
  import {GAP_SYMBOL} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
9
- import {IMonomerLibBase} from '@datagrok-libraries/bio/src/types';
9
+ import {IMonomerLibBase} from '@datagrok-libraries/bio/src/types/monomer-library';
10
10
  import {HelmType} from '@datagrok-libraries/bio/src/helm/types';
11
11
  import {HelmTypes, PolymerTypes} from '@datagrok-libraries/bio/src/helm/consts';
12
12
 
@@ -10,11 +10,10 @@ import {ConservationTrack, MSAHeaderTrack, MSAScrollingHeader, WebLogoTrack} fro
10
10
  import {MonomerPlacer} from '@datagrok-libraries/bio/src/utils/cell-renderer-monomer-placer';
11
11
  import {ALPHABET, TAGS as bioTAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
12
12
  import {_package} from '../package';
13
- import {getMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
14
13
  import {ISeqHandler} from '@datagrok-libraries/bio/src/utils/macromolecule/seq-handler';
15
14
  import * as RxJs from 'rxjs';
16
15
  import {filter} from 'rxjs/operators';
17
- import {IMonomerLib} from '@datagrok-libraries/bio/src/types';
16
+ import {IMonomerLib, getMonomerLibHelper} from '@datagrok-libraries/bio/src/types/monomer-library';
18
17
  import wu from 'wu';
19
18
 
20
19
  // ============================================================================