@datagrok/bio 2.12.16 → 2.12.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "name": "Aleksandr Tanas",
6
6
  "email": "atanas@datagrok.ai"
7
7
  },
8
- "version": "2.12.16",
8
+ "version": "2.12.17",
9
9
  "description": "Bioinformatics support (import/export of sequences, conversion, visualization, analysis). [See more](https://github.com/datagrok-ai/public/blob/master/packages/Bio/README.md) for details.",
10
10
  "repository": {
11
11
  "type": "git",
@@ -34,12 +34,12 @@
34
34
  ],
35
35
  "dependencies": {
36
36
  "@biowasm/aioli": "^3.1.0",
37
- "@datagrok-libraries/bio": "^5.40.8",
37
+ "@datagrok-libraries/bio": "^5.41.0",
38
38
  "@datagrok-libraries/chem-meta": "^1.2.5",
39
39
  "@datagrok-libraries/math": "^1.1.5",
40
40
  "@datagrok-libraries/ml": "^6.6.5",
41
41
  "@datagrok-libraries/tutorials": "^1.3.12",
42
- "@datagrok-libraries/utils": "^4.2.0",
42
+ "@datagrok-libraries/utils": "^4.2.2",
43
43
  "@webgpu/types": "^0.1.40",
44
44
  "ajv": "^8.12.0",
45
45
  "ajv-errors": "^3.0.0",
@@ -55,9 +55,9 @@
55
55
  "wu": "latest"
56
56
  },
