@datagrok/bio 2.18.0 → 2.18.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": "Leonid Stolbov",
6
6
  "email": "lstolbov@datagrok.ai"
7
7
  },
8
- "version": "2.18.0",
8
+ "version": "2.18.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",
@@ -44,7 +44,7 @@
44
44
  ],
45
45
  "dependencies": {
46
46
  "@biowasm/aioli": "^3.1.0",
47
- "@datagrok-libraries/bio": "^5.46.0",
47
+ "@datagrok-libraries/bio": "^5.48.1",
48
48
  "@datagrok-libraries/chem-meta": "^1.2.7",
49
49
  "@datagrok-libraries/math": "^1.2.4",
50
50
  "@datagrok-libraries/ml": "^6.7.6",
@@ -69,7 +69,6 @@
69
69
  "@datagrok-libraries/js-draw-lite": "^0.0.10",
70
70
  "@datagrok/chem": "^1.13.0",
71
71
  "@datagrok/dendrogram": "^1.2.33",
72
- "@datagrok/helm": "^2.7.0",
73
72
  "@types/node": "^17.0.24",
74
73
  "@types/wu": "^2.1.44",
75
74
  "@typescript-eslint/eslint-plugin": "^8.8.1",
package/src/package.ts CHANGED
@@ -1012,6 +1012,13 @@ export function bioSubstructureFilter(): BioSubstructureFilter {
1012
1012
  return new BioSubstructureFilter(_package.seqHelper, _package.logger);
1013
1013
  }
1014
1014
 
1015
+ //name: Bio Substructure Filter Test
1016
+ //description: Substructure filter for Helm package tests
1017
+ //output: object result
1018
+ export function bioSubstructureFilterTest(): BioSubstructureFilter {
1019
+ return new BioSubstructureFilter(_package.seqHelper, _package.logger);
1020
+ }
1021
+
1015
1022
  // -- Test apps --
1016
1023
 
1017
1024
  //name: webLogoLargeApp
@@ -27,7 +27,9 @@ category('activityCliffs', async () => {
27
27
  const seqEncodingFunc = DG.Func.find({name: 'macromoleculePreprocessingFunction', package: 'Bio'})[0];
28
28
  const helmEncodingFunc = DG.Func.find({name: 'helmPreprocessingFunction', package: 'Bio'})[0];
29
29
  before(async () => {
30
- helmHelper = await getHelmHelper(); // init Helm package
30
+ const helmPackInstalled = DG.Func.find({package: 'Helm', name: 'getHelmHelper'}).length;
31
+ if (helmPackInstalled)
32
+ helmHelper = await getHelmHelper(); // init Helm package
31
33
  monomerLibHelper = await getMonomerLibHelper();
32
34
  userLibSettings = await getUserLibSettings();
33
35
 
@@ -61,10 +63,13 @@ category('activityCliffs', async () => {
61
63
  });
62
64
 
63
65
  test('Helm', async () => {
64
- const df = await _package.files.readCsv('samples/HELM_50.csv');
65
- const _view = grok.shell.addTableView(df);
66
-
67
- await _testActivityCliffsOpen(df, DimReductionMethods.UMAP,
68
- 'HELM', 'Activity', 65, 20, BitArrayMetricsNames.Tanimoto, helmEncodingFunc);
66
+ const helmPackInstalled = DG.Func.find({package: 'Helm', name: 'getHelmHelper'}).length;
67
+ if (helmPackInstalled) {
68
+ const df = await _package.files.readCsv('samples/HELM_50.csv');
69
+ const _view = grok.shell.addTableView(df);
70
+
71
+ await _testActivityCliffsOpen(df, DimReductionMethods.UMAP,
72
+ 'HELM', 'Activity', 65, 20, BitArrayMetricsNames.Tanimoto, helmEncodingFunc);
73
+ }
69
74
  });
70
75
  });
@@ -65,7 +65,7 @@ category('renderers', () => {
65
65
 
66
66
  test('scatterPlotTooltip', async () => {
67
67
  await _testScatterPlotTooltip();
68
- });
68
+ }, {skipReason: 'GROK-17450'});
69
69
 
70
70
  async function _rendererMacromoleculeFasta() {
71
71
  const csv: string = await grok.dapi.files.readAsText('System:AppData/Bio/samples/FASTA.csv');
@@ -20,7 +20,7 @@ import {awaitGrid, readDataframe} from './utils';
20
20
  import {
21
21
  BioSubstructureFilter, FastaBioFilter, SeparatorBioFilter, SeparatorFilterProps
22
22
  } from '../widgets/bio-substructure-filter';
23
- import {BioFilterProps} from '../widgets/bio-substructure-filter-types';
23
+ import {BioFilterProps} from '@datagrok-libraries/bio/src/substructure-filter/bio-substructure-filter-types';
24
24
  import {HelmBioFilter} from '../widgets/bio-substructure-filter-helm';
25
25
 
26
26
  import {_package} from '../package-test';
@@ -62,7 +62,7 @@ category('bio-substructure-filters', async () => {
62
62
  const bf = filter.bioFilter as FastaBioFilter;
63
63
 
64
64
  await testEvent(df.onRowsFiltered, () => {}, () => {
65
- bf.props = new BioFilterProps(fSubStr);
65
+ bf.props = new BioFilterProps(fSubStr, undefined, _package.logger);
66
66
  }, 5000, 'testEvent onRowsFiltered');
67
67
  expect(filter.dataFrame!.filter.trueCount, fTrueCount);
68
68
  expect(filter.dataFrame?.filter.toBinaryString(), '10010000100000');
@@ -84,18 +84,18 @@ category('bio-substructure-filters', async () => {
84
84
  const bf = filter.bioFilter as SeparatorBioFilter;
85
85
 
86
86
  await testEvent(msa.onRowsFiltered, () => {}, () => {
87
- bf.props = new SeparatorFilterProps('meI');
87
+ bf.props = new SeparatorFilterProps('meI', undefined, _package.logger);
88
88
  }, 5000, 'testEvent onRowsFiltered');
89
89
  expect(filter.dataFrame!.filter.trueCount, 7);
90
90
  expect(filter.dataFrame!.filter.get(2), false);
91
91
 
92
92
  await testEvent(msa.onRowsFiltered, () => {}, () => {
93
- bf.props = new SeparatorFilterProps('/meI');
93
+ bf.props = new SeparatorFilterProps('/meI', undefined, _package.logger);
94
94
  }, 5000, 'testEvent onRowsFiltered');
95
95
  expect(filter.dataFrame!.filter.trueCount, 0);
96
96
 
97
97
  await testEvent(msa.onRowsFiltered, () => {}, () => {
98
- bf.props = new SeparatorFilterProps('meI-hHis', '-');
98
+ bf.props = new SeparatorFilterProps('meI-hHis', '-', _package.logger);
99
99
  }, 5000, 'testEvent onRowsFiltered');
100
100
  expect(filter.dataFrame!.filter.trueCount, 7);
101
101
  expect(filter.dataFrame!.filter.get(2), false);
@@ -152,61 +152,67 @@ category('bio-substructure-filters', async () => {
152
152
  // }, {timeout: 30000});
153
153
 
154
154
  test('helm-dialog', async () => {
155
- const logPrefix = 'Bio tests: substructureFilters/helm-dialog';
156
- const df = await readDataframe('tests/filter_HELM.csv');
157
- const view = grok.shell.addTableView(df);
158
- await grok.data.detectSemanticTypes(df);
159
- await df.meta.detectSemanticTypes();
160
-
161
- _package.logger.debug(`${logPrefix}, filter attaching.`);
162
- const filter = new BioSubstructureFilter(seqHelper, _package.logger);
163
- filter.attach(df);
164
- const dlg = ui.dialog('Test filters').add(filter.root).show(); // to waitForElementInDom
165
- await filter.awaitRendered();
166
- try {
167
- const bf = filter.bioFilter as HelmBioFilter;
168
- expect(filter.bioFilter !== null, true, 'bioFilter is not created');
169
-
170
- // filter 1
171
- _package.logger.debug(`${logPrefix}, filter 1 change awaiting...`);
172
- await testEvent(df.onRowsFiltered, () => {}, () => {
173
- bf.props = new BioFilterProps('PEPTIDE1{A.C}$$$$V2.0');
174
- }, 20000);
175
- _package.logger.debug(`${logPrefix}, filter 1 changed.`);
176
- expect(filter.dataFrame!.filter.trueCount, 1);
177
- expect(filter.dataFrame!.filter.toBinaryString(), '0001');
178
-
179
- // filter 2
180
- _package.logger.debug(`${logPrefix}, filter 2 change awaiting...`);
181
- await testEvent(df.onRowsFiltered, () => {}, () => {
182
- bf.props = new BioFilterProps('PEPTIDE1{C}$$$$V2.0');
183
- }, 20000);
184
- setTimeout(() => view.grid.invalidate(), 500);
185
- await awaitGrid(view.grid);
186
- await delay(1000);
187
- _package.logger.debug(`${logPrefix}, filter 2 changed.`);
188
- expect(filter.dataFrame!.filter.trueCount, 2);
189
- expect(filter.dataFrame!.filter.toBinaryString(), '1001');
190
- } finally {
191
- dlg.close();
155
+ const helmPackInstalled = DG.Func.find({package: 'Helm', name: 'getHelmHelper'}).length;
156
+ if (helmPackInstalled) {
157
+ const logPrefix = 'Bio tests: substructureFilters/helm-dialog';
158
+ const df = await readDataframe('tests/filter_HELM.csv');
159
+ const view = grok.shell.addTableView(df);
160
+ await grok.data.detectSemanticTypes(df);
161
+ await df.meta.detectSemanticTypes();
162
+
163
+ _package.logger.debug(`${logPrefix}, filter attaching.`);
164
+ const filter = new BioSubstructureFilter(seqHelper, _package.logger);
165
+ filter.attach(df);
166
+ const dlg = ui.dialog('Test filters').add(filter.root).show(); // to waitForElementInDom
167
+ await filter.awaitRendered();
168
+ try {
169
+ const bf = filter.bioFilter as HelmBioFilter;
170
+ expect(filter.bioFilter !== null, true, 'bioFilter is not created');
171
+
172
+ // filter 1
173
+ _package.logger.debug(`${logPrefix}, filter 1 change awaiting...`);
174
+ await testEvent(df.onRowsFiltered, () => {}, () => {
175
+ bf.props = new BioFilterProps('PEPTIDE1{A.C}$$$$V2.0', undefined, _package.logger);
176
+ }, 20000);
177
+ _package.logger.debug(`${logPrefix}, filter 1 changed.`);
178
+ expect(filter.dataFrame!.filter.trueCount, 1);
179
+ expect(filter.dataFrame!.filter.toBinaryString(), '0001');
180
+
181
+ // filter 2
182
+ _package.logger.debug(`${logPrefix}, filter 2 change awaiting...`);
183
+ await testEvent(df.onRowsFiltered, () => {}, () => {
184
+ bf.props = new BioFilterProps('PEPTIDE1{C}$$$$V2.0', undefined, _package.logger);
185
+ }, 20000);
186
+ setTimeout(() => view.grid.invalidate(), 500);
187
+ await awaitGrid(view.grid);
188
+ await delay(1000);
189
+ _package.logger.debug(`${logPrefix}, filter 2 changed.`);
190
+ expect(filter.dataFrame!.filter.trueCount, 2);
191
+ expect(filter.dataFrame!.filter.toBinaryString(), '1001');
192
+ } finally {
193
+ dlg.close();
194
+ }
195
+ await filter.awaitRendered();
196
+ await delay(3000); //TODO: await for grid.onLookChanged
192
197
  }
193
- await filter.awaitRendered();
194
- await delay(3000); //TODO: await for grid.onLookChanged
195
198
  }, {});
196
199
 
197
200
  // Generates unhandled exception accessing isFiltering before bioFilter created
198
201
  test('helm-view', async () => {
199
- const logPrefix = 'Bio tests: substructureFilters/helm-view';
200
- const df = await readDataframe('tests/filter_HELM.csv');
201
- const col = df.getCol('HELM string');
202
- await grok.data.detectSemanticTypes(df);
203
- const view = grok.shell.addTableView(df);
204
-
205
- const fg = view.getFiltersGroup();
206
-
207
- // await awaitCheck(() => fg.filters.length == 1, 'await filters.length == 1', 1000);
208
- // const filter = fg.filters.filter((f) => f.columnName == col.name)[0] as BioSubstructureFilter;
209
- await awaitGrid(view.grid);
202
+ const helmPackInstalled = DG.Func.find({package: 'Helm', name: 'getHelmHelper'}).length;
203
+ if (helmPackInstalled) {
204
+ const logPrefix = 'Bio tests: substructureFilters/helm-view';
205
+ const df = await readDataframe('tests/filter_HELM.csv');
206
+ const col = df.getCol('HELM string');
207
+ await grok.data.detectSemanticTypes(df);
208
+ const view = grok.shell.addTableView(df);
209
+
210
+ const fg = view.getFiltersGroup();
211
+
212
+ // await awaitCheck(() => fg.filters.length == 1, 'await filters.length == 1', 1000);
213
+ // const filter = fg.filters.filter((f) => f.columnName == col.name)[0] as BioSubstructureFilter;
214
+ await awaitGrid(view.grid);
215
+ }
210
216
  });
211
217
 
212
218
  test('sync-fasta', async () => {
@@ -228,7 +234,7 @@ category('bio-substructure-filters', async () => {
228
234
  const bf2 = f2.bioFilter as FastaBioFilter;
229
235
 
230
236
  await testEvent(df.onRowsFiltered, () => {}, () => {
231
- bf1.props = new BioFilterProps(fSubStr);
237
+ bf1.props = new BioFilterProps(fSubStr, undefined, _package.logger);
232
238
  }, 10000, 'await onRowsFiltered');
233
239
  expect(df.filter.trueCount, fTrueCount);
234
240
 
@@ -262,7 +268,7 @@ category('bio-substructure-filters', async () => {
262
268
  const bf2 = f2.bioFilter as SeparatorBioFilter;
263
269
 
264
270
  await testEvent(df.onRowsFiltered, () => {}, () => {
265
- bf1.props = new SeparatorFilterProps(fSubStr, fSepStr);
271
+ bf1.props = new SeparatorFilterProps(fSubStr, fSepStr, _package.logger);
266
272
  }, 10000, 'await onRowsFiltered');
267
273
  expect(df.filter.trueCount, fTrueCount);
268
274
 
@@ -276,46 +282,49 @@ category('bio-substructure-filters', async () => {
276
282
  });
277
283
 
278
284
  test('sync-helm', async () => {
279
- const df = await _package.files.readCsv('tests/filter_HELM.csv');
280
- await grok.data.detectSemanticTypes(df);
281
- const view = grok.shell.addTableView(df);
282
-
283
- const fSubStr: string = 'PEPTIDE1{A.C}$$$$V2.0';
284
- const fTrueCount: number = 1;
285
-
286
- const f1 = await createFilter('HELM string', df);
287
- const f2 = await createFilter('HELM string', df);
288
- const dlg = ui.dialog('Test filters').add(f1.root).add(f2.root).show(); // to waitForElementInDom
289
- await Promise.all([f1.awaitRendered(), f2.awaitRendered()]);
290
- try {
291
- expect(!!f1.bioFilter, true);
292
- expect(!!f2.bioFilter, true);
293
- expect(f1.bioFilter!.type, 'HelmBioFilter');
294
- expect(f2.bioFilter!.type, 'HelmBioFilter');
295
- const bf1 = f1.bioFilter as HelmBioFilter;
296
- const bf2 = f2.bioFilter as HelmBioFilter;
297
-
298
- await testEvent(df.onRowsFiltered, () => {}, () => {
299
- bf1.props = new BioFilterProps(fSubStr);
300
- }, 60000, 'await onRowsFiltered'); // wait to load monomers
285
+ const helmPackInstalled = DG.Func.find({package: 'Helm', name: 'getHelmHelper'}).length;
286
+ if (helmPackInstalled) {
287
+ const df = await _package.files.readCsv('tests/filter_HELM.csv');
288
+ await grok.data.detectSemanticTypes(df);
289
+ const view = grok.shell.addTableView(df);
290
+
291
+ const fSubStr: string = 'PEPTIDE1{A.C}$$$$V2.0';
292
+ const fTrueCount: number = 1;
293
+
294
+ const f1 = await createFilter('HELM string', df);
295
+ const f2 = await createFilter('HELM string', df);
296
+ const dlg = ui.dialog('Test filters').add(f1.root).add(f2.root).show(); // to waitForElementInDom
297
+ await Promise.all([f1.awaitRendered(), f2.awaitRendered()]);
298
+ try {
299
+ expect(!!f1.bioFilter, true);
300
+ expect(!!f2.bioFilter, true);
301
+ expect(f1.bioFilter!.type, 'HelmBioFilter');
302
+ expect(f2.bioFilter!.type, 'HelmBioFilter');
303
+ const bf1 = f1.bioFilter as HelmBioFilter;
304
+ const bf2 = f2.bioFilter as HelmBioFilter;
305
+
306
+ await testEvent(df.onRowsFiltered, () => {}, () => {
307
+ bf1.props = new BioFilterProps(fSubStr, undefined, _package.logger);
308
+ }, 60000, 'await onRowsFiltered'); // wait to load monomers
309
+ await awaitGrid(view.grid);
310
+ //debugger;
311
+
312
+ _package.logger.debug('Bio tests: substructureFilters/sync-helm, before changed event');
313
+ await delay(f1.debounceTime * 2);
314
+ _package.logger.debug('Bio tests: substructureFilters/sync-helm, after changed event');
315
+ expect(df.filter.trueCount, fTrueCount);
316
+
317
+ await f1.awaitRendered();
318
+ expect(bf2.props.substructure, fSubStr);
319
+ } finally {
320
+ f1.detach();
321
+ f2.detach();
322
+ dlg.close();
323
+ }
324
+ await Promise.all([f1.awaitRendered(), f2.awaitRendered()]);
301
325
  await awaitGrid(view.grid);
302
- //debugger;
303
-
304
- _package.logger.debug('Bio tests: substructureFilters/sync-helm, before changed event');
305
- await delay(f1.debounceTime * 2);
306
- _package.logger.debug('Bio tests: substructureFilters/sync-helm, after changed event');
307
- expect(df.filter.trueCount, fTrueCount);
308
-
309
- await f1.awaitRendered();
310
- expect(bf2.props.substructure, fSubStr);
311
- } finally {
312
- f1.detach();
313
- f2.detach();
314
- dlg.close();
326
+ await delay(3000); //TODO: await for grid.onLookChanged
315
327
  }
316
- await Promise.all([f1.awaitRendered(), f2.awaitRendered()]);
317
- await awaitGrid(view.grid);
318
- await delay(3000); //TODO: await for grid.onLookChanged
319
328
  });
320
329
 
321
330
  // two seq columns
@@ -360,36 +369,36 @@ category('bio-substructure-filters', async () => {
360
369
  const seq2Bf = seq2Filter.bioFilter as FastaBioFilter;
361
370
 
362
371
  await testEvent(df.onRowsFiltered, () => {}, () => {
363
- seq1Bf.props = new BioFilterProps(fSeq1SubStr);
372
+ seq1Bf.props = new BioFilterProps(fSeq1SubStr, undefined, _package.logger);
364
373
  }, 1000);
365
374
  await testEvent(df.onRowsFiltered, () => {}, () => {
366
- seq2Bf.props = new BioFilterProps('');
375
+ seq2Bf.props = new BioFilterProps('', undefined, _package.logger);
367
376
  }, 1000, 'testEvent onRowsFiltered on seq1');
368
377
  expect(df.filter.trueCount, fSeq1Trues.filter((v) => v === 1).length);
369
378
  expect(df.filter.toBinaryString(), fSeq1Trues.map((v) => v.toString()).join(''));
370
379
 
371
380
  await testEvent(df.onRowsFiltered, () => {}, () => {
372
- seq1Bf.props = new BioFilterProps('');
381
+ seq1Bf.props = new BioFilterProps('', undefined, _package.logger);
373
382
  }, 1000);
374
383
  await testEvent(df.onRowsFiltered, () => {}, () => {
375
- seq2Bf.props = new BioFilterProps(fSeq2SubStr);
384
+ seq2Bf.props = new BioFilterProps(fSeq2SubStr, undefined, _package.logger);
376
385
  }, 1000, 'testEvent onRowsFiltered on seq2');
377
386
  expect(df.filter.trueCount, fSeq2Trues.filter((v) => v === 1).length);
378
387
  expect(df.filter.toBinaryString(), fSeq2Trues.map((v) => v.toString()).join(''));
379
388
 
380
389
  await testEvent(df.onRowsFiltered, () => {}, () => {
381
- seq1Bf.props = new BioFilterProps('');
390
+ seq1Bf.props = new BioFilterProps('', undefined, _package.logger);
382
391
  }, 1000);
383
392
  await testEvent(df.onRowsFiltered, () => {}, () => {
384
- seq2Bf.props = new BioFilterProps('');
393
+ seq2Bf.props = new BioFilterProps('', undefined, _package.logger);
385
394
  }, 1000, 'testEvent onRowsFiltered on neither');
386
395
  expect(df.filter.trueCount, df.rowCount);
387
396
 
388
397
  await testEvent(df.onRowsFiltered, () => {}, () => {
389
- seq1Bf.props = new BioFilterProps(fSeq1SubStr);
398
+ seq1Bf.props = new BioFilterProps(fSeq1SubStr, undefined, _package.logger);
390
399
  }, 5000);
391
400
  await testEvent(df.onRowsFiltered, () => {}, () => {
392
- seq2Bf.props = new BioFilterProps(fSeq2SubStr);
401
+ seq2Bf.props = new BioFilterProps(fSeq2SubStr, undefined, _package.logger);
393
402
  }, 5000, 'testEvent onRowsFiltered on both');
394
403
  const bothTrues: number[] = wu.count(0).take(df.rowCount)
395
404
  .map((rowI) => fSeq1Trues[rowI] * fSeq2Trues[rowI]).toArray();
@@ -421,7 +430,7 @@ category('bio-substructure-filters', async () => {
421
430
  const seqFilter = fg.filters[0] as BioSubstructureFilter;
422
431
  const seqBf = seqFilter.bioFilter as FastaBioFilter;
423
432
  await testEvent(df.onRowsFiltered, () => {}, () => {
424
- seqBf.props = new BioFilterProps(fSubStr);
433
+ seqBf.props = new BioFilterProps(fSubStr, undefined, _package.logger);
425
434
  }, 1000, 'testEvent onRowsFiltered');
426
435
  expect(df.filter.trueCount, fTrueCount);
427
436
  expect(seqBf.props.substructure, fSubStr);
@@ -88,12 +88,17 @@ category('toAtomicLevel-ui', () => {
88
88
  await _testToAtomicLevelFunc(seqCol, false, testData.tgt);
89
89
  });
90
90
  }
91
- for (const [testName, testData] of Object.entries(tests)) {
92
- test(`${testName}-nonlinear`, async () => {
93
- const seqCol = await getSeqCol(testData);
94
- await _testToAtomicLevelFunc(seqCol, true, testData.tgt);
95
- });
96
- }
91
+
92
+ //test non-linear cases only if helm package is installed
93
+ const helmPackInstalled = DG.Func.find({package: 'Helm', name: 'getHelmHelper'}).length;
94
+ if (helmPackInstalled) {
95
+ for (const [testName, testData] of Object.entries(tests)) {
96
+ test(`${testName}-nonlinear`, async () => {
97
+ const seqCol = await getSeqCol(testData);
98
+ await _testToAtomicLevelFunc(seqCol, true, testData.tgt);
99
+ });
100
+ }
101
+ }
97
102
 
98
103
  async function _testToAtomicLevelFunc(
99
104
  seqCol: DG.Column<string>, nonlinear: boolean, tgt: TestDataTargetType,
@@ -15,8 +15,6 @@ const Tags = new class {
15
15
  tooltipHandlerTemp = 'tooltip-handler.Monomer';
16
16
  }();
17
17
 
18
- const svgMolOptions = {autoCrop: true, autoCropMargin: 0, suppressChiralText: true};
19
-
20
18
  export class MonomerCellRendererBack extends CellRendererWithMonomerLibBackBase {
21
19
  constructor(gridCol: DG.GridColumn | null, tableCol: DG.Column) {
22
20
  super(gridCol, tableCol);
@@ -25,6 +25,12 @@ const monomerRe = /[\w()]+/;
25
25
  //** Do not mess with monomer symbol with parenthesis enclosed in square brackets */
26
26
  const ambMonomerRe = RegExp(String.raw`\(${monomerRe}(,${monomerRe})+\)`);
27
27
 
28
+ const drawMoleculeCall = (s: string) => {
29
+ const canvas = ui.canvas(250, 250);
30
+ grok.chem.canvasMol(0, 0, 250, 250, canvas, s);
31
+ return canvas;
32
+ };
33
+
28
34
  export type MonomerLibDataType = { [polymerType: string]: { [monomerSymbol: string]: Monomer } };
29
35
 
30
36
  const whiteColorV = new Vector([255.0, 255.0, 255.0]);
@@ -189,10 +195,10 @@ export class MonomerLibBase implements IMonomerLibBase {
189
195
  const chemOptions = {autoCrop: true, autoCropMargin: 0, suppressChiralText: true};
190
196
  let structureEl: HTMLElement;
191
197
  if (monomer.molfile)
192
- structureEl = grok.chem.svgMol(monomer.molfile, undefined, undefined, chemOptions);
198
+ structureEl = drawMoleculeCall(monomer.molfile);
193
199
  else if (monomer.smiles) {
194
200
  structureEl = ui.divV([
195
- grok.chem.svgMol(monomer.smiles, undefined, undefined, chemOptions),
201
+ drawMoleculeCall(monomer.smiles),
196
202
  ui.divText('from smiles', {style: {fontSize: 'smaller'}}),
197
203
  ]);
198
204
  } else {
@@ -271,13 +277,12 @@ export class MonomerLibBase implements IMonomerLibBase {
271
277
  }
272
278
 
273
279
  const naSymbol: string | undefined = monomer[OPT.NATURAL_ANALOG];
274
- if (!res && naSymbol) {
280
+ if (!res && naSymbol)
275
281
  return this.getMonomerColors(biotype, naSymbol);
276
- }
277
282
  }
278
283
 
279
284
  if (!res)
280
- res = {textColor: "#202020", lineColor: "#202020", backgroundColor: "#A0A0A0"};
285
+ res = {textColor: '#202020', lineColor: '#202020', backgroundColor: '#A0A0A0'};
281
286
 
282
287
  return {
283
288
  textcolor: res.text ?? res.textColor,
@@ -14,12 +14,13 @@ import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
14
14
 
15
15
  import {updateDivInnerHTML} from '../utils/ui-utils';
16
16
  import {helmSubstructureSearch} from '../substructure-search/substructure-search';
17
- import {BioFilterBase, BioFilterProps} from './bio-substructure-filter-types';
17
+ import {BioFilterBase, BioFilterProps}
18
+ from '@datagrok-libraries/bio/src/substructure-filter/bio-substructure-filter-types';
18
19
 
19
20
  import {_package} from '../package';
20
21
 
21
22
  export class HelmBioFilter extends BioFilterBase<BioFilterProps> /* implements IRenderer */ {
22
- readonly emptyProps = new BioFilterProps('');
23
+ readonly emptyProps = new BioFilterProps('', undefined, _package.logger);
23
24
 
24
25
  helmEditor: IHelmWebEditor;
25
26
  _filterPanel = ui.div('', {style: {cursor: 'pointer'}});
@@ -68,7 +69,7 @@ export class HelmBioFilter extends BioFilterBase<BioFilterProps> /* implements I
68
69
  try {
69
70
  const webEditorValue = webEditorApp!.canvas!.getHelm(true)
70
71
  .replace(/<\/span>/g, '').replace(/<span style='background:#bbf;'>/g, '');
71
- this.props = new BioFilterProps(webEditorValue);
72
+ this.props = new BioFilterProps(webEditorValue, undefined, _package.logger);
72
73
  } catch (err: any) {
73
74
  this.logger.error(err);
74
75
  } finally {
@@ -23,8 +23,9 @@ import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
23
23
 
24
24
  import {helmSubstructureSearch, linearSubstructureSearch} from '../substructure-search/substructure-search';
25
25
  import {updateDivInnerHTML} from '../utils/ui-utils';
26
- import {BioFilterBase, BioFilterProps, IBioFilter, IFilterProps} from './bio-substructure-filter-types';
26
+ import {BioFilterBase, BioFilterProps, IBioFilter, IFilterProps} from '@datagrok-libraries/bio/src/substructure-filter/bio-substructure-filter-types';
27
27
  import {HelmBioFilter} from './bio-substructure-filter-helm';
28
+ import { _package } from '../package';
28
29
 
29
30
  const FILTER_SYNC_EVENT: string = 'bio-substructure-filter';
30
31
 
@@ -42,8 +43,9 @@ export class SeparatorFilterProps extends BioFilterProps {
42
43
  constructor(
43
44
  substructure: string,
44
45
  public readonly separator?: string,
46
+ logger?: DG.PackageLogger
45
47
  ) {
46
- super(substructure, false);
48
+ super(substructure, false, logger);
47
49
  this.readOnly = true;
48
50
  }
49
51
  }
@@ -276,7 +278,7 @@ export class BioSubstructureFilter extends DG.Filter implements IRenderer {
276
278
  }
277
279
 
278
280
  export class FastaBioFilter extends BioFilterBase<BioFilterProps> {
279
- readonly emptyProps = new BioFilterProps('');
281
+ readonly emptyProps = new BioFilterProps('', undefined, _package.logger);
280
282
 
281
283
  readonly substructureInput: DG.InputBase<string>;
282
284
 
@@ -288,7 +290,7 @@ export class FastaBioFilter extends BioFilterBase<BioFilterProps> {
288
290
  this.substructureInput = ui.input.string('', {
289
291
  value: '', onValueChanged: (value) => {
290
292
  window.setTimeout(() => {
291
- this.props = new BioFilterProps(value);
293
+ this.props = new BioFilterProps(value, undefined, _package.logger);
292
294
  if (!this._propsChanging) this.onChanged.next();
293
295
  }, 0 /* next event cycle */);
294
296
  }, placeholder: 'Substructure'
@@ -318,7 +320,7 @@ export class FastaBioFilter extends BioFilterBase<BioFilterProps> {
318
320
  }
319
321
 
320
322
  export class SeparatorBioFilter extends BioFilterBase<SeparatorFilterProps> {
321
- readonly emptyProps = new SeparatorFilterProps('', undefined);
323
+ readonly emptyProps = new SeparatorFilterProps('', undefined, _package.logger);
322
324
 
323
325
  readonly substructureInput: DG.InputBase<string>;
324
326
  readonly separatorInput: DG.InputBase<string>;
@@ -331,14 +333,14 @@ export class SeparatorBioFilter extends BioFilterBase<SeparatorFilterProps> {
331
333
 
332
334
  this.substructureInput = ui.input.string('', {
333
335
  value: '', onValueChanged: (value) => {
334
- this.props = new SeparatorFilterProps(value, this.props.separator);
336
+ this.props = new SeparatorFilterProps(value, this.props.separator, _package.logger);
335
337
  if (!this._propsChanging) this.onChanged.next();
336
338
  }, placeholder: 'Substructure'
337
339
  });
338
340
  this.separatorInput = ui.input.string('', {
339
341
  value: this.colSeparator = colSeparator, onValueChanged: (value) => {
340
342
  const separator: string | undefined = !!value ? value : undefined;
341
- this.props = new SeparatorFilterProps(this.props.substructure, separator);
343
+ this.props = new SeparatorFilterProps(this.props.substructure, separator, _package.logger);
342
344
  if (!this._propsChanging) this.onChanged.next();
343
345
  }, placeholder: 'Separator'
344
346
  });
@@ -361,7 +363,7 @@ export class SeparatorBioFilter extends BioFilterBase<SeparatorFilterProps> {
361
363
  get isFiltering(): boolean { return this.props.substructure !== ''; };
362
364
 
363
365
  resetFilter(): void {
364
- this.props = new SeparatorFilterProps('');
366
+ this.props = new SeparatorFilterProps('', undefined, _package.logger);
365
367
  }
366
368
 
367
369
  get filterPanel() {