@datagrok/helm 0.0.4 → 0.0.5

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
@@ -2,7 +2,7 @@
2
2
  "name": "@datagrok/helm",
3
3
  "beta": false,
4
4
  "friendlyName": "Helm",
5
- "version": "0.0.4",
5
+ "version": "0.0.5",
6
6
  "description": "",
7
7
  "dependencies": {
8
8
  "datagrok-api": "latest",
@@ -24,7 +24,7 @@
24
24
  "typescript": "latest"
25
25
  },
26
26
  "scripts": {
27
- "link-all": "",
27
+ "link-all": "npm link datagrok-api @datagrok-libraries/utils",
28
28
  "debug-helm": "webpack && grok publish ",
29
29
  "release-helm": "webpack && grok publish --release",
30
30
  "build-helm": "webpack",
@@ -44,5 +44,6 @@
44
44
  "type": "git",
45
45
  "url": "https://github.com/datagrok-ai/public.git",
46
46
  "directory": "packages/Helm"
47
- }
47
+ },
48
+ "category": "Bioinformatics"
48
49
  }
@@ -1,13 +1,18 @@
1
1
  import * as DG from "datagrok-api/dg";
2
2
  import * as grok from "datagrok-api/grok";
3
3
  import {runTests, tests} from '@datagrok-libraries/utils/src/test';
4
+ import './tests/helm-tests.ts'
5
+
6
+ export const _package = new DG.Package();
7
+ export {tests};
4
8
 
5
- export let _package = new DG.Package();
6
- export {tests}
7
9
 
8
10
  //name: test
11
+ //input: string category {optional: true}
12
+ //input: string test {optional: true}
9
13
  //output: dataframe result
10
- export async function test(): Promise<DG.DataFrame> {
11
- let data = await runTests();
14
+ //top-menu: Tools | Dev | JS API Tests
15
+ export async function test(category: string, test: string): Promise<DG.DataFrame> {
16
+ const data = await runTests({category, test});
12
17
  return DG.DataFrame.fromObjects(data)!;
13
- }
18
+ }
package/src/package.ts CHANGED
@@ -5,6 +5,7 @@ import * as DG from 'datagrok-api/dg';
5
5
 
6
6
  export const _package = new DG.Package();
7
7
 
8
+ const lru = new DG.LruCache<any, any>();
8
9
 
9
10
  //tags: init