57
57
  "devDependencies": {
58
- "@datagrok/chem": "^1.9.0",
59
- "@datagrok/dendrogram": "^1.2.27",
60
- "@datagrok/helm": "^2.1.30",
58
+ "@datagrok/chem": "^1.9.2",
59
+ "@datagrok/dendrogram": "^1.2.29",
60
+ "@datagrok/helm": "^2.1.34",
61
61
  "@types/node": "^17.0.24",
62
62
  "@types/wu": "latest",
63
63
  "@typescript-eslint/eslint-plugin": "latest",
package/src/package.ts CHANGED
@@ -3,6 +3,8 @@ 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 '@datagrok-libraries/bio/src/types/helm';
7
+
6
8
  import {Options} from '@datagrok-libraries/utils/src/type-declarations';
7
9
  import {DimReductionBaseEditor, PreprocessFunctionReturnType}
8
10
  from '@datagrok-libraries/ml/src/functionEditors/dimensionality-reduction-editor';
@@ -55,13 +57,9 @@ import {SplitToMonomersFunctionEditor} from './function-edtiors/split-to-monomer
55
57
  import {splitToMonomersUI} from './utils/split-to-monomers';
56
58
  import {MonomerCellRenderer} from './utils/monomer-cell-renderer';
57
59
  import {BioPackage, BioPackageProperties} from './package-types';
58
- // import {PackageSettingsEditorWidget} from './widgets/package-settings-editor-widget';
59
60
  import {getCompositionAnalysisWidget} from './widgets/composition-analysis-widget';
60
61
  import {MacromoleculeColumnWidget} from './utils/macromolecule-column-widget';
61
62
  import {addCopyMenuUI} from './utils/context-menu';
62
- import {getPolyToolDialog} from './utils/poly-tool/ui';
63
- import {PolyToolCsvLibHandler} from './utils/poly-tool/csv-to-json-monomer-lib-converter';
64
- import {_setPeptideColumn} from './utils/poly-tool/utils';
65
63
  import {getRegionDo} from './utils/get-region';
66
64
  import {GetRegionApp} from './apps/get-region-app';
67
65
  import {GetRegionFuncEditor} from './utils/get-region-func-editor';
@@ -77,7 +75,8 @@ import {DimReductionMethods} from '@datagrok-libraries/ml/src/multi-column-dimen
77
75
  import {
78
76
  ITSNEOptions, IUMAPOptions
79
77
  } from '@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/multi-column-dim-reducer';
80
- import {CyclizedNotationProvider} from './utils/poly-tool/cyclized';
78
+ import {CyclizedNotationProvider} from './utils/cyclized';
79
+ import {getMolColumnFromHelm} from './utils/helm-to-molfile/utils';
81
80
 
82
81
  export const _package = new BioPackage();
83
82
 
@@ -685,19 +684,6 @@ export function convertDialog() {
685
684
  convert(col);
686
685
  }
687
686
 
688
- //top-menu: Bio | Convert | PolyTool
689
- //name: polyTool
690
- //description: Perform cyclization of polymers
691
- export async function polyTool(): Promise<void> {
692
- let dialog: DG.Dialog;
693
- try {
694
- dialog = await getPolyToolDialog();
695
- dialog.show();
696
- } catch (err: any) {
697
- grok.shell.warning('To run PolyTool, open a dataframe with macromolecules');
698
- }
699
- }
700
-
701
687
  //name: monomerCellRenderer
702
688
  //tags: cellRenderer
703
689
  //meta.cellType: Monomer
@@ -1010,25 +996,6 @@ export async function demoBioHelmMsaSequenceSpace(): Promise<void> {
1010
996
  await demoBio05UI();
1011
997
  }
1012
998
 
1013
- //name: polyToolColumnChoice
1014
- //input: dataframe df [Input data table]
1015
- //input: column macroMolecule
1016
- export async function polyToolColumnChoice(df: DG.DataFrame, macroMolecule: DG.Column): Promise<void> {
1017
- _setPeptideColumn(macroMolecule);
1018
- await grok.data.detectSemanticTypes(df);
1019
- }
1020
-
1021
- //name: createMonomerLibraryForPolyTool
1022
- //input: file file
1023
- export async function createMonomerLibraryForPolyTool(file: DG.FileInfo) {
1024
- const fileContent = await file.readAsString();
1025
- const libHandler = new PolyToolCsvLibHandler(file.fileName, fileContent);
1026
- const libObject = await libHandler.getJson();
1027
- const jsonFileName = file.fileName.replace(/\.csv$/, '.json');
1028
- const jsonFileContent = JSON.stringify(libObject, null, 2);
1029
- DG.Utils.download(jsonFileName, jsonFileContent);
1030
- }
1031
-
1032
999
  //name: SDF to JSON Library
1033
1000
  //input: dataframe table
1034
1001
  export async function sdfToJsonLib(table: DG.DataFrame) {
@@ -1048,6 +1015,17 @@ export async function detectMacromoleculeProbe(file: DG.FileInfo, colName: strin
1048
1015
  await detectMacromoleculeProbeDo(csv, colName, probeCount);
1049
1016
  }
1050
1017
 
1018
+ //name: getMolFromHelm
1019
+ //input: dataframe df
1020
+ //input: column helmCol
1021
+ //input: bool chiralityEngine
1022
+ //output: column result
1023
+ export async function getMolFromHelm(
1024
+ df: DG.DataFrame, helmCol: DG.Column<string>, chiralityEngine?: boolean
1025
+ ): Promise<DG.Column<string>> {
1026
+ return getMolColumnFromHelm(df, helmCol, chiralityEngine);
1027
+ }
1028
+
1051
1029
  // -- Custom notation providers --
1052
1030
 
1053
1031
  //name: applyNotationProviderForCyclized
@@ -95,7 +95,7 @@ id3,QHIRE--LT
95
95
  const monLength: number = 3;
96
96
  const charWidth: number = 7;
97
97
  const sepWidth: number = 12;
98
- const colTemp: MonomerPlacer = new MonomerPlacer(null, seqCol, () => {
98
+ const colTemp: MonomerPlacer = new MonomerPlacer(null, seqCol, _package.logger, () => {
99
99
  const sh = SeqHandler.forColumn(seqCol);
100
100
  return {
101
101
  seqHandler: sh,
@@ -23,6 +23,7 @@ import {ISeqSplitted, SeqSplittedBase} from '@datagrok-libraries/bio/src/utils/m
23
23
  import {getSplitter} from '@datagrok-libraries/bio/src/utils/macromolecule/utils';
24
24
  import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
25
25
  import {alphabetPolymerTypes, IMonomerLib} from '@datagrok-libraries/bio/src/types/index';
26
+ import {getGridCellRendererBack} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
26
27
 
27
28
  import {
28
29
  Temps as mmcrTemps, Tags as mmcrTags,
@@ -63,27 +64,6 @@ type RendererGridCellTemp = {
63
64
  [mmcrTemps.monomerPlacer]: MonomerPlacer
64
65
  }
65
66
 
66
- function getRendererFridCellTempTemp(gridCell: DG.GridCell): RendererGridCellTemp {
67
- /** Primarily store/get MonomerPlacer at GridColumn, fallback at (Table) Column for scatter plot tooltip */
68
- let temp: RendererGridCellTemp | null = null;
69
-
70
- let gridCol: DG.GridColumn | null = null;
71
- try { gridCol = gridCell.gridColumn; } catch { gridCol = null; }
72
- temp = gridCol && gridCol.dart ? gridCol.temp as RendererGridCellTemp : null;
73
-
74
- if (!temp) {
75
- let tableCol: DG.Column | null = null;
76
- try { tableCol = gridCell.cell.column; } catch { tableCol = null; }
77
- if (!tableCol) {
78
- const k = 42;
79
- }
80
- temp = tableCol ? tableCol.temp as RendererGridCellTemp : null;
81
- }
82
- if (temp === null)
83
- throw new Error(`Monomer placer store (GridColumn or Column) not found.`);
84
- return temp;
85
- }
86
-
87
67
  export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
88
68
  private padding: number = 5;
89
69
 
@@ -105,9 +85,9 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
105
85
  // if (gridCell.cell.column.getTag(bioTAGS.aligned) !== ALIGNMENT.SEQ_MSA)
106
86
  // return;
107
87
 
108
- const tableCol: DG.Column = gridCell.cell.column;
109
- //const tableColTemp: TempType = tableCol.temp;
110
- const seqColTemp: MonomerPlacer = getRendererFridCellTempTemp(gridCell)[mmcrTemps.monomerPlacer];
88
+ const [_gridCol, tableCol, temp] =
89
+ getGridCellRendererBack<string, MonomerPlacer>(gridCell);
90
+ const seqColTemp: MonomerPlacer = temp['rendererBack'];
111
91
  if (!seqColTemp) return; // Can do nothing without precalculated data
112
92
 
113
93
  const gridCellBounds: DG.Rect = gridCell.bounds;
@@ -121,7 +101,7 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
121
101
  const argsX = e.offsetX - gridCell.gridColumn.left + (gridCell.gridColumn.left - gridCellBounds.x);
122
102
  const left: number | null = seqColTemp.getPosition(gridCell.tableRowIndex!, argsX);
123
103
 
124
- const seqCList: SeqSplittedBase = SeqHandler.forColumn(seqColTemp.col)
104
+ const seqCList: SeqSplittedBase = SeqHandler.forColumn(tableCol)
125
105
  .getSplitted(gridCell.tableRowIndex!).canonicals;
126
106
  if (left !== null && left < seqCList.length) {
127
107
  const monomerSymbol: string = seqCList[left];
@@ -190,9 +170,11 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
190
170
  (!isNaN(tagMaxMonomerLength) ? tagMaxMonomerLength : _package.properties?.MaxMonomerLength) ?? 4;
191
171
  }
192
172
 
193
- let seqColTemp: MonomerPlacer = getRendererFridCellTempTemp(gridCell)[mmcrTemps.monomerPlacer];
173
+ const [gridCol, _tc, temp] =
174
+ getGridCellRendererBack<string, MonomerPlacer>(gridCell);
175
+ let seqColTemp: MonomerPlacer = temp['rendererBack'];
194
176
  if (!seqColTemp) {
195
- seqColTemp = new MonomerPlacer(grid, tableCol,
177
+ seqColTemp = new MonomerPlacer(gridCol, tableCol, _package.logger,
196
178
  () => {
197
179
  const sh = SeqHandler.forColumn(tableCol);
198
180
  return {
@@ -217,7 +199,7 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
217
199
  const _maxIndex = maxLengthWords.length;
218
200
 
219
201
  // Store updated seqColTemp to the col temp
220
- if (seqColTemp.updated) getRendererFridCellTempTemp(gridCell)[mmcrTemps.monomerPlacer] = seqColTemp;
202
+ if (seqColTemp.updated) temp['rendererBack'] = seqColTemp;
221
203
 
222
204
  g.save();
223
205
  try {
@@ -1,8 +1,5 @@
1
- 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 {GAP_SYMBOL, INotationProvider, ISeqSplitted, SeqSplittedBase, SplitterFunc} from '@datagrok-libraries/bio/src/utils/macromolecule/types';
1
+ import {GAP_SYMBOL, INotationProvider, ISeqSplitted, SeqSplittedBase, SplitterFunc}
2
+ from '@datagrok-libraries/bio/src/utils/macromolecule/types';
6
3
  import {getSplitterWithSeparator, StringListSeqSplitted} from '@datagrok-libraries/bio/src/utils/macromolecule/utils';
7
4
  import {GapOriginals} from '@datagrok-libraries/bio/src/utils/seq-handler';
8
5
  import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
@@ -33,9 +30,8 @@ export class CyclizedSeqSplitted extends StringListSeqSplitted {
33
30
  if (!this._canonicals) {
34
31
  const len = this.length;
35
32
  this._canonicals = new Array<string>(len);
36
- for (let posIdx = 0; posIdx < len; ++posIdx) {
33
+ for (let posIdx = 0; posIdx < len; ++posIdx)
37
34
  this._canonicals[posIdx] = this.getCanonical(posIdx);
38
- }
39
35
  }
40
36
  return this._canonicals;
41
37
  }
@@ -116,6 +116,14 @@ export class MonomerLib implements IMonomerLib {
116
116
  this._onChanged.next();
117
117
  }
118
118
 
119
+ getSummary(): string {
120
+ const monTypeList: string[] = this.getPolymerTypes();
121
+ const resStr: string = monTypeList.length == 0 ? 'empty' : monTypeList.map((monType) => {
122
+ return `${monType} ${this.getMonomerSymbolsByType(monType).length}`;
123
+ }).join('\n');
124
+ return resStr;
125
+ }
126
+
119
127
  getTooltip(polymerType: string, monomerSymbol: string): HTMLElement {
120
128
  // getTooltip(monomer: Monomer): HTMLElement;
121
129
  // getTooltip(monomerOrPolymerType: string | Monomer, symbol?: string): HTMLElement {
@@ -163,8 +171,12 @@ export class MonomerLib implements IMonomerLib {
163
171
  label('Source'),
164
172
  ui.divText(monomer.lib?.source ?? 'unknown', {classes: 'ui-input-text'}),
165
173
  ], {classes: 'ui-input-root'}));
166
- } else
167
- res.append(ui.divText('Monomer not found'));
174
+ } else {
175
+ res.append(ui.divV([
176
+ ui.divText(`Monomer '${monomerSymbol}' of type '${polymerType}' not found.`),
177
+ ui.divText('Open the Context Panel, then expand Manage Libraries'),
178
+ ]));
179
+ }
168
180
  return res;
169
181
  }
170
182
  }
@@ -2,14 +2,15 @@ import * as grok from 'datagrok-api/grok';
2
2
  import * as ui from 'datagrok-api/ui';
3
3
  import * as DG from 'datagrok-api/dg';
4
4
 
5
+ import * as org from 'org';
5
6
  import $ from 'cash-dom';
6
- import {fromEvent, Observable, Subject, Unsubscribable} from 'rxjs';
7
+ import {fromEvent, Unsubscribable} from 'rxjs';
7
8
 
8
- import {IHelmWebEditor, IWebEditorApp} from '@datagrok-libraries/bio/src/helm/types';
9
+ import {IHelmWebEditor} from '@datagrok-libraries/bio/src/helm/types';
9
10
  import {getHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
10
11
  import {ILogger} from '@datagrok-libraries/bio/src/utils/logger';
11
12
  import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
12
- import {delay, testEvent} from '@datagrok-libraries/utils/src/test';
13
+ import {delay} from '@datagrok-libraries/utils/src/test';
13
14
 
14
15
  import {updateDivInnerHTML} from '../utils/ui-utils';
15
16
  import {helmSubstructureSearch} from '../substructure-search/substructure-search';
@@ -54,7 +55,7 @@ export class HelmBioFilter extends BioFilterBase<BioFilterProps> /* implements I
54
55
  this.logger.warning('TEST: HelmBioFilter.init().sync() waitForElementInDom ready');
55
56
  this.updateFilterPanel();
56
57
  let webEditorHost: HTMLDivElement | null;
57
- let webEditorApp: IWebEditorApp | null;
58
+ let webEditorApp: org.helm.IWebEditorApp | null;
58
59
  // TODO: Unsubscribe 'click' and 'sizeChanged'
59
60
  this.viewSubs.push(fromEvent(this._filterPanel, 'click').subscribe(() => {
60
61
  webEditorHost = ui.div();
@@ -16,7 +16,6 @@ import {TAGS as bioTAGS, NOTATION} from '@datagrok-libraries/bio/src/utils/macro
16
16
  import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
17
17
  import {delay, testEvent} from '@datagrok-libraries/utils/src/test';
18
18
  import {getHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
19
- import {IHelmWebEditor, IWebEditorApp} from '@datagrok-libraries/bio/src/helm/types';
20
19
  import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
21
20
  import {IRenderer} from '@datagrok-libraries/bio/src/types/renderer';
22
21
  import {ILogger} from '@datagrok-libraries/bio/src/utils/logger';
package/webpack.config.js CHANGED
@@ -41,6 +41,8 @@ module.exports = {
41
41
  'cash-dom': '$',
42
42
  'dayjs': 'dayjs',
43
43
  'wu': 'wu',
44
+ 'scil': 'scil',
45
+ 'org': 'org',
44
46
  },
45
47
  output: {
46
48
  filename: '[name].js',
@@ -1,40 +0,0 @@
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
- ];
@@ -1,40 +0,0 @@
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
- }
@@ -1,115 +0,0 @@
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
- }