@datagrok/bio 2.16.0 → 2.16.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "name": "Aleksandr Tanas",
6
6
  "email": "atanas@datagrok.ai"
7
7
  },
8
- "version": "2.16.0",
8
+ "version": "2.16.2",
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,7 +37,7 @@
37
37
  ],
38
38
  "dependencies": {
39
39
  "@biowasm/aioli": "^3.1.0",
40
- "@datagrok-libraries/bio": "^5.45.0",
40
+ "@datagrok-libraries/bio": "^5.45.2",
41
41
  "@datagrok-libraries/chem-meta": "^1.2.7",
42
42
  "@datagrok-libraries/math": "^1.2.1",
43
43
  "@datagrok-libraries/ml": "^6.7.4",
@@ -55,7 +55,7 @@
55
55
  "rxjs": "^6.5.5",
56
56
  "style-loader": "^3.3.1",
57
57
  "umap-js": "^1.3.3",
58
- "wu": "latest"
58
+ "wu": "^2.1.0"
59
59
  },
60
60
  "devDependencies": {
61
61
  "@datagrok-libraries/helm-web-editor": "^1.1.12",
@@ -64,18 +64,18 @@
64
64
  "@datagrok/dendrogram": "^1.2.33",
65
65
  "@datagrok/helm": "^2.5.3",
66
66
  "@types/node": "^17.0.24",
67
- "@types/wu": "latest",
68
- "@typescript-eslint/eslint-plugin": "latest",
69
- "@typescript-eslint/parser": "latest",
67
+ "@types/wu": "^2.1.44",
68
+ "@typescript-eslint/eslint-plugin": "^8.8.1",
69
+ "@typescript-eslint/parser": "^8.8.1",
70
70
  "datagrok-tools": "latest",
71
- "eslint": "latest",
72
- "eslint-config-google": "latest",
73
- "eslint-plugin-rxjs": "latest",
74
- "source-map-loader": "latest",
71
+ "eslint": "^9.12.0",
72
+ "eslint-config-google": "^0.14.0",
73
+ "eslint-plugin-rxjs": "^5.0.3",
74
+ "source-map-loader": "^5.0.0",
75
75
  "ts-loader": "^9.5.1",
76
76
  "typescript": "^5.5.3",
77
77
  "webpack": "^5.92.1",
78
- "webpack-bundle-analyzer": "latest",
78
+ "webpack-bundle-analyzer": "^4.10.2",
79
79
  "webpack-cli": "^5.1.4"
80
80
  },
