@datagrok/bio 2.15.13 → 2.16.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 (78) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/detectors.js +16 -11
  3. package/dist/455.js.map +1 -1
  4. package/dist/980.js +1 -1
  5. package/dist/980.js.map +1 -1
  6. package/dist/package-test.js +6 -6
  7. package/dist/package-test.js.map +1 -1
  8. package/dist/package.js +3 -3
  9. package/dist/package.js.map +1 -1
  10. package/package.json +5 -5
  11. package/src/analysis/sequence-activity-cliffs.ts +3 -4
  12. package/src/analysis/sequence-diversity-viewer.ts +5 -3
  13. package/src/analysis/sequence-similarity-viewer.ts +8 -5
  14. package/src/analysis/sequence-space.ts +3 -2
  15. package/src/calculations/monomerLevelMols.ts +3 -3
  16. package/src/demo/bio01-similarity-diversity.ts +4 -1
  17. package/src/package-test.ts +1 -1
  18. package/src/package-types.ts +35 -2
  19. package/src/package.ts +57 -71
  20. package/src/tests/WebLogo-layout-tests.ts +1 -1
  21. package/src/tests/WebLogo-positions-test.ts +11 -5
  22. package/src/tests/WebLogo-project-tests.ts +1 -1
  23. package/src/tests/activity-cliffs-utils.ts +11 -14
  24. package/src/tests/bio-tests.ts +85 -79
  25. package/src/tests/checkInputColumn-tests.ts +15 -10
  26. package/src/tests/converters-test.ts +12 -5
  27. package/src/tests/detectors-benchmark-tests.ts +5 -2
  28. package/src/tests/detectors-tests.ts +51 -44
  29. package/src/tests/detectors-weak-and-likely-tests.ts +12 -5
  30. package/src/tests/fasta-export-tests.ts +13 -5
  31. package/src/tests/helm-tests.ts +85 -0
  32. package/src/tests/mm-distance-tests.ts +14 -7
  33. package/src/tests/monomer-libraries-tests.ts +1 -1
  34. package/src/tests/msa-tests.ts +33 -24
  35. package/src/tests/renderers-monomer-placer-tests.ts +2 -5
  36. package/src/tests/renderers-test.ts +15 -9
  37. package/src/tests/scoring.ts +9 -6
  38. package/src/tests/seq-handler-get-helm-tests.ts +7 -5
  39. package/src/tests/seq-handler-get-region-tests.ts +9 -3
  40. package/src/tests/seq-handler-splitted-tests.ts +11 -5
  41. package/src/tests/seq-handler-tests.ts +17 -10
  42. package/src/tests/sequence-space-utils.ts +9 -4
  43. package/src/tests/splitters-test.ts +5 -4
  44. package/src/tests/substructure-filters-tests.ts +16 -13
  45. package/src/tests/to-atomic-level-tests.ts +5 -3
  46. package/src/tests/to-atomic-level-ui-tests.ts +4 -1
  47. package/src/tests/utils/detectors-utils.ts +4 -4
  48. package/src/utils/calculate-scores.ts +11 -9
  49. package/src/utils/cell-renderer-custom.ts +27 -17
  50. package/src/utils/cell-renderer.ts +14 -8
  51. package/src/utils/check-input-column.ts +13 -9
  52. package/src/utils/context-menu.ts +4 -4
  53. package/src/utils/convert.ts +21 -14
  54. package/src/utils/get-region-func-editor.ts +8 -5
  55. package/src/utils/get-region.ts +4 -5
  56. package/src/utils/helm-to-molfile/converter/helm.ts +4 -4
  57. package/src/utils/helm-to-molfile/utils.ts +5 -6
  58. package/src/utils/macromolecule-column-widget.ts +6 -7
  59. package/src/utils/monomer-cell-renderer-base.ts +8 -1
  60. package/src/utils/monomer-lib/lib-manager.ts +3 -2
  61. package/src/utils/monomer-lib/monomer-colors.ts +10 -10
  62. package/src/utils/monomer-lib/monomer-lib-base.ts +6 -1
  63. package/src/utils/monomer-lib/monomer-lib.ts +15 -9
  64. package/src/utils/multiple-sequence-alignment-ui.ts +30 -30
  65. package/src/utils/save-as-fasta.ts +19 -12
  66. package/src/utils/seq-helper/seq-handler.ts +859 -0
  67. package/src/utils/seq-helper/seq-helper.ts +11 -21
  68. package/src/utils/sequence-to-mol.ts +7 -8
  69. package/src/utils/split-to-monomers.ts +7 -2
  70. package/src/utils/types.ts +8 -7
  71. package/src/utils/ui-utils.ts +2 -2
  72. package/src/viewers/web-logo-viewer.ts +18 -16
  73. package/src/widgets/bio-substructure-filter.ts +1 -2
  74. package/src/widgets/composition-analysis-widget.ts +6 -6
  75. package/src/widgets/representations.ts +7 -4
  76. package/src/tests/detectors-custom-notation-tests.ts +0 -37
  77. package/src/utils/cyclized.ts +0 -89
  78. package/src/utils/dimerized.ts +0 -10
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "name": "Aleksandr Tanas",
6
6
  "email": "atanas@datagrok.ai"
7
7
  },
8
- "version": "2.15.13",
8
+ "version": "2.16.0",
9
9
  "description": "Bioinformatics support (import/export of sequences, conversion, visualization, analysis). [See more](https://github.com/datagrok-ai/public/blob/master/packages/Bio/README.md) for details.",
