@datagrok/sequence-translator 1.4.4 → 1.4.6

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 (41) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/detectors.js +24 -0
  3. package/dist/455.js +2 -0
  4. package/dist/455.js.map +1 -0
  5. package/dist/package-test.js +1 -1
  6. package/dist/package-test.js.map +1 -1
  7. package/dist/package.js +1 -1
  8. package/dist/package.js.map +1 -1
  9. package/files/polytool-rules/rules_example.json +2 -2
  10. package/files/samples/HELM.csv +6 -0
  11. package/files/samples/cyclized.csv +4 -3
  12. package/files/samples/cyclized_MSA.csv +5 -0
  13. package/package.json +13 -13
  14. package/src/apps/common/model/oligo-toolkit-package.ts +23 -4
  15. package/src/apps/common/view/components/molecule-img.ts +2 -2
  16. package/src/apps/pattern/model/data-manager.ts +9 -9
  17. package/src/apps/translator/view/ui.ts +8 -8
  18. package/src/consts.ts +12 -0
  19. package/src/global.d.ts +13 -0
  20. package/src/package-test.ts +3 -0
  21. package/src/package.ts +32 -5
  22. package/src/polytool/pt-conversion.ts +395 -81
  23. package/src/polytool/pt-dialog.ts +29 -13
  24. package/src/polytool/pt-enumeration-helm-dialog.ts +79 -34
  25. package/src/polytool/pt-enumeration-helm.ts +12 -8
  26. package/src/polytool/pt-placeholders-breadth-input.ts +4 -4
  27. package/src/polytool/pt-placeholders-input.ts +6 -6
  28. package/src/polytool/pt-unrule-dialog.ts +7 -3
  29. package/src/polytool/pt-unrule.ts +4 -3
  30. package/src/polytool/types.ts +4 -4
  31. package/src/tests/polytool-chain-from-notation-tests.ts +108 -18
  32. package/src/tests/polytool-chain-parse-notation-tests.ts +100 -0
  33. package/src/tests/polytool-convert-tests.ts +102 -25
  34. package/src/tests/polytool-detectors-custom-notation-test.ts +43 -0
  35. package/src/tests/polytool-enumerate-breadth-tests.ts +4 -4
  36. package/src/tests/toAtomicLevel-tests.ts +1 -1
  37. package/src/tests/utils/detect-macromolecule-utils.ts +64 -0
  38. package/src/tests/{utils.ts → utils/index.ts} +2 -2
  39. package/src/utils/context-menu.ts +2 -5
  40. package/src/utils/cyclized.ts +88 -0
  41. package/src/utils/dimerized.ts +10 -0