10
11
  export async function initChem(): Promise<void> {
@@ -17,56 +18,157 @@ export async function initChem(): Promise<void> {
17
18
 
18
19
 
19
20
  //name: helmCellRenderer
20
- //tags: cellRenderer,cellRenderer-HELM
21
- //meta.cellType: HELM
22
- //meta-cell-renderer-sem-type: HELM
21
+ //tags: cellRenderer,cellRenderer-Macromolecule
22
+ //meta.cellType: Macromolecule
23
+ //meta-cell-renderer-sem-type: Macromolecule
23
24
  //output: grid_cell_renderer result
24
25
  export function helmCellRenderer(): DG.GridCellRenderer {
25
26
  return new HelmCellRenderer();
26
27
  }
27
28
 
28
29
  //tags: cellEditor
29
- //description: HELM
30
+ //description: Macromolecule
30
31
  //input: grid_cell cell
31
32
  export function editMoleculeCell(cell: DG.GridCell): void {
32
33
  let view = ui.div();
33
- let app: { canvas: { helm: { setSequence: (arg0: any, arg1: string) => void; }; }; };
34
- setTimeout(function () {
35
- //@ts-ignore
36
- org.helm.webeditor.MolViewer.molscale = 0.8;
37
- //@ts-ignore
38
- app = new scil.helm.App(view, { showabout: false, mexfontsize: "90%", mexrnapinontab: true, topmargin: 20, mexmonomerstab: true, sequenceviewonly: false, mexfavoritefirst: true, mexfilter: true });
39
- });
34
+ org.helm.webeditor.MolViewer.molscale = 0.8;
35
+ let app = new scil.helm.App(view, { showabout: false, mexfontsize: "90%", mexrnapinontab: true, topmargin: 20, mexmonomerstab: true, sequenceviewonly: false, mexfavoritefirst: true, mexfilter: true });
36
+ var sizes = app.calculateSizes();
37
+ app.canvas.resize(sizes.rightwidth, sizes.topheight - 210);
38
+ var s = { width: sizes.rightwidth + "px", height: sizes.bottomheight + "px" };
39
+ //@ts-ignore
40
+ scil.apply(app.sequence.style, s);
41
+ //@ts-ignore
42
+ scil.apply(app.notation.style, s);
43
+ s = { width: sizes.rightwidth + "px", height: (sizes.bottomheight + app.toolbarheight) + "px" };
44
+ //@ts-ignore
45
+ scil.apply(app.properties.parent.style, s);
46
+ app.structureview.resize(sizes.rightwidth, sizes.bottomheight + app.toolbarheight);
47
+ app.mex.resize(sizes.topheight - 80);
40
48
  setTimeout(function() {
41
- //@ts-ignore
42
49
  app.canvas.helm.setSequence(cell.cell.value , 'HELM');
43
50
  }, 200);
44
-
45
- let dlg = ui.dialog()
51
+ //@ts-ignore
52
+ ui.dialog({ showHeader: false, showFooter: true })
46
53
  .add(view)
47
54
  .onOK(() => {
48
- view;
55
+ cell.cell.value = app.canvas.getHelm(true);
49
56
  }).show({ modal: true, fullScreen: true});
50
- dlg.root.children[0].remove();
51
- dlg.root.children[1].classList.remove('ui-panel');
52
- dlg.root.children[1].classList.remove('ui-box');
57
+ }
58
+
59
+ //name: Details
60
+ //tags: panel, widgets
61
+ //input: string helmString {semType: Macromolecule}
62
+ //output: widget result
63
+ export function detailsPanel(helmString: string){
64
+ //return new DG.Widget(ui.divText(lru.get(helmString)));
65
+ var result = lru.get(helmString).split(',');
66
+ return new DG.Widget(
67
+ ui.tableFromMap({
68
+ 'formula': result[0].replace(/<sub>/g, '').replace(/<\/sub>/g, ''),
69
+ 'molecular weight': result[1],
70
+ 'extinction coefficient': result[2],
71
+ 'molfile': result[3],
72
+ 'fasta': ui.wait(async () => ui.divText(await helmToFasta(helmString))),
73
+ 'rna analogue sequence': ui.wait(async () => ui.divText(await helmToRNA(helmString))),
74
+ 'smiles': ui.wait(async () => ui.divText(await helmToSmiles(helmString))),
75
+ 'peptide analogue sequence': ui.wait(async () => ui.divText(await helmToPeptide(helmString))),
76
+ })
77
+ )
78
+ }
79
+
80
+ async function accessServer(url: string, key: string) {
81
+ const params: RequestInit = {
82
+ method: 'GET',
83
+ headers: {
84
+ 'Accept': 'application/json',
85
+ }
86
+ };
87
+ const response = await fetch(url, params);
88
+ const json = await response.json();
89
+ return json[key];
90
+ }
91
+
92
+
93
+ //name: helmToFasta
94
+ //input: string helmString {semType: Macromolecule}
95
+ //output: string res
96
+ export async function helmToFasta(helmString: string) {
97
+ const url = `http://localhost:8081/WebService/service/Fasta/Produce/${helmString}`
98
+ return await accessServer(url, 'FastaFile');
99
+ }
100
+
101
+ //name: helmToRNA
102
+ //description: converts to rna analogue sequence
103
+ //input: string helmString {semType: Macromolecule}
104
+ //output: string res
105
+ export async function helmToRNA(helmString: string) {
106
+ const url = `http://localhost:8081/WebService/service/Fasta/Convert/RNA/${helmString}`
107
+ return await accessServer(url, 'Sequence');
108
+ }
109
+
110
+
111
+ //name: helmToPeptide
112
+ //description: converts to peptide analogue sequence
113
+ //input: string helmString {semType: Macromolecule}
114
+ //output: string res
115
+ export async function helmToPeptide(helmString: string) {
116
+ const url = `http://localhost:8081/WebService/service/Fasta/Convert/PEPTIDE/${helmString}`
117
+ return await accessServer(url, 'Sequence');
53
118
  }
54
119
 
55
120
  //name: helmToSmiles
56
- //tags: converter
121
+ //description: converts to smiles
122
+ //input: string helmString {semType: Macromolecule}
57
123
  //output: string smiles {semType: Molecule}
58
- export function helmToSmiles(helm: string): string {
59
- //todo: call webservice
60
- return 'foo';
124
+ export async function helmToSmiles(helmString: string) {
125
+ const url = `http://localhost:8081/WebService/service/SMILES/${helmString}`
126
+ return await accessServer(url, 'SMILES');
61
127
  }
62
128
 
63
- //name: helmToFasta
64
- //tags: converter
65
- //output: string smiles {semType: fasta}
66
- export function helmToFasta(helm: string): string {
67
- return 'foo';
129
+ function getRS(smiles: string) {
130
+ var new_s = smiles.match(/(?<=\[)[^\][]*(?=])/gm);
131
+ var res = {};
132
+ var el = '';
133
+ var digit;
134
+ for (var i = 0; i < new_s.length; i++) {
135
+ if (new_s[i] != null){
136
+ if (/\d/.test(new_s[i])) {
137
+ digit = new_s[i][new_s[i].length - 1];
138
+ new_s[i] = new_s[i].replace(/[0-9]/g, '');
139
+ for (var j = 0; j < new_s[i].length; j++) {
140
+ if (new_s[i][j] != ':'){
141
+ el += new_s[i][j];
142
+ }
143
+ }
144
+ res['R' + digit] = el;
145
+ el = '';
146
+ }
147
+ }
148
+ }
149
+ return res;
68
150
  }
69
151
 
152
+ //name: Monomer Manager
153
+ //input: column helmColumn {semType: Macromolecule}
154
+ export async function monomerManager(helmColumn: DG.Column) {
155
+ const file = await _package.files.readAsText('HELMCoreLibrary.json');
156
+ const df = DG.DataFrame.fromJson(file);
157
+ var m;
158
+ for (var i = 0; i < df.rowCount; i++){
159
+ m = {
160
+ 'id': df.get('symbol', i).toString(),
161
+ 'n': df.get('name', i).toString(),
162
+ 'na': df.get('naturalAnalog', i).toString(),
163
+ 'type': df.get('polymerType', i).toString(),
164
+ 'mt': df.get('monomerType', i).toString(),
165
+ 'm': df.get('molfile', i).toString(),
166
+ rs: Object.keys(getRS(df.get('smiles', i).toString())).length,
167
+ at: getRS(df.get('smiles', i).toString()),
168
+ }
169
+ org.helm.webeditor.Monomers.addOneMonomer(m);
170
+ }
171
+ }
70
172
 
71
173
  //name: helmColumnToSmiles
72
174
  //input: column helmColumn {semType: HELM}
@@ -74,14 +176,11 @@ export function helmColumnToSmiles(helmColumn: DG.Column) {
74
176
  //todo: add column with smiles to col.dataFrame.
75
177
  }
76
178
 
77
- // todo: "Details" panel (see Toxicity)
78
- // smiles, mol weight, mol formula, extinction coefficient, "combined"
79
-
80
179
 
81
180
  class HelmCellRenderer extends DG.GridCellRenderer {
82
181
 
83
- get name() { return 'helm'; }
84
- get cellType() { return 'helm'; }
182
+ get name() { return 'macromolecule'; }
183
+ get cellType() { return 'macromolecule'; }
85
184
  get defaultWidth(): number | null { return 400; }
86
185
  get defaultHeight(): number | null { return 100; }
87
186
 
@@ -91,7 +190,12 @@ class HelmCellRenderer extends DG.GridCellRenderer {
91
190
  host.setAttribute('data', gridCell.cell.value);
92
191
 
93
192
  gridCell.element = host;
94
- // @ts-ignore
95
- new JSDraw2.Editor(host, { width: w, height: h, skin: "w8", viewonly: true });
193
+ var canvas = new JSDraw2.Editor(host, { width: w, height: h, skin: "w8", viewonly: true });
194
+ var formula = canvas.getFormula(true);
195
+ var molWeight = Math.round(canvas.getMolWeight() * 100) / 100;
196
+ var coef = Math.round(canvas.getExtinctionCoefficient(true) * 100) / 100;
197
+ var molfile = canvas.getMolfile();
198
+ var result = formula + ', ' + molWeight + ', ' + coef + ', ' + molfile;
199
+ lru.set(gridCell.cell.value, result);
96
200
  }
97
201
  }
@@ -0,0 +1,35 @@
1
+ import {before, category, expect, test} from '@datagrok-libraries/utils/src/test';
2
+ import { helmToFasta, helmToPeptide, helmToRNA } from '../package';
3
+ import { _package } from '../package-test';
4
+ import * as DG from 'datagrok-api/dg';
5
+ import * as grok from 'datagrok-api/grok';
6
+
7
+
8
+ category('Helm', () => {
9
+
10
+ test('helmToFasta', async () => {
11
+ expect(await helmToFasta('RNA1{R(U)P.R(T)P.R(G)P.R(C)P.R(A)}$$$$'), '>RNA1UTGCA');
12
+ expect(await helmToFasta('RNA1{P.R(U).P.R(T)}$$$$'), '>RNA1UT');
13
+ expect(await helmToFasta('PEPTIDE1{A.G}$$$$V2.0'), '>PEPTIDE1AG')
14
+ });
15
+
16
+ test('helmToRNA', async () => {
17
+ expect(await helmToRNA('RNA1{R(U)P.R(T)P.R(G)P.R(C)P.R(A)}$$$$'), 'UTGCA');
18
+ expect(await helmToRNA('RNA1{P.R(U).P.R(T)}$$$$'), 'UT');
19
+ expect(await helmToRNA('RNA1{R(U)P.R(T)P}|RNA2{P.R(A)P.R(A)}$RNA1,RNA2,2:pair-6:pair|RNA1,RNA2,5:pair-3:pair$$$'), 'UT AA');
20
+ });
21
+
22
+ test('helmToPeptide', async () => {
23
+ expect(await helmToPeptide('PEPTIDE1{A.G}$$$$V2.0'), 'AG');
24
+ expect(await helmToPeptide('PEPTIDE1{L.V.A}|PEPTIDE2{L.V.A}$$$$'), 'LVA LVA');
25
+ expect(await helmToPeptide('PEPTIDE1{A.R.C.A.A.K.T.C.D.A}$PEPTIDE1,PEPTIDE1,8:R3-3:R3$$$'), 'ARCAAKTCDA');
26
+ });
27
+
28
+ test('detectHelm', async () => {
29
+ const file = await _package.files.readAsText('test.csv')
30
+ const df = DG.DataFrame.fromCsv(file);
31
+ let col = df.columns.byName('HELM string');
32
+ await grok.data.detectSemanticTypes(df);
33
+ expect(col.semType, DG.SEMTYPE.HELM);
34
+ });
35
+ });
package/tsconfig.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
8
8
  "module": "es2020", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
9
9
  "lib": ["es2020", "dom"], /* Specify library files to be included in the compilation. */
10
- // "allowJs": true, /* Allow javascript files to be compiled. */
10
+ "allowJs": true, /* Allow javascript files to be compiled. */
11
11
  // "checkJs": true, /* Report errors in .js files. */
12
12
  // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
13
13
  // "declaration": true, /* Generates corresponding '.d.ts' file. */
@@ -25,7 +25,7 @@
25
25
  // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
26
26
 
27
27
  /* Strict Type-Checking Options */
28
- "strict": true, /* Enable all strict type-checking options. */
28
+ "strict": false, /* Enable all strict type-checking options. */
29
29
  // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
30
30
  // "strictNullChecks": true, /* Enable strict null checks. */
31
31
  // "strictFunctionTypes": true, /* Enable strict checking of function types. */
package/webpack.config.js CHANGED
@@ -4,8 +4,12 @@ const packageName = path.parse(require('./package.json').name).name.toLowerCase(
4
4
  module.exports = {
5
5
  mode: 'development',
6
6
  entry: {
7
- test: {filename: 'package-test.js', library: {type: 'var', name:`${packageName}_test`}, import: './src/package-test.ts'},
8
- package: './src/package.ts'
7
+ package: './src/package.ts',
8
+ test: {
9
+ filename: 'package-test.js',
10
+ library: {type: 'var', name: `${packageName}_test`},
11
+ import: './src/package-test.ts',
12
+ },
9
13
  },
10
14
  resolve: {
11
15
  extensions: ['.wasm', '.mjs', '.js', '.json', '.ts', '.tsx'],