@datagrok/sequence-translator 1.3.10 → 1.3.12

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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@datagrok/sequence-translator",
3
3
  "friendlyName": "Sequence Translator",
4
- "version": "1.3.10",
4
+ "version": "1.3.12",
5
5
  "author": {
6
6
  "name": "Alexey Choposky",
7
7
  "email": "achopovsky@datagrok.ai"
@@ -22,9 +22,9 @@
22
22
  }
23
23
  ],
24
24
  "dependencies": {
25
- "@datagrok-libraries/bio": "5.42.5",
25
+ "@datagrok-libraries/bio": "5.42.9",
26
26
  "@datagrok-libraries/chem-meta": "^1.2.5",
27
- "@datagrok-libraries/tutorials": "^1.3.12",
27
+ "@datagrok-libraries/tutorials": "^1.3.13",
28
28
  "@datagrok-libraries/utils": "^4.2.13",
29
29
  "@types/react": "^18.0.15",
30
30
  "cash-dom": "^8.1.0",
@@ -39,10 +39,11 @@
39
39
  "wu": "latest"
40
40
  },
41
41
  "devDependencies": {
42
- "@datagrok-libraries/helm-web-editor": "^1.1.6",
43
- "@datagrok-libraries/js-draw-lite": "^0.0.4",
44
- "@datagrok/bio": "^2.13.3",
45
- "@datagrok/chem": "1.9.2",
42
+ "@datagrok-libraries/helm-web-editor": "^1.1.8",
43
+ "@datagrok-libraries/js-draw-lite": "^0.0.6",
44
+ "@datagrok/bio": "^2.14.2",
45
+ "@datagrok/helm": "^2.4.1",
46
+ "@datagrok/chem": "^1.11.3",
46
47
  "@types/jquery": "^3.5.14",
47
48
  "@types/js-yaml": "^4.0.5",
48
49
  "@types/lodash": "^4.14.202",
@@ -4,6 +4,7 @@ import * as DG from 'datagrok-api/dg';
4
4
 
5
5
  import {getMonomerLibHelper, IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
6
6
  import {IMonomerLib, Monomer} from '@datagrok-libraries/bio/src/types';
7
+ import {LoggerWrapper} from '@datagrok-libraries/bio/src/utils/logger';
7
8
 
8
9
  import {APP_NAME} from '../view/const';
9
10
  import {DEFAULT_LIB_FILENAME, FALLBACK_LIB_PATH} from './data-loader/const';
@@ -12,7 +13,6 @@ import {ITranslationHelper} from '../../../types';
12
13
  import {SequenceValidator} from './parsing-validation/sequence-validator';
13
14
  import {JsonData, loadJsonData} from './data-loader/json-loader';
14
15
  import {MonomerLibWrapper} from './monomer-lib/lib-wrapper';
15
- import {_package} from '../../../package';
16
16
  import {FormatConverter} from '../../translator/model/format-converter';
17
17
  import {FormatDetector} from './parsing-validation/format-detector';
18
18
  import {highlightInvalidSubsequence} from '../view/components/colored-input/input-painters';
@@ -39,8 +39,10 @@ export class OligoToolkitPackage extends DG.Package implements ITranslationHelpe
39
39
  return this._monomerLibWrapper;
40
40
  }
41
41
 
42
- constructor() {
42
+ constructor(opts: { debug: boolean } = {debug: false}) {
43
43
  super();
44
+ // @ts-ignore
45
+ super._logger = new LoggerWrapper(super.logger, opts.debug);
44
46
  }
45
47
 
46
48
  private initPromise?: Promise<void>;
@@ -51,7 +53,7 @@ export class OligoToolkitPackage extends DG.Package implements ITranslationHelpe
51
53
  const packageSettings = await this.getSettings();
52
54
  let monomersPath: string = packageSettings['MonomersPath'];
53
55
  if (!monomersPath || !(await grok.dapi.files.exists(monomersPath))) {
54
- _package.logger.warning(`Monomers path '${monomersPath}' not found. ` +
56
+ this.logger.warning(`Monomers path '${monomersPath}' not found. ` +
55
57
  `Fallback to monomers sample path '${FALLBACK_LIB_PATH}'.`);
56
58
  monomersPath = FALLBACK_LIB_PATH;
57
59
  }
@@ -8,6 +8,7 @@ import './tests/formats-to-helm';
8
8
  import './tests/helm-to-nucleotides';
9
9
  import './tests/formats-support';
10
10
  import './tests/files-tests';
11
+ import './tests/polytool-enumerate-tests';
11
12
 
12
13
  import {OligoToolkitTestPackage} from './tests/utils';
13
14
 
package/src/package.ts CHANGED
@@ -16,14 +16,14 @@ import {demoOligoPatternUI, demoOligoStructureUI, demoOligoTranslatorUI} from '.
16
16
  import {getExternalAppViewFactories} from './plugins/mermade';
17
17
 
18
18
  //polytool specific
19
- import {getPolyToolConversionDialog} from './polytool/pt-dialog';
19
+ import {getPolyToolConversionDialog, polyToolEnumerateHelmUI, polyToolEnumerateChemUI} from './polytool/pt-dialog';
20
20
  import {_setPeptideColumn} from './polytool/utils';
21
21
  import {PolyToolCsvLibHandler} from './polytool/csv-to-json-monomer-lib-converter';
22
22
  import {ITranslationHelper} from './types';
23
- import {polyToolEnumerateHelmUI, polyToolEnumerateChemUI} from './polytool/pt-ui';
24
23
  import {addContextMenuUI} from './utils/context-menu';
24
+ import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
25
25
 
26
- export const _package: OligoToolkitPackage = new OligoToolkitPackage();
26
+ export const _package: OligoToolkitPackage = new OligoToolkitPackage(/*{debug: true}/**/);
27
27
 
28
28
  //name: Oligo Toolkit
29
29
  //meta.icon: img/icons/toolkit.png
@@ -169,15 +169,15 @@ export async function polyToolConvert(): Promise<void> {
169
169
  //name: polyToolEnumerateHelm
170
170
  //description: Perform cyclization of polymers
171
171
  export async function polyToolEnumerateHelm(): Promise<void> {
172
- polyToolEnumerateHelmUI();
172
+ await polyToolEnumerateHelmUI();
173
173
  }
174
174
 
175
- // //top-menu: Bio | Convert | PolyTool-Enumerate Chem
176
- // //name: polyToolEnumerateChem
177
- // //description: Perform cyclization of polymers
178
- // export async function polyToolEnumerateChem(): Promise<void> {
179
- // polyToolEnumerateChemUI();
180
- // }
175
+ //top-menu: Bio | Convert | PolyTool-Enumerate Chem
176
+ //name: polyToolEnumerateChem
177
+ //description: Perform cyclization of polymers
178
+ export async function polyToolEnumerateChem(): Promise<void> {
179
+ polyToolEnumerateChemUI();
180
+ }
181
181
 
182
182
  //name: polyToolColumnChoice
183
183
  //input: dataframe df [Input data table]
@@ -210,28 +210,40 @@ export function addContextMenu(event: DG.EventData): void {
210
210
  // //meta.icon: img/icons/structure.png
211
211
  // //meta.browsePath: PolyTool
212
212
  // //tags: app
213
- // //output: view v
214
- // export async function ptConverterApp(): Promise<DG.ViewBase> {
215
- // const view = await getSpecifiedAppView(APP_NAME.STRUCTURE);
216
- // return view;
213
+ // export async function ptConverterApp(): Promise<void> {
214
+ // const view = grok.shell.v as DG.TableView;
215
+ // const table = view.dataFrame;
216
+ // const colNames = table.columns.names();
217
+ // let covertableName = '';
218
+
219
+ // for (let i = 0; i < colNames.length; i++) {
220
+ // const col = table.columns.byName(colNames[i]);
221
+ // if (col.semType === DG.SEMTYPE.MACROMOLECULE && col.meta.units === NOTATION.SEPARATOR) {
222
+ // covertableName = colNames[i];
223
+ // break;
224
+ // }
225
+ // }
226
+
227
+ // if (covertableName === '')
228
+ // grok.shell.error('To run the app open a view with convertable separator notation for macromolecules');
229
+ // else {
230
+ // const dialog = await getPolyToolConversionDialog();
231
+ // dialog.show();
232
+ // }
217
233
  // }
218
234
 
219
- // //name: PolyTool Enumerator Helm
220
- // //meta.icon: img/icons/structure.png
221
- // //meta.browsePath: PolyTool
222
- // //tags: app
223
- // //output: view v
224
- // export async function ptEnumeratorHelmApp(): Promise<DG.ViewBase> {
225
- // const view = await getSpecifiedAppView(APP_NAME.STRUCTURE);
226
- // return view;
227
- // }
235
+ //name: PolyTool Enumerator Helm
236
+ //meta.icon: img/icons/structure.png
237
+ //meta.browsePath: PolyTool
238
+ //tags: app
239
+ export async function ptEnumeratorHelmApp(): Promise<void> {
240
+ await polyToolEnumerateHelmUI();
241
+ }
228
242
 
229
- // //name: PolyTool Enumerator Chem
230
- // //meta.icon: img/icons/structure.png
231
- // //meta.browsePath: PolyTool
232
- // //tags: app
233
- // //output: view v
234
- // export async function ptEnumeratorChemApp(): Promise<DG.ViewBase> {
235
- // const view = await getSpecifiedAppView(APP_NAME.STRUCTURE);
236
- // return view;
237
- // }
243
+ //name: PolyTool Enumerator Chem
244
+ //meta.icon: img/icons/structure.png
245
+ //meta.browsePath: PolyTool
246
+ //tags: app
247
+ export async function ptEnumeratorChemApp(): Promise<void> {
248
+ polyToolEnumerateChemUI();
249
+ }
@@ -26,3 +26,13 @@ export const R_GROUP_BLOCK_DUMMY = [
26
26
  'label': 'R3'
27
27
  }
28
28
  ];
29
+
30
+ export const PT_ERROR_DATAFRAME = 'No dataframe with macromolecule columns open';
31
+ export const PT_WARNING_COLUMN = 'No marcomolecule column chosen!';
32
+
33
+ export const PT_UI_GET_HELM = 'Get HELM';
34
+ export const PT_UI_ADD_HELM = 'Add HELM column';
35
+ export const PT_UI_USE_CHIRALITY = 'Chirality engine';
36
+ export const PT_UI_DIALOG_CONVERSION = 'Poly Tool Conversion';
37
+ export const PT_UI_DIALOG_ENUMERATION = 'Poly Tool Enumeration';
38
+ export const PT_UI_RULES_USED = 'Rules used';
@@ -297,6 +297,7 @@ export async function addTransformedColumn(
297
297
  df.columns.add(targetHelmCol);
298
298
  }
299
299
 
300
+ // toAtomicLevel
300
301
  const molCol = await grok.functions.call('Bio:getMolFromHelm', {
301
302
  'df': df,
302
303
  'helmCol': targetHelmCol,
@@ -3,11 +3,14 @@ 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 $ from 'cash-dom';
6
7
  import wu from 'wu';
8
+ import {Unsubscribable} from 'rxjs';
7
9
 
8
10
  import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
9
11
  import {getHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
10
- import {HelmAtom} from '@datagrok-libraries/bio/src/helm/types';
12
+ import {HelmAtom, HelmMol} from '@datagrok-libraries/bio/src/helm/types';
13
+ // import {FormsViewer} from '@datagrok-libraries/utils/src/viewers/forms-viewer';
11
14
 
12
15
  import {RuleInputs, RULES_PATH, RULES_STORAGE_NAME} from './pt-rules';
13
16
  import {addTransformedColumn} from './pt-conversion';
@@ -15,20 +18,87 @@ import {addTransformedColumn} from './pt-conversion';
15
18
  import {handleError} from './utils';
16
19
  import {defaultErrorHandler} from '../utils/err-info';
17
20
  import {getLibrariesList} from './utils';
18
- import {getEnumerationHelm, PT_HELM_EXAMPLE} from './pt-enumeration-helm';
21
+ import {getPtEnumeratorHelm, PT_HELM_EXAMPLE} from './pt-enumeration-helm';
19
22
  import {getEnumerationChem, PT_CHEM_EXAMPLE} from './pt-enumeration-chem';
23
+ import {
24
+ PolyToolEnumeratorParams, PolyToolEnumeratorType, PolyToolEnumeratorTypes, PolyToolPlaceholders
25
+ } from './types';
26
+
27
+ import {_package} from '../package';
28
+ import {PolyToolPlaceholdersInput} from './pt-placeholders-input';
29
+ import {InputBase} from 'datagrok-api/dg';
30
+ import {PT_ERROR_DATAFRAME, PT_UI_ADD_HELM, PT_UI_DIALOG_CONVERSION, PT_UI_DIALOG_ENUMERATION, PT_UI_GET_HELM, PT_UI_RULES_USED, PT_UI_USE_CHIRALITY, PT_WARNING_COLUMN} from './const';
31
+ import {PolyToolEnumerateDialog} from './pt-enumeration-helm-dialog';
32
+
33
+ export async function polyToolEnumerateHelmUI(cell?: DG.Cell): Promise<void> {
34
+ const maxWidth = window.innerWidth;
35
+ const maxHeight = window.innerHeight;
36
+
37
+ try {
38
+ const resizeInputs = () => {
39
+ const contentHeight = $(dialog.root).find('div.d4-dialog-contents').get(0)!.clientHeight;
40
+
41
+ const fitInputs: { [idx: number]: number } = {1: 1 /*, 3: 0.5*/};
42
+ const fitInputsSumHeight = Object.values(fitInputs).reduce((sum, h) => sum + h, 0);
43
+
44
+ const otherInputsHeight: number = dialog.inputs.filter((input, idx) => !(idx in fitInputs))
45
+ .map((input) => input.root.offsetHeight).reduce((sum, h) => sum + h, 0);
46
+ const remainFitHeight = contentHeight - otherInputsHeight - 38;
47
+ dialog.inputs.forEach((input, idx) => {
48
+ if (idx in fitInputs) {
49
+ const inputFitHeight = remainFitHeight * fitInputs[idx] / fitInputsSumHeight;
50
+ input.root.style.height = `${inputFitHeight}px`;
51
+ }
52
+ });
53
+ };
54
+ const [dialog, inputs] = await PolyToolEnumerateDialog.create2(cell, resizeInputs);
55
+
56
+ let isFirstShow = true;
57
+ ui.onSizeChanged(dialog.root).subscribe(() => {
58
+ if (isFirstShow) {
59
+ const dialogInputList = dialog.inputs;
60
+ const dialogRootCash = $(dialog.root);
61
+ const contentMaxHeight = maxHeight
62
+ - dialogRootCash.find('div.d4-dialog-header').get(0)!.offsetHeight
63
+ - dialogRootCash.find('div.d4-dialog-footer').get(0)!.offsetHeight;
64
+
65
+ // dialog.inputs2.macromolecule.root.style.backgroundColor = '#CCFFCC';
66
+
67
+ const dialogWidth = maxWidth * 0.7;
68
+ const dialogHeight = maxHeight * 0.7;
69
+
70
+ // Centered, but resizable dialog
71
+ dialog.root.style.width = `${Math.min(maxWidth, dialogWidth)}px`;
72
+ dialog.root.style.height = `${Math.min(maxHeight, dialogHeight)}px`;
73
+ dialog.root.style.left = `${Math.floor((maxWidth - dialog.root.offsetWidth) / 2)}px`;
74
+ dialog.root.style.top = `${Math.floor((maxHeight - dialog.root.offsetHeight) / 2)}px`;
75
+
76
+ isFirstShow = false;
77
+ }
78
+
79
+ resizeInputs();
80
+ });
20
81
 
21
- const PT_ERROR_DATAFRAME = 'No dataframe with macromolecule columns open';
22
- const PT_WARNING_COLUMN = 'No marcomolecule column chosen!';
82
+ _package.logger.debug('PolyToolEnumerateHelmUI: dialog before show');
83
+ const res = dialog.show({width: Math.max(350, maxWidth * 0.7), /* center: true,*/ resizable: true});
84
+ _package.logger.debug('PolyToolEnumerateHelmUI: dialog after show');
85
+ const k = 42;
86
+ } catch (_err: any) {
87
+ grok.shell.warning('To run PolyTool Enumeration, sketch the macromolecule and select monomers to vary');
88
+ }
89
+ }
23
90
 
24
- const PT_UI_GET_HELM = 'Get HELM';
25
- const PT_UI_ADD_HELM = 'Add HELM column';
26
- const PT_UI_USE_CHIRALITY = 'Chirality engine';
27
- const PT_UI_DIALOG_CONVERSION = 'Poly Tool Conversion';
28
- const PT_UI_DIALOG_ENUMERATION = 'Poly Tool Enumeration';
29
- const PT_UI_RULES_USED = 'Rules used';
91
+ export function polyToolEnumerateChemUI(cell?: DG.Cell): void {
92
+ getPolyToolEnumerationChemDialog(cell)
93
+ .then((dialog) => {
94
+ dialog.show({resizable: true});
95
+ })
96
+ .catch((_err: any) => {
97
+ grok.shell.warning('To run PolyTool Enumeration, sketch the molecule and specify the R group to vary');
98
+ });
99
+ }
30
100
 
31
- export async function getPolyToolConversionDialog(): Promise<DG.Dialog> {
101
+ export async function getPolyToolConversionDialog(targetCol?: DG.Column): Promise<DG.Dialog> {
32
102
  const targetColumns = grok.shell.t.columns.bySemTypeAll(DG.SEMTYPE.MACROMOLECULE);
33
103
  if (!targetColumns)
34
104
  throw new Error(PT_ERROR_DATAFRAME);
@@ -38,6 +108,8 @@ export async function getPolyToolConversionDialog(): Promise<DG.Dialog> {
38
108
  filter: (col: DG.Column) => col.semType === DG.SEMTYPE.MACROMOLECULE
39
109
  });
40
110
 
111
+ targetColumnInput.value = targetCol ? targetCol : targetColumnInput.value;
112
+
41
113
  const generateHelmChoiceInput = ui.input.bool(PT_UI_GET_HELM, {value: true});
42
114
  ui.tooltip.bind(generateHelmChoiceInput.root, PT_UI_ADD_HELM);
43
115
 
@@ -82,62 +154,7 @@ export async function getPolyToolConversionDialog(): Promise<DG.Dialog> {
82
154
  return dialog;
83
155
  }
84
156
 
85
- export async function getPolyToolEnumerationHelmDialog(cell?: DG.Cell): Promise<DG.Dialog> {
86
- const [libList, helmHelper] = await Promise.all([
87
- getLibrariesList(), getHelmHelper()]);
88
-
89
- const helmValue = cell ? cell.value : PT_HELM_EXAMPLE;
90
-
91
- const helmInput = helmHelper.createHelmInput('Macromolecule', {value: helmValue});
92
- const screenLibrary = ui.input.choice('Library to use', {value: null, items: libList});
93
-
94
- helmInput.input.setAttribute('style', `min-width:250px!important;`);
95
- screenLibrary.input.setAttribute('style', `min-width:250px!important;`);
96
-
97
- const div = ui.div([
98
- helmInput.root,
99
- screenLibrary.root
100
- ]);
101
-
102
- // Displays the molecule from a current cell (monitors changes)
103
- const cccSubs = grok.events.onCurrentCellChanged.subscribe(() => {
104
- const cell = grok.shell.tv.dataFrame.currentCell;
105
-
106
- if (cell.column.semType === DG.SEMTYPE.MACROMOLECULE && cell.column.meta.units === NOTATION.HELM)
107
- helmInput.stringValue = cell.value;
108
- });
109
-
110
- const dialog = ui.dialog(PT_UI_DIALOG_ENUMERATION)
111
- .add(div)
112
- .onOK(async () => {
113
- try {
114
- const helmString = helmInput.stringValue;
115
- const helmSelections: number[] = wu.enumerate<HelmAtom>(helmInput.value.atoms)
116
- .filter(([a, aI]) => a.highlighted)
117
- .map(([a, aI]) => aI).toArray();
118
- if (helmString === undefined || helmString === '') {
119
- grok.shell.warning('PolyTool: no molecule was provided');
120
- } else if (helmSelections === undefined || helmSelections.length < 1) {
121
- grok.shell.warning('PolyTool: no selection was provided');
122
- } else {
123
- const molecules = await getEnumerationHelm(helmString, helmSelections, screenLibrary.value!);
124
- const molCol = DG.Column.fromStrings('Enumerated', molecules);
125
- const df = DG.DataFrame.fromColumns([molCol]);
126
- grok.shell.addTableView(df);
127
- }
128
- } catch (err: any) {
129
- defaultErrorHandler(err);
130
- } finally {
131
- cccSubs.unsubscribe();
132
- }
133
- }).onCancel(() => {
134
- cccSubs.unsubscribe();
135
- });
136
-
137
- return dialog;
138
- }
139
-
140
- export async function getPolyToolEnumerationChemDialog(cell?: DG.Cell): Promise<DG.Dialog> {
157
+ async function getPolyToolEnumerationChemDialog(cell?: DG.Cell): Promise<DG.Dialog> {
141
158
  const [libList, helmHelper] = await Promise.all([
142
159
  getLibrariesList(), getHelmHelper()]);
143
160
 
@@ -147,9 +164,6 @@ export async function getPolyToolEnumerationChemDialog(cell?: DG.Cell): Promise<
147
164
  // sketcher.setMolFile(col.tags[ALIGN_BY_SCAFFOLD_TAG]);
148
165
  molInput.onChanged.subscribe((_: any) => {
149
166
  molValue = molInput.getMolFile();
150
- // col.tags[ALIGN_BY_SCAFFOLD_TAG] = molFile;
151
- // col.temp[ALIGN_BY_SCAFFOLD_TAG] = molFile;
152
- // col.dataFrame?.fireValuesChanged();
153
167
  });
154
168
  molInput.root.classList.add('ui-input-editor');
155
169
  molInput.root.style.marginTop = '3px';
@@ -29,7 +29,7 @@ export const PT_CHEM_EXAMPLE = `
29
29
  2.4544 0.4877 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
30
30
  -1.8175 -1.9896 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
31
31
  -3.2453 0.4877 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
32
- 3.1670 1.7285 0.0000 R# 0 0 0 0 0 0 0 0 0 0 0 0
32
+ 3.1670 1.7285 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
33
33
  1.7149 2.5513 0.0000 R# 0 0 0 0 0 0 0 0 0 0 0 0
34
34
  2 1 2 0 0 0 0
35
35
  3 1 1 0 0 0 0
@@ -55,18 +55,15 @@ export const PT_CHEM_EXAMPLE = `
55
55
  14 10 1 0 0 0 0
56
56
  15 21 1 0 0 0 0
57
57
  12 22 1 0 0 0 0
58
- M RGP 2 21 1 22 2
58
+ M RGP 1 22 1
59
59
  M END`;
60
60
 
61
61
  export async function getEnumerationChem(molString: string, screenLibrary: string):
62
62
  Promise<string[]> {
63
+
63
64
  const variableMonomers = await getAvailableMonomers(screenLibrary);
64
65
  const variableMols = await getAvailableMonomerMols(screenLibrary);
65
-
66
- const idx = molString.indexOf('M RGP');
67
- const rCount = parseInt(molString.slice(idx + 6, idx + 9)); //extracting from molfile positions
68
- const size = 1 * variableMonomers.length;
69
- const enumerations = new Array<string>(size);
66
+ const enumerations = new Array<string>(variableMonomers.length);
70
67
 
71
68
  const rdkitModule: RDModule = await grok.functions.call('Chem:getRdKitModule');
72
69
  const molScaffold: RDMol = rdkitModule.get_mol(molString);
@@ -84,22 +81,24 @@ export async function getEnumerationChem(molString: string, screenLibrary: strin
84
81
  molSubst.delete();
85
82
  }
86
83
 
87
- //TODO: get for all R groups
88
- for (let i = 0; i < 1; i++) {
89
- for (let j = 0; j < variableMonomers.length; j++) {
90
- try {
91
- const smiResRaw = `${smiScaffold}.${smilesSubsts[j]}`.replaceAll('[1*]C', 'C([1*])').replaceAll('[1*]c', 'c([1*])').replaceAll('[1*]O', 'O([1*])').replaceAll('[1*]N', 'N([1*])');
92
- const smiRes = `${smiResRaw}`.replaceAll('([1*])', '9').replaceAll('[1*]', '9');
93
- const molRes: RDMol = rdkitModule.get_mol(smiRes);
94
-
95
- enumerations[i * variableMonomers.length + j] = molRes.get_v3Kmolblock();
96
- molRes.delete();
97
- }
98
- catch(err:any) {
99
- enumerations[i * variableMonomers.length + j] = '';
100
- }
101
- }
84
+ for (let i = 0; i < variableMonomers.length; i++) {
85
+ let molRes: RDMol | null = null;
86
+ try {
87
+ //TODO: use RDKit linking function when exposed
88
+ const smiResRaw = `${smiScaffold}.${smilesSubsts[i]}`.replaceAll('[1*]C', 'C([1*])').replaceAll('[1*]c', 'c([1*])').replaceAll('[1*]O', 'O([1*])').replaceAll('[1*]N', 'N([1*])');
89
+ const smiRes = `${smiResRaw}`.replaceAll('([1*])', '9').replaceAll('[1*]', '9');
90
+ molRes = rdkitModule.get_mol(smiRes, JSON.stringify({mappedDummiesAreRGroups: true}))
91
+ let molV3 = molRes.get_v3Kmolblock();
92
+ enumerations[i] = molV3;
93
+ }
94
+ catch(err:any) {
95
+ enumerations[i] = '';
96
+ }
97
+ finally {
98
+ molRes?.delete();
99
+ }
102
100
  }
101
+
103
102
 
104
103
  return enumerations;
105
104
  }