@datagrok/sequence-translator 1.2.6 → 1.2.9

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 (102) hide show
  1. package/.eslintrc.json +5 -5
  2. package/CHANGELOG.md +12 -0
  3. package/dist/package-test.js +2 -1
  4. package/dist/package-test.js.LICENSE.txt +8 -0
  5. package/dist/package-test.js.map +1 -1
  6. package/dist/package.js +2 -1
  7. package/dist/package.js.LICENSE.txt +8 -0
  8. package/dist/package.js.map +1 -1
  9. package/files/pattern-app-data.json +80 -0
  10. package/package.json +21 -14
  11. package/src/{model → apps/common/model}/const.ts +1 -1
  12. package/src/{model/data-loading-utils → apps/common/model/data-loader}/const.ts +7 -2
  13. package/src/apps/common/model/data-loader/json-loader.ts +48 -0
  14. package/src/{model/data-loading-utils → apps/common/model/data-loader}/types.ts +13 -6
  15. package/src/{model → apps/common/model}/monomer-lib/lib-wrapper.ts +9 -12
  16. package/src/apps/common/model/oligo-toolkit-package.ts +30 -0
  17. package/src/{model → apps/common/model}/parsing-validation/format-detector.ts +5 -5
  18. package/src/{model → apps/common/model}/parsing-validation/format-handler.ts +18 -19
  19. package/src/{model → apps/common/model}/parsing-validation/sequence-validator.ts +1 -1
  20. package/src/apps/common/view/app-ui-base.ts +28 -0
  21. package/src/apps/common/view/combined-app-ui.ts +66 -0
  22. package/src/{view/utils → apps/common/view/components}/colored-input/colored-text-input.ts +1 -1
  23. package/src/{view/utils → apps/common/view/components}/draw-molecule.ts +1 -1
  24. package/src/{view/utils → apps/common/view/components}/molecule-img.ts +3 -3
  25. package/src/{view/const/ui.ts → apps/common/view/const.ts} +4 -4
  26. package/src/apps/common/view/isolated-app-ui.ts +43 -0
  27. package/src/{view/monomer-lib-viewer/viewer.ts → apps/common/view/monomer-lib-viewer.ts} +2 -2
  28. package/src/apps/common/view/utils.ts +29 -0
  29. package/src/apps/pattern/model/const.ts +121 -0
  30. package/src/apps/pattern/model/data-manager.ts +297 -0
  31. package/src/apps/pattern/model/event-bus.ts +470 -0
  32. package/src/apps/pattern/model/router.ts +46 -0
  33. package/src/apps/pattern/model/subscription-manager.ts +21 -0
  34. package/src/apps/pattern/model/translator.ts +68 -0
  35. package/src/apps/pattern/model/types.ts +52 -0
  36. package/src/apps/pattern/model/utils.ts +110 -0
  37. package/src/apps/pattern/view/components/bulk-convert/column-input.ts +69 -0
  38. package/src/apps/pattern/view/components/bulk-convert/table-controls.ts +37 -0
  39. package/src/apps/pattern/view/components/bulk-convert/table-input.ts +95 -0
  40. package/src/apps/pattern/view/components/edit-block-controls.ts +196 -0
  41. package/src/apps/pattern/view/components/left-section.ts +44 -0
  42. package/src/apps/pattern/view/components/load-block-controls.ts +198 -0
  43. package/src/apps/pattern/view/components/numeric-label-visibility-controls.ts +69 -0
  44. package/src/apps/pattern/view/components/right-section.ts +148 -0
  45. package/src/apps/pattern/view/components/strand-editor/dialog.ts +79 -0
  46. package/src/apps/pattern/view/components/strand-editor/header-controls.ts +105 -0
  47. package/src/apps/pattern/view/components/strand-editor/strand-controls.ts +159 -0
  48. package/src/apps/pattern/view/components/terminal-modification-editor.ts +127 -0
  49. package/src/apps/pattern/view/components/translation-examples-block.ts +139 -0
  50. package/src/{view/style/pattern-app.css → apps/pattern/view/style.css} +4 -0
  51. package/src/apps/pattern/view/svg-utils/const.ts +63 -0
  52. package/src/apps/pattern/view/svg-utils/dimensions-calculator.ts +498 -0
  53. package/src/apps/pattern/view/svg-utils/svg-display-manager.ts +45 -0
  54. package/src/apps/pattern/view/svg-utils/svg-element-factory.ts +82 -0
  55. package/src/apps/pattern/view/svg-utils/svg-renderer.ts +396 -0
  56. package/src/apps/pattern/view/svg-utils/utils.ts +37 -0
  57. package/src/apps/pattern/view/types.ts +14 -0
  58. package/src/apps/pattern/view/ui.ts +61 -0
  59. package/src/{model/structure-app → apps/structure/model}/mol-transformations.ts +3 -3
  60. package/src/{model/structure-app → apps/structure/model}/monomer-code-parser.ts +9 -10
  61. package/src/{model/structure-app → apps/structure/model}/oligo-structure.ts +4 -4
  62. package/src/{model/structure-app → apps/structure/model}/sequence-to-molfile.ts +2 -2
  63. package/src/{view/apps/oligo-structure.ts → apps/structure/view/ui.ts} +31 -17
  64. package/src/{model/translator-app → apps/translator/model}/conversion-utils.ts +25 -7
  65. package/src/{model/translator-app → apps/translator/model}/format-converter.ts +7 -12
  66. package/src/{view/const/oligo-translator.ts → apps/translator/view/const.ts} +2 -0
  67. package/src/apps/translator/view/ui.ts +547 -0
  68. package/src/demo/demo-st-ui.ts +12 -32
  69. package/src/package.ts +76 -56
  70. package/src/plugins/mermade.ts +9 -9
  71. package/src/polytool/const.ts +40 -0
  72. package/src/polytool/csv-to-json-monomer-lib-converter.ts +40 -0
  73. package/src/polytool/cyclized.ts +56 -0
  74. package/src/polytool/monomer-lib-handler.ts +115 -0
  75. package/src/polytool/transformation.ts +326 -0
  76. package/src/polytool/ui.ts +59 -0
  77. package/src/polytool/utils.ts +20 -0
  78. package/src/tests/const.ts +5 -5
  79. package/src/tests/formats-support.ts +6 -6
  80. package/src/tests/formats-to-helm.ts +5 -5
  81. package/src/tests/helm-to-nucleotides.ts +5 -5
  82. package/tsconfig.json +4 -10
  83. package/webpack.config.js +3 -0
  84. package/files/axolabs-style.json +0 -97
  85. package/src/model/data-loading-utils/json-loader.ts +0 -38
  86. package/src/model/pattern-app/const.ts +0 -33
  87. package/src/model/pattern-app/draw-svg.ts +0 -193
  88. package/src/model/pattern-app/helpers.ts +0 -96
  89. package/src/model/pattern-app/oligo-pattern.ts +0 -111
  90. package/src/view/app-ui.ts +0 -193
  91. package/src/view/apps/oligo-pattern.ts +0 -759
  92. package/src/view/apps/oligo-translator.ts +0 -184
  93. /package/src/{model → apps/common/model}/helpers.ts +0 -0
  94. /package/src/{model → apps/common/model}/monomer-lib/const.ts +0 -0
  95. /package/src/{view/utils → apps/common/view/components}/app-info-dialog.ts +0 -0
  96. /package/src/{view/utils → apps/common/view/components}/colored-input/input-painters.ts +0 -0
  97. /package/src/{view/style/colored-text-input.css → apps/common/view/components/colored-input/style.css} +0 -0
  98. /package/src/{view/utils → apps/common/view/components}/router.ts +0 -0
  99. /package/src/{model/structure-app → apps/structure/model}/const.ts +0 -0
  100. /package/src/{view/style/structure-app.css → apps/structure/view/style.css} +0 -0
  101. /package/src/{model/translator-app → apps/translator/model}/const.ts +0 -0
  102. /package/src/{view/style/translator-app.css → apps/translator/view/style.css} +0 -0
