@datagrok/helm 2.2.0 → 2.2.1
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 +11 -0
- package/dist/package-test.js +1 -1
- package/dist/package-test.js.map +1 -1
- package/dist/package.js +1 -1
- package/dist/package.js.map +1 -1
- package/package.json +10 -10
- package/src/cell-renderer.ts +5 -3
- package/src/constants.ts +0 -11
- package/src/helm-monomer-placer.ts +3 -19
- package/src/package-test.ts +5 -2
- package/src/package-utils.ts +133 -0
- package/src/package.ts +33 -87
- package/src/tests/get-monomer-tests.ts +210 -0
- package/src/tests/helm-tests.ts +1 -0
- package/src/types/index.ts +0 -0
- package/src/utils/dummy-monomer.ts +163 -48
- package/src/utils/get-hovered.ts +7 -18
- package/src/utils/get-monomer.ts +111 -0
- package/src/utils/helm-grid-cell-renderer.ts +3 -5
- package/src/utils/helm-service.ts +14 -41
- /package/src/tests/{get-molfiles.ts → get-molfiles-tests.ts} +0 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datagrok/helm",
|
|
3
3
|
"friendlyName": "Helm",
|
|
4
|
-
"version": "2.2.
|
|
4
|
+
"version": "2.2.1",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Oleksandra Serhiienko",
|
|
7
7
|
"email": "oserhiienko@datagrok.ai"
|
|
@@ -15,30 +15,30 @@
|
|
|
15
15
|
"helm/JSDraw/Pistoia.HELM.js"
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@datagrok-libraries/bio": "^5.41.
|
|
18
|
+
"@datagrok-libraries/bio": "^5.41.2",
|
|
19
19
|
"@datagrok-libraries/chem-meta": "^1.2.5",
|
|
20
20
|
"@datagrok-libraries/utils": "^4.2.2",
|
|
21
21
|
"cash-dom": "^8.1.1",
|
|
22
|
-
"datagrok-api": "^1.17.
|
|
22
|
+
"datagrok-api": "^1.17.4",
|
|
23
23
|
"dayjs": "^1.10.6",
|
|
24
24
|
"rxjs": "^6.5.5",
|
|
25
25
|
"wu": "latest"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
+
"@datagrok/bio": "^2.12.18",
|
|
29
|
+
"@datagrok/chem": "^1.9.2",
|
|
28
30
|
"@types/node": "17.0.45",
|
|
29
31
|
"@types/wu": "latest",
|
|
32
|
+
"@typescript-eslint/eslint-plugin": "^5.11.0",
|
|
33
|
+
"@typescript-eslint/parser": "^5.11.0",
|
|
34
|
+
"eslint": "^8.18.0",
|
|
35
|
+
"eslint-config-google": "^0.14.0",
|
|
30
36
|
"path": "^0.12.7",
|
|
31
37
|
"source-map-loader": "^4.0.1",
|
|
32
38
|
"ts-loader": "^9.2.6",
|
|
33
39
|
"typescript": "^4.8.4",
|
|
34
40
|
"webpack": "^5.76.3",
|
|
35
|
-
"webpack-cli": "^4.9.1"
|
|
36
|
-
"@typescript-eslint/eslint-plugin": "^5.11.0",
|
|
37
|
-
"@typescript-eslint/parser": "^5.11.0",
|
|
38
|
-
"eslint": "^8.18.0",
|
|
39
|
-
"eslint-config-google": "^0.14.0",
|
|
40
|
-
"@datagrok/bio": "^2.12.17",
|
|
41
|
-
"@datagrok/chem": "^1.9.2"
|
|
41
|
+
"webpack-cli": "^4.9.1"
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|
|
44
44
|
"link-all": "npm link @datagrok-libraries/chem-meta datagrok-api @datagrok-libraries/utils @datagrok-libraries/bio",
|
package/src/cell-renderer.ts
CHANGED
|
@@ -7,13 +7,13 @@ import wu from 'wu';
|
|
|
7
7
|
|
|
8
8
|
import {printLeftOrCentered} from '@datagrok-libraries/bio/src/utils/cell-renderer';
|
|
9
9
|
import {errorToConsole} from '@datagrok-libraries/utils/src/to-console';
|
|
10
|
+
import {getGridCellRendererBack} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
|
|
10
11
|
|
|
11
12
|
import {findMonomers, parseHelm, removeGapsFromHelm} from './utils';
|
|
12
13
|
import {HelmMonomerPlacer, ISeqMonomer} from './helm-monomer-placer';
|
|
13
14
|
import {getHoveredMonomerFallback, getHoveredMonomerFromEditorMol} from './utils/get-hovered';
|
|
14
|
-
import {getGridCellRendererBack} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
import {getMonomerLib} from './package';
|
|
17
17
|
|
|
18
18
|
const enum tempTAGS {
|
|
19
19
|
helmSumMaxLengthWords = 'helm-sum-maxLengthWords',
|
|
@@ -73,7 +73,9 @@ export class HelmCellRenderer extends DG.GridCellRenderer {
|
|
|
73
73
|
if (seqMonomer) {
|
|
74
74
|
if (!missedMonomers.has(seqMonomer.symbol)) {
|
|
75
75
|
const tooltipElements: HTMLElement[] = [ui.div(seqMonomer.symbol)];
|
|
76
|
-
const
|
|
76
|
+
const monomerLib = getMonomerLib();
|
|
77
|
+
const monomerDiv = monomerLib ? monomerLib.getTooltip(seqMonomer.polymerType, seqMonomer.symbol) :
|
|
78
|
+
ui.divText('Monomer library is not available.');
|
|
77
79
|
tooltipElements.push(monomerDiv);
|
|
78
80
|
ui.tooltip.show(ui.divV(tooltipElements), e.x + 16, e.y + 16);
|
|
79
81
|
} else {
|
package/src/constants.ts
CHANGED
|
@@ -12,17 +12,6 @@ export const jsonSdfMonomerLibDict = {
|
|
|
12
12
|
'symbol': 'MonomerCode'
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
-
export type WebEditorMonomer = {
|
|
16
|
-
/** symbol */ id: string,
|
|
17
|
-
/** name */ n: string,
|
|
18
|
-
/** natural analog */ na?: string,
|
|
19
|
-
/** polymer type */type: string,
|
|
20
|
-
/** monomer type */ mt: string,
|
|
21
|
-
/** molfile */ m: string,
|
|
22
|
-
/** substituents */ at: { [group: string]: string },
|
|
23
|
-
/** number of substituents */ rs: number
|
|
24
|
-
};
|
|
25
|
-
|
|
26
15
|
export const SMILES = 'smiles';
|
|
27
16
|
export const RGROUPS = 'rgroups';
|
|
28
17
|
export const MONOMER_SYMBOL = 'symbol';
|
|
@@ -8,19 +8,18 @@ import wu from 'wu';
|
|
|
8
8
|
|
|
9
9
|
import {IMonomerLib, Monomer} from '@datagrok-libraries/bio/src/types/index';
|
|
10
10
|
import {CellRendererBackBase} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
|
|
11
|
+
import {IEditorMol} from '@datagrok-libraries/bio/src/types/helm-web-editor';
|
|
11
12
|
|
|
12
13
|
import {getParts, parseHelm} from './utils';
|
|
13
14
|
|
|
14
15
|
import {_package, getMonomerLib} from './package';
|
|
15
16
|
|
|
16
17
|
export interface ISeqMonomer {
|
|
17
|
-
polymerType:
|
|
18
|
-
symbol: string
|
|
18
|
+
polymerType: org.helm.PolymerType;
|
|
19
|
+
symbol: string;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
export class HelmMonomerPlacer extends CellRendererBackBase<string> {
|
|
22
|
-
public readonly monomerLib: IMonomerLib;
|
|
23
|
-
|
|
24
23
|
private _allPartsList: (string[] | null)[];
|
|
25
24
|
private _lengthsList: (number[] | null)[];
|
|
26
25
|
private _editorMolList: (JSDraw2.IEditorMol | null)[];
|
|
@@ -34,8 +33,6 @@ export class HelmMonomerPlacer extends CellRendererBackBase<string> {
|
|
|
34
33
|
tableCol: DG.Column<string>
|
|
35
34
|
) {
|
|
36
35
|
super(gridCol, tableCol, _package.logger);
|
|
37
|
-
this.monomerLib = getMonomerLib();
|
|
38
|
-
this.subs.push(this.monomerLib.onChanged.subscribe(this.monomerLibOnChanged.bind(this)));
|
|
39
36
|
}
|
|
40
37
|
|
|
41
38
|
protected override reset(): void {
|
|
@@ -80,19 +77,6 @@ export class HelmMonomerPlacer extends CellRendererBackBase<string> {
|
|
|
80
77
|
return [allParts, lengths];
|
|
81
78
|
}
|
|
82
79
|
|
|
83
|
-
getMonomer(monomer: ISeqMonomer): Monomer | null {
|
|
84
|
-
let res: Monomer | null = null;
|
|
85
|
-
if (monomer.polymerType)
|
|
86
|
-
res = this.monomerLib.getMonomer(monomer.polymerType, monomer.symbol);
|
|
87
|
-
else {
|
|
88
|
-
for (const polymerType of this.monomerLib.getPolymerTypes()) {
|
|
89
|
-
res = this.monomerLib.getMonomer(polymerType, monomer.symbol);
|
|
90
|
-
if (res) break;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
return res;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
80
|
// -- Handle events --
|
|
97
81
|
|
|
98
82
|
private monomerLibOnChanged(_value: any): void {
|
package/src/package-test.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import * as DG from 'datagrok-api/dg';
|
|
2
2
|
import * as grok from 'datagrok-api/grok';
|
|
3
3
|
|
|
4
|
+
import '@datagrok-libraries/bio/src/types/helm';
|
|
4
5
|
import {runTests, tests, TestContext} from '@datagrok-libraries/utils/src/test';
|
|
5
6
|
|
|
6
7
|
import './tests/helm-tests.ts';
|
|
7
8
|
import './tests/findMonomers-tests';
|
|
8
9
|
import './tests/helm-service-tests';
|
|
9
10
|
import './tests/renderers-tests';
|
|
10
|
-
import './tests/get-molfiles';
|
|
11
|
+
import './tests/get-molfiles-tests';
|
|
11
12
|
import './tests/properties-widget-tests';
|
|
12
13
|
import './tests/get-all-parts-tests';
|
|
14
|
+
import './tests/get-monomer-tests';
|
|
13
15
|
|
|
14
16
|
export const _package = new DG.Package();
|
|
15
17
|
export {tests};
|
|
@@ -21,6 +23,7 @@ export {tests};
|
|
|
21
23
|
//input: object testContext {optional: true}
|
|
22
24
|
//output: dataframe result
|
|
23
25
|
export async function test(category: string, test: string, testContext: TestContext): Promise<DG.DataFrame> {
|
|
24
|
-
|
|
26
|
+
// verbose: true - for tests returning dataframe
|
|
27
|
+
const data = await runTests({category, test, testContext, verbose: true});
|
|
25
28
|
return DG.DataFrame.fromObjects(data)!;
|
|
26
29
|
}
|
package/src/package-utils.ts
CHANGED
|
@@ -2,8 +2,19 @@ import * as ui from 'datagrok-api/ui';
|
|
|
2
2
|
import * as grok from 'datagrok-api/grok';
|
|
3
3
|
import * as DG from 'datagrok-api/dg';
|
|
4
4
|
|
|
5
|
+
import * as org from 'org';
|
|
6
|
+
import * as scil from 'scil';
|
|
7
|
+
import * as JSDraw2 from 'JSDraw2';
|
|
8
|
+
import Atom = JSDraw2.Atom;
|
|
9
|
+
|
|
10
|
+
import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
|
|
5
11
|
import {HelmServiceBase} from '@datagrok-libraries/bio/src/viewers/helm-service';
|
|
12
|
+
import {IMonomerLib, HelmType} from '@datagrok-libraries/bio/src/types';
|
|
13
|
+
import {ILogger} from '@datagrok-libraries/bio/src/utils/logger';
|
|
14
|
+
|
|
6
15
|
import {HelmService} from './utils/helm-service';
|
|
16
|
+
import {GetMonomerFunc, GetMonomerResType, getWebEditorMonomer} from './utils/get-monomer';
|
|
17
|
+
|
|
7
18
|
|
|
8
19
|
type HelmWindowType = Window & {
|
|
9
20
|
$helmService?: HelmServiceBase,
|
|
@@ -15,3 +26,125 @@ export function _getHelmService(): HelmServiceBase {
|
|
|
15
26
|
if (!res) res = window.$helmService = new HelmService();
|
|
16
27
|
return res;
|
|
17
28
|
}
|
|
29
|
+
|
|
30
|
+
export function initHelmPatchDojo(): void {
|
|
31
|
+
// patch window.dojox.gfx.svg.Text.prototype.getTextWidth hangs
|
|
32
|
+
/** get the text width in pixels */
|
|
33
|
+
// @ts-ignore
|
|
34
|
+
window.dojox.gfx.svg.Text.prototype.getTextWidth = function() {
|
|
35
|
+
const rawNode = this.rawNode;
|
|
36
|
+
const oldParent = rawNode.parentNode;
|
|
37
|
+
const _measurementNode = rawNode.cloneNode(true);
|
|
38
|
+
_measurementNode.style.visibility = 'hidden';
|
|
39
|
+
|
|
40
|
+
// solution to the "orphan issue" in FF
|
|
41
|
+
let _width = 0;
|
|
42
|
+
const _text = _measurementNode.firstChild.nodeValue;
|
|
43
|
+
oldParent.appendChild(_measurementNode);
|
|
44
|
+
|
|
45
|
+
// solution to the "orphan issue" in Opera
|
|
46
|
+
// (nodeValue == "" hangs firefox)
|
|
47
|
+
if (_text != '') {
|
|
48
|
+
let watchdogCounter = 100;
|
|
49
|
+
while (!_width && --watchdogCounter > 0) { // <-- hangs
|
|
50
|
+
//Yang: work around svgweb bug 417 -- http://code.google.com/p/svgweb/issues/detail?id=417
|
|
51
|
+
if (_measurementNode.getBBox)
|
|
52
|
+
_width = parseInt(_measurementNode.getBBox().width);
|
|
53
|
+
else
|
|
54
|
+
_width = 68;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
oldParent.removeChild(_measurementNode);
|
|
58
|
+
return _width;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export const helmJsonReplacer = (key: string, value: any): any => {
|
|
63
|
+
switch (key) {
|
|
64
|
+
case '_parent': {
|
|
65
|
+
return `${value.toString()}`;
|
|
66
|
+
}
|
|
67
|
+
default:
|
|
68
|
+
return value;
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export class HelmPackage extends DG.Package {
|
|
73
|
+
public getMonomerOriginal: GetMonomerFunc;
|
|
74
|
+
public alertOriginal: (s: string) => void;
|
|
75
|
+
|
|
76
|
+
/** Patches Pistoia Monomers.getMonomer method to utilize DG Bio monomer Lib */
|
|
77
|
+
public initHelmPatchPistoia(monomerLib: IMonomerLib, logger: ILogger): void {
|
|
78
|
+
const logPrefix: string = 'Helm: initHelmPatchPistoia()';
|
|
79
|
+
const monomers = org.helm.webeditor.Monomers;
|
|
80
|
+
|
|
81
|
+
this.getMonomerOriginal = monomers.getMonomer.bind(monomers);
|
|
82
|
+
this.logger.debug(`${logPrefix}, this.getMonomerOriginal stored`);
|
|
83
|
+
|
|
84
|
+
this.alertOriginal = scil.Utils.alert;
|
|
85
|
+
|
|
86
|
+
org.helm.webeditor.Monomers.getMonomer = (
|
|
87
|
+
a: Atom<HelmType> | HelmType, name: string
|
|
88
|
+
): GetMonomerResType => {
|
|
89
|
+
const logPrefixInt = `${logPrefix}, org.helm.webeditor.Monomers.getMonomer()`;
|
|
90
|
+
try {
|
|
91
|
+
// logger.debug(`${logPrefixInt}, a: ${JSON.stringify(a, helmJsonReplacer)}, name: '${name}'`);
|
|
92
|
+
|
|
93
|
+
// Creates monomers in lib
|
|
94
|
+
const dgWem = getWebEditorMonomer(monomerLib, a, name);
|
|
95
|
+
|
|
96
|
+
// // Returns null for gap
|
|
97
|
+
// const oWem = this.getMonomerOriginal(a, name);
|
|
98
|
+
// if (!oWem)
|
|
99
|
+
// logger.warning(`${logPrefixInt}, getMonomerOriginal( a: ${a}, name: ${name}) returns null`);
|
|
100
|
+
return dgWem; //dgWem;
|
|
101
|
+
} catch (err) {
|
|
102
|
+
const [errMsg, errStack] = errInfo(err);
|
|
103
|
+
logger.error(`${logPrefixInt}, Error: ${errMsg}`, undefined, errStack);
|
|
104
|
+
throw err;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
scil.Utils.alert = (s: string): void => {
|
|
108
|
+
logger.warning(`${logPrefix}, scil.Utils.alert() s = 's'.`);
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
// @ts-ignore, intercept with proxy to observe access and usage
|
|
112
|
+
org.helm.webeditor.Monomers = new class {
|
|
113
|
+
constructor(base: org.helm.IMonomers) {
|
|
114
|
+
return new Proxy(base, {
|
|
115
|
+
get(target: any, p: string | symbol, _receiver: any): any {
|
|
116
|
+
return target[p];
|
|
117
|
+
},
|
|
118
|
+
set(target: any, p: string | symbol, newValue: any, _receiver: any): boolean {
|
|
119
|
+
if (p != 'sugars' && p != 'linkers' && p != 'bases' && p != 'aas') {
|
|
120
|
+
const k = 11;
|
|
121
|
+
}
|
|
122
|
+
target[p] = newValue;
|
|
123
|
+
return true;
|
|
124
|
+
},
|
|
125
|
+
apply(target: any, thisArg: any, argArray: any[]): any {
|
|
126
|
+
return target[thisArg](...argArray);
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}(org.helm.webeditor.Monomers) as org.helm.IMonomers;
|
|
131
|
+
|
|
132
|
+
// @ts-ignore, intercept with proxy to observe access and usage
|
|
133
|
+
org.helm.webeditor = new class {
|
|
134
|
+
constructor(base: org.helm.IOrgHelmWebEditor) {
|
|
135
|
+
return new Proxy(base, {
|
|
136
|
+
get(target: any, p: string | symbol, _receiver: any): any {
|
|
137
|
+
return target[p];
|
|
138
|
+
},
|
|
139
|
+
set(target: any, p: string | symbol, newValue: any, _receiver: any): boolean {
|
|
140
|
+
target[p] = newValue;
|
|
141
|
+
return true;
|
|
142
|
+
},
|
|
143
|
+
apply(target: any, thisArg: any, argArray: any[]): any {
|
|
144
|
+
return target[thisArg](...argArray);
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}(org.helm.webeditor) as org.helm.IOrgHelmWebEditor;
|
|
149
|
+
}
|
|
150
|
+
}
|
package/src/package.ts
CHANGED
|
@@ -6,9 +6,9 @@ import * as DG from 'datagrok-api/dg';
|
|
|
6
6
|
// import '@datagrok-libraries/bio/src/types/dojo';
|
|
7
7
|
// import * as dojo from 'DOJO';
|
|
8
8
|
import '@datagrok-libraries/bio/src/types/helm';
|
|
9
|
+
import '@datagrok-libraries/bio/src/types/jsdraw2';
|
|
9
10
|
import * as scil from 'scil';
|
|
10
11
|
import * as org from 'org';
|
|
11
|
-
import '@datagrok-libraries/bio/src/types/jsdraw2';
|
|
12
12
|
import * as JSDraw2 from 'JSDraw2';
|
|
13
13
|
|
|
14
14
|
import $ from 'cash-dom';
|
|
@@ -20,50 +20,15 @@ import {IMonomerLib, Monomer} from '@datagrok-libraries/bio/src/types';
|
|
|
20
20
|
import {IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
|
|
21
21
|
import {HelmServiceBase} from '@datagrok-libraries/bio/src/viewers/helm-service';
|
|
22
22
|
|
|
23
|
-
import {findMonomers, parseHelm} from './utils';
|
|
24
23
|
import {HelmCellRenderer} from './cell-renderer';
|
|
25
24
|
import {HelmHelper} from './helm-helper';
|
|
26
25
|
import {getPropertiesWidget} from './widgets/properties-widget';
|
|
27
26
|
import {HelmGridCellRenderer, HelmGridCellRendererBack} from './utils/helm-grid-cell-renderer';
|
|
28
|
-
import {_getHelmService} from './package-utils';
|
|
29
|
-
|
|
30
|
-
import {WebEditorMonomer, RGROUP_CAP_GROUP_NAME, RGROUP_LABEL, SMILES} from './constants';
|
|
27
|
+
import {_getHelmService, HelmPackage, initHelmPatchDojo} from './package-utils';
|
|
31
28
|
|
|
32
29
|
let monomerLib: IMonomerLib | null = null;
|
|
33
30
|
|
|
34
|
-
export const _package = new
|
|
35
|
-
|
|
36
|
-
function initHelmPatchDojo(): void {
|
|
37
|
-
// patch window.dojox.gfx.svg.Text.prototype.getTextWidth hangs
|
|
38
|
-
/** get the text width in pixels */
|
|
39
|
-
// @ts-ignore
|
|
40
|
-
window.dojox.gfx.svg.Text.prototype.getTextWidth = function() {
|
|
41
|
-
const rawNode = this.rawNode;
|
|
42
|
-
const oldParent = rawNode.parentNode;
|
|
43
|
-
const _measurementNode = rawNode.cloneNode(true);
|
|
44
|
-
_measurementNode.style.visibility = 'hidden';
|
|
45
|
-
|
|
46
|
-
// solution to the "orphan issue" in FF
|
|
47
|
-
let _width = 0;
|
|
48
|
-
const _text = _measurementNode.firstChild.nodeValue;
|
|
49
|
-
oldParent.appendChild(_measurementNode);
|
|
50
|
-
|
|
51
|
-
// solution to the "orphan issue" in Opera
|
|
52
|
-
// (nodeValue == "" hangs firefox)
|
|
53
|
-
if (_text != '') {
|
|
54
|
-
let watchdogCounter = 100;
|
|
55
|
-
while (!_width && --watchdogCounter > 0) { // <-- hangs
|
|
56
|
-
//Yang: work around svgweb bug 417 -- http://code.google.com/p/svgweb/issues/detail?id=417
|
|
57
|
-
if (_measurementNode.getBBox)
|
|
58
|
-
_width = parseInt(_measurementNode.getBBox().width);
|
|
59
|
-
else
|
|
60
|
-
_width = 68;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
oldParent.removeChild(_measurementNode);
|
|
64
|
-
return _width;
|
|
65
|
-
};
|
|
66
|
-
}
|
|
31
|
+
export const _package = new HelmPackage();
|
|
67
32
|
|
|
68
33
|
//tags: init
|
|
69
34
|
export async function initHelm(): Promise<void> {
|
|
@@ -71,31 +36,42 @@ export async function initHelm(): Promise<void> {
|
|
|
71
36
|
_package.logger.debug(`${logPrefix}, start`);
|
|
72
37
|
org.helm.webeditor.kCaseSensitive = true; // GROK-13880
|
|
73
38
|
|
|
74
|
-
|
|
39
|
+
await Promise.all([
|
|
75
40
|
new Promise((resolve, reject) => {
|
|
76
41
|
// @ts-ignore
|
|
77
42
|
dojo.ready(function() { resolve(null); });
|
|
78
43
|
}).then(() => {
|
|
79
44
|
initHelmPatchDojo();
|
|
80
45
|
}),
|
|
81
|
-
|
|
46
|
+
(async () => {
|
|
47
|
+
const libHelper = await getMonomerLibHelper();
|
|
48
|
+
return libHelper.getBioLib();
|
|
49
|
+
})()
|
|
82
50
|
])
|
|
83
51
|
.then(([_, lib]: [unknown, IMonomerLib]) => {
|
|
84
52
|
_package.logger.debug(`${logPrefix}, then(), lib loaded`);
|
|
85
53
|
monomerLib = lib;
|
|
86
54
|
rewriteLibraries(); // initHelm()
|
|
55
|
+
_package.initHelmPatchPistoia(monomerLib, _package.logger);
|
|
56
|
+
|
|
87
57
|
monomerLib.onChanged.subscribe((_) => {
|
|
88
58
|
try {
|
|
59
|
+
const libSummary = monomerLib!.getSummary();
|
|
60
|
+
const isLibEmpty = Object.keys(libSummary).length == 0;
|
|
61
|
+
const libSummaryLog = isLibEmpty ? 'empty' : Object.entries(libSummary)
|
|
62
|
+
.map(([pt, count]) => `${pt}: ${count}`)
|
|
63
|
+
.join(', ');
|
|
89
64
|
const logPrefixInt = `${logPrefix} monomerLib.onChanged()`;
|
|
90
|
-
_package.logger.debug(`${logPrefixInt}, start,
|
|
91
|
-
rewriteLibraries(); // initHelm()
|
|
65
|
+
_package.logger.debug(`${logPrefixInt}, start, lib: { ${libSummaryLog} }`);
|
|
92
66
|
|
|
93
|
-
const
|
|
94
|
-
.
|
|
95
|
-
.
|
|
96
|
-
const libMsg: string = `Monomer lib updated:<br /> ${
|
|
67
|
+
const libSummaryHtml = isLibEmpty ? 'empty' : Object.entries(libSummary)
|
|
68
|
+
.map(([pt, count]) => `${pt} ${count}`)
|
|
69
|
+
.join('<br />');
|
|
70
|
+
const libMsg: string = `Monomer lib updated:<br /> ${libSummaryHtml}`;
|
|
97
71
|
grok.shell.info(libMsg);
|
|
98
72
|
|
|
73
|
+
_package.logger.debug(`${logPrefixInt}, org,helm.webeditor.Monomers updating ...`);
|
|
74
|
+
rewriteLibraries(); // initHelm()
|
|
99
75
|
_package.logger.debug(`${logPrefixInt}, end, org.helm.webeditor.Monomers completed`);
|
|
100
76
|
} catch (err: any) {
|
|
101
77
|
const errMsg = errorToConsole(err);
|
|
@@ -111,10 +87,11 @@ export async function initHelm(): Promise<void> {
|
|
|
111
87
|
errRes.stack = err.stack;
|
|
112
88
|
throw errRes;
|
|
113
89
|
});
|
|
90
|
+
_package.logger.debug(`${logPrefix}, end`);
|
|
114
91
|
}
|
|
115
92
|
|
|
116
|
-
export function getMonomerLib(): IMonomerLib {
|
|
117
|
-
return monomerLib
|
|
93
|
+
export function getMonomerLib(): IMonomerLib | null {
|
|
94
|
+
return monomerLib;
|
|
118
95
|
}
|
|
119
96
|
|
|
120
97
|
/** Fills org.helm.webeditor.Monomers dictionary for WebEditor */
|
|
@@ -125,7 +102,7 @@ function rewriteLibraries() {
|
|
|
125
102
|
monomerSymbols.forEach((monomerSymbol) => {
|
|
126
103
|
let isBroken = false;
|
|
127
104
|
const monomer: Monomer = monomerLib!.getMonomer(polymerType, monomerSymbol)!;
|
|
128
|
-
const webEditorMonomer: WebEditorMonomer = {
|
|
105
|
+
const webEditorMonomer: org.helm.WebEditorMonomer = {
|
|
129
106
|
id: monomerSymbol,
|
|
130
107
|
m: monomer.molfile,
|
|
131
108
|
n: monomer.name,
|
|
@@ -137,6 +114,7 @@ function rewriteLibraries() {
|
|
|
137
114
|
};
|
|
138
115
|
|
|
139
116
|
if (monomer.rgroups.length > 0) {
|
|
117
|
+
// @ts-ignore
|
|
140
118
|
webEditorMonomer.rs = monomer.rgroups.length;
|
|
141
119
|
const at: { [prop: string]: any } = {};
|
|
142
120
|
monomer.rgroups.forEach((it) => {
|
|
@@ -144,6 +122,7 @@ function rewriteLibraries() {
|
|
|
144
122
|
});
|
|
145
123
|
webEditorMonomer.at = at;
|
|
146
124
|
} else if (monomer[SMILES] != null) {
|
|
125
|
+
// @ts-ignore
|
|
147
126
|
webEditorMonomer.rs = Object.keys(getRS(monomer[SMILES].toString())).length;
|
|
148
127
|
webEditorMonomer.at = getRS(monomer[SMILES].toString());
|
|
149
128
|
} else
|
|
@@ -177,19 +156,7 @@ export function helmCellRenderer(): HelmCellRenderer {
|
|
|
177
156
|
}
|
|
178
157
|
|
|
179
158
|
function checkMonomersAndOpenWebEditor(cell: DG.Cell, value?: string, units?: string) {
|
|
180
|
-
|
|
181
|
-
const monomerList: string[] = parseHelm(cellValue);
|
|
182
|
-
const missedMonomerSet = findMonomers(monomerList);
|
|
183
|
-
if (missedMonomerSet.size === 0)
|
|
184
|
-
webEditor(cell, value, units);
|
|
185
|
-
else if (missedMonomerSet.size === 1 && missedMonomerSet.has(GapOriginals[NOTATION.HELM]))
|
|
186
|
-
grok.shell.warning(`WebEditor doesn't support Helm with gaps '${GapOriginals[NOTATION.HELM]}'.`);
|
|
187
|
-
else {
|
|
188
|
-
grok.shell.warning(
|
|
189
|
-
`Monomers ${Array.from(missedMonomerSet).map((m) => `'${m}'`).join(', ')} are not found. <br/>` +
|
|
190
|
-
`Please specify the monomer library to use. <br/>` +
|
|
191
|
-
`<a href="https://datagrok.ai/help/datagrok/solutions/domains/bio/#manage-monomer-libraries" target="_blank">Learn more</a>`);
|
|
192
|
-
}
|
|
159
|
+
openWebEditor(cell, value, units);
|
|
193
160
|
}
|
|
194
161
|
|
|
195
162
|
//tags: cellEditor
|
|
@@ -224,7 +191,7 @@ export function propertiesWidget(sequence: DG.SemanticValue): DG.Widget {
|
|
|
224
191
|
return getPropertiesWidget(sequence);
|
|
225
192
|
}
|
|
226
193
|
|
|
227
|
-
function
|
|
194
|
+
function openWebEditor(cell: DG.Cell, value?: string, units?: string) {
|
|
228
195
|
const view = ui.div();
|
|
229
196
|
// const df = grok.shell.tv.grid.dataFrame;
|
|
230
197
|
// const col = df.columns.bySemType('Macromolecule')!;
|
|
@@ -273,30 +240,6 @@ function webEditor(cell: DG.Cell, value?: string, units?: string) {
|
|
|
273
240
|
}).show({modal: true, fullScreen: true});
|
|
274
241
|
}
|
|
275
242
|
|
|
276
|
-
function getRS(smiles: string) {
|
|
277
|
-
const newS = smiles.match(/(?<=\[)[^\][]*(?=])/gm);
|
|
278
|
-
const res: { [name: string]: string } = {};
|
|
279
|
-
let el = '';
|
|
280
|
-
let digit;
|
|
281
|
-
if (!!newS) {
|
|
282
|
-
for (let i = 0; i < newS.length; i++) {
|
|
283
|
-
if (newS[i] != null) {
|
|
284
|
-
if (/\d/.test(newS[i])) {
|
|
285
|
-
digit = newS[i][newS[i].length - 1];
|
|
286
|
-
newS[i] = newS[i].replace(/[0-9]/g, '');
|
|
287
|
-
for (let j = 0; j < newS[i].length; j++) {
|
|
288
|
-
if (newS[i][j] != ':')
|
|
289
|
-
el += newS[i][j];
|
|
290
|
-
}
|
|
291
|
-
res['R' + digit] = el;
|
|
292
|
-
el = '';
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
return res;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
243
|
//name: getMolfiles
|
|
301
244
|
//input: column col {semType: Macromolecule}
|
|
302
245
|
//output: column res
|
|
@@ -329,6 +272,9 @@ export async function getHelmHelper(): Promise<IHelmHelper> {
|
|
|
329
272
|
|
|
330
273
|
import {testEvent} from '@datagrok-libraries/utils/src/test';
|
|
331
274
|
import {CellRendererBackAsyncBase} from '@datagrok-libraries/bio/src/utils/cell-renderer-async-base';
|
|
275
|
+
import {RGROUP_CAP_GROUP_NAME, RGROUP_LABEL, SMILES} from './constants';
|
|
276
|
+
import {getRS} from './utils/dummy-monomer';
|
|
277
|
+
import {getMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
|
|
332
278
|
|
|
333
279
|
//name: measureCellRenderer
|
|
334
280
|
export async function measureCellRenderer(): Promise<void> {
|