@datagrok/bio 2.23.2 → 2.24.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 (48) hide show
  1. package/.eslintrc.json +0 -2
  2. package/CHANGELOG.md +5 -0
  3. package/README.md +1 -1
  4. package/dist/package-test.js +3 -3
  5. package/dist/package-test.js.map +1 -1
  6. package/dist/package.js +2 -2
  7. package/dist/package.js.map +1 -1
  8. package/package.json +2 -2
  9. package/src/package-types.ts +1 -1
  10. package/src/package.ts +9 -3
  11. package/src/tests/activity-cliffs-tests.ts +2 -2
  12. package/src/tests/monomer-libraries-tests.ts +8 -6
  13. package/src/tests/renderers-monomer-placer-tests.ts +1 -1
  14. package/src/tests/scoring.ts +1 -1
  15. package/src/tests/seq-handler-get-helm-tests.ts +1 -1
  16. package/src/tests/splitters-test.ts +2 -2
  17. package/src/tests/substructure-filters-tests.ts +11 -11
  18. package/src/tests/to-atomic-level-tests.ts +2 -2
  19. package/src/tests/to-atomic-level-ui-tests.ts +13 -14
  20. package/src/utils/cell-renderer.ts +1 -1
  21. package/src/utils/helm-to-molfile/converter/converter.ts +1 -1
  22. package/src/utils/helm-to-molfile/converter/mol-bonds.ts +1 -1
  23. package/src/utils/helm-to-molfile/converter/monomer-wrapper.ts +1 -1
  24. package/src/utils/helm-to-molfile/converter/polymer.ts +1 -1
  25. package/src/utils/helm-to-molfile/utils.ts +3 -2
  26. package/src/utils/monomer-cell-renderer-base.ts +1 -2
  27. package/src/utils/monomer-lib/consts.ts +1 -6
  28. package/src/utils/monomer-lib/lib-manager.ts +239 -112
  29. package/src/utils/monomer-lib/library-file-manager/monomers-lib-provider.ts +378 -0
  30. package/src/utils/monomer-lib/library-file-manager/ui.ts +119 -80
  31. package/src/utils/monomer-lib/monomer-colors.ts +37 -39
  32. package/src/utils/monomer-lib/monomer-lib-base.ts +3 -4
  33. package/src/utils/monomer-lib/monomer-lib.ts +7 -7
  34. package/src/utils/monomer-lib/monomer-manager/duplicate-monomer-manager.ts +3 -3
  35. package/src/utils/monomer-lib/monomer-manager/monomer-manager.ts +90 -81
  36. package/src/utils/monomer-lib/web-editor-monomer-of-library.ts +2 -1
  37. package/src/utils/seq-helper/seq-handler.ts +16 -3
  38. package/src/utils/seq-helper/seq-helper.ts +1 -2
  39. package/src/utils/sequence-to-mol.ts +1 -1
  40. package/src/viewers/web-logo-viewer.ts +1 -1
  41. package/src/widgets/composition-analysis-widget.ts +1 -1
  42. package/src/widgets/sequence-scrolling-widget.ts +1 -2
  43. package/test-console-output-1.log +672 -720
  44. package/test-record-1.mp4 +0 -0
  45. package/src/utils/monomer-lib/library-file-manager/custom-monomer-lib-handlers.ts +0 -41
  46. package/src/utils/monomer-lib/library-file-manager/event-manager.ts +0 -93
  47. package/src/utils/monomer-lib/library-file-manager/file-manager.ts +0 -317
  48. package/src/utils/monomer-lib/monomer-set.ts +0 -61
@@ -6,18 +6,20 @@ import * as ui from 'datagrok-api/ui';
6
6
  import * as DG from 'datagrok-api/dg';
7
7
 
8
8
  import {IMonomerManager, INewMonomerForm} from '@datagrok-libraries/bio/src/utils/monomer-ui';
9
- import {IMonomerLib, Monomer, RGroup} from '@datagrok-libraries/bio/src/types';
9
+ import {findProviderWithLibraryName, IMonomerLib, IMonomerLibProvider, Monomer, RGroup} from '@datagrok-libraries/bio/src/types/monomer-library';
10
10
  import {DUMMY_MONOMER, HELM_RGROUP_FIELDS} from '@datagrok-libraries/bio/src/utils/const';