10
10
  "repository": {
11
11
  "type": "git",
@@ -37,10 +37,10 @@
37
37
  ],
38
38
  "dependencies": {
39
39
  "@biowasm/aioli": "^3.1.0",
40
- "@datagrok-libraries/bio": "^5.44.5",
40
+ "@datagrok-libraries/bio": "^5.45.0",
41
41
  "@datagrok-libraries/chem-meta": "^1.2.7",
42
42
  "@datagrok-libraries/math": "^1.2.1",
43
- "@datagrok-libraries/ml": "^6.7.3",
43
+ "@datagrok-libraries/ml": "^6.7.4",
44
44
  "@datagrok-libraries/tutorials": "^1.4.3",
45
45
  "@datagrok-libraries/utils": "^4.3.6",
46
46
  "@webgpu/types": "^0.1.40",
@@ -58,8 +58,8 @@
58
58
  "wu": "latest"
59
59
  },
60
60
  "devDependencies": {
61
- "@datagrok-libraries/helm-web-editor": "^1.1.11",
62
- "@datagrok-libraries/js-draw-lite": "^0.0.8",
61
+ "@datagrok-libraries/helm-web-editor": "^1.1.12",
62
+ "@datagrok-libraries/js-draw-lite": "^0.0.9",
63
63
  "@datagrok/chem": "^1.12.3",
64
64
  "@datagrok/dendrogram": "^1.2.33",
65
65
  "@datagrok/helm": "^2.5.3",
@@ -10,11 +10,10 @@ import {AvailableMetrics, DistanceMetricsSubjects, StringMetricsNames} from '@da
10
10
  import {drawMoleculeDifferenceOnCanvas} from '../utils/cell-renderer';
11
11
  import {invalidateMols, MONOMERIC_COL_TAGS} from '../substructure-search/substructure-search';
12
12
  import {TAGS as bioTAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
13
- import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
14
13
  import {ISeqSplitted} from '@datagrok-libraries/bio/src/utils/macromolecule/types';
15
14
  import {HelmType} from '@datagrok-libraries/bio/src/helm/types';
16
15
 
17
- import {getMonomerLib} from '../package';
16
+ import {_package} from '../package';
18
17
 
19
18
  export async function getDistances(col: DG.Column, seq: string): Promise<Array<number>> {
20
19
  const stringArray = col.toList();
@@ -108,7 +107,7 @@ export function createPropPanelElement(params: ITooltipAndPanelParams): HTMLDivE
108
107
  });
109
108
 
110
109
  const molDifferences: { [key: number]: HTMLCanvasElement } = {};
111
- const sh = SeqHandler.forColumn(params.seqCol);
110
+ const sh = _package.seqHelper.getSeqHandler(params.seqCol);
112
111
  const biotype = sh.defaultBiotype;
113
112
  const subParts1 = sh.getSplitted(params.points[0]);
114
113
  const subParts2 = sh.getSplitted(params.points[1]);
@@ -138,7 +137,7 @@ export function createDifferenceCanvas(
138
137
  const canvas = document.createElement('canvas');
139
138
  const context = canvas.getContext('2d');
140
139
  canvas.height = 30;
141
- const monomerLib = getMonomerLib();
140
+ const monomerLib = _package.monomerLib;
142
141
  drawMoleculeDifferenceOnCanvas(context!, 0, 0, 0, 30,
143
142
  wu.count(0).take(subParts1.length).map((posIdx) => subParts1.getCanonical(posIdx)).toArray(),
144
143
  wu.count(0).take(subParts2.length).map((posIdx) => subParts2.getCanonical(posIdx)).toArray(),
@@ -7,7 +7,7 @@ import {SequenceSearchBaseViewer} from './sequence-search-base-viewer';
7
7
  import {getMonomericMols} from '../calculations/monomerLevelMols';
8
8
  import {updateDivInnerHTML} from '../utils/ui-utils';
9
9
  import {Subject} from 'rxjs';
10
- import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
10
+ import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
11
11
  import {getEncodedSeqSpaceCol} from './sequence-space';
12
12
  import {MmDistanceFunctionsNames} from '@datagrok-libraries/ml/src/macromolecule-distance-functions';
13
13
  import {DistanceMatrixService, dmLinearIndex} from '@datagrok-libraries/ml/src/distance-matrix';
@@ -19,7 +19,9 @@ export class SequenceDiversityViewer extends SequenceSearchBaseViewer {
19
19
  columnNames = [];
20
20
  computeCompleted = new Subject<boolean>();
21
21
 
22
- constructor() {
22
+ constructor(
23
+ private readonly seqHelper: ISeqHelper,
24
+ ) {
23
25
  super('diversity');
24
26
  this.diverseColumnLabel = this.string('diverseColumnLabel', null);
25
27
  }
@@ -29,7 +31,7 @@ export class SequenceDiversityViewer extends SequenceSearchBaseViewer {
29
31
  return;
30
32
  if (this.dataFrame) {
31
33
  if (computeData && this.moleculeColumn) {
32
- const sh = SeqHandler.forColumn(this.moleculeColumn);
34
+ const sh = this.seqHelper.getSeqHandler(this.moleculeColumn);
33
35
  await (sh.isFasta() ? this.computeByMM() : this.computeByChem());
34
36
 
35
37
  const diverseColumnName: string = this.diverseColumnLabel != null ? this.diverseColumnLabel :
@@ -7,7 +7,7 @@ import {getMonomericMols} from '../calculations/monomerLevelMols';
7
7
  import {createDifferenceCanvas, createDifferencesWithPositions} from './sequence-activity-cliffs';
8
8
  import {updateDivInnerHTML} from '../utils/ui-utils';
9
9
  import {Subject} from 'rxjs';
10
- import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
10
+ import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
11
11
  import {alignSequencePair} from '@datagrok-libraries/bio/src/utils/macromolecule/alignment';
12
12
  import {KnnResult, SparseMatrixService} from '@datagrok-libraries/ml/src/distance-matrix/sparse-matrix-service';
13
13
  import {getEncodedSeqSpaceCol} from './sequence-space';
@@ -32,7 +32,10 @@ export class SequenceSimilarityViewer extends SequenceSearchBaseViewer {
32
32
  kPrevNeighbors: number = 0;
33
33
  demo?: boolean;
34
34
 
35
- constructor(demo?: boolean) {
35
+ constructor(
36
+ private readonly seqHelper: ISeqHelper,
37
+ demo?: boolean,
38
+ ) {
36
39
  super('similarity');
37
40
  this.cutoff = this.float('cutoff', 0.01, {min: 0, max: 1});
38
41
  this.hotSearch = this.bool('hotSearch', true);
@@ -52,7 +55,7 @@ export class SequenceSimilarityViewer extends SequenceSearchBaseViewer {
52
55
  this.curIdx = this.dataFrame!.currentRowIdx == -1 ? 0 : this.dataFrame!.currentRowIdx;
53
56
  if (computeData && !this.gridSelect) {
54
57
  this.targetMoleculeIdx = this.dataFrame!.currentRowIdx == -1 ? 0 : this.dataFrame!.currentRowIdx;
55
- const sh = SeqHandler.forColumn(this.moleculeColumn!);
58
+ const sh = this.seqHelper.getSeqHandler(this.moleculeColumn!);
56
59
 
57
60
  await (!sh.isHelm() ? this.computeByMM() : this.computeByChem());
58
61
  const similarColumnName: string = this.similarColumnLabel != null ? this.similarColumnLabel :
@@ -125,8 +128,8 @@ export class SequenceSimilarityViewer extends SequenceSearchBaseViewer {
125
128
  const molDifferences: { [key: number]: HTMLCanvasElement } = {};
126
129
  const molColName = this.molCol?.name!;
127
130
  const resCol: DG.Column<string> = resDf.col(molColName)!;
128
- const molColSh = SeqHandler.forColumn(this.moleculeColumn!);
129
- const resSh = SeqHandler.forColumn(resCol);
131
+ const molColSh = this.seqHelper.getSeqHandler(this.moleculeColumn!);
132
+ const resSh = this.seqHelper.getSeqHandler(resCol);
130
133
  const subParts1 = molColSh.getSplitted(this.targetMoleculeIdx);
131
134
  const subParts2 = resSh.getSplitted(resDf.currentRowIdx);
132
135
  const alignment = alignSequencePair(subParts1, subParts2);
@@ -4,10 +4,11 @@ import * as grok from 'datagrok-api/grok';
4
4
 
5
5
  import {BitArrayMetrics} from '@datagrok-libraries/ml/src/typed-metrics';
6
6
  import {mmDistanceFunctionArgs} from '@datagrok-libraries/ml/src/macromolecule-distance-functions/types';
7
- import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
8
7
  import {getMonomerSubstitutionMatrix} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
9
8
  import {MmDistanceFunctionsNames} from '@datagrok-libraries/ml/src/macromolecule-distance-functions';
10
9
 
10
+ import {_package} from '../package';
11
+
11
12
  export interface ISequenceSpaceResult {
12
13
  distance?: Float32Array;
13
14
  coordinates: DG.ColumnList;
@@ -18,7 +19,7 @@ export async function getEncodedSeqSpaceCol(
18
19
  ): Promise<{ seqList: string[], options: { [_: string]: any } }> {
19
20
  // encodes sequences using utf characters to also support multichar and non fasta sequences
20
21
  const rowCount = seqCol.length;
21
- const sh = SeqHandler.forColumn(seqCol);
22
+ const sh = _package.seqHelper.getSeqHandler(seqCol);
22
23
  const encList = Array<string>(rowCount);
23
24
  let charCodeCounter = 1; // start at 1, 0 is reserved for null.
24
25
  const charCodeMap = new Map<string, string>();
@@ -4,17 +4,17 @@ import * as DG from 'datagrok-api/dg';
4
4
 
5
5
  import wu from 'wu';
6
6
 
7
- import {getHelmMonomers} from '../package';
8
- import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
9
7
  import {ISeqSplitted} from '@datagrok-libraries/bio/src/utils/macromolecule/types';
10
8
  import {GAP_SYMBOL} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
11
9
 
10
+ import {_package, getHelmMonomers} from '../package';
11
+
12
12
  const V2000_ATOM_NAME_POS = 31;
13
13
 
14
14
  export async function getMonomericMols(
15
15
  mcol: DG.Column<string>, pattern: boolean = false, monomersDict?: Map<string, string>
16
16
  ): Promise<DG.Column> {
17
- const sh = SeqHandler.forColumn(mcol);
17
+ const sh = _package.seqHelper.getSeqHandler(mcol);
18
18
  let molV3000Array;
19
19
  monomersDict ??= new Map();
20
20
  const monomers = sh.isHelm() ?
@@ -7,10 +7,13 @@ import {DemoScript} from '@datagrok-libraries/tutorials/src/demo-script';
7
7
  import {handleError} from './utils';
8
8
  import {SequenceDiversityViewer} from '../analysis/sequence-diversity-viewer';
9
9
  import {SequenceSimilarityViewer} from '../analysis/sequence-similarity-viewer';
10
+ import {getSeqHelper, ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
10
11
 
11
12
  const dataFn: string = 'samples/FASTA_PT_activity.csv';
12
13
 
13
14
  export async function demoBio01UI() {
15
+ let seqHelper: ISeqHelper = await getSeqHelper();
16
+
14
17
  let view: DG.TableView;
15
18
  let df: DG.DataFrame;
16
19
 
@@ -37,7 +40,7 @@ export async function demoBio01UI() {
37
40
  delay: 2000,
38
41
  })
39
42
  .step('Find the most similar sequences to the current one', async () => {
40
- const simViewer = new SequenceSimilarityViewer(true);
43
+ const simViewer = new SequenceSimilarityViewer(seqHelper, true);
41
44
  view.addViewer(simViewer, {
42
45
  moleculeColumnName: 'sequence',
43
46
  similarColumnLabel: 'Similar to current',
@@ -8,7 +8,6 @@ import './tests/_first-tests';
8
8
  import './tests/Palettes-test';
9
9
  import './tests/detectors-tests';
10
10
  import './tests/detectors-weak-and-likely-tests';
11
- import './tests/detectors-custom-notation-tests';
12
11
  import './tests/detectors-benchmark-tests';
13
12
  import './tests/msa-tests';
14
13
  import './tests/splitters-test';
@@ -31,6 +30,7 @@ import './tests/seq-handler-tests';
31
30
  import './tests/seq-handler-splitted-tests';
32
31
  import './tests/seq-handler-get-region-tests';
33
32
  import './tests/seq-handler-get-helm-tests';
33
+ import './tests/helm-tests';
34
34
  import './tests/to-atomic-level-tests';
35
35
  import './tests/to-atomic-level-ui-tests';
36
36
  import './tests/mm-distance-tests';
@@ -7,6 +7,9 @@ import {Observable, Subject} from 'rxjs';
7
7
  import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
8
8
  import {LoggerWrapper} from '@datagrok-libraries/bio/src/utils/logger';
9
9
  import {RDModule} from '@datagrok-libraries/chem-meta/src/rdkit-api';
10
+ import {SeqHelper} from './utils/seq-helper';
11
+ import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
12
+ import {IMonomerLib, IMonomerLibBase, IMonomerSet} from '@datagrok-libraries/bio/src/types';
10
13
 
11
14
  /** Names of package properties/settings declared in properties section of {@link './package.json'} */
12
15
  export const enum BioPackagePropertiesNames {
@@ -60,8 +63,33 @@ export class BioPackageProperties extends Map<string, any> {
60
63
  export class BioPackage extends DG.Package {
61
64
  private _properties: BioPackageProperties;
62
65
 
66
+ private _seqHelper: ISeqHelper;
67
+ public get seqHelper(): ISeqHelper {
68
+ if (!this._seqHelper)
69
+ throw new Error('Package Bio .seqHelper is not initialized.');
70
+ return this._seqHelper;
71
+ };
72
+
73
+ private _monomerLib: IMonomerLib;
74
+ public get monomerLib(): IMonomerLib {
75
+ if (!this._monomerLib)
76
+ throw new Error('Package Bio .monomerLib is not initialized.');
77
+ return this._monomerLib;
78
+ };
79
+
80
+ private _monomerSets: IMonomerSet;
81
+ public get monomerSets(): IMonomerSet {
82
+ if (!this._monomerSets)
83
+ throw new Error('Package Bio .monomerSets is not initialized.');
84
+ return this._monomerSets;
85
+ };
86
+
63
87
  private _rdKitModule: RDModule;
64
- public get rdKitModule(): RDModule { return this._rdKitModule;};
88
+ public get rdKitModule(): RDModule {
89
+ if (!this._rdKitModule)
90
+ throw new Error('Package Bio .rdKitModule is not initialized.');
91
+ return this._rdKitModule;
92
+ };
65
93
 
66
94
  /** Package properties/settings declared in properties section of {@link './package.json'} */
67
95
  public get properties(): BioPackageProperties { return this._properties; };
@@ -78,7 +106,12 @@ export class BioPackage extends DG.Package {
78
106
  super._logger = new LoggerWrapper(super.logger, opts.debug);
79
107
  }
80
108
 
81
- public completeInit(rdKitModule: RDModule): void {
109
+ public completeInit(
110
+ seqHelper: ISeqHelper, monomerLib: IMonomerLib, monomerSets: IMonomerSet, rdKitModule: RDModule
111
+ ): void {
112
+ this._seqHelper = seqHelper;
113
+ this._monomerLib = monomerLib;
114
+ this._monomerSets = monomerSets;
82
115
  this._rdKitModule = rdKitModule;
83
116
  this._initialized = true;
84
117
  }
package/src/package.ts CHANGED
@@ -9,8 +9,7 @@ import {getActivityCliffs} from '@datagrok-libraries/ml/src/viewers/activity-cli
9
9
  import {MmDistanceFunctionsNames} from '@datagrok-libraries/ml/src/macromolecule-distance-functions';
10
10
  import {BitArrayMetrics, KnownMetrics} from '@datagrok-libraries/ml/src/typed-metrics';
11
11
  import {NOTATION, TAGS as bioTAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
12
- import {SeqHandler, SeqTemps} from '@datagrok-libraries/bio/src/utils/seq-handler';
13
- import {IMonomerLib, IMonomerSet} from '@datagrok-libraries/bio/src/types';
12
+ import {IMonomerLib, IMonomerLibBase, IMonomerSet} from '@datagrok-libraries/bio/src/types';
14
13
  import {SeqPalette} from '@datagrok-libraries/bio/src/seq-palettes';
15
14
  import {FastaFileHandler} from '@datagrok-libraries/bio/src/utils/fasta-handler';
16
15
  import {SCORE} from '@datagrok-libraries/bio/src/utils/macromolecule/scoring';
@@ -66,12 +65,11 @@ import {GetRegionApp} from './apps/get-region-app';
66
65
  import {GetRegionFuncEditor} from './utils/get-region-func-editor';
67
66
  import {sequenceToMolfile} from './utils/sequence-to-mol';
68
67
  import {detectMacromoleculeProbeDo} from './utils/detect-macromolecule-probe';
69
- import {CyclizedNotationProvider} from './utils/cyclized';
70
- import {DimerizedNotationProvider} from './utils/dimerized';
71
68
  import {getMolColumnFromHelm} from './utils/helm-to-molfile/utils';
72
69
  import {MonomerManager} from './utils/monomer-lib/monomer-manager/monomer-manager';
73
70
  import {calculateScoresWithEmptyValues} from './utils/calculate-scores';
74
71
  import {SeqHelper} from './utils/seq-helper/seq-helper';
72
+ import {ISeqHandler} from '@datagrok-libraries/bio/src/utils/macromolecule/seq-handler';
75
73
 
76
74
  export const _package = new BioPackage(/*{debug: true}/**/);
77
75
 
@@ -99,9 +97,6 @@ export class SeqPaletteCustom implements SeqPalette {
99
97
  }
100
98
  }
101
99
 
102
- let monomerLib: IMonomerLib | null = null;
103
- let monomerSets: IMonomerSet | null = null;
104
-
105
100
  let initBioPromise: Promise<void> | null = null;
106
101
 
107
102
  //tags: init
@@ -115,21 +110,26 @@ export async function initBio(): Promise<void> {
115
110
  async function initBioInt() {
116
111
  const logPrefix = 'Bio: _package.initBio()';
117
112
  _package.logger.debug(`${logPrefix}, start`);
113
+ let monomerLib!: IMonomerLib;
114
+ let monomerSets!: IMonomerSet;
118
115
  let rdKitModule!: RDModule;
119
- let monomerLibManager: MonomerLibManager;
116
+ let libHelper!: MonomerLibManager;
120
117
  const t1: number = window.performance.now();
121
118
  await Promise.all([
122
119
  (async () => {
123
- monomerLibManager = await MonomerLibManager.getInstance();
120
+ libHelper = await MonomerLibManager.getInstance();
124
121
  // Fix user lib settings for explicit stuck from a terminated test
125
122
  const libSettings = await getUserLibSettings();
126
123
  if (libSettings.explicit) {
127
124
  libSettings.explicit = [];
128
125
  await setUserLibSettings(libSettings);
129
126
  }
130
- await Promise.all([monomerLibManager.loadMonomerLib(), monomerLibManager.loadMonomerSets()]);
131
- monomerLib = monomerLibManager.getMonomerLib();
132
- monomerSets = monomerLibManager.getMonomerSets();
127
+ libHelper.awaitLoaded(Infinity).then(() => {
128
+ // Do not wait for monomers and sets loaded
129
+ return Promise.all([libHelper.loadMonomerLib(), libHelper.loadMonomerSets()]);
130
+ });
131
+ monomerLib = libHelper.getMonomerLib();
132
+ monomerSets = libHelper.getMonomerSets();
133
133
  })(),
134
134
  (async () => {
135
135
  const pkgProps = await _package.getProperties();
@@ -141,8 +141,8 @@ async function initBioInt() {
141
141
  const t2: number = window.performance.now();
142
142
  _package.logger.debug(`${logPrefix}, loading ET: ${t2 - t1} ms`);
143
143
  });
144
-
145
- _package.completeInit(rdKitModule);
144
+ const seqHelper = new SeqHelper(libHelper, rdKitModule);
145
+ _package.completeInit(seqHelper, monomerLib, monomerSets, rdKitModule);
146
146
 
147
147
  const monomers: string[] = [];
148
148
  const logPs: number[] = [];
@@ -174,7 +174,7 @@ async function initBioInt() {
174
174
  //input: column col {semType: Macromolecule}
175
175
  //output: widget result
176
176
  export function sequenceTooltip(col: DG.Column): DG.Widget<any> {
177
- const resWidget = new MacromoleculeColumnWidget(col);
177
+ const resWidget = new MacromoleculeColumnWidget(col, _package.seqHelper);
178
178
  const _resPromise = resWidget.init().then(() => { })
179
179
  .catch((err: any) => {
180
180
  const errMsg = err instanceof Error ? err.message : err.toString();
@@ -187,19 +187,14 @@ export function sequenceTooltip(col: DG.Column): DG.Widget<any> {
187
187
  //name: getBioLib
188
188
  //output: object monomerLib
189
189
  export function getBioLib(): IMonomerLib {
190
- return monomerLib!;
191
- }
192
-
193
- // For sync internal use, on initialized package
194
- export function getMonomerLib(): IMonomerLib {
195
- return monomerLib!;
190
+ return _package.monomerLib;
196
191
  }
197
192
 
198
193
  //name: getSeqHandler
199
194
  //input: column sequence { semType: Macromolecule }
200
195
  //output: object result
201
- export function getSeqHandler(sequence: DG.Column<string>): SeqHandler {
202
- return SeqHandler.forColumn(sequence);
196
+ export function getSeqHandler(sequence: DG.Column<string>): ISeqHandler {
197
+ return _package.seqHelper.getSeqHandler(sequence);
203
198
  }
204
199
 
205
200
  // -- Panels --
@@ -215,7 +210,7 @@ export function getRegionPanel(seqCol: DG.Column<string>): DG.Widget {
215
210
  if (funcList.length !== 1) throw new Error(`Package '${_package.name}' func '${funcName}' not found`);
216
211
  const func = funcList[0];
217
212
  const funcCall = func.prepare({table: seqCol.dataFrame, sequence: seqCol});
218
- const funcEditor = new GetRegionFuncEditor(funcCall);
213
+ const funcEditor = new GetRegionFuncEditor(funcCall, _package.seqHelper);
219
214
  return funcEditor.widget();
220
215
  }
221
216
 
@@ -236,7 +231,7 @@ export async function libraryPanel(_seqColumn: DG.Column): Promise<DG.Widget> {
236
231
  //input: funccall call
237
232
  export function GetRegionEditor(call: DG.FuncCall): void {
238
233
  try {
239
- const funcEditor = new GetRegionFuncEditor(call);
234
+ const funcEditor = new GetRegionFuncEditor(call, _package.seqHelper);
240
235
  funcEditor.dialog();
241
236
  } catch (err: any) {
242
237
  const errMsg = err instanceof Error ? err.message : err.toString();
@@ -364,7 +359,7 @@ export function macroMolColumnPropertyPanel(molColumn: DG.Column): DG.Widget {
364
359
  //input: semantic_value sequence { semType: Macromolecule }
365
360
  //output: widget result
366
361
  export function compositionAnalysisWidget(sequence: DG.SemanticValue): DG.Widget {
367
- return getCompositionAnalysisWidget(sequence, monomerLib!);
362
+ return getCompositionAnalysisWidget(sequence, _package.monomerLib, _package.seqHelper);
368
363
  }
369
364
 
370
365
  //name: MacromoleculeDifferenceCellRenderer
@@ -635,8 +630,10 @@ export async function toAtomicLevel(
635
630
  const pi = DG.TaskBarProgressIndicator.create('Converting to atomic level ...');
636
631
  try {
637
632
  await initBioPromise;
638
- const monomerLib = (await getMonomerLibHelper()).getMonomerLib();
639
- await sequenceToMolfile(table, seqCol, nonlinear, highlight, monomerLib, _package.rdKitModule);
633
+ const monomerLib = _package.monomerLib;
634
+ const seqHelper = _package.seqHelper;
635
+ const rdKitModule = _package.rdKitModule;
636
+ await sequenceToMolfile(table, seqCol, nonlinear, highlight, monomerLib, seqHelper, rdKitModule);
640
637
  } finally {
641
638
  pi.close();
642
639
  }
@@ -647,7 +644,7 @@ export async function toAtomicLevel(
647
644
  //description: Performs multiple sequence alignment
648
645
  //tags: bio, panel
649
646
  export function multipleSequenceAlignmentDialog(): void {
650
- multipleSequenceAlignmentUI()
647
+ multipleSequenceAlignmentUI({}, _package.seqHelper)
651
648
  .catch((err: any) => {
652
649
  const [errMsg, errStack] = errInfo(err);
653
650
  if (err instanceof MsaWarning) {
@@ -666,10 +663,12 @@ export function multipleSequenceAlignmentDialog(): void {
666
663
  //tags: bio
667
664
  //input: column sequenceCol {semType: Macromolecule}
668
665
  //input: column clustersCol
666
+ //input: object options = undefined { optional: true }
669
667
  //output: column result
670
- export async function alignSequences(sequenceCol: DG.Column<string> | null = null,
671
- clustersCol: DG.Column | null = null): Promise<DG.Column<string>> {
672
- return multipleSequenceAlignmentUI({col: sequenceCol, clustersCol});
668
+ export async function alignSequences(
669
+ sequenceCol: DG.Column<string> | null = null, clustersCol: DG.Column | null = null, options?: any
670
+ ): Promise<DG.Column<string>> {
671
+ return multipleSequenceAlignmentUI({col: sequenceCol, clustersCol: clustersCol, ...options}, _package.seqHelper);
673
672
  }
674
673
 
675
674
  //top-menu: Bio | Analyze | Composition
@@ -686,7 +685,7 @@ export async function compositionAnalysis(): Promise<void> {
686
685
  if (col.semType != DG.SEMTYPE.MACROMOLECULE)
687
686
  return false;
688
687
 
689
- const _colSh = SeqHandler.forColumn(col);
688
+ const _colSh = _package.seqHelper.getSeqHandler(col);
690
689
  // TODO: prevent for cyclic, branched or multiple chains in Helm
691
690
  return true;
692
691
  });
@@ -705,7 +704,7 @@ export async function compositionAnalysis(): Promise<void> {
705
704
  return;
706
705
  } else if (colList.length > 1) {
707
706
  const colListNames: string [] = colList.map((col) => col.name);
708
- const selectedCol = colList.find((c) => { return SeqHandler.forColumn(c).isMsa(); });
707
+ const selectedCol = colList.find((c) => { return _package.seqHelper.getSeqHandler(c).isMsa(); });
709
708
  const colInput: DG.InputBase = ui.input.choice(
710
709
  'Column', {value: selectedCol ? selectedCol.name : colListNames[0], items: colListNames});
711
710
  ui.dialog({
@@ -756,8 +755,8 @@ export function importBam(fileContent: string): DG.DataFrame [] {
756
755
  //top-menu: Bio | Convert | Notation...
757
756
  //name: convertDialog
758
757
  export function convertDialog() {
759
- const col = getMacromoleculeColumns()[0];
760
- convert(col);
758
+ const col: DG.Column<string> | undefined = getMacromoleculeColumns()[0];
759
+ convert(col, _package.seqHelper);
761
760
  }
762
761
 
763
762
  //top-menu: Bio | Convert | TestConvert
@@ -774,7 +773,7 @@ export async function convertSeqNotation(sequence: string, targetNotation: NOTAT
774
773
  const semType = await grok.functions.call('Bio:detectMacromolecule', {col: col});
775
774
  if (semType)
776
775
  col.semType = semType;
777
- const converterSh = SeqHandler.forColumn(col);
776
+ const converterSh = _package.seqHelper.getSeqHandler(col);
778
777
  const newColumn = converterSh.convert(targetNotation, separator);
779
778
  return newColumn.get(0);
780
779
  } catch (err: any) {
@@ -851,14 +850,15 @@ export async function testDetectMacromolecule(path: string): Promise<DG.DataFram
851
850
  //input: column sequence { semType: Macromolecule }
852
851
  //output: dataframe result
853
852
  //editor: Bio:SplitToMonomersEditor
854
- export async function splitToMonomersTopMenu(table: DG.DataFrame, sequence: DG.Column): Promise<void> {
855
- await splitToMonomersUI(table, sequence);
853
+ export async function splitToMonomersTopMenu(table: DG.DataFrame, sequence: DG.Column): Promise<DG.DataFrame> {
854
+ return await splitToMonomersUI(table, sequence);
856
855
  }
857
856
 
858
857
  //name: Bio: getHelmMonomers
859
858
  //input: column sequence {semType: Macromolecule}
859
+ //output: object result
860
860
  export function getHelmMonomers(sequence: DG.Column<string>): string[] {
861
- const sh = SeqHandler.forColumn(sequence);
861
+ const sh = _package.seqHelper.getSeqHandler(sequence);
862
862
  const stats = sh.stats;
863
863
  return Object.keys(stats.freq);
864
864
  }
@@ -869,7 +869,7 @@ export function getHelmMonomers(sequence: DG.Column<string>): string[] {
869
869
  //meta.icon: files/icons/sequence-similarity-viewer.svg
870
870
  //output: viewer result
871
871
  export function similaritySearchViewer(): SequenceSimilarityViewer {
872
- return new SequenceSimilarityViewer();
872
+ return new SequenceSimilarityViewer(_package.seqHelper);
873
873
  }
874
874
 
875
875
  //top-menu: Bio | Search | Similarity Search
@@ -887,7 +887,7 @@ export function similaritySearchTopMenu(): void {
887
887
  //meta.icon: files/icons/sequence-diversity-viewer.svg
888
888
  //output: viewer result
889
889
  export function diversitySearchViewer(): SequenceDiversityViewer {
890
- return new SequenceDiversityViewer();
890
+ return new SequenceDiversityViewer(_package.seqHelper);
891
891
  }
892
892
 
893
893
  //top-menu: Bio | Search | Diversity Search
@@ -928,13 +928,14 @@ export function SubsequenceSearchTopMenu(macromolecules: DG.Column): void {
928
928
  //name: Identity Scoring
929
929
  //description: Adds a column with fraction of matching monomers
930
930
  //input: dataframe table [Table containing Macromolecule column]
931
- //input: column macromolecules {semType: Macromolecule} [Sequences to score]
931
+ //input: column macromolecule {semType: Macromolecule} [Sequences to score]
932
932
  //input: string reference [Sequence, matching column format]
933
933
  //output: column scores
934
934
  export async function sequenceIdentityScoring(
935
935
  table: DG.DataFrame, macromolecule: DG.Column, reference: string
936
936
  ): Promise<DG.Column<number>> {
937
- const scores = calculateScoresWithEmptyValues(table, macromolecule, reference, SCORE.IDENTITY);
937
+ const seqHelper = _package.seqHelper;
938
+ const scores = calculateScoresWithEmptyValues(table, macromolecule, reference, SCORE.IDENTITY, seqHelper);
938
939
  return scores;
939
940
  }
940
941
 
@@ -942,13 +943,14 @@ export async function sequenceIdentityScoring(
942
943
  //name: Similarity Scoring
943
944
  //description: Adds a column with similarity scores, calculated as sum of monomer fingerprint similarities
944
945
  //input: dataframe table [Table containing Macromolecule column]
945
- //input: column macromolecules {semType: Macromolecule} [Sequences to score]
946
+ //input: column macromolecule {semType: Macromolecule} [Sequences to score]
946
947
  //input: string reference [Sequence, matching column format]
947
948
  //output: column scores
948
949
  export async function sequenceSimilarityScoring(
949
950
  table: DG.DataFrame, macromolecule: DG.Column, reference: string
950
951
  ): Promise<DG.Column<number>> {
951
- const scores = calculateScoresWithEmptyValues(table, macromolecule, reference, SCORE.SIMILARITY);
952
+ const seqHelper = _package.seqHelper;
953
+ const scores = calculateScoresWithEmptyValues(table, macromolecule, reference, SCORE.SIMILARITY, seqHelper);
952
954
  return scores;
953
955
  }
954
956
 
@@ -1046,13 +1048,13 @@ export function longSeqTableSeparator(): void {
1046
1048
 
1047
1049
  //name: longSeqTableFasta
1048
1050
  export function longSeqTableFasta(): void {
1049
- const df = DG.DataFrame.fromColumns([generateLongSequence2(NOTATION.FASTA)]);
1051
+ const df = DG.DataFrame.fromColumns([generateLongSequence2(_package.seqHelper, NOTATION.FASTA)]);
1050
1052
  grok.shell.addTableView(df);
1051
1053
  }
1052
1054
 
1053
1055
  //name: longSeqTableHelm
1054
1056
  export function longSeqTableHelm(): void {
1055
- const df = DG.DataFrame.fromColumns([generateLongSequence2(NOTATION.HELM)]);
1057
+ const df = DG.DataFrame.fromColumns([generateLongSequence2(_package.seqHelper, NOTATION.HELM)]);
1056
1058
  grok.shell.addTableView(df);
1057
1059
  }
1058
1060
 
@@ -1062,7 +1064,7 @@ export function longSeqTableHelm(): void {
1062
1064
  //input: object cell
1063
1065
  //input: object menu
1064
1066
  export function addCopyMenu(cell: DG.Cell, menu: DG.Menu): void {
1065
- addCopyMenuUI(cell, menu);
1067
+ addCopyMenuUI(cell, menu, _package.seqHelper);
1066
1068
  }
1067
1069
 
1068
1070
  // -- Demo --
@@ -1148,7 +1150,9 @@ export async function seq2atomic(seq: string, nonlinear: boolean): Promise<strin
1148
1150
  if (semType) seqCol.semType = semType;
1149
1151
 
1150
1152
  const monomerLib = (await getMonomerLibHelper()).getMonomerLib();
1151
- const res = (await sequenceToMolfile(df, seqCol, nonlinear, false, monomerLib, _package.rdKitModule))?.molCol?.get(0);
1153
+ const seqHelper = _package.seqHelper;
1154
+ const rdKitModule = await getRdKitModule();
1155
+ const res = (await sequenceToMolfile(df, seqCol, nonlinear, false, monomerLib, seqHelper, rdKitModule))?.molCol?.get(0);
1152
1156
  return res ?? undefined;
1153
1157
  } catch (err: any) {
1154
1158
  const [errMsg, errStack] = errInfo(err);
@@ -1192,7 +1196,7 @@ export async function seqIdentity(seq: string, ref: string): Promise<number | nu
1192
1196
  const semType = await grok.functions.call('Bio:detectMacromolecule', {col: seqCol});
1193
1197
  if (!semType) throw new Error('Macromolecule required');
1194
1198
 
1195
- const resCol = await calculateScoresWithEmptyValues(df, seqCol, ref, SCORE.IDENTITY);
1199
+ const resCol = await calculateScoresWithEmptyValues(df, seqCol, ref, SCORE.IDENTITY, _package.seqHelper);
1196
1200
  return resCol.get(0);
1197
1201
  } catch (err: any) {
1198
1202
  const [errMsg, errStack] = errInfo(err);
@@ -1214,7 +1218,7 @@ export async function detectMacromoleculeProbe(file: DG.FileInfo, colName: strin
1214
1218
  //name: getSeqHelper
1215
1219
  //output: object result
1216
1220
  export async function getSeqHelper(): Promise<ISeqHelper> {
1217
- return SeqHelper.getInstance();
1221
+ return _package.seqHelper;
1218
1222
  }
1219
1223
 
1220
1224
  //name: getMolFromHelm
@@ -1225,25 +1229,7 @@ export async function getSeqHelper(): Promise<ISeqHelper> {
1225
1229
  export function getMolFromHelm(
1226
1230
  df: DG.DataFrame, helmCol: DG.Column<string>, chiralityEngine: boolean
1227
1231
  ): Promise<DG.Column<string>> {
1228
- return getMolColumnFromHelm(df, helmCol, chiralityEngine, getMonomerLib());
1229
- }
1230
-
1231
- // -- Custom notation providers --
1232
-
1233
- //name: applyNotationProviderForCyclized
1234
- //input: column col
1235
- //input: string separator
1236
- export function applyNotationProviderForCyclized(col: DG.Column<string>, separator: string) {
1237
- col.meta.units = NOTATION.CUSTOM;
1238
- col.temp[SeqTemps.notationProvider] = new CyclizedNotationProvider(separator);
1239
- }
1240
-
1241
- //name: applyNotationProviderForDimerized
1242
- //input: column col
1243
- //input: string separator
1244
- export function applyNotationProviderForDimerized(col: DG.Column<string>, separator: string) {
1245
- col.meta.units = NOTATION.CUSTOM;
1246
- col.temp[SeqTemps.notationProvider] = new DimerizedNotationProvider(separator);
1232
+ return getMolColumnFromHelm(df, helmCol, chiralityEngine, _package.monomerLib);
1247
1233
  }
1248
1234
 
1249
1235
  //name: test1
@@ -11,7 +11,7 @@ import {Debounces, WebLogoViewer} from '../viewers/web-logo-viewer';
11
11
 
12
12
  import {_package} from '../package-test';
13
13
 
14
- category('WebLogo-layout', () => {
14
+ category('WebLogo.layout', () => {
15
15
  test('fasta', async () => {
16
16
  const df = await _package.files.readCsv('tests/filter_FASTA.csv');
17
17
  const col = df.getCol('fasta');