@@ -9,7 +9,10 @@ import {getHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
9
9
  import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
10
10
  import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
11
11
  import {getSeqHelper, ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
12
- import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
12
+ import {MmcrTemps} from '@datagrok-libraries/bio/src/utils/cell-renderer-consts';
13
+ import {buildMonomerHoverLink} from '@datagrok-libraries/bio/src/monomer-works/monomer-hover';
14
+ import {getRdKitModule} from '@datagrok-libraries/bio/src/chem/rdkit-module';
15
+ import {RDModule} from '@datagrok-libraries/chem-meta/src/rdkit-api';
13
16
 
14
17
  import {getRules, RuleInputs, Rules, RULES_PATH, RULES_STORAGE_NAME} from './pt-rules';
15
18
  import {doPolyToolConvert, getOverriddenLibrary} from './pt-conversion';
@@ -35,17 +38,18 @@ type PolyToolEnumerateChemSerialized = {
35
38
  screenLibrary: string | null;
36
39
  }
37
40
 
38
- export function polyToolEnumerateChemUI(cell?: DG.Cell): void {
39
- getPolyToolEnumerationChemDialog(cell)
40
- .then((dialog) => {
41
- dialog.show({resizable: true});
42
- })
43
- .catch((_err: any) => {
44
- grok.shell.warning('To run PolyTool Enumeration, sketch the molecule and specify the R group to vary');
45
- });
41
+ export async function polyToolEnumerateChemUI(cell?: DG.Cell): Promise<void> {
42
+ await _package.initPromise;
43
+ try {
44
+ const dialog = await getPolyToolEnumerationChemDialog(cell);
45
+ dialog.show({resizable: true});
46
+ } catch (_err: any) {
47
+ grok.shell.warning('To run PolyTool Enumeration, sketch the molecule and specify the R group to vary');
48
+ }
46
49
  }
47
50
 
48
51
  export async function polyToolConvertUI(): Promise<void> {
52
+ await _package.initPromise;
49
53
  let dialog: DG.Dialog;
50
54
  try {
51
55
  dialog = await getPolyToolConvertDialog();
@@ -74,7 +78,7 @@ export async function getPolyToolConvertDialog(srcCol?: DG.Column): Promise<DG.D
74
78
  table: srcColVal.dataFrame, value: srcColVal,
75
79
  filter: (col: DG.Column) => {
76
80
  if (col.semType !== DG.SEMTYPE.MACROMOLECULE) return false;
77
- const sh = SeqHandler.forColumn(col);
81
+ const sh = _package.seqHelper.getSeqHandler(col);
78
82
  return sh.notation === NOTATION.CUSTOM;
79
83
  }
80
84
  });
@@ -231,6 +235,11 @@ async function getPolyToolEnumerationChemDialog(cell?: DG.Cell): Promise<DG.Dial
231
235
  }
232
236
  }
233
237
 
238
+ function dealGroups(col: DG.Column<string>): void {
239
+ for (let i = 0; i < col.length; i++)
240
+ col.set(i, col.get(i)!.replaceAll('undefined', 'H'));
241
+ }
242
+
234
243
  /** Returns Helm and molfile columns. */
235
244
  export async function polyToolConvert(
236
245
  seqCol: DG.Column<string>, generateHelm: boolean, chiralityEngine: boolean, ruleFiles: string[]
@@ -241,11 +250,11 @@ export async function polyToolConvert(
241
250
  if (!df) return colName;
242
251
  return df.columns.getUnusedName(colName);
243
252
  };
244
- await getHelmHelper(); // initializes JSDraw and org
253
+ const helmHelper = await getHelmHelper(); // initializes JSDraw and org
245
254
 
246
255
  const table = seqCol.dataFrame;
247
256
  const rules = await getRules(ruleFiles);
248
- const resList = doPolyToolConvert(seqCol.toList(), rules);
257
+ const resList = doPolyToolConvert(seqCol.toList(), rules, helmHelper);
249
258
 
250
259
  const resHelmColName = getUnusedName(table, `transformed(${seqCol.name})`);
251
260
  const resHelmCol = DG.Column.fromType(DG.COLUMN_TYPE.STRING, resHelmColName, resList.length)
@@ -256,17 +265,24 @@ export async function polyToolConvert(
256
265
  if (generateHelm && table) table.columns.add(resHelmCol, true);
257
266
 
258
267
  const seqHelper: ISeqHelper = await getSeqHelper();
268
+ const rdKitModule: RDModule = await getRdKitModule();
259
269
  const lib = await getOverriddenLibrary(rules);
270
+ const resHelmColTemp = resHelmCol.temp;
271
+ resHelmColTemp[MmcrTemps.overriddenLibrary] = lib;
272
+ resHelmCol.temp = resHelmColTemp;
260
273
  const toAtomicLevelRes =
261
274
  await seqHelper.helmToAtomicLevel(resHelmCol, chiralityEngine, /* highlight */ generateHelm, lib);
262
275
  const resMolCol = toAtomicLevelRes.molCol!;
263
-
276
+ dealGroups(resMolCol);
264
277
  resMolCol.name = getUnusedName(table, `molfile(${seqCol.name})`);
265
278
  resMolCol.semType = DG.SEMTYPE.MOLECULE;
266
279
  if (table) {
267
280
  table.columns.add(resMolCol, true);
268
281
  await grok.data.detectSemanticTypes(table);
269
282
  }
283
+
284
+ buildMonomerHoverLink(resHelmCol, resMolCol, lib, seqHelper, rdKitModule);
285
+
270
286
  return [resHelmCol, resMolCol];
271
287
  } finally {
272
288
  pi.close();
@@ -5,10 +5,8 @@ import * as DG from 'datagrok-api/dg';
5
5
  import $ from 'cash-dom';
6
6
  import wu from 'wu';
7
7
  import {fromEvent, Unsubscribable} from 'rxjs';
8
-
9
- import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
10
- import {HelmAtom, HelmMol} from '@datagrok-libraries/helm-web-editor/src/types/org-helm';
11
- import {getHelmHelper, HelmInputBase} from '@datagrok-libraries/bio/src/helm/helm-helper';
8
+ import {HelmAtom} from '@datagrok-libraries/helm-web-editor/src/types/org-helm';
9
+ import {getHelmHelper, HelmInputBase, IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
12
10
  import {getMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
13
11
  import {HelmType, PolymerType} from '@datagrok-libraries/bio/src/helm/types';
14
12
  import {helmTypeToPolymerType} from '@datagrok-libraries/bio/src/monomer-works/monomer-works';
@@ -16,19 +14,18 @@ import {getSeqHelper, ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-he
16
14
  import '@datagrok-libraries/bio/src/types/input';
17
15
  import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
18
16
  import {InputColumnBase} from '@datagrok-libraries/bio/src/types/input';
19
- import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
20
17
 
21
- import {
22
- PolyToolEnumeratorParams, PolyToolEnumeratorType, PolyToolEnumeratorTypes
23
- } from './types';
18
+ import {PolyToolEnumeratorParams, PolyToolEnumeratorType, PolyToolEnumeratorTypes} from './types';
24
19
  import {getLibrariesList} from './utils';
25
20
  import {doPolyToolEnumerateHelm, PT_HELM_EXAMPLE} from './pt-enumeration-helm';
26
21
  import {PolyToolPlaceholdersInput} from './pt-placeholders-input';
27
22
  import {defaultErrorHandler} from '../utils/err-info';
28
23
  import {PolyToolPlaceholdersBreadthInput} from './pt-placeholders-breadth-input';
29
24
  import {PT_UI_DIALOG_ENUMERATION} from './const';
25
+ import {PolyToolDataRole, PolyToolTags} from '../consts';
26
+ import {Chain} from './pt-conversion';
30
27
 
31
- import {_package} from '../package';
28
+ import {_package, applyNotationProviderForCyclized} from '../package';
32
29
 
33
30
  type PolyToolEnumerateInputs = {
34
31
  macromolecule: HelmInputBase;
@@ -36,8 +33,9 @@ type PolyToolEnumerateInputs = {
36
33
  placeholdersBreadth: PolyToolPlaceholdersBreadthInput;
37
34
  enumeratorType: DG.ChoiceInput<PolyToolEnumeratorType>
38
35
  trivialNameCol: InputColumnBase,
39
- toAtomicLevel: DG.InputBase<boolean>;
40
36
  keepOriginal: DG.InputBase<boolean>;
37
+ toAtomicLevel: DG.InputBase<boolean>;
38
+ toHarmonizedSequence: DG.InputBase<boolean>;
41
39
  };
42
40
 
43
41
  type PolyToolEnumerateHelmSerialized = {
@@ -46,11 +44,14 @@ type PolyToolEnumerateHelmSerialized = {
46
44
  placeholdersBreadth: string;
47
45
  enumeratorType: PolyToolEnumeratorType;
48
46
  trivialNameCol: string;
49
- toAtomicLevel: boolean;
50
47
  keepOriginal: boolean;
48
+ toAtomicLevel: boolean;
49
+ toHarmonizedSequence: boolean;
51
50
  };
52
51
 
53
52
  export async function polyToolEnumerateHelmUI(cell?: DG.Cell): Promise<void> {
53
+ await _package.initPromise;
54
+
54
55
  const maxWidth = window.innerWidth;
55
56
  const maxHeight = window.innerHeight;
56
57
 
@@ -117,7 +118,6 @@ export async function polyToolEnumerateHelmUI(cell?: DG.Cell): Promise<void> {
117
118
  }
118
119
  }
119
120
 
120
-
121
121
  async function getPolyToolEnumerateDialog(
122
122
  cell?: DG.Cell, resizeInputs?: () => void
123
123
  ): Promise<DG.Dialog> {
@@ -160,10 +160,12 @@ async function getPolyToolEnumerateDialog(
160
160
  showRowHeader: false,
161
161
  showCellTooltip: false,
162
162
  }),
163
- toAtomicLevel: ui.input.bool(
164
- 'To atomic level', {value: false}),
165
163
  keepOriginal: ui.input.bool(
166
164
  'Keep original', {value: false}),
165
+ toAtomicLevel: ui.input.bool(
166
+ 'To atomic level', {value: false}),
167
+ toHarmonizedSequence: ui.input.bool(
168
+ 'To harmonized sequence', {value: false}),
167
169
  trivialNameCol: ui.input.column2(
168
170
  'Trivial name', {
169
171
  table: cell?.dataFrame,
@@ -184,6 +186,7 @@ async function getPolyToolEnumerateDialog(
184
186
  }),
185
187
  };
186
188
 
189
+ inputs.toHarmonizedSequence.root.style.display = 'none';
187
190
  inputs.trivialNameCol.addOptions(trivialNameSampleDiv);
188
191
 
189
192
  let placeholdersValidity: string | null = null;
@@ -308,11 +311,12 @@ async function getPolyToolEnumerateDialog(
308
311
  inputs.macromolecule.root.style.setProperty('min-width', '250px', 'important');
309
312
  // inputs.macromolecule.root.style.setProperty('max-height', '300px', 'important');
310
313
 
314
+ const phPosSet = new Set<number>(inputs.placeholders.placeholdersValue.map((ph) => ph.position));
311
315
  const updateMolView = () => {
312
316
  const mol = inputs.macromolecule.molValue;
313
317
  for (let aI = 0; aI < mol.atoms.length; aI++) {
314
318
  const a = mol.atoms[aI];
315
- a.highlighted = aI in inputs.placeholders.placeholdersValue;
319
+ a.highlighted = phPosSet.has(aI);
316
320
  }
317
321
  inputs.macromolecule.redraw();
318
322
  };
@@ -359,22 +363,33 @@ async function getPolyToolEnumerateDialog(
359
363
  if (resizeInputs) resizeInputs();
360
364
  };
361
365
 
362
- const fillForCurrentCell = async (cell?: DG.Cell): Promise<void> => {
366
+ const fillForCurrentCell = async (cell?: DG.Cell): Promise<PolyToolDataRole> => {
367
+ let resDataRole;
363
368
  let helmValue: string;
364
369
  let table: DG.DataFrame | undefined = undefined;
365
370
  if (cell && cell.rowIndex >= 0 && cell?.column.semType == DG.SEMTYPE.MACROMOLECULE) {
366
- const sh = SeqHandler.forColumn(cell.column);
367
- helmValue = await sh.getHelm(cell.rowIndex);
371
+ const sh = _package.seqHelper.getSeqHandler(cell.column);
372
+ const mValue = await sh.getValue(cell.rowIndex);
373
+ helmValue = mValue.value;
368
374
  table = cell.dataFrame;
375
+ resDataRole = (mValue.tags[PolyToolTags.dataRole] as PolyToolDataRole.template) ?? PolyToolDataRole.macromolecule;
369
376
  } else {
370
377
  helmValue = PT_HELM_EXAMPLE;
378
+ resDataRole = PolyToolDataRole.macromolecule;
371
379
  }
372
-
373
380
  inputs.macromolecule.stringValue = helmValue;
381
+
382
+ if (resDataRole === PolyToolDataRole.template) {
383
+ inputs.toAtomicLevel.root.style.display = 'none';
384
+ } else {
385
+ inputs.toAtomicLevel.root.style.removeProperty('display');
386
+ }
387
+
374
388
  fillTrivialNameList(table);
389
+ return resDataRole;
375
390
  };
376
391
 
377
- await fillForCurrentCell(cell);
392
+ let dataRole: PolyToolDataRole = await fillForCurrentCell(cell);
378
393
 
379
394
  const exec = async (): Promise<void> => {
380
395
  try {
@@ -397,10 +412,12 @@ async function getPolyToolEnumerateDialog(
397
412
  const params: PolyToolEnumeratorParams = {
398
413
  placeholders: inputs.placeholders.placeholdersValue,
399
414
  type: inputs.enumeratorType.value!,
400
- placeholdersBreadth: inputs.placeholdersBreadth.placeholdersBreadthValue,
415
+ breadthPlaceholders: inputs.placeholdersBreadth.placeholdersBreadthValue,
401
416
  keepOriginal: inputs.keepOriginal.value,
402
417
  };
403
- const enumeratorResDf = await polyToolEnumerateHelm(srcHelm, srcId, params, inputs.toAtomicLevel.value, seqHelper);
418
+ const toAtomicLevelV = inputs.toAtomicLevel.value && dataRole == PolyToolDataRole.macromolecule;
419
+ const enumeratorResDf = await polyToolEnumerateHelm(srcHelm, dataRole, srcId, params,
420
+ toAtomicLevelV, seqHelper, helmHelper);
404
421
  grok.shell.addTableView(enumeratorResDf);
405
422
  }
406
423
  } catch (err: any) {
@@ -414,8 +431,8 @@ async function getPolyToolEnumerateDialog(
414
431
  .add(inputs.enumeratorType)
415
432
  .add(inputs.placeholdersBreadth)
416
433
  .add(inputs.trivialNameCol)
417
- .add(inputs.toAtomicLevel)
418
- .add(inputs.keepOriginal)
434
+ .add(ui.divH([inputs.keepOriginal.root, inputs.toAtomicLevel.root, inputs.toHarmonizedSequence.root],
435
+ {style: {width: '100%'}}))
419
436
  .add(warningsTextDiv)
420
437
  // .addButton('Enumerate', () => {
421
438
  // execDialog()
@@ -433,8 +450,9 @@ async function getPolyToolEnumerateDialog(
433
450
  enumeratorType: inputs.enumeratorType.value,
434
451
  placeholdersBreadth: inputs.placeholdersBreadth.stringValue,
435
452
  trivialNameCol: inputs.trivialNameCol.stringValue,
436
- toAtomicLevel: inputs.toAtomicLevel.value,
437
453
  keepOriginal: inputs.keepOriginal.value,
454
+ toAtomicLevel: inputs.toAtomicLevel.value,
455
+ toHarmonizedSequence: inputs.toHarmonizedSequence.value,
438
456
  };
439
457
  },
440
458
  /* applyInput */ (x: PolyToolEnumerateHelmSerialized): void => {
@@ -443,8 +461,9 @@ async function getPolyToolEnumerateDialog(
443
461
  inputs.enumeratorType.value = x.enumeratorType;
444
462
  inputs.placeholdersBreadth.stringValue = x.placeholdersBreadth;
445
463
  inputs.trivialNameCol.stringValue = x.trivialNameCol;
446
- inputs.toAtomicLevel.value = x.toAtomicLevel;
447
464
  inputs.keepOriginal.value = x.keepOriginal;
465
+ inputs.toAtomicLevel.value = x.toAtomicLevel;
466
+ inputs.toHarmonizedSequence.value = x.toHarmonizedSequence;
448
467
  });
449
468
  return dialog;
450
469
  } catch (err: any) {
@@ -453,23 +472,49 @@ async function getPolyToolEnumerateDialog(
453
472
  }
454
473
  }
455
474
 
475
+ /**
476
+ * @param {DG.SemanticValue} srcValue Source value to enumerate, either of data role
477
+ * {@link PolyToolDataRole.template} or {@link PolyToolDataRole.macromolecule}
478
+ * */
456
479
  async function polyToolEnumerateHelm(
457
- srcHelm: string, srcId: { value: string, colName: string } | null, params: PolyToolEnumeratorParams,
458
- toAtomicLevel: boolean, seqHelper: ISeqHelper,
480
+ srcHelm: string, dataRole: PolyToolDataRole, srcId: { value: string, colName: string } | null,
481
+ params: PolyToolEnumeratorParams, toAtomicLevel: boolean, seqHelper: ISeqHelper, helmHelper: IHelmHelper
459
482
  ): Promise<DG.DataFrame> {
460
483
  const pi = DG.TaskBarProgressIndicator.create('PolyTool enumerating...');
461
484
  try {
462
485
  await getHelmHelper(); // initializes JSDraw and org
463
486
 
464
487
  const resList = doPolyToolEnumerateHelm(srcHelm, srcId?.value ?? '', params);
465
- const enumHelmCol = DG.Column.fromType(DG.COLUMN_TYPE.STRING, 'Enumerated', resList.length)
466
- .init((rowIdx: number) => resList[rowIdx][0]);
467
- const enumeratorResDf = DG.DataFrame.fromColumns([enumHelmCol]);
488
+ let enumCol: DG.Column<string>;
489
+ switch (dataRole) {
490
+ case PolyToolDataRole.macromolecule: {
491
+ enumCol = DG.Column.fromType(DG.COLUMN_TYPE.STRING, 'Enumerated', resList.length)
492
+ .init((rowIdx: number) => resList[rowIdx][0]);
493
+ break;
494
+ }
495
+ case PolyToolDataRole.template: {
496
+ const templateList: string[] = new Array<string>(resList.length);
497
+ for (let rowIdx = 0; rowIdx < resList.length; rowIdx++) {
498
+ const pseudoHelm = resList[rowIdx][0];
499
+ const chain = Chain.parseHelm(pseudoHelm, helmHelper);
500
+ templateList[rowIdx] = chain.getNotation();
501
+ }
502
+ enumCol = DG.Column.fromList(DG.COLUMN_TYPE.STRING, 'Enumerated', templateList);
503
+ // enumCol.semType = DG.SEMTYPE.MACROMOLECULE;
504
+ // enumCol.setTag(PolyToolTags.dataRole, PolyToolDataRole.template);
505
+ // applyNotationProviderForCyclized(enumCol, '-');
506
+ break;
507
+ }
508
+ }
509
+ const enumeratorResDf = DG.DataFrame.fromColumns([enumCol]);
510
+ await grok.data.detectSemanticTypes(enumeratorResDf);
511
+ if (dataRole == PolyToolDataRole.template) {
512
+ applyNotationProviderForCyclized(enumCol, '-');
513
+ }
468
514
 
469
- if (toAtomicLevel) {
515
+ if (toAtomicLevel && dataRole != PolyToolDataRole.template) {
470
516
  const seqHelper: ISeqHelper = await getSeqHelper();
471
- const toAtomicLevelRes = await seqHelper.helmToAtomicLevel(enumHelmCol, true, true);
472
- toAtomicLevelRes.molCol!.semType = DG.SEMTYPE.MOLECULE;
517
+ const toAtomicLevelRes = await seqHelper.helmToAtomicLevel(enumCol, true, true);
473
518
  enumeratorResDf.columns.add(toAtomicLevelRes.molCol!, false);
474
519
  }
475
520
 
@@ -4,13 +4,14 @@ import * as DG from 'datagrok-api/dg';
4
4
 
5
5
  import {
6
6
  HelmType, HelmMol,
7
- JSDraw2ModuleType, OrgType
7
+ JSDraw2ModuleType, OrgType,
8
+ IHelmEditorOptions
8
9
  } from '@datagrok-libraries/bio/src/helm/types';
9
10
 
10
11
 
11
12
  import {Chain} from './pt-conversion';
12
13
  import {getAvailableMonomers} from './utils';
13
- import {PolyToolEnumeratorParams, PolyToolEnumeratorTypes, PolyToolPlaceholders, PolyToolPlaceholdersBreadth} from './types';
14
+ import {PolyToolEnumeratorParams, PolyToolEnumeratorTypes, PolyToolPlaceholder, PolyToolBreadthPlaceholder} from './types';
14
15
 
15
16
  // For example keep monomers presented in HELMCoreLibrary.json only (not [NH2])
16
17
  export const PT_HELM_EXAMPLE = 'PEPTIDE1{R.[Aca].T.G.H.F.G.A.A.Y.P.E.[meI]}$$$$';
@@ -43,14 +44,14 @@ function polyToolEnumeratorCore(m: HelmMol, start: number, end: number, monomerL
43
44
  * @param placeholders Placeholders by zero-based position key
44
45
  * @returns {string[]} List of enumerated molecules in Helm format
45
46
  */
46
- function getPtEnumeratorSingle(m: HelmMol, placeholders: PolyToolPlaceholders): HelmMol[] {
47
+ function getPtEnumeratorSingle(m: HelmMol, placeholders: PolyToolPlaceholder[]): HelmMol[] {
47
48
  const coreResList: HelmMol[][] = placeholders
48
49
  .map((ph) => polyToolEnumeratorCore(m, ph.position, ph.position, ph.monomers));
49
50
  const resMolList = coreResList.reduce((acc, posList) => acc.concat(posList), []);
50
51
  return resMolList;
51
52
  }
52
53
 
53
- function getPtEnumeratorMatrix(m: HelmMol, placeholders: PolyToolPlaceholders): HelmMol[] {
54
+ function getPtEnumeratorMatrix(m: HelmMol, placeholders: PolyToolPlaceholder[]): HelmMol[] {
54
55
  let resMolList = [m];
55
56
  for (const ph of placeholders) {
56
57
  const phResMolList: HelmMol[][] = resMolList.map((m: HelmMol) => polyToolEnumeratorCore(m, ph.position, ph.position, ph.monomers));
@@ -59,7 +60,10 @@ function getPtEnumeratorMatrix(m: HelmMol, placeholders: PolyToolPlaceholders):
59
60
  return resMolList;
60
61
  }
61
62
 
62
- function getPtEnumeratorBreadth(m: HelmMol, placeholdersBreadth: PolyToolPlaceholdersBreadth): HelmMol[] {
63
+ function getPtEnumeratorBreadth(m: HelmMol, placeholdersBreadth: PolyToolBreadthPlaceholder[]): HelmMol[] {
64
+ if (placeholdersBreadth.length == 0)
65
+ return [];
66
+
63
67
  let resMolList = [m];
64
68
  for (const phb of placeholdersBreadth) {
65
69
  const phResMolList: HelmMol[][] = resMolList.map((m: HelmMol) => polyToolEnumeratorCore(m, phb.start, phb.end, phb.monomers));
@@ -72,7 +76,7 @@ function getPtEnumeratorBreadth(m: HelmMol, placeholdersBreadth: PolyToolPlaceho
72
76
  export function doPolyToolEnumerateHelm(
73
77
  helm: string, id: string, params: PolyToolEnumeratorParams
74
78
  ): [ /* helm */ string, /* id */ string][] {
75
- const molHandler = new JSDraw2.MolHandler<HelmType>();
79
+ const molHandler = new JSDraw2.MolHandler<HelmType, IHelmEditorOptions>();
76
80
  const plugin = new org.helm.webeditor.Plugin(molHandler);
77
81
  org.helm.webeditor.IO.parseHelm(plugin, helm, new JSDraw2.Point(0, 0), undefined);
78
82
  const m = molHandler.m;
@@ -93,8 +97,8 @@ export function doPolyToolEnumerateHelm(
93
97
  }
94
98
 
95
99
  let resBreadthMolList: HelmMol[] = [];
96
- if (params.placeholdersBreadth) {
97
- resBreadthMolList = getPtEnumeratorBreadth(molHandler.m, params.placeholdersBreadth);
100
+ if (params.breadthPlaceholders) {
101
+ resBreadthMolList = getPtEnumeratorBreadth(molHandler.m, params.breadthPlaceholders);
98
102
  }
99
103
  resMolList = resMolList.concat(resBreadthMolList);
100
104
 
@@ -3,7 +3,7 @@ import * as grok from 'datagrok-api/grok';
3
3
  import * as DG from 'datagrok-api/dg';
4
4
 
5
5
  import {Unsubscribable} from 'rxjs';
6
- import {PolyToolPlaceholders, PolyToolPlaceholdersBreadth} from './types';
6
+ import {PolyToolBreadthPlaceholder} from './types';
7
7
  import {parseMonomerSymbolList} from './pt-placeholders-input';
8
8
 
9
9
  export class PolyToolPlaceholdersBreadthInput extends DG.JsInputBase<DG.DataFrame> {
@@ -21,7 +21,7 @@ export class PolyToolPlaceholdersBreadthInput extends DG.JsInputBase<DG.DataFram
21
21
 
22
22
  setStringValue(str: string): void { this.grid.dataFrame = DG.DataFrame.fromCsv(str); }
23
23
 
24
- get placeholdersBreadthValue(): PolyToolPlaceholdersBreadth {
24
+ get placeholdersBreadthValue(): PolyToolBreadthPlaceholder[] {
25
25
  return dfToPlaceholdersBreadth(this.grid.dataFrame);
26
26
  }
27
27
 
@@ -97,8 +97,8 @@ export class PolyToolPlaceholdersBreadthInput extends DG.JsInputBase<DG.DataFram
97
97
  }
98
98
  }
99
99
 
100
- export function dfToPlaceholdersBreadth(df: DG.DataFrame): PolyToolPlaceholdersBreadth {
101
- const res: PolyToolPlaceholdersBreadth = [];
100
+ export function dfToPlaceholdersBreadth(df: DG.DataFrame): PolyToolBreadthPlaceholder[] {
101
+ const res: PolyToolBreadthPlaceholder[] = [];
102
102
  for (let rowI = 0; rowI < df.rowCount; rowI++) {
103
103
  const startPos = parseInt(df.get('Start', rowI)) - 1;
104
104
  const endPos = parseInt(df.get('End', rowI)) - 1;
@@ -4,7 +4,7 @@ import * as DG from 'datagrok-api/dg';
4
4
 
5
5
  import {Unsubscribable} from 'rxjs';
6
6
 
7
- import {PolyToolPlaceholders} from './types';
7
+ import {PolyToolPlaceholder} from './types';
8
8
 
9
9
  export class PolyToolPlaceholdersInput extends DG.JsInputBase<DG.DataFrame> {
10
10
  get inputType(): string { return 'Positions'; }
@@ -21,7 +21,7 @@ export class PolyToolPlaceholdersInput extends DG.JsInputBase<DG.DataFrame> {
21
21
 
22
22
  setStringValue(str: string): void { this.grid.dataFrame = DG.DataFrame.fromCsv(str); }
23
23
 
24
- get placeholdersValue(): PolyToolPlaceholders {
24
+ get placeholdersValue(): PolyToolPlaceholder[] {
25
25
  return dfToPlaceholders(this.grid.dataFrame);
26
26
  }
27
27
 
@@ -95,8 +95,8 @@ export class PolyToolPlaceholdersInput extends DG.JsInputBase<DG.DataFrame> {
95
95
  }
96
96
  }
97
97
 
98
- export function getPlaceholdersFromText(src: string): PolyToolPlaceholders {
99
- const res: PolyToolPlaceholders = [];
98
+ export function getPlaceholdersFromText(src: string): PolyToolPlaceholder[] {
99
+ const res: PolyToolPlaceholder[] = [];
100
100
  for (const line of src.split('\n')) {
101
101
  const lineM = /^\s*(?<pos>\d+)\s*:\s*(?<monomers>.+)$/.exec(line);
102
102
  if (lineM) {
@@ -108,8 +108,8 @@ export function getPlaceholdersFromText(src: string): PolyToolPlaceholders {
108
108
  return res;
109
109
  }
110
110
 
111
- export function dfToPlaceholders(df: DG.DataFrame): PolyToolPlaceholders {
112
- const res: PolyToolPlaceholders = [];
111
+ export function dfToPlaceholders(df: DG.DataFrame): PolyToolPlaceholder[] {
112
+ const res: PolyToolPlaceholder[] = [];
113
113
  for (let rowI = 0; rowI < df.rowCount; rowI++) {
114
114
  const pos = parseInt(df.get('Position', rowI)) - 1;
115
115
  if (!isNaN(pos)) {
@@ -4,15 +4,17 @@ import * as DG from 'datagrok-api/dg';
4
4
 
5
5
  import {Unsubscribable} from 'rxjs';
6
6
 
7
- import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
8
7
  import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
9
8
  import {getUnusedColName} from '@datagrok-libraries/bio/src/monomer-works/utils';
9
+ import {getHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
10
10
 
11
11
  import {defaultErrorHandler} from '../utils/err-info';
12
12
  import {doPolyToolUnrule} from './pt-unrule';
13
13
  import {getRules, RuleInputs, RULES_PATH, RULES_STORAGE_NAME} from './pt-rules';
14
14
  import {PT_ERROR_DATAFRAME, PT_UI_DIALOG_UNRULE, PT_UI_RULES_USED} from './const';
15
15
 
16
+ import {_package} from '../package';
17
+
16
18
  type PolyToolUnruleSerialized = {
17
19
  rules: string[];
18
20
  };
@@ -34,7 +36,7 @@ export async function getPolyToolUnruleDialog(srcCol?: DG.Column<string>): Promi
34
36
  table: srcColVal.dataFrame, value: srcColVal,
35
37
  filter: (col: DG.Column) => {
36
38
  if (col.semType !== DG.SEMTYPE.MACROMOLECULE) return false;
37
- const sh = SeqHandler.forColumn(col);
39
+ const sh = _package.seqHelper.getSeqHandler(col);
38
40
  return sh.notation === NOTATION.HELM;
39
41
  }
40
42
  });
@@ -87,9 +89,11 @@ export async function polyToolUnrule(
87
89
  ): Promise<DG.Column> {
88
90
  const pi = DG.TaskBarProgressIndicator.create('PolyTool unrule...');
89
91
  try {
92
+ const helmHelper = await getHelmHelper();
93
+
90
94
  const table = srcCol.dataFrame;
91
95
  const rules = await getRules(ruleFiles);
92
- const resHelmList = doPolyToolUnrule(srcCol.toList(), rules);
96
+ const resHelmList = doPolyToolUnrule(srcCol.toList(), rules, helmHelper);
93
97
  const resHelmColName = `harmonized(srcCol.name)`;
94
98
  const resHelmCol = DG.Column.fromList(DG.COLUMN_TYPE.STRING, resHelmColName, resHelmList,);
95
99
  resHelmCol.semType = DG.SEMTYPE.MACROMOLECULE;
@@ -9,6 +9,7 @@ import {getPolyToolUnruleDialog} from './pt-unrule-dialog';
9
9
  import {Rules} from './pt-rules';
10
10
 
11
11
  import {_package} from '../package';
12
+ import {IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
12
13
 
13
14
  export async function polyToolUnruleUI(): Promise<void> {
14
15
  let dialog: DG.Dialog;
@@ -23,14 +24,14 @@ export async function polyToolUnruleUI(): Promise<void> {
23
24
  }
24
25
 
25
26
  /** Returns list of harmonized sequences. Covered with tests. */
26
- export function doPolyToolUnrule(helms: string[], rules: Rules): string[] {
27
+ export function doPolyToolUnrule(helms: string[], rules: Rules, helmHelper: IHelmHelper): string[] {
27
28
  const resHrzSeqList = new Array<string>(helms.length);
28
29
  for (let i = 0; i < helms.length; ++i) {
29
30
  if (!helms[i])
30
31
  resHrzSeqList[i] = '';
31
32
  else {
32
- const chain = Chain.fromHelm(helms[i]);
33
- resHrzSeqList[i] = chain.getNotation(rules);
33
+ const chain = Chain.parseHelm(helms[i], helmHelper);
34
+ resHrzSeqList[i] = chain.getNotation();
34
35
  }
35
36
  }
36
37
  return resHrzSeqList;
@@ -11,15 +11,15 @@ export enum PolyToolEnumeratorTypes {
11
11
 
12
12
  export type PolyToolEnumeratorType = typeof PolyToolEnumeratorTypes[keyof typeof PolyToolEnumeratorTypes];
13
13
 
14
- export type PolyToolPlaceholders = { position: number, monomers: string[] } [];
14
+ export type PolyToolPlaceholder = { position: number, monomers: string[] };
15
15
 
16
- export type PolyToolPlaceholdersBreadth = { start: number, end: number, monomers: string[] }[];
16
+ export type PolyToolBreadthPlaceholder = { start: number, end: number, monomers: string[] };
17
17
 
18
18
  export type PolyToolEnumeratorParams = {
19
19
  type: PolyToolEnumeratorType;
20
20
  /** position key is zero-based */
21
- placeholders?: PolyToolPlaceholders;
22
- placeholdersBreadth?: PolyToolPlaceholdersBreadth;
21
+ placeholders?: PolyToolPlaceholder[];
22
+ breadthPlaceholders?: PolyToolBreadthPlaceholder[];
23
23
  keepOriginal?: boolean;
24
24
  trivialName?: boolean;
25
25
  }