package/src/package.ts CHANGED
@@ -1,94 +1,73 @@
1
+ import DG from 'datagrok-api/dg';
1
2
  import * as grok from 'datagrok-api/grok';
2
- import * as ui from 'datagrok-api/ui';
3
- import * as DG from 'datagrok-api/dg';
4
-
5
- import {AppUIFactory, CombinedAppUI} from './view/app-ui';
6
- import {tryCatch} from './model/helpers';
7
- import {LIB_PATH, DEFAULT_LIB_FILENAME} from './model/data-loading-utils/const';
8
- import {IMonomerLib} from '@datagrok-libraries/bio/src/types';
9
- import {getMonomerLibHelper, IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
10
- import {getJsonData} from './model/data-loading-utils/json-loader';
11
- import {SequenceToMolfileConverter} from './model/structure-app/sequence-to-molfile';
12
- import {linkStrandsV3000} from './model/structure-app/mol-transformations';
13
- import {MonomerLibWrapper} from './model/monomer-lib/lib-wrapper';
14
- import {FormatDetector} from './model/parsing-validation/format-detector';
15
- import {SequenceValidator} from './model/parsing-validation/sequence-validator';
16
- import {demoOligoTranslatorUI, demoOligoPatternUI, demoOligoStructureUI} from './demo/demo-st-ui';
17
- import {FormatConverter} from './model/translator-app/format-converter';
18
- import {APP} from './view/const/ui';
3
+ import {loadJsonData} from './apps/common/model/data-loader/json-loader';
4
+ import {MonomerLibWrapper} from './apps/common/model/monomer-lib/lib-wrapper';
5
+ import {OligoToolkitPackage} from './apps/common/model/oligo-toolkit-package';
6
+ import {FormatDetector} from './apps/common/model/parsing-validation/format-detector';
7
+ import {SequenceValidator} from './apps/common/model/parsing-validation/sequence-validator';
8
+ import {APP_NAME} from './apps/common/view/const';
9
+ import {getSpecifiedAppUI} from './apps/common/view/utils';
10
+ import {CombinedAppUI} from './apps/common/view/combined-app-ui';
11
+ import {linkStrandsV3000} from './apps/structure/model/mol-transformations';
12
+ import {SequenceToMolfileConverter} from './apps/structure/model/sequence-to-molfile';
13
+ import {FormatConverter} from './apps/translator/model/format-converter';
14
+ import {demoOligoPatternUI, demoOligoStructureUI, demoOligoTranslatorUI} from './demo/demo-st-ui';
19
15
  import {getExternalAppViewFactories} from './plugins/mermade';
20
16
 
21
- class StPackage extends DG.Package {
22
- private _monomerLib?: IMonomerLib;
23
-
24
- get monomerLib(): IMonomerLib {
25
- if (!this._monomerLib)
26
- throw new Error ('Monomer lib not loaded')
27
- return this._monomerLib!;
28
- }
29
-
30
- public async initMonomerLib(): Promise<void> {
31
- if (this._monomerLib !== undefined)
32
- return;
33
-
34
- const pi: DG.TaskBarProgressIndicator = DG.TaskBarProgressIndicator.create(
35
- `Initializing ${APP.COMBINED} monomer library ...`);
36
- await tryCatch(async () => {
37
- const libHelper: IMonomerLibHelper = await getMonomerLibHelper();
38
- this._monomerLib = await libHelper.readLibrary(LIB_PATH, DEFAULT_LIB_FILENAME);
39
- }, () => pi.close());
40
- }
41
- }
42
-
43
- export const _package: StPackage = new StPackage();
44
-
45
- async function buildLayout(appName: string): Promise<void> {
46
- await initSequenceTranslatorLibData();
47
- const appUI = AppUIFactory.getUI(appName);
48
- await appUI.createAppLayout();
49
- }
17
+ import {getPolyToolDialog} from './polytool/ui';
18
+ import {_setPeptideColumn} from './polytool/utils';
19
+ import {PolyToolCsvLibHandler} from './polytool/csv-to-json-monomer-lib-converter';
50
20
 
21
+ export const _package: OligoToolkitPackage = new OligoToolkitPackage();
51
22
 
52
23
  //name: Oligo Toolkit
53
24
  //meta.icon: img/icons/toolkit.png
54
25
  //meta.browsePath: Oligo
55
26
  //tags: app
56
- export async function oligoToolkitApp(): Promise<void> {
27
+ //output: view v
28
+ export async function oligoToolkitApp(): Promise<DG.ViewBase> {
57
29
  await initSequenceTranslatorLibData();
58
30
  const externalViewFactories = await getExternalAppViewFactories();
59
31
  if (!externalViewFactories)
60
32
  throw new Error('External app view factories not loaded');
61
33
  const appUI = new CombinedAppUI(externalViewFactories!);
62
- await appUI.createAppLayout();
34
+ const view = await appUI.getAppView();
35
+ return view;
63
36
  }
64
37
 
65
38
  //name: Oligo Translator
66
39
  //meta.icon: img/icons/translator.png
67
40
  //meta.browsePath: Oligo
68
41
  //tags: app
69
- export async function oligoTranslatorApp(): Promise<void> {
70
- await buildLayout(APP.TRANSLATOR);
42
+ //output: view v
43
+ export async function oligoTranslatorApp(): Promise<DG.ViewBase> {
44
+ const view = await getSpecifiedAppView(APP_NAME.TRANSLATOR);
45
+ return view;
71
46
  }
72
47
 
73
48
  //name: Oligo Pattern
74
49
  //meta.icon: img/icons/pattern.png
75
50
  //meta.browsePath: Oligo
76
51
  //tags: app
77
- export async function oligoPatternApp(): Promise<void> {
78
- await buildLayout(APP.PATTERN);
52
+ //output: view v
53
+ export async function oligoPatternApp(): Promise<DG.ViewBase> {
54
+ const view = await getSpecifiedAppView(APP_NAME.PATTERN);
55
+ return view;
79
56
  }
80
57
 
81
58
  //name: Oligo Structure
82
59
  //meta.icon: img/icons/structure.png
83
60
  //meta.browsePath: Oligo
84
61
  //tags: app
85
- export async function oligoStructureApp(): Promise<void> {
86
- await buildLayout(APP.STRUCTRE);
62
+ //output: view v
63
+ export async function oligoStructureApp(): Promise<DG.ViewBase> {
64
+ const view = await getSpecifiedAppView(APP_NAME.STRUCTURE);
65
+ return view;
87
66
  }
88
67
 
89
68
  //name: initSequenceTranslatorLibData
90
69
  export async function initSequenceTranslatorLibData(): Promise<void> {
91
- await getJsonData();
70
+ await loadJsonData();
92
71
  await _package.initMonomerLib();
93
72
  }
94
73
 
@@ -152,7 +131,48 @@ export async function demoOligoStructure(): Promise<void> {
152
131
  //input: string sourceFormat
153
132
  //input: string targetFormat
154
133
  //output: string result
155
- export async function translateOligonucleotideSequence(sequence: string, sourceFormat: string, targetFormat: string): Promise<string> {
134
+ export async function translateOligonucleotideSequence(
135
+ sequence: string, sourceFormat: string, targetFormat: string
136
+ ): Promise<string> {
156
137
  await initSequenceTranslatorLibData();
157
138
  return (new FormatConverter(sequence, sourceFormat)).convertTo(targetFormat);
158
139
  }
140
+
141
+ async function getSpecifiedAppView(appName: string): Promise<DG.ViewBase> {
142
+ await initSequenceTranslatorLibData();
143
+ const appUI = getSpecifiedAppUI(appName);
144
+ const view = await appUI.getAppView();
145
+ return view;
146
+ }
147
+
148
+ //top-menu: Bio | Convert | PolyTool
149
+ //name: polyTool
150
+ //description: Perform cyclization of polymers
151
+ export async function polyTool(): Promise<void> {
152
+ let dialog: DG.Dialog;
153
+ try {
154
+ dialog = await getPolyToolDialog();
155
+ dialog.show();
156
+ } catch (err: any) {
157
+ grok.shell.warning('To run PolyTool, open a dataframe with macromolecules');
158
+ }
159
+ }
160
+
161
+ //name: polyToolColumnChoice
162
+ //input: dataframe df [Input data table]
163
+ //input: column macroMolecule
164
+ export async function polyToolColumnChoice(df: DG.DataFrame, macroMolecule: DG.Column): Promise<void> {
165
+ _setPeptideColumn(macroMolecule);
166
+ await grok.data.detectSemanticTypes(df);
167
+ }
168
+
169
+ //name: createMonomerLibraryForPolyTool
170
+ //input: file file
171
+ export async function createMonomerLibraryForPolyTool(file: DG.FileInfo) {
172
+ const fileContent = await file.readAsString();
173
+ const libHandler = new PolyToolCsvLibHandler(file.fileName, fileContent);
174
+ const libObject = await libHandler.getJson();
175
+ const jsonFileName = file.fileName.replace(/\.csv$/, '.json');
176
+ const jsonFileContent = JSON.stringify(libObject, null, 2);
177
+ DG.Utils.download(jsonFileName, jsonFileContent);
178
+ }
@@ -3,19 +3,19 @@ import * as grok from 'datagrok-api/grok';
3
3
  import * as ui from 'datagrok-api/ui';
4
4
  import * as DG from 'datagrok-api/dg';
5
5
 
6
- import {ExternalPluginUI} from '../view/app-ui';
7
- import {ColoredTextInput} from '../view/utils/colored-input/colored-text-input';
8
- import {highlightInvalidSubsequence} from '../view/utils/colored-input/input-painters';
9
- import {codesToSymbolsDictionary} from '../model/data-loading-utils/json-loader';
6
+ import {ExternalPluginUI} from '../apps/common/view/utils';
7
+ import {ColoredTextInput} from '../apps/common/view/components/colored-input/colored-text-input';
8
+ import {highlightInvalidSubsequence} from '../apps/common/view/components/colored-input/input-painters';
9
+ import {CODES_TO_SYMBOLS_DICT} from '../apps/common/model/data-loader/json-loader';
10
10
  import {MERMADE} from './const';
11
11
 
12
12
  export async function getExternalAppViewFactories(): Promise<{[name: string]: () => DG.View} | undefined> {
13
13
  const externalPluginData = {
14
- [MERMADE.FUNCTION_NAME]: {
14
+ [MERMADE.FUNCTION_NAME]: {
15
15
  tabName: MERMADE.TAB_NAME,
16
16
  parameters: getMerMadeParameters()
17
17
  },
18
- }
18
+ };
19
19
 
20
20
  const result: {[tabName: string]: () => DG.View} = {};
21
21
 
@@ -30,7 +30,7 @@ export async function getExternalAppViewFactories(): Promise<{[name: string]: ()
30
30
 
31
31
  result[data.tabName] = () => pluginUI.getView();
32
32
  } catch (err) {
33
- console.warn(`Plugin ${pluginName} not loaded, reason:`, err)
33
+ console.warn(`Plugin ${pluginName} not loaded, reason:`, err);
34
34
  continue;
35
35
  }
36
36
  }
@@ -43,6 +43,6 @@ function getMerMadeParameters(): {[name: string]: any} {
43
43
 
44
44
  return {
45
45
  coloredInput: input,
46
- codes: codesToSymbolsDictionary
47
- }
46
+ codes: CODES_TO_SYMBOLS_DICT
47
+ };
48
48
  }
@@ -0,0 +1,40 @@
1
+ import {HELM_REQUIRED_FIELD} from '@datagrok-libraries/bio/src/utils/const';
2
+
3
+ export const ALL_MONOMERS = '<All>';
4
+
5
+ export const enum TRANSFORMATION_TYPE {
6
+ CYCLIZATION = 'Cyclization',
7
+ }
8
+
9
+ export const enum CYCLIZATION_TYPE {
10
+ NO = 'N-O',
11
+ NCys = 'N-Cys',
12
+ R3 = 'R3-R3',
13
+ }
14
+
15
+ export const helmFieldsToPolyToolInputFields = {
16
+ [HELM_REQUIRED_FIELD.SYMBOL]: 'Short Name',
17
+ [HELM_REQUIRED_FIELD.NAME]: 'Medium Name',
18
+ [HELM_REQUIRED_FIELD.SMILES]: 'SMILES',
19
+ };
20
+
21
+ export const R_GROUP_BLOCK_DUMMY = [
22
+ {
23
+ 'capGroupSMILES': '[*:1][H]',
24
+ 'alternateId': 'R1-H',
25
+ 'capGroupName': 'H',
26
+ 'label': 'R1'
27
+ },
28
+ {
29
+ 'capGroupSMILES': 'O[*:2]',
30
+ 'alternateId': 'R2-OH',
31
+ 'capGroupName': 'OH',
32
+ 'label': 'R2'
33
+ },
34
+ {
35
+ 'capGroupSMILES': '[*:3][H]',
36
+ 'alternateId': 'R3-H',
37
+ 'capGroupName': 'H',
38
+ 'label': 'R3'
39
+ }
40
+ ];
@@ -0,0 +1,40 @@
1
+ import * as DG from 'datagrok-api/dg';
2
+
3
+ import {PolyToolMonomerLibHandler} from './monomer-lib-handler';
4
+
5
+ /** Handler of custom monomer libs for PolyTool */
6
+ export class PolyToolCsvLibHandler {
7
+ constructor(private fileName: string, private fileContent: string) {
8
+ this.validateFileType();
9
+ const df = DG.DataFrame.fromCsv(this.fileContent);
10
+ const json = this.toJson(df);
11
+ this.polyToolMonomerLib = new PolyToolMonomerLibHandler(json);
12
+ this.validateContent();
13
+ }
14
+
15
+ private polyToolMonomerLib: PolyToolMonomerLibHandler;
16
+
17
+ async getJson(): Promise<any> {
18
+ const rawLibData = this.polyToolMonomerLib.getJsonMonomerLib();
19
+ return rawLibData;
20
+ }
21
+
22
+ private toJson(df: DG.DataFrame): any[] {
23
+ return Array.from({length: df.rowCount}, (_, idx) =>
24
+ df.columns.names().reduce((entry: { [key: string]: any }, colName) => {
25
+ entry[colName] = df.get(colName, idx);
26
+ return entry;
27
+ }, {})
28
+ );
29
+ }
30
+
31
+ private validateFileType(): void {
32
+ if (!this.fileName.endsWith('.csv'))
33
+ throw new Error(`File ${this.fileName} is not an CSV file`);
34
+ }
35
+
36
+ private validateContent(): void {
37
+ if (!this.polyToolMonomerLib.isValid())
38
+ throw new Error('Invalid format of CSV monomer lib');
39
+ }
40
+ }
@@ -0,0 +1,56 @@
1
+ import {GAP_SYMBOL, INotationProvider, ISeqSplitted, SeqSplittedBase, SplitterFunc}
2
+ from '@datagrok-libraries/bio/src/utils/macromolecule/types';
3
+ import {getSplitterWithSeparator, StringListSeqSplitted} from '@datagrok-libraries/bio/src/utils/macromolecule/utils';
4
+ import {GapOriginals} from '@datagrok-libraries/bio/src/utils/seq-handler';
5
+ import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
6
+
7
+ export class CyclizedNotationProvider implements INotationProvider {
8
+ private readonly separatorSplitter: SplitterFunc;
9
+ public readonly splitter: SplitterFunc;
10
+
11
+ constructor(
12
+ public readonly separator: string
13
+ ) {
14
+ this.separatorSplitter = getSplitterWithSeparator(this.separator);
15
+ this.splitter = this._splitter.bind(this);
16
+ }
17
+
18
+ private _splitter(seq: string): ISeqSplitted {
19
+ const baseSS: ISeqSplitted = this.separatorSplitter(seq);
20
+ return new CyclizedSeqSplitted(baseSS.originals, GapOriginals[NOTATION.SEPARATOR]);
21
+ };
22
+ }
23
+
24
+ /** Gets canonical monomers for original ones with cyclization marks */
25
+ export class CyclizedSeqSplitted extends StringListSeqSplitted {
26
+ private readonly seqCList: (string | null)[];
27
+
28
+ private _canonicals: string[] | null = null;
29
+ override get canonicals(): SeqSplittedBase {
30
+ if (!this._canonicals) {
31
+ const len = this.length;
32
+ this._canonicals = new Array<string>(len);
33
+ for (let posIdx = 0; posIdx < len; ++posIdx)
34
+ this._canonicals[posIdx] = this.getCanonical(posIdx);
35
+ }
36
+ return this._canonicals;
37
+ }
38
+
39
+ override getCanonical(posIdx: number): string {
40
+ if (this.isGap(posIdx)) return GAP_SYMBOL;
41
+
42
+ let cmRes: string | null = this.seqCList[posIdx];
43
+ if (cmRes === null) {
44
+ const om = this.getOriginal(posIdx);
45
+ cmRes = om;
46
+ if (om[om.length - 1] === ')')
47
+ cmRes = this.seqCList[posIdx] = om.replace(/\(\d+\)$/, '');
48
+ }
49
+ return cmRes;
50
+ }
51
+
52
+ constructor(seqOList: SeqSplittedBase, gapOriginalMonomer: string) {
53
+ super(seqOList, gapOriginalMonomer);
54
+ this.seqCList = new Array<string | null>(this.length).fill(null);
55
+ }
56
+ }
@@ -0,0 +1,115 @@
1
+ /* Do not change these import lines to match external modules in webpack configuration */
2
+ import * as grok from 'datagrok-api/grok';
3
+ import * as ui from 'datagrok-api/ui';
4
+ import * as DG from 'datagrok-api/dg';
5
+
6
+ import {HELM_FIELDS, DUMMY_MONOMER} from '@datagrok-libraries/bio/src/utils/const';
7
+ import {
8
+ helmFieldsToPolyToolInputFields, R_GROUP_BLOCK_DUMMY
9
+ } from './const';
10
+ import {Monomer, RGroup} from '@datagrok-libraries/bio/src/types/index';
11
+
12
+ export class PolyToolMonomerLibHandler {
13
+ constructor(private rawLib: any[]) { }
14
+
15
+ isValid(): boolean {
16
+ return this.rawLib.every((entry) => {
17
+ return typeof entry === 'object' &&
18
+ Object.values(helmFieldsToPolyToolInputFields).every((field) => {
19
+ return field in entry &&
20
+ typeof entry[field] === 'string';
21
+ });
22
+ });
23
+ }
24
+
25
+ getJsonMonomerLib(): any {
26
+ const resultLib: any[] = [];
27
+ this.rawLib.forEach((rawMonomer) => {
28
+ const monomer = this.prepareMonomer(rawMonomer);
29
+ resultLib.push(monomer);
30
+ });
31
+ return resultLib;
32
+ }
33
+
34
+ private prepareMonomer(rawMonomer: any): Monomer {
35
+ const monomer: Monomer = {...DUMMY_MONOMER};
36
+
37
+ Object.entries(helmFieldsToPolyToolInputFields).forEach(([key, value]) => {
38
+ const monomerSymbol = rawMonomer[value] as string;
39
+ //@ts-ignore
40
+ monomer[key] = monomerSymbol;
41
+ });
42
+
43
+ let key = HELM_FIELDS.SMILES;
44
+ const rawSmiles = rawMonomer[helmFieldsToPolyToolInputFields[key]];
45
+ const smilesHandler = new SmilesHandler(rawSmiles);
46
+ const smiles = smilesHandler.getCappedSmiles();
47
+ monomer[key] = smiles;
48
+
49
+ key = HELM_FIELDS.RGROUPS;
50
+ monomer[key] = RGroupHandler.getRGroups(smilesHandler.getNumberOfRGroups());
51
+
52
+ key = HELM_FIELDS.MOLFILE;
53
+ monomer[key] = new MolBlockHandler(smilesHandler.getSmilesWithRGroups()).getMolfile();
54
+
55
+ return monomer;
56
+ }
57
+ }
58
+
59
+ class SmilesHandler {
60
+ constructor(rawSmiles: string) {
61
+ const regex = /\[R(\d+)\]/g;
62
+ let i = 0;
63
+ this.smilesWithRGroups = rawSmiles.replace(regex, (_, capturedDigit) => { ++i; return `[${capturedDigit}*]`; });
64
+ this.numberOfRGroups = i;
65
+ }
66
+
67
+ private numberOfRGroups: number;
68
+ private smilesWithRGroups: string;
69
+
70
+ getSmilesWithRGroups(): string {
71
+ return this.smilesWithRGroups;
72
+ }
73
+
74
+ getCappedSmiles(): string {
75
+ const smiles = this.capRGroups();
76
+ return smiles;
77
+ }
78
+
79
+ getNumberOfRGroups(): number {
80
+ return this.numberOfRGroups;
81
+ }
82
+
83
+ private capRGroups(): string {
84
+ let result = this.smilesWithRGroups.replace('[1*]', '[H:1]');
85
+ result = result.replace('[2*]', '[OH:2]');
86
+ return result.replace('[3*]', '[H:3]');
87
+ }
88
+ }
89
+
90
+ class RGroupHandler {
91
+ private constructor() {};
92
+
93
+ static getRGroups(numberOfRGroups: number): RGroup[] {
94
+ return R_GROUP_BLOCK_DUMMY.slice(0, numberOfRGroups);
95
+ }
96
+ }
97
+
98
+ class MolBlockHandler {
99
+ constructor(private smilesWithRGroups: string) { }
100
+
101
+ getMolfile(): string {
102
+ let molfile = DG.chem.convert(this.smilesWithRGroups, DG.chem.Notation.Smiles, DG.chem.Notation.MolBlock);
103
+ molfile = this.restoreRGPLine(molfile);
104
+ molfile = this.fixRGroupSymbols(molfile);
105
+ return molfile;
106
+ }
107
+
108
+ private restoreRGPLine(rawMolfile: string): string {
109
+ return rawMolfile.replace('M ISO', 'M RGP');
110
+ }
111
+
112
+ private fixRGroupSymbols(molfile: string): string {
113
+ return molfile.replace(/\bR\b/g, 'R#');
114
+ }
115
+ }