81
81
  "scripts": {
@@ -6,13 +6,15 @@ import wu from 'wu';
6
6
 
7
7
  import {ITooltipAndPanelParams} from '@datagrok-libraries/ml/src/viewers/activity-cliffs';
8
8
  import {getSimilarityFromDistance} from '@datagrok-libraries/ml/src/distance-metrics-methods';
9
+ import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
9
10
  import {AvailableMetrics, DistanceMetricsSubjects, StringMetricsNames} from '@datagrok-libraries/ml/src/typed-metrics';
10
- import {drawMoleculeDifferenceOnCanvas} from '../utils/cell-renderer';
11
- import {invalidateMols, MONOMERIC_COL_TAGS} from '../substructure-search/substructure-search';
12
11
  import {TAGS as bioTAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
13
12
  import {ISeqSplitted} from '@datagrok-libraries/bio/src/utils/macromolecule/types';
14
13
  import {HelmType} from '@datagrok-libraries/bio/src/helm/types';
15
14
 
15
+ import {drawMoleculeDifferenceOnCanvas} from '../utils/cell-renderer';
16
+ import {invalidateMols, MONOMERIC_COL_TAGS} from '../substructure-search/substructure-search';
17
+
16
18
  import {_package} from '../package';
17
19
 
18
20
  export async function getDistances(col: DG.Column, seq: string): Promise<Array<number>> {
@@ -46,11 +48,11 @@ export async function getSimilaritiesMatrix(
46
48
  return simArr;
47
49
  }
48
50
 
49
- export async function getChemSimilaritiesMatrix(dim: number, seqCol: DG.Column,
51
+ export async function getChemSimilaritiesMatrix(dim: number, seqCol: DG.Column, seqHelper: ISeqHelper,
50
52
  df: DG.DataFrame, colName: string, simArr: (DG.Column | null)[])
51
53
  : Promise<(DG.Column | null)[]> {
52
54
  if (seqCol.version !== seqCol.temp[MONOMERIC_COL_TAGS.LAST_INVALIDATED_VERSION])
53
- await invalidateMols(seqCol, false);
55
+ await invalidateMols(seqCol, seqHelper, false);
54
56
  const fpDf = DG.DataFrame.create(seqCol.length);
55
57
  fpDf.columns.addNewString(colName).init((i) => seqCol.temp[MONOMERIC_COL_TAGS.MONOMERIC_MOLS].get(i));
56
58
  const res = await grok.functions.call('Chem:getChemSimilaritiesMatrix', {
@@ -50,7 +50,7 @@ export class SequenceDiversityViewer extends SequenceSearchBaseViewer {
50
50
  }
51
51
 
52
52
  private async computeByChem() {
53
- const monomericMols = await getMonomericMols(this.moleculeColumn!);
53
+ const monomericMols = await getMonomericMols(this.moleculeColumn!, this.seqHelper);
54
54
  //need to create df to calculate fingerprints
55
55
  const _monomericMolsDf = DG.DataFrame.fromColumns([monomericMols]);
56
56
  this.renderMolIds = await grok.functions.call('Chem:callChemDiversitySearch', {
@@ -86,7 +86,7 @@ export class SequenceSimilarityViewer extends SequenceSearchBaseViewer {
86
86
  }
87
87
 
88
88
  private async computeByChem() {
89
- const monomericMols = await getMonomericMols(this.moleculeColumn!);
89
+ const monomericMols = await getMonomericMols(this.moleculeColumn!, this.seqHelper);
90
90
  //need to create df to calculate fingerprints
91
91
  const _monomericMolsDf = DG.DataFrame.fromColumns([monomericMols]);
92
92
  const df = await grok.functions.call('Chem:callChemSimilaritySearch', {
@@ -6,19 +6,18 @@ import wu from 'wu';
6
6
 
7
7
  import {ISeqSplitted} from '@datagrok-libraries/bio/src/utils/macromolecule/types';
8
8
  import {GAP_SYMBOL} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
9
-
10
- import {_package, getHelmMonomers} from '../package';
9
+ import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
11
10
 
12
11
  const V2000_ATOM_NAME_POS = 31;
13
12
 
14
13
  export async function getMonomericMols(
15
- mcol: DG.Column<string>, pattern: boolean = false, monomersDict?: Map<string, string>
14
+ mcol: DG.Column<string>, seqHelper: ISeqHelper, pattern: boolean = false, monomersDict?: Map<string, string>
16
15
  ): Promise<DG.Column> {
17
- const sh = _package.seqHelper.getSeqHandler(mcol);
16
+ const sh = seqHelper.getSeqHandler(mcol);
18
17
  let molV3000Array;
19
18
  monomersDict ??= new Map();
20
19
  const monomers = sh.isHelm() ?
21
- getHelmMonomers(mcol) : Object.keys(sh.stats.freq).filter((it) => it !== '');
20
+ seqHelper.getSeqMonomers(mcol) : Object.keys(sh.stats.freq).filter((it) => it !== '');
22
21
 
23
22
  for (let i = 0; i < monomers.length; i++) {
24
23
  if (!monomersDict.has(monomers[i]))
@@ -7,7 +7,6 @@ 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
10
  import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
12
11
  import {IMonomerLib, IMonomerLibBase, IMonomerSet} from '@datagrok-libraries/bio/src/types';
13
12
 
package/src/package.ts CHANGED
@@ -562,7 +562,7 @@ export async function macromoleculePreprocessingFunction(
562
562
  export async function helmPreprocessingFunction(
563
563
  col: DG.Column<string>, _metric: BitArrayMetrics): Promise<PreprocessFunctionReturnType> {
564
564
  if (col.version !== col.temp[MONOMERIC_COL_TAGS.LAST_INVALIDATED_VERSION])
565
- await invalidateMols(col, false);
565
+ await invalidateMols(col, _package.seqHelper, false);
566
566
  const molCol = col.temp[MONOMERIC_COL_TAGS.MONOMERIC_MOLS];
567
567
  const fingerPrints: DG.Column<DG.BitSet | null> =
568
568
  await grok.functions.call('Chem:getMorganFingerprints', {molColumn: molCol});
@@ -858,9 +858,7 @@ export async function splitToMonomersTopMenu(table: DG.DataFrame, sequence: DG.C
858
858
  //input: column sequence {semType: Macromolecule}
859
859
  //output: object result
860
860
  export function getHelmMonomers(sequence: DG.Column<string>): string[] {
861
- const sh = _package.seqHelper.getSeqHandler(sequence);
862
- const stats = sh.stats;
863
- return Object.keys(stats.freq);
861
+ return _package.seqHelper.getSeqMonomers(sequence);
864
862
  }
865
863
 
866
864
 
@@ -908,7 +906,7 @@ export function searchSubsequenceEditor(call: DG.FuncCall) {
908
906
  if (columns.length === 1)
909
907
  call.func.prepare({macromolecules: columns[0]}).call(true);
910
908
  else
911
- new SubstructureSearchDialog(columns);
909
+ new SubstructureSearchDialog(columns, _package.seqHelper);
912
910
  }
913
911
 
914
912
  //top-menu: Bio | Search | Subsequence Search ...
@@ -980,7 +978,7 @@ export function saveAsFasta() {
980
978
  //output: filter result
981
979
  //meta.semType: Macromolecule
982
980
  export function bioSubstructureFilter(): BioSubstructureFilter {
983
- return new BioSubstructureFilter();
981
+ return new BioSubstructureFilter(_package.seqHelper, _package.logger);
984
982
  }
985
983
 
986
984
  // -- Test apps --
@@ -2,10 +2,12 @@ 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
4
 
5
- import {getMonomericMols} from '../calculations/monomerLevelMols';
6
- import {updateDivInnerHTML} from '../utils/ui-utils';
7
5
  import {delay} from '@datagrok-libraries/utils/src/test';
8
6
  import {TAGS as bioTAGS, NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
7
+ import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
8
+
9
+ import {getMonomericMols} from '../calculations/monomerLevelMols';
10
+ import {updateDivInnerHTML} from '../utils/ui-utils';
9
11
 
10
12
  export const MONOMER_MOLS_COL = 'monomeric-mols';
11
13
 
@@ -29,7 +31,9 @@ export class SubstructureSearchDialog {
29
31
  col: DG.Column;
30
32
  dialog: DG.Dialog;
31
33
 
32
- constructor(columns: DG.Column<string>[]) {
34
+ constructor(columns: DG.Column<string>[],
35
+ private readonly seqHelper: ISeqHelper
36
+ ) {
33
37
  this.col = columns[0];
34
38
  this.createUI();
35
39
  }
@@ -96,7 +100,7 @@ export class SubstructureSearchDialog {
96
100
  substructure = substructure.replaceAll(this.separatorInput.value, this.separator);
97
101
  let matches: DG.BitSet;
98
102
  if (this.units === NOTATION.HELM)
99
- matches = await helmSubstructureSearch(substructure, this.col);
103
+ matches = await helmSubstructureSearch(substructure, this.col, this.seqHelper);
100
104
  else
101
105
  matches = linearSubstructureSearch(substructure, this.col);
102
106
  this.col.dataFrame.filter.and(matches);
@@ -129,14 +133,16 @@ function prepareSubstructureRegex(substructure: string, separator: string) {
129
133
  return re;
130
134
  }
131
135
 
132
- export async function helmSubstructureSearch(substructure: string, col: DG.Column<string>): Promise<DG.BitSet> {
136
+ export async function helmSubstructureSearch(
137
+ substructure: string, col: DG.Column<string>, seqHelper: ISeqHelper
138
+ ): Promise<DG.BitSet> {
133
139
  if (col.version !== col.temp[MONOMERIC_COL_TAGS.LAST_INVALIDATED_VERSION])
134
- await invalidateMols(col, true);
140
+ await invalidateMols(col, seqHelper, true);
135
141
  const substructureCol: DG.Column<string> = DG.Column.string('helm', 1).init((_i) => substructure);
136
142
  substructureCol.semType = DG.SEMTYPE.MACROMOLECULE;
137
143
  substructureCol.meta.units = NOTATION.HELM;
138
144
  const substructureMolsCol =
139
- await getMonomericMols(substructureCol, true, col.temp[MONOMERIC_COL_TAGS.MONOMERS_DICT]);
145
+ await getMonomericMols(substructureCol, seqHelper, true, col.temp[MONOMERIC_COL_TAGS.MONOMERS_DICT]);
140
146
  const matchesCol = await grok.functions.call('Chem:searchSubstructure', {
141
147
  molStringsColumn: col.temp[MONOMERIC_COL_TAGS.MONOMERIC_MOLS],
142
148
  molString: substructureMolsCol.get(0),
@@ -145,12 +151,12 @@ export async function helmSubstructureSearch(substructure: string, col: DG.Colum
145
151
  return matchesCol.get(0);
146
152
  }
147
153
 
148
- export async function invalidateMols(col: DG.Column<string>, pattern: boolean) {
154
+ export async function invalidateMols(col: DG.Column<string>, seqHelper: ISeqHelper, pattern: boolean): Promise<void> {
149
155
  const progressBar = DG.TaskBarProgressIndicator.create(`Invalidating molfiles for ${col.name}`);
150
156
  try {
151
157
  await delay(10);
152
158
  const monomersDict = new Map();
153
- const monomericMolsCol = await getMonomericMols(col, pattern, monomersDict);
159
+ const monomericMolsCol = await getMonomericMols(col, seqHelper, pattern, monomersDict);
154
160
  col.temp[MONOMERIC_COL_TAGS.MONOMERIC_MOLS] = monomericMolsCol;
155
161
  col.temp[MONOMERIC_COL_TAGS.MONOMERS_DICT] = monomersDict;
156
162
  col.temp[MONOMERIC_COL_TAGS.LAST_INVALIDATED_VERSION] = col.version;
@@ -11,7 +11,7 @@ import {
11
11
  getUserLibSettings, setUserLibSettings
12
12
  } from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
13
13
  import {UserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/types';
14
- import {getHelmHelper, IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
14
+ import {getSeqHelper, ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
15
15
 
16
16
  import {awaitGrid, readDataframe} from './utils';
17
17
 
@@ -24,13 +24,13 @@ import {HelmBioFilter} from '../widgets/bio-substructure-filter-helm';
24
24
  import {_package} from '../package-test';
25
25
 
26
26
  category('bio-substructure-filters', async () => {
27
- let helmHelper: IHelmHelper;
27
+ let seqHelper: ISeqHelper;
28
28
  let monomerLibHelper: IMonomerLibHelper;
29
29
  /** Backup actual user's monomer libraries settings */
30
30
  let userLibSettings: UserLibSettings;
31
31
 
32
32
  before(async () => {
33
- helmHelper = await getHelmHelper(); // init Helm package
33
+ seqHelper = await getSeqHelper();
34
34
  monomerLibHelper = await getMonomerLibHelper();
35
35
  userLibSettings = await getUserLibSettings();
36
36
 
@@ -51,7 +51,7 @@ category('bio-substructure-filters', async () => {
51
51
  const fSubStr: string = 'MD';
52
52
  const fTrueCount: number = 3;
53
53
 
54
- const filter = await createBioSubstructureFilter();
54
+ const filter = new BioSubstructureFilter(seqHelper, _package.logger);
55
55
  filter.attach(df);
56
56
  await filter.awaitRendered();
57
57
  try {
@@ -68,11 +68,11 @@ category('bio-substructure-filters', async () => {
68
68
  filter.detach();
69
69
  }
70
70
  await filter.awaitRendered();
71
- }, {skipReason: 'GROK-16782'});
71
+ });
72
72
 
73
73
  test('separator', async () => {
74
74
  const msa = await readDataframe('tests/filter_MSA.csv');
75
- const filter = await createBioSubstructureFilter();
75
+ const filter = new BioSubstructureFilter(seqHelper, _package.logger);
76
76
  await grok.data.detectSemanticTypes(msa);
77
77
  filter.attach(msa);
78
78
  await filter.awaitRendered();
@@ -101,7 +101,7 @@ category('bio-substructure-filters', async () => {
101
101
  filter.detach();
102
102
  }
103
103
  await filter.awaitRendered();
104
- }, {skipReason: 'GROK-16782'});
104
+ });
105
105
 
106
106
  // test('helm', async () => {
107
107
  // const df = await readDataframe('tests/filter_HELM.csv');
@@ -156,7 +156,7 @@ category('bio-substructure-filters', async () => {
156
156
  const view = grok.shell.addTableView(df);
157
157
 
158
158
  _package.logger.debug(`${logPrefix}, filter attaching.`);
159
- const filter = await createBioSubstructureFilter();
159
+ const filter = new BioSubstructureFilter(seqHelper, _package.logger);
160
160
  filter.attach(df);
161
161
  const dlg = ui.dialog('Test filters').add(filter.root).show(); // to waitForElementInDom
162
162
  await filter.awaitRendered();
@@ -187,7 +187,7 @@ category('bio-substructure-filters', async () => {
187
187
  }
188
188
  await filter.awaitRendered();
189
189
  await delay(3000); //TODO: await for grid.onLookChanged
190
- }, {skipReason: 'GROK-16782'});
190
+ });
191
191
 
192
192
  // Generates unhandled exception accessing isFiltering before bioFilter created
193
193
  test('helm-view', async () => {
@@ -234,7 +234,7 @@ category('bio-substructure-filters', async () => {
234
234
  f2.detach();
235
235
  }
236
236
  await Promise.all([f1.awaitRendered(), f2.awaitRendered()]);
237
- }, {skipReason: 'GROK-16782'});
237
+ });
238
238
 
239
239
  // MSA filter has the second input field for separator
240
240
  test('sync-msa', async () => {
@@ -268,7 +268,7 @@ category('bio-substructure-filters', async () => {
268
268
  f2.detach();
269
269
  }
270
270
  await Promise.all([f1.awaitRendered(), f2.awaitRendered()]);
271
- }, {skipReason: 'GROK-16782'});
271
+ });
272
272
 
273
273
  test('sync-helm', async () => {
274
274
  const df = await _package.files.readCsv('tests/filter_HELM.csv');
@@ -311,7 +311,7 @@ category('bio-substructure-filters', async () => {
311
311
  await Promise.all([f1.awaitRendered(), f2.awaitRendered()]);
312
312
  await awaitGrid(view.grid);
313
313
  await delay(3000); //TODO: await for grid.onLookChanged
314
- }, {skipReason: 'GROK-16782'});
314
+ });
315
315
 
316
316
  // two seq columns
317
317
 
@@ -449,24 +449,20 @@ category('bio-substructure-filters', async () => {
449
449
  await delay(100);
450
450
  await awaitGrid(view.grid);
451
451
  });
452
+
453
+ async function createFilter(colName: string, df: DG.DataFrame): Promise<BioSubstructureFilter> {
454
+ if (!df.columns.names().includes(colName)) {
455
+ throw new Error(`The column '${colName}' not found. ` +
456
+ `Available in data frame are ${JSON.stringify(df.columns.names())}`);
457
+ }
458
+
459
+ const filter = new BioSubstructureFilter(seqHelper, _package.logger);
460
+ filter.attach(df);
461
+ filter.applyState({columnName: colName});
462
+ filter.column = df.col(colName);
463
+ filter.columnName = colName;
464
+ //filter.tableName = df.name;
465
+ return filter;
466
+ };
452
467
  });
453
468
 
454
- async function createFilter(colName: string, df: DG.DataFrame): Promise<BioSubstructureFilter> {
455
- if (!df.columns.names().includes(colName)) {
456
- throw new Error(`The column '${colName}' not found. ` +
457
- `Available in data frame are ${JSON.stringify(df.columns.names())}`);
458
- }
459
-
460
- const filter = await createBioSubstructureFilter();
461
- filter.attach(df);
462
- filter.applyState({columnName: colName});
463
- filter.column = df.col(colName);
464
- filter.columnName = colName;
465
- //filter.tableName = df.name;
466
- return filter;
467
- };
468
-
469
- async function createBioSubstructureFilter(): Promise<BioSubstructureFilter> {
470
- const filter = await grok.functions.call('Bio:bioSubstructureFilter');
471
- return filter.dart.jsFilter as BioSubstructureFilter;
472
- }
@@ -16,6 +16,8 @@ import {HelmTypes} from '@datagrok-libraries/bio/src/helm/consts';
16
16
  import {HelmType} from '@datagrok-libraries/bio/src/helm/types';
17
17
  import {ISeqHandler, ConvertFunc, JoinerFunc, SeqTemps} from '@datagrok-libraries/bio/src/utils/macromolecule/seq-handler';
18
18
 
19
+ import {SeqHelper} from './seq-helper';
20
+
19
21
  /* eslint-enable max-len */
20
22
 
21
23
  /** Class for handling notation units in Macromolecule columns and
@@ -30,7 +32,9 @@ export class SeqHandler implements ISeqHandler {
30
32
 
31
33
  private _splitter: SplitterFunc | null = null;
32
34
 
33
- protected constructor(col: DG.Column<string>) {
35
+ protected constructor(col: DG.Column<string>,
36
+ private readonly seqHelper: SeqHelper,
37
+ ) {
34
38
  if (col.type !== DG.TYPE.STRING)
35
39
  throw new Error(`Unexpected column type '${col.type}', must be '${DG.TYPE.STRING}'.`);
36
40
  this._column = col;
@@ -50,12 +54,12 @@ export class SeqHandler implements ISeqHandler {
50
54
  // The following detectors and setters are to be called because the column is likely
51
55
  // as the UnitsHandler constructor was called on the column.
52
56
  if (this.isFasta())
53
- SeqHandler.setUnitsToFastaColumn(this);
57
+ this.seqHelper.setUnitsToFastaColumn(this);
54
58
  else if (this.isSeparator()) {
55
59
  const separator = col.getTag(TAGS.separator);
56
- SeqHandler.setUnitsToSeparatorColumn(this, separator);
60
+ this.seqHelper.setUnitsToSeparatorColumn(this, separator);
57
61
  } else if (this.isHelm())
58
- SeqHandler.setUnitsToHelmColumn(this);
62
+ this.seqHelper.setUnitsToHelmColumn(this);
59
63
  else
60
64
  throw new Error(`Unexpected units '${this.column.meta.units}'.`);
61
65
  }
@@ -85,33 +89,6 @@ export class SeqHandler implements ISeqHandler {
85
89
  this.columnVersion = this.column.version;
86
90
  }
87
91
 
88
- public static setUnitsToFastaColumn(uh: SeqHandler) {
89
- if (uh.column.semType !== DG.SEMTYPE.MACROMOLECULE || uh.column.meta.units !== NOTATION.FASTA)
90
- throw new Error(`The column of notation '${NOTATION.FASTA}' must be '${DG.SEMTYPE.MACROMOLECULE}'.`);
91
-
92
- uh.column.meta.units = NOTATION.FASTA;
93
- SeqHandler.setTags(uh);
94
- }
95
-
96
- public static setUnitsToSeparatorColumn(uh: SeqHandler, separator?: string) {
97
- if (uh.column.semType !== DG.SEMTYPE.MACROMOLECULE || uh.column.meta.units !== NOTATION.SEPARATOR)
98
- throw new Error(`The column of notation '${NOTATION.SEPARATOR}' must be '${DG.SEMTYPE.MACROMOLECULE}'.`);
99
- if (!separator)
100
- throw new Error(`The column of notation '${NOTATION.SEPARATOR}' must have the separator tag.`);
101
-
102
- uh.column.meta.units = NOTATION.SEPARATOR;
103
- uh.column.setTag(TAGS.separator, separator);
104
- SeqHandler.setTags(uh);
105
- }
106
-
107
- public static setUnitsToHelmColumn(uh: SeqHandler) {
108
- if (uh.column.semType !== DG.SEMTYPE.MACROMOLECULE)
109
- throw new Error(`The column of notation '${NOTATION.HELM}' must be '${DG.SEMTYPE.MACROMOLECULE}'`);
110
-
111
- uh.column.meta.units = NOTATION.HELM;
112
- SeqHandler.setTags(uh);
113
- }
114
-
115
92
  /** From detectMacromolecule */
116
93
  public static setTags(uh: SeqHandler): void {
117
94
  const units = uh.column.meta.units as NOTATION;
@@ -141,7 +118,7 @@ export class SeqHandler implements ISeqHandler {
141
118
  }
142
119
  }
143
120
 
144
- protected get column(): DG.Column { return this._column; }
121
+ get column(): DG.Column { return this._column; }
145
122
 
146
123
  public get length(): number { return this._column.length; }
147
124
 
@@ -741,11 +718,11 @@ export class SeqHandler implements ISeqHandler {
741
718
  }
742
719
 
743
720
  /** Gets a column's UnitsHandler object from temp slot or creates a new and stores it to the temp slot. */
744
- public static forColumn(col: DG.Column<string>): SeqHandler {
721
+ public static forColumn(col: DG.Column<string>, seqHelper: SeqHelper): SeqHandler {
745
722
  // TODO: Invalidate col.temp[Temps.uh] checking column's metadata
746
723
  let res = col.temp[SeqTemps.seqHandler];
747
724
  if (!res || res.columnVersion !== col.version)
748
- res = col.temp[SeqTemps.seqHandler] = new SeqHandler(col);
725
+ res = col.temp[SeqTemps.seqHandler] = new SeqHandler(col, seqHelper);
749
726
  return res;
750
727
  }
751
728
 
@@ -17,6 +17,8 @@ import {IMonomerLibBase} from '@datagrok-libraries/bio/src/types/index';
17
17
  import {HelmToMolfileConverter} from '../helm-to-molfile/converter';
18
18
  import {ISeqHandler} from '@datagrok-libraries/bio/src/utils/macromolecule/seq-handler';
19
19
  import {SeqHandler} from './seq-handler';
20
+ import {Column} from 'datagrok-api/dg';
21
+ import {NOTATION, TAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
20
22
 
21
23
  type SeqHelperWindowType = Window & { $seqHelperPromise?: Promise<SeqHelper> };
22
24
  declare const window: SeqHelperWindowType;
@@ -28,7 +30,12 @@ export class SeqHelper implements ISeqHelper {
28
30
  ) {}
29
31
 
30
32
  getSeqHandler(seqCol: DG.Column<string>): ISeqHandler {
31
- return SeqHandler.forColumn(seqCol);
33
+ return SeqHandler.forColumn(seqCol, this);
34
+ }
35
+
36
+ getSeqMonomers(seqCol: Column<string>): string[] {
37
+ const sh = this.getSeqHandler(seqCol);
38
+ return Object.keys(sh.stats.freq);
32
39
  }
33
40
 
34
41
  // TODO: Move to the Helm package
@@ -89,4 +96,31 @@ export class SeqHelper implements ISeqHelper {
89
96
 
90
97
  return {molCol: molCol, warnings: []};
91
98
  }
99
+
100
+ public setUnitsToFastaColumn(uh: SeqHandler) {
101
+ if (uh.column.semType !== DG.SEMTYPE.MACROMOLECULE || uh.column.meta.units !== NOTATION.FASTA)
102
+ throw new Error(`The column of notation '${NOTATION.FASTA}' must be '${DG.SEMTYPE.MACROMOLECULE}'.`);
103
+
104
+ uh.column.meta.units = NOTATION.FASTA;
105
+ SeqHandler.setTags(uh);
106
+ }
107
+
108
+ public setUnitsToSeparatorColumn(uh: SeqHandler, separator?: string) {
109
+ if (uh.column.semType !== DG.SEMTYPE.MACROMOLECULE || uh.column.meta.units !== NOTATION.SEPARATOR)
110
+ throw new Error(`The column of notation '${NOTATION.SEPARATOR}' must be '${DG.SEMTYPE.MACROMOLECULE}'.`);
111
+ if (!separator)
112
+ throw new Error(`The column of notation '${NOTATION.SEPARATOR}' must have the separator tag.`);
113
+
114
+ uh.column.meta.units = NOTATION.SEPARATOR;
115
+ uh.column.setTag(TAGS.separator, separator);
116
+ SeqHandler.setTags(uh);
117
+ }
118
+
119
+ public setUnitsToHelmColumn(uh: SeqHandler) {
120
+ if (uh.column.semType !== DG.SEMTYPE.MACROMOLECULE)
121
+ throw new Error(`The column of notation '${NOTATION.HELM}' must be '${DG.SEMTYPE.MACROMOLECULE}'`);
122
+
123
+ uh.column.meta.units = NOTATION.HELM;
124
+ SeqHandler.setTags(uh);
125
+ }
92
126
  }
@@ -10,6 +10,7 @@ import {getHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
10
10
  import {ILogger} from '@datagrok-libraries/bio/src/utils/logger';
11
11
  import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
12
12
  import {delay} from '@datagrok-libraries/utils/src/test';
13
+ import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
13
14
 
14
15
  import {updateDivInnerHTML} from '../utils/ui-utils';
15
16
  import {helmSubstructureSearch} from '../substructure-search/substructure-search';
@@ -32,7 +33,9 @@ export class HelmBioFilter extends BioFilterBase<BioFilterProps> /* implements I
32
33
 
33
34
  get type(): string { return 'HelmBioFilter'; }
34
35
 
35
- constructor() {
36
+ constructor(
37
+ private readonly seqHelper: ISeqHelper,
38
+ ) {
36
39
  super();
37
40
  this.logger = _package.logger;
38
41
  }
@@ -138,7 +141,7 @@ export class HelmBioFilter extends BioFilterBase<BioFilterProps> /* implements I
138
141
  _package.logger.debug(`${logPrefix}, start`);
139
142
  try {
140
143
  await delay(10);
141
- const res = await helmSubstructureSearch(this.props.substructure, column);
144
+ const res = await helmSubstructureSearch(this.props.substructure, column, this.seqHelper);
142
145
  return res;
143
146
  } finally {
144
147
  _package.logger.debug(`${logPrefix}, end`);