@datagrok/bio 2.11.39 → 2.11.41
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/CHANGELOG.md +12 -0
- package/dist/package-test.js +5 -5
- package/dist/package-test.js.LICENSE.txt +8 -0
- package/dist/package-test.js.map +1 -1
- package/dist/package.js +5 -5
- package/dist/package.js.LICENSE.txt +8 -0
- package/dist/package.js.map +1 -1
- package/files/polytool-rules/rules_template.csv +1 -0
- package/package.json +1 -1
- package/src/package.ts +4 -3
- package/src/utils/helm-to-molfile.ts +30 -6
- package/src/utils/poly-tool/transformation.ts +45 -44
- package/src/utils/poly-tool/ui.ts +136 -50
|
@@ -0,0 +1 @@
|
|
|
1
|
+
code,monomer1,monomer2,modification1,modification2,R1,R2
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"name": "Leonid Stolbov",
|
|
6
6
|
"email": "lstolbov@datagrok.ai"
|
|
7
7
|
},
|
|
8
|
-
"version": "2.11.
|
|
8
|
+
"version": "2.11.41",
|
|
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",
|
package/src/package.ts
CHANGED
|
@@ -59,7 +59,7 @@ import {BioPackage, BioPackageProperties} from './package-types';
|
|
|
59
59
|
import {getCompositionAnalysisWidget} from './widgets/composition-analysis-widget';
|
|
60
60
|
import {MacromoleculeColumnWidget} from './utils/macromolecule-column-widget';
|
|
61
61
|
import {addCopyMenuUI} from './utils/context-menu';
|
|
62
|
-
import {
|
|
62
|
+
import {PolyTool} from './utils/poly-tool/ui';
|
|
63
63
|
import {PolyToolCsvLibHandler} from './utils/poly-tool/csv-to-json-monomer-lib-converter';
|
|
64
64
|
import {_setPeptideColumn} from './utils/poly-tool/utils';
|
|
65
65
|
import {getRegionDo} from './utils/get-region';
|
|
@@ -689,10 +689,11 @@ export function convertDialog() {
|
|
|
689
689
|
//top-menu: Bio | Convert | PolyTool
|
|
690
690
|
//name: polyTool
|
|
691
691
|
//description: Perform cyclization of polymers
|
|
692
|
-
export function polyTool(): void {
|
|
692
|
+
export async function polyTool(): Promise<void> {
|
|
693
|
+
const polytool = new PolyTool();
|
|
693
694
|
let dialog: DG.Dialog;
|
|
694
695
|
try {
|
|
695
|
-
dialog = getPolyToolDialog();
|
|
696
|
+
dialog = await polytool.getPolyToolDialog();
|
|
696
697
|
dialog.show();
|
|
697
698
|
} catch (err: any) {
|
|
698
699
|
grok.shell.warning('To run PolyTool, open a dataframe with macromolecules');
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/* Do not change these import lines to match external modules in webpack configuration */
|
|
2
2
|
import * as grok from 'datagrok-api/grok';
|
|
3
|
-
import * as ui from 'datagrok-api/ui';
|
|
4
3
|
import * as DG from 'datagrok-api/dg';
|
|
4
|
+
import * as OCL from 'openchemlib/full';
|
|
5
5
|
|
|
6
6
|
import {MolfileHandler} from '@datagrok-libraries/chem-meta/src/parsing-utils/molfile-handler';
|
|
7
7
|
import {MolfileHandlerBase} from '@datagrok-libraries/chem-meta/src/parsing-utils/molfile-handler-base';
|
|
8
|
-
import {RDModule} from '@datagrok-libraries/chem-meta/src/rdkit-api';
|
|
8
|
+
import {RDModule, RDMol} from '@datagrok-libraries/chem-meta/src/rdkit-api';
|
|
9
9
|
import {HELM_POLYMER_TYPE, HELM_RGROUP_FIELDS} from '@datagrok-libraries/bio/src/utils/const';
|
|
10
10
|
import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
|
|
11
11
|
|
|
@@ -51,10 +51,10 @@ export async function helm2mol(df: DG.DataFrame, helmCol: DG.Column<string>): Pr
|
|
|
51
51
|
|
|
52
52
|
/** Translate HELM column into molfile column and append to the dataframe */
|
|
53
53
|
export async function getMolColumnFromHelm(
|
|
54
|
-
df: DG.DataFrame, helmCol: DG.Column<string
|
|
54
|
+
df: DG.DataFrame, helmCol: DG.Column<string>, chiralityEngine?: boolean
|
|
55
55
|
): Promise<DG.Column<string>> {
|
|
56
56
|
const converter = new HelmToMolfileConverter(helmCol, df);
|
|
57
|
-
const molCol = await converter.convertToRdKitBeautifiedMolfileColumn();
|
|
57
|
+
const molCol = await converter.convertToRdKitBeautifiedMolfileColumn(chiralityEngine);
|
|
58
58
|
molCol.semType = DG.SEMTYPE.MOLECULE;
|
|
59
59
|
return molCol;
|
|
60
60
|
}
|
|
@@ -89,7 +89,28 @@ export class HelmToMolfileConverter {
|
|
|
89
89
|
return smiles;
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
async
|
|
92
|
+
async getMolV3000ViaOCL(beautifiedMols: (RDMol | null)[], columnName: string) {
|
|
93
|
+
const beautifiedMolV2000 = beautifiedMols.map((mol) => {
|
|
94
|
+
if (mol === null)
|
|
95
|
+
return '';
|
|
96
|
+
const molBlock = mol.get_molblock();
|
|
97
|
+
mol!.delete();
|
|
98
|
+
return molBlock;
|
|
99
|
+
});
|
|
100
|
+
const molv3000Arr = new Array<string>(beautifiedMolV2000.length);
|
|
101
|
+
const chiralityPb = DG.TaskBarProgressIndicator.create(`Handling chirality...`);
|
|
102
|
+
for (let i = 0; i < beautifiedMolV2000.length; i++) {
|
|
103
|
+
const oclMolecule = OCL.Molecule.fromMolfile(beautifiedMolV2000[i]);
|
|
104
|
+
const molV3000 = oclMolecule.toMolfileV3();
|
|
105
|
+
molv3000Arr[i] = molV3000.replace('STERAC1', 'STEABS');
|
|
106
|
+
const progress = i/beautifiedMolV2000.length*100;
|
|
107
|
+
chiralityPb.update(progress, `${progress?.toFixed(2)}% of molecules completed`);
|
|
108
|
+
}
|
|
109
|
+
chiralityPb.close();
|
|
110
|
+
return DG.Column.fromStrings(columnName, molv3000Arr);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async convertToRdKitBeautifiedMolfileColumn(chiralityEngine?: boolean): Promise<DG.Column<string>> {
|
|
93
114
|
const smiles = await this.getSmilesList();
|
|
94
115
|
const rdKitModule: RDModule = await grok.functions.call('Chem:getRdKitModule');
|
|
95
116
|
const beautifiedMols = smiles.map((item) =>{
|
|
@@ -103,13 +124,16 @@ export class HelmToMolfileConverter {
|
|
|
103
124
|
return mol;
|
|
104
125
|
});
|
|
105
126
|
const columnName = this.df.columns.getUnusedName(`molfile(${this.helmColumn.name})`);
|
|
127
|
+
|
|
128
|
+
if (chiralityEngine)
|
|
129
|
+
return await this.getMolV3000ViaOCL(beautifiedMols, columnName);
|
|
106
130
|
return DG.Column.fromStrings(columnName, beautifiedMols.map((mol) => {
|
|
107
131
|
if (mol === null)
|
|
108
132
|
return '';
|
|
109
133
|
const molBlock = mol.get_v3Kmolblock();
|
|
110
134
|
mol!.delete();
|
|
111
135
|
return molBlock;
|
|
112
|
-
}));
|
|
136
|
+
}));
|
|
113
137
|
}
|
|
114
138
|
|
|
115
139
|
async convertToMolfileV2KColumn(): Promise<DG.Column<string>> {
|
|
@@ -4,12 +4,14 @@ import * as DG from 'datagrok-api/dg';
|
|
|
4
4
|
|
|
5
5
|
import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
6
6
|
import {UnitsHandler} from '@datagrok-libraries/bio/src/utils/units-handler';
|
|
7
|
-
import {
|
|
7
|
+
import {ALIGNMENT, ALPHABET} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
8
|
+
|
|
8
9
|
import {HELM_WRAPPER} from './const';
|
|
9
10
|
import {getMolColumnFromHelm} from '../helm-to-molfile';
|
|
10
|
-
import {ALIGNMENT, ALPHABET} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
11
11
|
|
|
12
|
-
const
|
|
12
|
+
export const RULES_PATH = 'System:AppData/Bio/polytool-rules/';
|
|
13
|
+
export const RULES_STORAGE_NAME = 'Polytool';
|
|
14
|
+
|
|
13
15
|
|
|
14
16
|
type ConnectionData = {
|
|
15
17
|
allPos1: number[],
|
|
@@ -28,7 +30,7 @@ type Rule = {
|
|
|
28
30
|
secondR: number
|
|
29
31
|
}
|
|
30
32
|
|
|
31
|
-
function addCommonTags(col: DG.Column):void {
|
|
33
|
+
function addCommonTags(col: DG.Column): void {
|
|
32
34
|
col.setTag('quality', DG.SEMTYPE.MACROMOLECULE);
|
|
33
35
|
col.setTag('aligned', ALIGNMENT.SEQ);
|
|
34
36
|
col.setTag('alphabet', ALPHABET.PT);
|
|
@@ -54,7 +56,7 @@ class TransformationCommon {
|
|
|
54
56
|
protected getLinkedPositions(helm: string, rules: Rule[]): [number, number][] {
|
|
55
57
|
const seq = helm.replace(HELM_WRAPPER.LEFT, '').replace(HELM_WRAPPER.RIGHT, '');
|
|
56
58
|
const monomers = seq.split('.').map((m) => { return m.replace('[', '').replace(']', ''); });
|
|
57
|
-
const result:[number, number][] = new Array<[number, number]>(rules.length);
|
|
59
|
+
const result: [number, number][] = new Array<[number, number]>(rules.length);
|
|
58
60
|
|
|
59
61
|
for (let i = 0; i < rules.length; i++) {
|
|
60
62
|
let firstFound = false;
|
|
@@ -109,27 +111,31 @@ class TransformationCommon {
|
|
|
109
111
|
return result;
|
|
110
112
|
}
|
|
111
113
|
|
|
112
|
-
protected getRules(
|
|
113
|
-
const ruleCount =
|
|
114
|
+
protected getRules(rulesTables: DG.DataFrame[]): Rule[] {
|
|
115
|
+
const ruleCount = rulesTables.map((df) => df.rowCount).reduce((a, b) => a + b);
|
|
114
116
|
const rules: Rule[] = new Array<Rule>(ruleCount);
|
|
115
|
-
const codeCol = rulesTable.columns.byName('code');
|
|
116
|
-
const monomer1Col = rulesTable.columns.byName('monomer1');
|
|
117
|
-
const monomer2Col = rulesTable.columns.byName('monomer2');
|
|
118
|
-
const modification1Col = rulesTable.columns.byName('modification1');
|
|
119
|
-
const modification2Col = rulesTable.columns.byName('modification2');
|
|
120
|
-
const r1Col = rulesTable.columns.byName('R1');
|
|
121
|
-
const r2Col = rulesTable.columns.byName('R2');
|
|
122
117
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
118
|
+
let counter = 0;
|
|
119
|
+
for (let i = 0; i < rulesTables.length; i++) {
|
|
120
|
+
const codeCol = rulesTables[i].columns.byName('code');
|
|
121
|
+
const monomer1Col = rulesTables[i].columns.byName('monomer1');
|
|
122
|
+
const monomer2Col = rulesTables[i].columns.byName('monomer2');
|
|
123
|
+
const modification1Col = rulesTables[i].columns.byName('modification1');
|
|
124
|
+
const modification2Col = rulesTables[i].columns.byName('modification2');
|
|
125
|
+
const r1Col = rulesTables[i].columns.byName('R1');
|
|
126
|
+
const r2Col = rulesTables[i].columns.byName('R2');
|
|
127
|
+
|
|
128
|
+
for (let j = 0; j < rulesTables[i].rowCount; j++, counter++) {
|
|
129
|
+
rules[counter] = {
|
|
130
|
+
code: codeCol.get(j),
|
|
131
|
+
firstMonomer: monomer1Col.get(j),
|
|
132
|
+
secondMonomer: monomer2Col.get(j),
|
|
133
|
+
firstModification: modification1Col.get(j),
|
|
134
|
+
secondModification: modification2Col.get(j),
|
|
135
|
+
firstR: r1Col.get(j),
|
|
136
|
+
secondR: r2Col.get(j),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
133
139
|
}
|
|
134
140
|
|
|
135
141
|
return rules;
|
|
@@ -163,7 +169,7 @@ class TransformationCommon {
|
|
|
163
169
|
allAttaches2.push(rules[i].secondR);
|
|
164
170
|
|
|
165
171
|
helm = HELM_WRAPPER.LEFT;
|
|
166
|
-
for (let i = 0; i < monomers.length; i
|
|
172
|
+
for (let i = 0; i < monomers.length; i++) {
|
|
167
173
|
if (i != monomers.length - 1)
|
|
168
174
|
helm = helm + monomers[i] + '.';
|
|
169
175
|
else
|
|
@@ -178,8 +184,8 @@ class TransformationCommon {
|
|
|
178
184
|
return cycledHelm;
|
|
179
185
|
}
|
|
180
186
|
|
|
181
|
-
transform(
|
|
182
|
-
const rules = this.getRules(
|
|
187
|
+
transform(rulesTables: DG.DataFrame[]): string[] {
|
|
188
|
+
const rules = this.getRules(rulesTables);
|
|
183
189
|
const resultList = this.helmColumn.toList().map((helm: string) => {
|
|
184
190
|
if (this.hasTerminals(helm))
|
|
185
191
|
return this.getTransformedHelm(helm, rules);
|
|
@@ -212,37 +218,32 @@ function getHelmCycle(helm: string, source: ConnectionData): string {
|
|
|
212
218
|
|
|
213
219
|
cycled += '$$$';
|
|
214
220
|
return cycled;
|
|
215
|
-
// return helm.replace(HELM_WRAPPER.RIGHT,
|
|
216
|
-
// `}$PEPTIDE1,PEPTIDE1,${
|
|
217
|
-
// source.monomerPosition
|
|
218
|
-
// }:R${
|
|
219
|
-
// source.attachmentPoint
|
|
220
|
-
// }-${
|
|
221
|
-
// target.monomerPosition
|
|
222
|
-
// }:R${
|
|
223
|
-
// target.attachmentPoint
|
|
224
|
-
// }${'$'.repeat(6)}`
|
|
225
|
-
// );
|
|
226
221
|
}
|
|
227
222
|
|
|
228
223
|
export async function addTransformedColumn(
|
|
229
|
-
molColumn: DG.Column<string>, addHelm: boolean
|
|
224
|
+
molColumn: DG.Column<string>, addHelm: boolean, ruleFiles: string[], chiralityEngine?: boolean
|
|
230
225
|
): Promise<void> {
|
|
231
226
|
const df = molColumn.dataFrame;
|
|
232
227
|
const uh = UnitsHandler.getOrCreate(molColumn);
|
|
233
228
|
const sourceHelmCol = uh.convert(NOTATION.HELM);
|
|
234
229
|
const pt = PolymerTransformation.getInstance(sourceHelmCol);
|
|
235
|
-
const fileSource = new DG.FileSource(
|
|
236
|
-
|
|
237
|
-
const
|
|
238
|
-
|
|
230
|
+
const fileSource = new DG.FileSource(RULES_PATH);
|
|
231
|
+
|
|
232
|
+
const rulesRawFrames: DG.DataFrame[] = new Array<DG.DataFrame>(ruleFiles.length);
|
|
233
|
+
|
|
234
|
+
for (let i = 0; i < ruleFiles.length; i++) {
|
|
235
|
+
const rulesRaw = await fileSource.readAsText(ruleFiles[i].replace(RULES_PATH, ''));
|
|
236
|
+
rulesRawFrames[i] = DG.DataFrame.fromCsv(rulesRaw);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const targetList = pt.transform(rulesRawFrames);
|
|
239
240
|
const helmColName = df.columns.getUnusedName('transformed(' + molColumn.name + ')');
|
|
240
241
|
const targetHelmCol = DG.Column.fromList('string', helmColName, targetList);
|
|
241
242
|
|
|
242
243
|
addCommonTags(targetHelmCol);
|
|
243
244
|
targetHelmCol.setTag('units', NOTATION.HELM);
|
|
244
245
|
|
|
245
|
-
const molCol = await getMolColumnFromHelm(df, targetHelmCol);
|
|
246
|
+
const molCol = await getMolColumnFromHelm(df, targetHelmCol, chiralityEngine);
|
|
246
247
|
molCol.name = df.columns.getUnusedName('molfile(' + molColumn.name + ')');
|
|
247
248
|
|
|
248
249
|
if (addHelm) {
|
|
@@ -3,60 +3,146 @@ 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 {HELM_POLYMER_TYPE} from '@datagrok-libraries/bio/src/utils/const';
|
|
7
|
-
import {MonomerLibManager} from '../monomer-lib/lib-manager';
|
|
8
|
-
import {ALL_MONOMERS, CYCLIZATION_TYPE, TRANSFORMATION_TYPE} from './const';
|
|
9
6
|
import {addTransformedColumn} from './transformation';
|
|
10
|
-
import
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const targetColumnInput = ui.columnInput(
|
|
22
|
-
'Column', grok.shell.t, targetColumns[0], null,
|
|
23
|
-
{filter: (col: DG.Column) => col.semType === DG.SEMTYPE.MACROMOLECULE}
|
|
24
|
-
);
|
|
25
|
-
|
|
26
|
-
const generateHelmChoiceInput = ui.boolInput('Get HELM', true);
|
|
27
|
-
ui.tooltip.bind(generateHelmChoiceInput.root, 'Add HELM column');
|
|
28
|
-
|
|
29
|
-
// let rulesTable: DG.DataFrame = DG.DataFrame.create();
|
|
30
|
-
|
|
31
|
-
const ruleFileInput = ui.button('ADD RULES', () => {
|
|
32
|
-
DG.Utils.openFile({
|
|
33
|
-
accept: '.csv',
|
|
34
|
-
open: async (selectedFile) => {
|
|
35
|
-
const content = await selectedFile.text();
|
|
36
|
-
// rulesTable = DG.DataFrame.fromCsv(content);
|
|
37
|
-
await grok.dapi.files.writeAsText(RULE_PATH + `${selectedFile.name}`, content);
|
|
38
|
-
//console.log(df.toCsv());
|
|
39
|
-
},
|
|
40
|
-
});
|
|
7
|
+
import {RULES_PATH, RULES_STORAGE_NAME} from './transformation';
|
|
8
|
+
|
|
9
|
+
export type UserRuleSettings = {
|
|
10
|
+
included: string[],
|
|
11
|
+
notIncluded: string[],
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async function getAllAvailableRuleFiles(): Promise<string[]> {
|
|
15
|
+
const list = await grok.dapi.files.list(RULES_PATH);
|
|
16
|
+
const paths = list.map((fileInfo) => {
|
|
17
|
+
return fileInfo.fullPath;
|
|
41
18
|
});
|
|
42
19
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
20
|
+
return paths;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function getUserRulesSettings(): Promise<UserRuleSettings> {
|
|
24
|
+
const resStr: string = await grok.dapi.userDataStorage.getValue(RULES_STORAGE_NAME, 'Settings', true);
|
|
25
|
+
const res = resStr ? JSON.parse(resStr) : {included: [], enotIncludedxplicit: []};
|
|
26
|
+
|
|
27
|
+
res.included = res.included instanceof Array ? res.included : [];
|
|
28
|
+
res.notIncluded = res.notIncluded instanceof Array ? res.notIncluded : [];
|
|
29
|
+
|
|
30
|
+
return res!;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async function setUserLibSettings(value: UserRuleSettings): Promise<void> {
|
|
34
|
+
await grok.dapi.userDataStorage.postValue(RULES_STORAGE_NAME, 'Settings', JSON.stringify(value), true);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export class PolyTool {
|
|
38
|
+
ruleFiles: string[];
|
|
39
|
+
userRuleSettings: UserRuleSettings;
|
|
40
|
+
ruleFilesInputs: HTMLDivElement;// DG.InputBase<boolean | null>[];
|
|
41
|
+
dialog: DG.Dialog;
|
|
42
|
+
|
|
43
|
+
constructor() {
|
|
44
|
+
this.ruleFiles = [];
|
|
45
|
+
this.userRuleSettings = {included: [], notIncluded: []};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private updateRulesSelectionStatus(ruleFileName: string, isSelected: boolean): void {
|
|
49
|
+
const isRuleFileSelected = this.userRuleSettings.included.includes(ruleFileName);
|
|
50
|
+
|
|
51
|
+
if (!isRuleFileSelected && isSelected) {
|
|
52
|
+
this.userRuleSettings.included.push(ruleFileName);
|
|
53
|
+
this.userRuleSettings.included = this.userRuleSettings.included.sort();
|
|
54
|
+
|
|
55
|
+
const index = this.userRuleSettings.notIncluded.indexOf(ruleFileName);
|
|
56
|
+
if (index > -1)
|
|
57
|
+
this.userRuleSettings.notIncluded.splice(index, 1);
|
|
58
|
+
} else {
|
|
59
|
+
const index = this.userRuleSettings.included.indexOf(ruleFileName);
|
|
60
|
+
if (index > -1)
|
|
61
|
+
this.userRuleSettings.included.splice(index, 1);
|
|
62
|
+
|
|
63
|
+
this.userRuleSettings.notIncluded.push(ruleFileName);
|
|
64
|
+
this.userRuleSettings.notIncluded = this.userRuleSettings.notIncluded.sort();
|
|
58
65
|
}
|
|
66
|
+
|
|
67
|
+
setUserLibSettings(this.userRuleSettings);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private getAddButton(): HTMLButtonElement {
|
|
71
|
+
return ui.button('ADD RULES', () => {
|
|
72
|
+
DG.Utils.openFile({
|
|
73
|
+
accept: '.csv',
|
|
74
|
+
open: async (selectedFile) => {
|
|
75
|
+
const content = await selectedFile.text();
|
|
76
|
+
await grok.dapi.files.writeAsText(RULES_PATH + `${selectedFile.name}`, content);
|
|
77
|
+
this.updateRulesSelectionStatus(selectedFile.name, false);
|
|
78
|
+
const cb = ui.boolInput(
|
|
79
|
+
selectedFile.name,
|
|
80
|
+
false,
|
|
81
|
+
(isSelected: boolean) => this.updateRulesSelectionStatus(RULES_PATH + `${selectedFile.name}`, isSelected)
|
|
82
|
+
);
|
|
83
|
+
this.ruleFilesInputs.append(cb.root);
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private async getRuleFilesBlock(): Promise<DG.InputBase<boolean | null>[]> {
|
|
90
|
+
this.ruleFiles = await getAllAvailableRuleFiles();
|
|
91
|
+
this.userRuleSettings = await getUserRulesSettings();
|
|
92
|
+
const cBoxes: DG.InputBase<boolean | null>[] = [];
|
|
93
|
+
|
|
94
|
+
for (let i = 0; i < this.ruleFiles.length; i++) {
|
|
95
|
+
const ruleFileName = this.ruleFiles[i];
|
|
96
|
+
const isRuleFileSelected = this.userRuleSettings.included.includes(ruleFileName);
|
|
97
|
+
const cb = ui.boolInput(
|
|
98
|
+
ruleFileName.replace(RULES_PATH, ''),
|
|
99
|
+
isRuleFileSelected,
|
|
100
|
+
(isSelected: boolean) => this.updateRulesSelectionStatus(ruleFileName, isSelected)
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
cBoxes.push(cb);
|
|
104
|
+
}
|
|
105
|
+
return cBoxes;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async getPolyToolDialog(): Promise<DG.Dialog> {
|
|
109
|
+
const targetColumns = grok.shell.t.columns.bySemTypeAll(DG.SEMTYPE.MACROMOLECULE);
|
|
110
|
+
if (!targetColumns)
|
|
111
|
+
throw new Error('No dataframe with macromolecule columns open');
|
|
112
|
+
|
|
113
|
+
const targetColumnInput = ui.columnInput(
|
|
114
|
+
'Column', grok.shell.t, targetColumns[0], null,
|
|
115
|
+
{filter: (col: DG.Column) => col.semType === DG.SEMTYPE.MACROMOLECULE}
|
|
59
116
|
);
|
|
60
117
|
|
|
61
|
-
|
|
118
|
+
const generateHelmChoiceInput = ui.boolInput('Get HELM', true);
|
|
119
|
+
ui.tooltip.bind(generateHelmChoiceInput.root, 'Add HELM column');
|
|
120
|
+
|
|
121
|
+
const addButton = this.getAddButton();
|
|
122
|
+
this.ruleFilesInputs = ui.div(await this.getRuleFilesBlock());
|
|
123
|
+
//const rulesFiles = ui.div(this.ruleFilesInputs);
|
|
124
|
+
const chiralityEngineInput = ui.boolInput('Chirality engine', false);
|
|
125
|
+
|
|
126
|
+
const div = ui.div([
|
|
127
|
+
targetColumnInput,
|
|
128
|
+
generateHelmChoiceInput,
|
|
129
|
+
chiralityEngineInput,
|
|
130
|
+
'Rules used',
|
|
131
|
+
this.ruleFilesInputs,
|
|
132
|
+
addButton
|
|
133
|
+
]);
|
|
134
|
+
|
|
135
|
+
this.dialog = ui.dialog('Poly Tool')
|
|
136
|
+
.add(div)
|
|
137
|
+
.onOK(async () => {
|
|
138
|
+
const molCol = targetColumnInput.value;
|
|
139
|
+
if (!molCol) {
|
|
140
|
+
grok.shell.warning('No marcomolecule column chosen!');
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
addTransformedColumn(molCol!, generateHelmChoiceInput.value!, this.userRuleSettings.included, chiralityEngineInput.value!);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
return this.dialog;
|
|
147
|
+
}
|
|
62
148
|
}
|