11
11
  import {ItemsGrid} from '@datagrok-libraries/utils/src/items-grid';
12
12
  import {mostSimilarNaturalAnalog} from '@datagrok-libraries/bio/src/utils/macromolecule/monomers';
13
13
  import {PolymerType, MonomerType} from '@datagrok-libraries/bio/src/helm/types';
14
14
 
15
15
  import {MonomerLibManager} from '../lib-manager';
16
- import {LIB_PATH} from '../consts';
17
16
 
18
- import '../../../../css/monomer-manager.css';
19
17
  import {MONOMER_RENDERER_TAGS} from '@datagrok-libraries/bio/src/utils/cell-renderer';
20
18
  import {BioTags} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
19
+ //@ts-ignore
20
+ import '../../../../css/monomer-manager.css';
21
+ import {Subscription} from 'rxjs';
22
+
21
23
 
22
24
  // columns of monomers dataframe, note that rgroups is hidden and will be displayed as separate columns
23
25
  export enum MONOMER_DF_COLUMN_NAMES {
@@ -268,7 +270,6 @@ export class MonomerManager implements IMonomerManager {
268
270
  if (!this.instance) {
269
271
  const monManager = await MonomerLibManager.getInstance();
270
272
  await monManager.awaitLoaded();
271
- await monManager.loadLibrariesPromise;
272
273
  this.instance = new MonomerManager(monManager);
273
274
  }
274
275
  return this.instance;
@@ -277,19 +278,18 @@ export class MonomerManager implements IMonomerManager {
277
278
  public static async getNewInstance(): Promise<MonomerManager> {
278
279
  const monManager = await MonomerLibManager.getInstance();
279
280
  await monManager.awaitLoaded();
280
- await monManager.loadLibrariesPromise;
281
281
  return new MonomerManager(monManager);
282
282
  }
283
283
 
284
- async createNewMonomerLib(libName: string, _monomers: Monomer[]): Promise<void> {
284
+ async createNewMonomerLib(providerName: string, libName: string, _monomers: Monomer[]): Promise<void> {
285
285
  this.tv?.grid && ui.setUpdateIndicator(this.tv.grid.root, true);
286
286
  try {
287
- const monomersString = JSON.stringify(_monomers.map((m) => ({...m, lib: undefined, wem: undefined})), null, 2);
288
- if (!libName.endsWith('.json'))
289
- libName += '.json';
290
- await (await this.monomerLibManamger.getFileManager()).addLibraryFile(monomersString, libName);
291
- await grok.dapi.files.writeAsText(LIB_PATH + libName, monomersString);
292
- await this.monomerLibManamger.loadLibraries(false);
287
+ const provider = (await this.monomerLibManamger.getProviders()).find((p) => p.name === providerName);
288
+ if (!provider)
289
+ throw new Error(`Provider ${providerName} not found`);
290
+ const monomersMapped = _monomers.map((m) => ({...m, lib: undefined, wem: undefined}));
291
+ await provider.addOrUpdateLibrary(libName, monomersMapped);
292
+ await this.monomerLibManamger.loadMonomerLib(false);
293
293
 
294
294
  //await this.monomerLibManamger.loadLibraries(true);
295
295
  grok.shell.v = await this.getViewRoot(libName);
@@ -302,7 +302,7 @@ export class MonomerManager implements IMonomerManager {
302
302
  }
303
303
 
304
304
  async createNewLibDialog(monomers?: Monomer[]) {
305
- const monomerLibs = (await this.monomerLibManamger.getFileManager()).getValidLibraryPaths();
305
+ const monomerLibs = await this.monomerLibManamger.getAvaliableLibraryNames();
306
306
  const libNameInput = ui.input.string('Library Name', {
307
307
  placeholder: 'Enter library name',
308
308
  nullable: false,
@@ -311,20 +311,20 @@ export class MonomerManager implements IMonomerManager {
311
311
  d.getButton('Create')?.classList?.toggle('d4-disabled', !!res);
312
312
  }
313
313
  });
314
- function getFileNameInputValue() {
315
- let fileName = libNameInput.value;
316
- if (!fileName.endsWith('.json'))
317
- fileName += '.json';
318
- return fileName;
319
- };
320
314
  function validateInput(v: string) {
321
315
  if (!v || !v.trim()) return 'Library name cannot be empty';
322
- if ((v.endsWith('.json') && monomerLibs.includes(v)) || monomerLibs.includes(v + '.json'))
316
+ if (monomerLibs.includes(v) || monomerLibs.includes(v + '.json'))
323
317
  return 'Library with this name already exists';
324
318
  return null;
325
319
  }
326
320
  libNameInput.addValidator(validateInput);
321
+ const providersNames = (await this.monomerLibManamger.getProviders()).map((p) => p.name);
322
+ const providerInput = ui.input.choice('Storage', {items: providersNames, value: providersNames[0], nullable: false, tooltipText: 'Select storage provider for the new library'});
323
+ if (providersNames.length === 1)
324
+ providerInput.readOnly = true; // consider hiding instead
325
+
327
326
  const d = ui.dialog('Create New Library')
327
+ .add(providerInput)
328
328
  .add(libNameInput)
329
329
  .addButton('Create', async () => {
330
330
  const vr = validateInput(libNameInput.value);
@@ -332,8 +332,12 @@ export class MonomerManager implements IMonomerManager {
332
332
  grok.shell.warning(vr);
333
333
  return;
334
334
  }
335
+ if (!providerInput.value) {
336
+ grok.shell.warning('Please select storage provider');
337
+ return;
338
+ }
335
339
  try {
336
- await this.createNewMonomerLib(getFileNameInputValue(), monomers ?? []);
340
+ await this.createNewMonomerLib(providerInput.value!, libNameInput.value!, monomers ?? []);
337
341
  } catch (e) {
338
342
  grok.shell.error('Error creating library');
339
343
  console.error(e);
@@ -350,12 +354,14 @@ export class MonomerManager implements IMonomerManager {
350
354
  return this._newMonomerForm;
351
355
  }
352
356
 
357
+ private _contextMenuSub: Subscription | null = null;
353
358
  private async getMonomersTableView(fileName?: string, addView = true): Promise<DG.TableView> {
354
359
  const df = await this.getMonomersDf(fileName);
355
360
  this.tv = DG.TableView.create(df, addView);
356
361
 
357
362
  this.adjustTable();
358
- this.tv.subs.push(
363
+ this._contextMenuSub?.unsubscribe();
364
+ this._contextMenuSub =
359
365
  grok.events.onContextMenu.subscribe(({args}) => {
360
366
  if (!args || !args.menu || !args.context || args.context.type !== DG.VIEWER.GRID || !args.context.tableView ||
361
367
  args.context.tableView.id !== (this.tv!.id ?? '') || !args.item || !args.item.isTableCell || (args.item.tableRowIndex ?? -1) < 0)
@@ -385,8 +391,8 @@ export class MonomerManager implements IMonomerManager {
385
391
  this._newMonomerForm.removeMonomers([monomer], this.libInput.value!);
386
392
  });
387
393
  }
388
- })
389
- );
394
+ });
395
+
390
396
  this.tv.grid && (this.tv.grid.props.allowEdit = false); // disable editing
391
397
  return this.tv;
392
398
  }
@@ -410,7 +416,7 @@ export class MonomerManager implements IMonomerManager {
410
416
  private _skipLibInputOnchange: boolean = false;
411
417
 
412
418
  async getViewRoot(libName?: string, addView = true) {
413
- const availableMonLibs = (await this.monomerLibManamger.getFileManager()).getValidLibraryPaths();
419
+ const availableMonLibs = await this.monomerLibManamger.getAvaliableLibraryNames();
414
420
  this._newMonomerForm.molSketcher.resize();
415
421
  if (addView && (this.tv = this.findActiveManagerView()) && (libName ?? this.libInput.value)) {
416
422
  // get monomer library list
@@ -475,7 +481,10 @@ export class MonomerManager implements IMonomerManager {
475
481
  return grok.shell.error('No library selected');
476
482
  let lib: string | null = null;
477
483
  try {
478
- lib = await grok.dapi.files.readAsText(LIB_PATH + libName);
484
+ const provider = await findProviderWithLibraryName(await this.monomerLibManamger.getProviders(), libName);
485
+ if (!provider)
486
+ throw new Error(`Library ${libName} not found in any provider`);
487
+ lib = await provider.getLibraryAsString(libName);
479
488
  } catch (e) {
480
489
  grok.shell.error(`Error reading library ${libName}`);
481
490
  return console.error(e);
@@ -518,8 +527,19 @@ export class MonomerManager implements IMonomerManager {
518
527
  async getMonomersDf(fileName?: string) {
519
528
  this.tv?.grid && ui.setUpdateIndicator(this.tv.grid.root, true);
520
529
  try {
521
- fileName ??= (await this.monomerLibManamger.getFileManager()).getValidLibraryPaths()[0];
522
- this.activeMonomerLib = await this.monomerLibManamger.readLibrary(LIB_PATH, fileName);
530
+ let provider: IMonomerLibProvider | null = null;
531
+ const providers = await this.monomerLibManamger.getProviders();
532
+ if (providers.length === 0)
533
+ throw new Error('No monomer library providers available');
534
+ if (!fileName) {
535
+ provider = providers[0];
536
+ fileName = (await provider.listLibraries())[0];
537
+ } else {
538
+ provider = await findProviderWithLibraryName(providers, fileName);
539
+ if (!provider)
540
+ throw new Error(`Library ${fileName} not found in any provider`);
541
+ }
542
+ this.activeMonomerLib = await this.monomerLibManamger.readSingleLibrary(provider!.name, fileName);
523
543
  if (!this.activeMonomerLib) {
524
544
  grok.shell.error(`Library ${fileName} not found`);
525
545
  return DG.DataFrame.create();
@@ -548,19 +568,20 @@ export class MonomerManager implements IMonomerManager {
548
568
  .add(ui.divText('Do you wish to continue?'))
549
569
  .onOK(async () => {
550
570
  const monomerDf = this.tv?.dataFrame;
551
- let libName = this.libInput.value;
571
+ const libName = this.libInput.value;
552
572
  if (!monomerDf || !libName) {
553
573
  grok.shell.error('No monomer library loaded');
554
574
  return;
555
575
  }
556
576
  this.tv?.grid && ui.setUpdateIndicator(this.tv.grid.root, true);
557
577
  try {
578
+ const provider = await findProviderWithLibraryName(await this.monomerLibManamger.getProviders(), libName);
579
+ if (!provider)
580
+ throw new Error(`Library ${libName} not found in any provider`); // should not happen
558
581
  const monomers = await Promise.all(new Array(monomerDf.rowCount).fill(0).map((_, i) => monomerFromDfRow(monomerDf.rows.get(i))));
559
- const monomersString = JSON.stringify(monomers.map((m) => ({...m, lib: undefined, wem: undefined})), null, 2);
560
- if (!libName.endsWith('.json'))
561
- libName += '.json';
562
- await grok.dapi.files.writeAsText(LIB_PATH + libName, monomersString);
563
- await this.monomerLibManamger.loadLibraries(true);
582
+ const monomersString = monomers.map((m) => ({...m, lib: undefined, wem: undefined}));
583
+ await provider.addOrUpdateLibrary(libName, monomersString);
584
+ await this.monomerLibManamger.loadMonomerLib(true);
564
585
  //await this.monomerLibManamger.loadLibraries(true);
565
586
  grok.shell.v = await this.getViewRoot(libName);
566
587
  } catch (e) {
@@ -998,73 +1019,61 @@ class MonomerForm implements INewMonomerForm {
998
1019
  }
999
1020
 
1000
1021
  async removeMonomers(monomers: Monomer[], libName: string, notify = true) {
1001
- let libJSON: Monomer[] = [];
1002
- try {
1003
- const libTXT = await grok.dapi.files.readAsText(LIB_PATH + libName);
1004
- libJSON = JSON.parse(libTXT);
1005
- } catch (e) {
1006
- grok.shell.error(`Error reading library ${libName}`);
1007
- return console.error(e);
1008
- }
1009
- const monomerIdxs = monomers.map((monomer) => findLastIndex(libJSON, (m) => m.symbol === monomer.symbol && m.polymerType === monomer.polymerType));
1010
- for (let i = 0; i < monomerIdxs.length; i++) {
1011
- const monomerIdx = monomerIdxs[i];
1012
- if (monomerIdx === -1) {
1013
- grok.shell.error(`Monomer ${monomers[i].symbol} not found in library ${libName}`);
1014
- return;
1015
- }
1022
+ const provider = await findProviderWithLibraryName(await this.monomerLibManager.getProviders(), libName);
1023
+ if (!provider) {
1024
+ grok.shell.error(`Library ${libName} not found in any provider`);
1025
+ return;
1016
1026
  }
1017
-
1018
- const removingMonomers = monomerIdxs.map((idx) => libJSON[idx]);
1019
- const infoTables = ui.divV(removingMonomers.map((m) => this.getMonomerInfoTable(m)), {style: {maxHeight: '500px', overflow: 'scroll'}});
1020
- const isPlural = removingMonomers.length > 1;
1027
+ const infoTables = ui.divV(monomers.map((m) => this.getMonomerInfoTable(m)), {style: {maxHeight: '500px', overflow: 'scroll'}});
1028
+ const isPlural = monomers.length > 1;
1021
1029
  const promptText = isPlural ?
1022
- `Are you sure you want to remove monomers ${removingMonomers.map((m) => m.symbol).join(', ')} from ${libName} library?` :
1023
- `Are you sure you want to remove monomer with symbol ${removingMonomers[0].symbol} from ${libName} library?`;
1030
+ `Are you sure you want to remove monomers ${monomers.map((m) => m.symbol).join(', ')} from ${libName} library?` :
1031
+ `Are you sure you want to remove monomer with symbol ${monomers[0].symbol} from ${libName} library?`;
1024
1032
 
1025
1033
 
1026
1034
  const dlg = ui.dialog('Remove Monomer' + (isPlural ? 's' : ''))
1027
1035
  .add(ui.h1(promptText))
1028
1036
  .add(infoTables)
1029
1037
  .addButton('Remove', async () => {
1030
- libJSON = libJSON.filter((m) => !removingMonomers.includes(m));
1031
- await grok.dapi.files.writeAsText(LIB_PATH + libName, JSON.stringify(libJSON, null, 2));
1032
- await (await MonomerLibManager.getInstance()).loadLibraries(true);
1038
+ await provider.deleteMonomersFromLibrary(libName, monomers);
1039
+ await this.monomerLibManager.loadMonomerLib(true);
1033
1040
  await this.refreshTable();
1034
-
1035
1041
  if (notify)
1036
- grok.shell.info(`Monomer${isPlural ? 's' : ''} ${removingMonomers.map((m) => m.symbol).join(', ')} ${isPlural ? 'were' : 'was'} successfully removed from ${libName} library`);
1042
+ grok.shell.info(`Monomer${isPlural ? 's' : ''} ${monomers.map((m) => m.symbol).join(', ')} ${isPlural ? 'were' : 'was'} successfully removed from ${libName} library`);
1037
1043
  dlg.close();
1038
1044
  })
1039
1045
  .show();
1040
1046
  }
1041
1047
 
1042
1048
  private async addMonomerToLib(monomer: Monomer, libName: string) {
1043
- // TODO: permissions logic;
1044
- let libJSON: Monomer[] = [];
1045
- try {
1046
- const libTXT = await grok.dapi.files.readAsText(LIB_PATH + libName);
1047
- libJSON = JSON.parse(libTXT);
1048
- } catch (e) {
1049
- grok.shell.error(`Error reading library ${libName}`);
1050
- return console.error(e);
1049
+ // TODO: permissions logic -- to be handled on the side of providers;
1050
+ const curDf = this.getMonomersDataFrame();
1051
+ if (!curDf) {
1052
+ grok.shell.error('No monomer library loaded');
1053
+ return;
1054
+ }
1055
+ const polymerTypes = curDf?.col(MONOMER_DF_COLUMN_NAMES.POLYMER_TYPE)?.toList() ?? [];
1056
+ const symbols = curDf?.col(MONOMER_DF_COLUMN_NAMES.SYMBOL)?.toList() ?? [];
1057
+ const monomerSmiles = curDf?.col(MONOMER_DF_COLUMN_NAMES.MONOMER)?.toList() ?? [];
1058
+ if (polymerTypes.length !== symbols.length || polymerTypes.length !== monomerSmiles.length) {
1059
+ grok.shell.error('Monomer library data frame is corrupted');
1060
+ return;
1051
1061
  }
1052
1062
  // check if monomer with given symbol exists in library. search from the end to get the last monomer with that symbol (there can be duplicates)
1053
- const existingMonomerIdx = findLastIndex(libJSON, (m) => m.symbol === monomer.symbol && m.polymerType === monomer.polymerType);
1063
+ const existingMonomerIdx = polymerTypes.findIndex((pt, idx) => pt === monomer.polymerType && symbols[idx] === monomer.symbol);
1054
1064
  // check if the same structure already exists in the library. as everything is in canonical smiles, we can directly do string matching
1055
- const existingStructureIdx = this.getMonomersDataFrame()?.col(MONOMER_DF_COLUMN_NAMES.MONOMER)?.toList()?.findIndex((smi) => smi === monomer.smiles);
1065
+ const existingStructureIdx = monomerSmiles.findIndex((smi) => smi === monomer.smiles);
1056
1066
 
1057
1067
  const saveLib = async () => {
1058
1068
  try {
1059
- // first remove the existing monomer with that symbol
1060
- const monomerIdx = libJSON.findIndex((m) => m.symbol === monomer.symbol && m.polymerType === monomer.polymerType);
1061
- if (monomerIdx >= 0)
1062
- libJSON[monomerIdx] = {...monomer, lib: undefined, wem: undefined};
1063
- else
1064
- libJSON.push({...monomer, lib: undefined, wem: undefined});
1065
-
1066
- await grok.dapi.files.writeAsText(LIB_PATH + libName, JSON.stringify(libJSON, null, 2));
1067
- await (await MonomerLibManager.getInstance()).loadLibraries(true);
1069
+ const provider = await findProviderWithLibraryName(await this.monomerLibManager.getProviders(), libName);
1070
+ if (!provider) {
1071
+ grok.shell.error(`Library ${libName} not found in any provider`);
1072
+ return;
1073
+ }
1074
+ await provider.updateOrAddMonomersInLibrary(libName, [{...monomer, lib: undefined, wem: undefined}]);
1075
+
1076
+ await this.monomerLibManager.loadMonomerLib(true);
1068
1077
  await this.refreshTable(monomer.symbol);
1069
1078
  this._molChanged = false; // reset the flag
1070
1079
  grok.shell.info(`Monomer ${monomer.symbol} was successfully saved in library ${libName}`);
@@ -1077,7 +1086,7 @@ class MonomerForm implements INewMonomerForm {
1077
1086
  let infoTable: HTMLDivElement | null = null;
1078
1087
  let promptMessage = '';
1079
1088
  if (existingMonomerIdx >= 0) {
1080
- infoTable = this.getMonomerInfoTable(libJSON[existingMonomerIdx]);
1089
+ infoTable = this.getMonomerInfoTable(await monomerFromDfRow(curDf!.row(existingMonomerIdx)));
1081
1090
  promptMessage = `Monomer with symbol '${monomer.symbol}' already exists in library ${libName}.\nAre you sure you want to overwrite it?`;
1082
1091
  } else if ((existingStructureIdx ?? -1) >= 0) {
1083
1092
  const m = await monomerFromDfRow(this.getMonomersDataFrame()!.rows.get(existingStructureIdx!));
@@ -1145,7 +1154,7 @@ class MonomerForm implements INewMonomerForm {
1145
1154
  }
1146
1155
  }
1147
1156
 
1148
- function findLastIndex<T>(ar: ArrayLike<T>, pred: (el: T) => boolean): number {
1157
+ export function findLastIndex<T>(ar: ArrayLike<T>, pred: (el: T) => boolean): number {
1149
1158
  let foundIdx = -1;
1150
1159
  for (let i = ar.length - 1; i >= 0; i--) {
1151
1160
  if (pred(ar[i])) {
@@ -1,9 +1,10 @@
1
+ /* eslint-disable max-len */
1
2
  import * as grok from 'datagrok-api/grok';
2
3
  import * as ui from 'datagrok-api/ui';
3
4
  import * as DG from 'datagrok-api/dg';
4
5
 
5
6
  import {HelmType, IWebEditorMonomer, MonomerType, PolymerType, WebEditorRGroups} from '@datagrok-libraries/bio/src/helm/types';
6
- import {IMonomerLibBase, Monomer} from '@datagrok-libraries/bio/src/types/index';
7
+ import {IMonomerLibBase, Monomer} from '@datagrok-libraries/bio/src/types/monomer-library';
7
8
  import {HELM_OPTIONAL_FIELDS as OPT, HELM_REQUIRED_FIELD as REQ, HELM_RGROUP_FIELDS as RGP} from '@datagrok-libraries/bio/src/utils/const';
8
9
 
9
10
  import {BrokenWebEditorMonomer} from './web-editor-monomer-dummy';
@@ -6,11 +6,11 @@ import wu from 'wu';
6
6
 
7
7
  /* eslint-disable max-len */
8
8
  import {ALIGNMENT, ALPHABET, candidateAlphabets, getSplitterWithSeparator, NOTATION, positionSeparator, splitterAsFasta, splitterAsHelm, TAGS} from '@datagrok-libraries/bio/src/utils/macromolecule/index';
9
- import {INotationProvider, ISeqConnection, ISeqSplitted, SeqColStats, SplitterFunc,} from '@datagrok-libraries/bio/src/utils/macromolecule/types';
9
+ import {CandidateType, INotationProvider, ISeqConnection, ISeqSplitted, SeqColStats, SplitterFunc,} from '@datagrok-libraries/bio/src/utils/macromolecule/types';
10
10
  import {detectAlphabet, detectHelmAlphabet, splitterAsFastaSimple, StringListSeqSplitted} from '@datagrok-libraries/bio/src/utils/macromolecule/utils';
11
11
  import {mmDistanceFunctions, MmDistanceFunctionsNames} from '@datagrok-libraries/ml/src/macromolecule-distance-functions';
12
12
  import {mmDistanceFunctionType} from '@datagrok-libraries/ml/src/macromolecule-distance-functions/types';
13
- import {getMonomerLibHelper, IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
13
+ import {getMonomerLibHelper, IMonomerLibHelper} from '@datagrok-libraries/bio/src/types/monomer-library';
14
14
  import {HELM_POLYMER_TYPE, HELM_WRAPPERS_REGEXP, PHOSPHATE_SYMBOL} from '@datagrok-libraries/bio/src/utils/const';
15
15
  import {GAP_SYMBOL, GapOriginals} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
16
16
  import {CellRendererBackBase, GridCellRendererTemp} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
@@ -201,7 +201,20 @@ export class SeqHandler implements ISeqHandler {
201
201
  } else if (units === NOTATION.HELM) {
202
202
  let alphabet = uh.column.getTag(TAGS.alphabet);
203
203
  if (alphabet === null) {
204
- alphabet = detectHelmAlphabet(uh.stats.freq, candidateAlphabets, uh.defaultGapOriginal);
204
+ // const cats = uh.column.categories;
205
+ // const splitter = uh.getSplitter();
206
+ // const samples = Array.from(new Set(
207
+ // wu.count(0).take(Math.min(100, cats.length)).map((_) => Math.floor(Math.random() * cats.length)).toArray())
208
+ // ).map((catIndex) => cats[catIndex]).filter((s) => (s?.length ?? 0) > 0).map((s) => splitter(s));
209
+ // // splitted helm has info about polymer types
210
+ // const polymerTypes = new Set<HELM_POLYMER_TYPE>();
211
+ // for (const ss of samples) {
212
+ // ss.graphInfo?.polymerTypes
213
+ // }
214
+ // increase the detection threshold for candidate alphabets
215
+ const modifiedCandidateAlphabets = candidateAlphabets.map((ca) => new CandidateType(ca.name, ca.alphabet, 0.9));
216
+
217
+ alphabet = detectHelmAlphabet(uh.stats.freq, modifiedCandidateAlphabets, uh.defaultGapOriginal);
205
218
  uh.column.setTag(TAGS.alphabet, alphabet);
206
219
  }
207
220
  }
@@ -6,12 +6,11 @@ import wu from 'wu';
6
6
 
7
7
  import {ISeqHelper, ToAtomicLevelRes} from '@datagrok-libraries/bio/src/utils/seq-helper';
8
8
  import {RDModule, RDMol} from '@datagrok-libraries/chem-meta/src/rdkit-api';
9
- import {IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
10
9
  import {getHelmHelper, IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
11
10
  import {MolfileWithMap} from '@datagrok-libraries/bio/src/monomer-works/types';
12
11
  import {getMolColName} from '@datagrok-libraries/bio/src/monomer-works/utils';
13
12
  import {ChemTags} from '@datagrok-libraries/chem-meta/src/consts';
14
- import {IMonomerLibBase} from '@datagrok-libraries/bio/src/types/index';
13
+ import {IMonomerLibBase, IMonomerLibHelper} from '@datagrok-libraries/bio/src/types/monomer-library';
15
14
 
16
15
  import {HelmToMolfileConverter} from '../helm-to-molfile/converter';
17
16
  import {ISeqHandler} from '@datagrok-libraries/bio/src/utils/macromolecule/seq-handler';
@@ -3,7 +3,7 @@ import * as ui from 'datagrok-api/ui';
3
3
  import * as DG from 'datagrok-api/dg';
4
4
 
5
5
  import {_toAtomicLevel} from '@datagrok-libraries/bio/src/monomer-works/to-atomic-level';
6
- import {IMonomerLib} from '@datagrok-libraries/bio/src/types';
6
+ import {IMonomerLib} from '@datagrok-libraries/bio/src/types/monomer-library';
7
7
  import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
8
8
  import {getSeqHelper, ISeqHelper, ToAtomicLevelRes} from '@datagrok-libraries/bio/src/utils/seq-helper';
9
9
  import {RDModule} from '@datagrok-libraries/chem-meta/src/rdkit-api';
@@ -25,7 +25,7 @@ import {ISeqSplitted} from '@datagrok-libraries/bio/src/utils/macromolecule/type
25
25
  import {testEvent} from '@datagrok-libraries/utils/src/test';
26
26
  import {PromiseSyncer} from '@datagrok-libraries/bio/src/utils/syncer';
27
27
  import {GAP_SYMBOL} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
28
- import {IMonomerLibBase} from '@datagrok-libraries/bio/src/types/index';
28
+ import {IMonomerLibBase} from '@datagrok-libraries/bio/src/types/monomer-library';
29
29
  import {HelmType} from '@datagrok-libraries/bio/src/helm/types';
30
30
  import {undefinedColor} from '@datagrok-libraries/bio/src/utils/cell-renderer-monomer-placer';
31
31
 
@@ -6,7 +6,7 @@ import wu from 'wu';
6
6
 
7
7
  import {TAGS as bioTAGS, ALPHABET} from '@datagrok-libraries/bio/src/utils/macromolecule';
8
8
  import {GAP_SYMBOL} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
9
- import {IMonomerLibBase} from '@datagrok-libraries/bio/src/types';
9
+ import {IMonomerLibBase} from '@datagrok-libraries/bio/src/types/monomer-library';
10
10
  import {HelmType} from '@datagrok-libraries/bio/src/helm/types';
11
11
  import {HelmTypes, PolymerTypes} from '@datagrok-libraries/bio/src/helm/consts';
12
12
 
@@ -10,11 +10,10 @@ import {ConservationTrack, MSAHeaderTrack, MSAScrollingHeader, WebLogoTrack} fro
10
10
  import {MonomerPlacer} from '@datagrok-libraries/bio/src/utils/cell-renderer-monomer-placer';
11
11
  import {ALPHABET, TAGS as bioTAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
12
12
  import {_package} from '../package';
13
- import {getMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
14
13
  import {ISeqHandler} from '@datagrok-libraries/bio/src/utils/macromolecule/seq-handler';
15
14
  import * as RxJs from 'rxjs';
16
15
  import {filter} from 'rxjs/operators';
17
- import {IMonomerLib} from '@datagrok-libraries/bio/src/types';
16
+ import {IMonomerLib, getMonomerLibHelper} from '@datagrok-libraries/bio/src/types/monomer-library';
18
17
  import wu from 'wu';
19
18
 
20
19
  // ============================================================================