@datagrok/helm 2.7.0 → 2.7.2
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 +8 -0
- package/dist/package-dojo.js +1 -1
- package/dist/package-dojo.js.map +1 -1
- 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/files/samples/HELM.csv +541 -0
- package/files/samples/HELM_50.csv +51 -0
- package/files/tests/filter_HELM.csv +5 -0
- package/package.json +4 -3
- package/src/package-test.ts +3 -0
- package/src/tests/helm-activity-cliffs.ts +77 -0
- package/src/tests/helm-substructure-filter.ts +163 -0
- package/src/tests/to-atomic-level-ui-non-linear.ts +96 -0
- package/src/tests/utils.ts +12 -0
- package/src/utils/helm-grid-cell-renderer.ts +15 -13
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
DBID,HELM,Activity,Cluster
|
|
2
|
+
DBID55,PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Aze.dV.E.N.dV.Phe_4Me}$$$$,2.1058521,1
|
|
3
|
+
DBID83,PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.meM.D-Chg.dV.E.N.D-Orn.D-aThr.Phe_4Me}$$$$,4.4416509,3
|
|
4
|
+
DBID02,PEPTIDE1{meI.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.D-Cit.N.D-Orn.D-aThr.Phe_4Me}$$$$,5.0234375,1
|
|
5
|
+
DBID05,PEPTIDE1{meI.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.Dsu.N.D-Orn.D-aThr.Phe_4Me}$$$$,5.0660219,2
|
|
6
|
+
DBID34,PEPTIDE1{meI.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.Tyr_tBu.N.D-Orn.D-aThr.Phe_4Me}$$$$,5.6578050,4
|
|
7
|
+
DBID02,PEPTIDE1{aHyp.Hcy.N.T.W.Q.Phe_4NH2.D-Tyr_Et.Tyr_ab-dehydroMe.dV.Cys_SEt.N.D-Orn.D-aThr.Phe_4Me}$$$$,7.9036875,3
|
|
8
|
+
DBID64,PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.E.N.A.D-aThr.Phe_4Me}$$$$,3.8863654,2
|
|
9
|
+
DBID75,PEPTIDE1{meI.hHis.Aca.N.T.Tyr_Me.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.E.N.dV.Phe_4Me}$$$$,4.6697459,2
|
|
10
|
+
DBID74,PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.A.dV.E.N.D-Orn.D-aThr.Phe_4Me}$$$$,2.7280300,4
|
|
11
|
+
DBID60,"PEPTIDE1{meI.Pip.dK.Thr_PO3H2.[L-hArg(Et,Et)].D-Tyr_Et.Tyr_ab-dehydroMe.dV.E.N.D-Orn.D-aThr.Phe_4Me}$$$$",4.4462886,2
|
|
12
|
+
DBID96,PEPTIDE1{meI.hHis.D-Hyp.N.T.dK.Thr_PO3H2.Trp_Ome.D-Tyr_Et.Tyr_ab-dehydroMe.dV.E.N.D-Orn.D-aThr.Phe_4Me}$$$$,4.3900189,4
|
|
13
|
+
DBID56,PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.E.N.Phe_3Cl.meK.Phe_4Me}$$$$,3.6875632,4
|
|
14
|
+
DBID65,PEPTIDE1{Gly_allyl.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.Thr_PO3H2.N.D-Orn.D-aThr.Phe_4Me}$$$$,6.1076937,1
|
|
15
|
+
DBID45,PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.E.N.Nle.D-aThr.Phe_4Me}$$$$,3.2512414,0
|
|
16
|
+
DBID13,PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.E.N.D-Orn.dF.Phe_4Me}$$$$,7.2294617,0
|
|
17
|
+
DBID94,PEPTIDE1{meI.hHis.Aca.N.T.D-Orn.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.E.N.pnG.Phe_4Me}$$$$,0.6217819,3
|
|
18
|
+
DBID79,PEPTIDE1{meI.Pip.dK.Thr_PO3H2.D-Thz.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.D-Thz.N.D-Orn.D-aThr.Phe_4Me}$$$$,4.4476070,1
|
|
19
|
+
DBID21,PEPTIDE1{meI.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.Nle.aIle.Phe_4Me}$$$$,4.9557114,1
|
|
20
|
+
DBID10,PEPTIDE1{meY.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.E.N.pnG.Phe_4Me}$$$$,1.3188239,1
|
|
21
|
+
DBID86,PEPTIDE1{meI.Aca.N.T.W.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.E.N.D-Orn.D-aThr.Phe_4Me}$$$$,7.6897125,2
|
|
22
|
+
DBID52,PEPTIDE1{meI.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.hHis.D-aThr.Phe_4Me}$$$$,4.0970631,2
|
|
23
|
+
DBID27,PEPTIDE1{meI.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.3Pal.D-aThr.Phe_4Me}$$$$,2.7782860,3
|
|
24
|
+
DBID98,PEPTIDE1{meI.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.Thr_PO3H2.D-aThr.Phe_4Me}$$$$,4.9825664,2
|
|
25
|
+
DBID94,PEPTIDE1{meI.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.D-Nle.Phe_4Me}$$$$,4.0829563,2
|
|
26
|
+
DBID86,PEPTIDE1{D-Nva.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.pnG.Phe_4Me}$$$$,2.7203233,3
|
|
27
|
+
DBID48,PEPTIDE1{meI.Thr_PO3H2.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Cys_SEt.N.Phe_3Cl.aIle.Phe_4Me}$$$$,0.7954721,1
|
|
28
|
+
DBID22,PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.seC.Tyr_ab-dehydroMe.meN.E.N.dV.Phe_4Me}$$$$,5.0775967,1
|
|
29
|
+
DBID54,PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.meN.E.N.3Pal.D-aThr.Phe_4Me}$$$$,4.1724143,3
|
|
30
|
+
DBID17,PEPTIDE1{D-Tic.Hcy.N.T.W.Q.Phe_4NH2.D-Tyr_Et.Tyr_ab-dehydroMe.dV.Cys_SEt.N.dV.Phe_4Me}$$$$,3.1429222,3
|
|
31
|
+
DBID76,PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.meN.E.N.dV.meF}$$$$,3.1327622,0
|
|
32
|
+
DBID20,PEPTIDE1{meI.Aca.N.T.Ser_PO3H2.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.pnG.Phe_4Me}$$$$,3.8640671,1
|
|
33
|
+
DBID01,PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.E.N.H.P.Phe_4Me}$$$$,4.1827374,3
|
|
34
|
+
DBID93,PEPTIDE1{Phe_4Sdihydroorotamido.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.pnG.Phe_4Me}$$$$,2.6165285,1
|
|
35
|
+
DBID89,PEPTIDE1{meI.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.D-Thz.Phe_4Me}$$$$,3.2189791,0
|
|
36
|
+
DBID30,PEPTIDE1{meI.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Met_O2.dV.E.N.H.D-aThr.Phe_4Me}$$$$,1.0362210,3
|
|
37
|
+
DBID07,PEPTIDE1{meI.Aca.N.T.D-1Nal.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.H.D-aThr.Phe_4Me}$$$$,3.8830254,4
|
|
38
|
+
DBID51,PEPTIDE1{meI.Aca.N.T.meV.Thr_PO3H2.Aca.D-Tyr_Et.Met_O2.D-Dap.Thr_PO3H2.N.H.D-aThr.Phe_4Me}$$$$,5.1701312,2
|
|
39
|
+
DBID95,PEPTIDE1{meI.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.pnG.Phe_4Br.Phe_4Me}$$$$,3.1820068,1
|
|
40
|
+
DBID47,PEPTIDE1{meI.Aca.N.T.dK.Q.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.dV.Phe_4Me}$$$$,4.4652672,1
|
|
41
|
+
DBID16,PEPTIDE1{meI.Aca.Q.T.W.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.dV.Phe_4Me}$$$$,2.8669512,4
|
|
42
|
+
DBID52,PEPTIDE1{meI.hHis.Hcy.Q.T.W.Q.Phe_4NH2.D-Tyr_Et.Tyr_ab-dehydroMe.dV.pnG.N.aMePhe.Phe_4Me}$$$$,3.2571971,1
|
|
43
|
+
DBID41,PEPTIDE1{meI.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.V.Phe_4Me}$$$$,4.4447875,0
|
|
44
|
+
DBID78,PEPTIDE1{meI.Aca.Aca.T.dK.Q.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.D-Dap.Thr_PO3H2.N.Thr_PO3H2.Phe_4Me}$$$$,2.4899697,4
|
|
45
|
+
DBID95,PEPTIDE1{meI.hHis.Aca.Q.T.W.Q.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.Cya.N.F.Phe_4Me}$$$$,0.3957288,4
|
|
46
|
+
DBID92,PEPTIDE1{meI.hHis.Aca.Q.T.W.Q.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.pnG.N.F.aIle.Phe_4Me}$$$$,2.9058776,3
|
|
47
|
+
DBID88,PEPTIDE1{meI.hHis.Hcy.Q.T.W.Q.Phe_4NH2.D-Tyr_Et.Tyr_ab-dehydroMe.dV.pnG.N.dV.Phe_4Me}$$$$,2.1254258,0
|
|
48
|
+
DBID10,PEPTIDE1{meI.Bux.Hcy.Q.T.W.Q.Phe_4NH2.D-Tyr_Et.Tyr_ab-dehydroMe.dV.Cys_SEt.N.Bmt.Phe_4Me}$$$$,1.7159123,0
|
|
49
|
+
DBID86,PEPTIDE1{D-Tyr_Et.hHis.Aca.Q.T.W.Q.Aca.D-Tyr_Et.Tyr_ab-dehydroMe.dV.E.N.dV.Phe_4Me}$$$$,1.5285099,0
|
|
50
|
+
DBID43,PEPTIDE1{meI.hHis.Hcy.Q.T.W.Q.Phe_4NH2.dP.Tyr_ab-dehydroMe.dV.E.N.Bmt.Phe_4Me}$$$$,3.9470999,3
|
|
51
|
+
DBID26,PEPTIDE1{meI.hHis.Hcy.Q.T.W.Q.Phe_4NH2.D-Tyr_Et.Tyr_ab-dehydroMe.dV.pnG.N.Bmt.Phe_4Me}$$$$,3.7495575,4
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datagrok/helm",
|
|
3
3
|
"friendlyName": "Helm",
|
|
4
|
-
"version": "2.7.
|
|
4
|
+
"version": "2.7.2",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Maria Dolotova",
|
|
7
7
|
"email": "mdolotova@datagrok.ai"
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"css/helm.css"
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@datagrok-libraries/bio": "^5.
|
|
19
|
+
"@datagrok-libraries/bio": "^5.48.2",
|
|
20
20
|
"@datagrok-libraries/chem-meta": "^1.2.7",
|
|
21
21
|
"cash-dom": "^8.1.1",
|
|
22
22
|
"@datagrok-libraries/utils": "^4.4.0",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@datagrok-libraries/helm-web-editor": "^1.1.13",
|
|
31
31
|
"@datagrok-libraries/js-draw-lite": "^0.0.10",
|
|
32
|
-
"@datagrok/bio": "
|
|
32
|
+
"@datagrok/bio": "^2.18.1",
|
|
33
33
|
"@datagrok/chem": "^1.13.0",
|
|
34
34
|
"@types/node": "17.0.45",
|
|
35
35
|
"@types/webpack-env": "^1.18.5",
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
},
|
|
51
51
|
"scripts": {
|
|
52
52
|
"link-all": "npm link @datagrok-libraries/chem-meta datagrok-api @datagrok-libraries/utils @datagrok-libraries/bio",
|
|
53
|
+
"link-bio": "npm link @datagrok-libraries/bio",
|
|
53
54
|
"debug-helm": "webpack && grok publish",
|
|
54
55
|
"release-helm": "webpack && grok publish --release",
|
|
55
56
|
"build-helm": "webpack",
|
package/src/package-test.ts
CHANGED
|
@@ -19,6 +19,9 @@ import './tests/parse-helm-tests';
|
|
|
19
19
|
import './tests/helm-web-editor-tests';
|
|
20
20
|
import './tests/helm-input-tests';
|
|
21
21
|
import './tests/helm-helper-tests';
|
|
22
|
+
import './tests/helm-substructure-filter';
|
|
23
|
+
import './tests/helm-activity-cliffs';
|
|
24
|
+
import './tests/to-atomic-level-ui-non-linear';
|
|
22
25
|
|
|
23
26
|
export const _package = new DG.Package();
|
|
24
27
|
export {tests};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import * as grok from 'datagrok-api/grok';
|
|
2
|
+
import * as DG from 'datagrok-api/dg';
|
|
3
|
+
|
|
4
|
+
import {after, before, category, test} from '@datagrok-libraries/utils/src/test';
|
|
5
|
+
|
|
6
|
+
import {BitArrayMetricsNames} from '@datagrok-libraries/ml/src/typed-metrics';
|
|
7
|
+
import {getMonomerLibHelper, IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
|
|
8
|
+
import {
|
|
9
|
+
getUserLibSettings, setUserLibSettings
|
|
10
|
+
} from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
|
|
11
|
+
import {UserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/types';
|
|
12
|
+
import {DimReductionMethods} from '@datagrok-libraries/ml/src/multi-column-dimensionality-reduction/types';
|
|
13
|
+
import {getHelmHelper, IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
|
|
14
|
+
import {expect} from '@datagrok-libraries/utils/src/test';
|
|
15
|
+
import {MmDistanceFunctionsNames} from '@datagrok-libraries/ml/src/macromolecule-distance-functions';
|
|
16
|
+
import {BitArrayMetrics} from '@datagrok-libraries/ml/src/typed-metrics';
|
|
17
|
+
import {BYPASS_LARGE_DATA_WARNING} from '@datagrok-libraries/ml/src/functionEditors/consts';
|
|
18
|
+
|
|
19
|
+
import {_package} from '../package-test';
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
category('activityCliffs', async () => {
|
|
23
|
+
let helmHelper: IHelmHelper;
|
|
24
|
+
let monomerLibHelper: IMonomerLibHelper;
|
|
25
|
+
/** Backup actual user's monomer libraries settings */
|
|
26
|
+
let userLibSettings: UserLibSettings;
|
|
27
|
+
const helmEncodingFunc = DG.Func.find({name: 'helmPreprocessingFunction', package: 'Bio'})[0];
|
|
28
|
+
before(async () => {
|
|
29
|
+
helmHelper = await getHelmHelper(); // init Helm package
|
|
30
|
+
monomerLibHelper = await getMonomerLibHelper();
|
|
31
|
+
userLibSettings = await getUserLibSettings();
|
|
32
|
+
|
|
33
|
+
// Test 'helm' requires default monomer library loaded
|
|
34
|
+
await monomerLibHelper.loadMonomerLibForTests();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
after(async () => {
|
|
38
|
+
// UserDataStorage.put() replaces existing data
|
|
39
|
+
await setUserLibSettings(userLibSettings);
|
|
40
|
+
await monomerLibHelper.loadMonomerLib(true); // load user settings libraries
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
test('Helm', async () => {
|
|
45
|
+
const df = await _package.files.readCsv('samples/HELM_50.csv');
|
|
46
|
+
const _view = grok.shell.addTableView(df);
|
|
47
|
+
|
|
48
|
+
await _testActivityCliffsOpen(df, DimReductionMethods.UMAP,
|
|
49
|
+
'HELM', 'Activity', 65, 20, BitArrayMetricsNames.Tanimoto, helmEncodingFunc);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
async function _testActivityCliffsOpen(df: DG.DataFrame, drMethod: DimReductionMethods,
|
|
55
|
+
seqColName: string, activityColName: string, similarityThr: number, tgtNumberCliffs: number,
|
|
56
|
+
similarityMetric: MmDistanceFunctionsNames | BitArrayMetrics, preprocessingFunction: DG.Func,
|
|
57
|
+
): Promise<void> {
|
|
58
|
+
await grok.data.detectSemanticTypes(df);
|
|
59
|
+
const scatterPlot = (await grok.functions.call('Bio:activityCliffs', {
|
|
60
|
+
table: df,
|
|
61
|
+
molecules: df.getCol(seqColName),
|
|
62
|
+
activities: df.getCol(activityColName),
|
|
63
|
+
similarity: similarityThr,
|
|
64
|
+
methodName: drMethod,
|
|
65
|
+
similarityMetric: similarityMetric,
|
|
66
|
+
preprocessingFunction: preprocessingFunction,
|
|
67
|
+
options: {[`${BYPASS_LARGE_DATA_WARNING}`]: true},
|
|
68
|
+
demo: false,
|
|
69
|
+
})) as DG.Viewer | undefined;
|
|
70
|
+
expect(scatterPlot != null, true);
|
|
71
|
+
|
|
72
|
+
const cliffsLink = Array.from(scatterPlot!.root.children).find((el) => {
|
|
73
|
+
const classList: string[] = el.className.split(' ');
|
|
74
|
+
return ['ui-btn', 'ui-btn-ok'].every((reqClassName) => classList.includes(reqClassName));
|
|
75
|
+
});
|
|
76
|
+
expect((cliffsLink as HTMLElement).innerText.toLowerCase(), `${tgtNumberCliffs} cliffs`);
|
|
77
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/* eslint-disable max-lines */
|
|
2
|
+
/* eslint-disable max-lines-per-function */
|
|
3
|
+
import * as grok from 'datagrok-api/grok';
|
|
4
|
+
import * as ui from 'datagrok-api/ui';
|
|
5
|
+
import * as DG from 'datagrok-api/dg';
|
|
6
|
+
|
|
7
|
+
import {after, before, category, test, expect, delay, testEvent} from '@datagrok-libraries/utils/src/test';
|
|
8
|
+
import {getMonomerLibHelper, IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
|
|
9
|
+
import {
|
|
10
|
+
getUserLibSettings, setUserLibSettings
|
|
11
|
+
} from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
|
|
12
|
+
import {UserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/types';
|
|
13
|
+
import {getSeqHelper, ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
14
|
+
|
|
15
|
+
import {awaitGrid, readDataframe} from './utils';
|
|
16
|
+
|
|
17
|
+
import {BioFilterProps, IBioFilter}
|
|
18
|
+
from '@datagrok-libraries/bio/src/substructure-filter/bio-substructure-filter-types';
|
|
19
|
+
|
|
20
|
+
import {_package} from '../package-test';
|
|
21
|
+
|
|
22
|
+
category('bio-substructure-filters', async () => {
|
|
23
|
+
let seqHelper: ISeqHelper;
|
|
24
|
+
let monomerLibHelper: IMonomerLibHelper;
|
|
25
|
+
/** Backup actual user's monomer libraries settings */
|
|
26
|
+
let userLibSettings: UserLibSettings;
|
|
27
|
+
|
|
28
|
+
before(async () => {
|
|
29
|
+
seqHelper = await getSeqHelper();
|
|
30
|
+
monomerLibHelper = await getMonomerLibHelper();
|
|
31
|
+
userLibSettings = await getUserLibSettings();
|
|
32
|
+
|
|
33
|
+
// Test 'helm' requires default monomer library loaded
|
|
34
|
+
await monomerLibHelper.loadMonomerLibForTests(); // load default libraries
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
after(async () => {
|
|
38
|
+
// UserDataStorage.put() replaces existing data
|
|
39
|
+
await setUserLibSettings(userLibSettings);
|
|
40
|
+
await monomerLibHelper.loadMonomerLib(true); // load user settings libraries
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
test('helm-dialog', async () => {
|
|
45
|
+
const logPrefix = 'Bio tests: substructureFilters/helm-dialog';
|
|
46
|
+
const df = await readDataframe('tests/filter_HELM.csv');
|
|
47
|
+
const view = grok.shell.addTableView(df);
|
|
48
|
+
await grok.data.detectSemanticTypes(df);
|
|
49
|
+
await df.meta.detectSemanticTypes();
|
|
50
|
+
|
|
51
|
+
_package.logger.debug(`${logPrefix}, filter attaching.`);
|
|
52
|
+
const filter = await grok.functions.call('Bio:bioSubstructureFilterTest');
|
|
53
|
+
filter.attach(df);
|
|
54
|
+
const dlg = ui.dialog('Test filters').add(filter.root).show(); // to waitForElementInDom
|
|
55
|
+
await filter.awaitRendered();
|
|
56
|
+
try {
|
|
57
|
+
const bf = filter.bioFilter as IBioFilter;
|
|
58
|
+
expect(filter.bioFilter !== null, true, 'bioFilter is not created');
|
|
59
|
+
|
|
60
|
+
// filter 1
|
|
61
|
+
_package.logger.debug(`${logPrefix}, filter 1 change awaiting...`);
|
|
62
|
+
await testEvent(df.onRowsFiltered, () => {}, () => {
|
|
63
|
+
bf.props = new BioFilterProps('PEPTIDE1{A.C}$$$$V2.0', undefined, _package.logger);
|
|
64
|
+
}, 20000);
|
|
65
|
+
_package.logger.debug(`${logPrefix}, filter 1 changed.`);
|
|
66
|
+
expect(filter.dataFrame!.filter.trueCount, 1);
|
|
67
|
+
expect(filter.dataFrame!.filter.toBinaryString(), '0001');
|
|
68
|
+
|
|
69
|
+
// filter 2
|
|
70
|
+
_package.logger.debug(`${logPrefix}, filter 2 change awaiting...`);
|
|
71
|
+
await testEvent(df.onRowsFiltered, () => {}, () => {
|
|
72
|
+
bf.props = new BioFilterProps('PEPTIDE1{C}$$$$V2.0', undefined, _package.logger);
|
|
73
|
+
}, 20000);
|
|
74
|
+
setTimeout(() => view.grid.invalidate(), 500);
|
|
75
|
+
await awaitGrid(view.grid);
|
|
76
|
+
await delay(1000);
|
|
77
|
+
_package.logger.debug(`${logPrefix}, filter 2 changed.`);
|
|
78
|
+
expect(filter.dataFrame!.filter.trueCount, 2);
|
|
79
|
+
expect(filter.dataFrame!.filter.toBinaryString(), '1001');
|
|
80
|
+
} finally {
|
|
81
|
+
dlg.close();
|
|
82
|
+
}
|
|
83
|
+
await filter.awaitRendered();
|
|
84
|
+
await delay(3000); //TODO: await for grid.onLookChanged
|
|
85
|
+
}, {});
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
// Generates unhandled exception accessing isFiltering before bioFilter created
|
|
89
|
+
test('helm-view', async () => {
|
|
90
|
+
const logPrefix = 'Bio tests: substructureFilters/helm-view';
|
|
91
|
+
const df = await readDataframe('tests/filter_HELM.csv');
|
|
92
|
+
const col = df.getCol('HELM string');
|
|
93
|
+
await grok.data.detectSemanticTypes(df);
|
|
94
|
+
const view = grok.shell.addTableView(df);
|
|
95
|
+
|
|
96
|
+
const fg = view.getFiltersGroup();
|
|
97
|
+
|
|
98
|
+
// await awaitCheck(() => fg.filters.length == 1, 'await filters.length == 1', 1000);
|
|
99
|
+
// const filter = fg.filters.filter((f) => f.columnName == col.name)[0] as BioSubstructureFilter;
|
|
100
|
+
await awaitGrid(view.grid);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
test('sync-helm', async () => {
|
|
105
|
+
const df = await _package.files.readCsv('tests/filter_HELM.csv');
|
|
106
|
+
await grok.data.detectSemanticTypes(df);
|
|
107
|
+
const view = grok.shell.addTableView(df);
|
|
108
|
+
|
|
109
|
+
const fSubStr: string = 'PEPTIDE1{A.C}$$$$V2.0';
|
|
110
|
+
const fTrueCount: number = 1;
|
|
111
|
+
|
|
112
|
+
const f1 = await createFilter('HELM string', df);
|
|
113
|
+
const f2 = await createFilter('HELM string', df);
|
|
114
|
+
const dlg = ui.dialog('Test filters').add(f1.root).add(f2.root).show(); // to waitForElementInDom
|
|
115
|
+
await Promise.all([f1.awaitRendered(), f2.awaitRendered()]);
|
|
116
|
+
try {
|
|
117
|
+
expect(!!f1.bioFilter, true);
|
|
118
|
+
expect(!!f2.bioFilter, true);
|
|
119
|
+
expect(f1.bioFilter!.type, 'HelmBioFilter');
|
|
120
|
+
expect(f2.bioFilter!.type, 'HelmBioFilter');
|
|
121
|
+
const bf1 = f1.bioFilter as IBioFilter;
|
|
122
|
+
const bf2 = f2.bioFilter as IBioFilter;
|
|
123
|
+
|
|
124
|
+
await testEvent(df.onRowsFiltered, () => {}, () => {
|
|
125
|
+
bf1.props = new BioFilterProps(fSubStr, undefined, _package.logger);
|
|
126
|
+
}, 60000, 'await onRowsFiltered'); // wait to load monomers
|
|
127
|
+
await awaitGrid(view.grid);
|
|
128
|
+
//debugger;
|
|
129
|
+
|
|
130
|
+
_package.logger.debug('Bio tests: substructureFilters/sync-helm, before changed event');
|
|
131
|
+
await delay(f1.debounceTime * 2);
|
|
132
|
+
_package.logger.debug('Bio tests: substructureFilters/sync-helm, after changed event');
|
|
133
|
+
expect(df.filter.trueCount, fTrueCount);
|
|
134
|
+
|
|
135
|
+
await f1.awaitRendered();
|
|
136
|
+
expect((bf2.props as BioFilterProps).substructure, fSubStr);
|
|
137
|
+
} finally {
|
|
138
|
+
f1.detach();
|
|
139
|
+
f2.detach();
|
|
140
|
+
dlg.close();
|
|
141
|
+
}
|
|
142
|
+
await Promise.all([f1.awaitRendered(), f2.awaitRendered()]);
|
|
143
|
+
await awaitGrid(view.grid);
|
|
144
|
+
await delay(3000); //TODO: await for grid.onLookChanged
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
async function createFilter(colName: string, df: DG.DataFrame): Promise<any> {
|
|
149
|
+
if (!df.columns.names().includes(colName)) {
|
|
150
|
+
throw new Error(`The column '${colName}' not found. ` +
|
|
151
|
+
`Available in data frame are ${JSON.stringify(df.columns.names())}`);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const filter = await grok.functions.call('Bio:bioSubstructureFilterTest');
|
|
155
|
+
filter.attach(df);
|
|
156
|
+
filter.applyState({columnName: colName});
|
|
157
|
+
filter.column = df.col(colName);
|
|
158
|
+
filter.columnName = colName;
|
|
159
|
+
//filter.tableName = df.name;
|
|
160
|
+
return filter;
|
|
161
|
+
};
|
|
162
|
+
} );
|
|
163
|
+
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import * as DG from 'datagrok-api/dg';
|
|
2
|
+
import * as grok from 'datagrok-api/grok';
|
|
3
|
+
|
|
4
|
+
import {after, before, category, expect, test} from '@datagrok-libraries/utils/src/test';
|
|
5
|
+
import {IMonomerLib} from '@datagrok-libraries/bio/src/types';
|
|
6
|
+
import {getMonomerLibHelper, IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
|
|
7
|
+
import {getUserLibSettings, setUserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
|
|
8
|
+
import {UserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/types';
|
|
9
|
+
|
|
10
|
+
import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
11
|
+
import {getRdKitModule} from '@datagrok-libraries/bio/src/chem/rdkit-module';
|
|
12
|
+
import {RDModule} from '@datagrok-libraries/chem-meta/src/rdkit-api';
|
|
13
|
+
|
|
14
|
+
type TestDataTargetType = { atomCount: number, bondCount: number };
|
|
15
|
+
type TestDataType = {
|
|
16
|
+
src: { seq: string, units: NOTATION },
|
|
17
|
+
tgt: TestDataTargetType,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
category('toAtomicLevel-ui', () => {
|
|
21
|
+
let monomerLibHelper: IMonomerLibHelper;
|
|
22
|
+
let userLibSettings: UserLibSettings;
|
|
23
|
+
let monomerLib: IMonomerLib;
|
|
24
|
+
let rdKitModule: RDModule;
|
|
25
|
+
|
|
26
|
+
before(async () => {
|
|
27
|
+
rdKitModule = await getRdKitModule();
|
|
28
|
+
monomerLibHelper = await getMonomerLibHelper();
|
|
29
|
+
userLibSettings = await getUserLibSettings();
|
|
30
|
+
|
|
31
|
+
// Test 'helm' requires default monomer library loaded
|
|
32
|
+
await monomerLibHelper.loadMonomerLibForTests(); // load default libraries
|
|
33
|
+
|
|
34
|
+
monomerLib = monomerLibHelper.getMonomerLib();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
after(async () => {
|
|
38
|
+
// UserDataStorage.put() replaces existing data
|
|
39
|
+
await setUserLibSettings(userLibSettings);
|
|
40
|
+
await monomerLibHelper.loadMonomerLib(true); // load user settings libraries
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const tests: { [testName: string]: TestDataType } = {
|
|
44
|
+
'fasta': {
|
|
45
|
+
src: {seq: 'MDYKETLLMPK', units: NOTATION.FASTA},
|
|
46
|
+
tgt: {atomCount: 94, bondCount: 95},
|
|
47
|
+
},
|
|
48
|
+
'fasta-with-gap': {
|
|
49
|
+
src: {seq: 'MD-YKETLLMPK', units: NOTATION.FASTA},
|
|
50
|
+
tgt: {atomCount: 94, bondCount: 95},
|
|
51
|
+
},
|
|
52
|
+
'helm': {
|
|
53
|
+
src: {seq: 'PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2}$$$$', units: NOTATION.HELM},
|
|
54
|
+
tgt: {atomCount: 68, bondCount: 68},
|
|
55
|
+
},
|
|
56
|
+
'helm-with-gap': {
|
|
57
|
+
src: {seq: 'PEPTIDE1{meI.hHis.*.Aca.N.T.dK.Thr_PO3H2}$$$$', units: NOTATION.HELM},
|
|
58
|
+
tgt: {atomCount: 68, bondCount: 68},
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const getDfAndSeqCol = async (testData: TestDataType): Promise<{df: DG.DataFrame, seqCol: DG.Column<string>}> => {
|
|
63
|
+
const seq = testData.src.seq;
|
|
64
|
+
const df = DG.DataFrame.fromColumns([DG.Column.fromList(DG.COLUMN_TYPE.STRING, 'seq', [seq])]);
|
|
65
|
+
await grok.data.detectSemanticTypes(df);
|
|
66
|
+
return {df: df, seqCol: df.getCol('seq')};
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
for (const [testName, testData] of Object.entries(tests)) {
|
|
70
|
+
test(`${testName}-nonlinear`, async () => {
|
|
71
|
+
const res = await getDfAndSeqCol(testData);
|
|
72
|
+
await _testToAtomicLevelFunc(res.df, res.seqCol, true, testData.tgt);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async function _testToAtomicLevelFunc(
|
|
77
|
+
df: DG.DataFrame, seqCol: DG.Column<string>, nonlinear: boolean, tgt: TestDataTargetType,
|
|
78
|
+
): Promise<void> {
|
|
79
|
+
await grok.functions.call('Bio:toAtomicLevel', {
|
|
80
|
+
table: df, seqCol: seqCol, nonlinear: true, highlight: false
|
|
81
|
+
});
|
|
82
|
+
const molCol = df.col('molfile(seq)');
|
|
83
|
+
expect(molCol?.semType, DG.SEMTYPE.MOLECULE);
|
|
84
|
+
const resMolStr = molCol?.get(0)!;
|
|
85
|
+
const resRdMol = rdKitModule.get_mol(resMolStr);
|
|
86
|
+
expect(resRdMol != null, true, 'No molecule generated');
|
|
87
|
+
try {
|
|
88
|
+
const resAtomCount = resRdMol.get_num_atoms();
|
|
89
|
+
const resBondCount = resRdMol.get_num_bonds();
|
|
90
|
+
expect(resAtomCount, tgt.atomCount);
|
|
91
|
+
expect(resBondCount, tgt.bondCount);
|
|
92
|
+
} finally {
|
|
93
|
+
resRdMol.delete();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
});
|
package/src/tests/utils.ts
CHANGED
|
@@ -4,6 +4,7 @@ import * as DG from 'datagrok-api/dg';
|
|
|
4
4
|
|
|
5
5
|
import {delay, testEvent} from '@datagrok-libraries/utils/src/test';
|
|
6
6
|
import {getHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
|
|
7
|
+
import {_package} from '../package-test';
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
export async function initHelmMainPackage(): Promise<void> {
|
|
@@ -15,3 +16,14 @@ export async function awaitGrid(grid: DG.Grid, timeout: number = 5000): Promise<
|
|
|
15
16
|
await testEvent(grid.onAfterDrawContent, () => {},
|
|
16
17
|
() => { grid.invalidate(); }, timeout);
|
|
17
18
|
}
|
|
19
|
+
|
|
20
|
+
export async function readDataframe(tableName: string): Promise<DG.DataFrame> {
|
|
21
|
+
const file = await loadFileAsText(tableName);
|
|
22
|
+
const df = DG.DataFrame.fromCsv(file);
|
|
23
|
+
df.name = tableName.replace('.csv', '');
|
|
24
|
+
return df;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export async function loadFileAsText(name: string): Promise<string> {
|
|
28
|
+
return await _package.files.readAsText(name);
|
|
29
|
+
}
|
|
@@ -23,7 +23,7 @@ import {getHoveredMonomerFromEditorMol, getSeqMonomerFromHelmAtom} from './get-h
|
|
|
23
23
|
import {_package, getHelmService} from '../package';
|
|
24
24
|
|
|
25
25
|
export class HelmGridCellRendererBack extends CellRendererBackAsyncBase<HelmProps, HelmAux> {
|
|
26
|
-
private _auxList:
|
|
26
|
+
private _auxList: Map<string, HelmAux | null>;
|
|
27
27
|
|
|
28
28
|
private sysMonomerLib: IMonomerLibBase | null = null;
|
|
29
29
|
private helmHelper: IHelmHelper | null = null;
|
|
@@ -70,7 +70,7 @@ export class HelmGridCellRendererBack extends CellRendererBackAsyncBase<HelmProp
|
|
|
70
70
|
const logPrefix = `${this.toLog()}.reset()`;
|
|
71
71
|
this.logger.debug(`${logPrefix}, start`);
|
|
72
72
|
super.reset();
|
|
73
|
-
this._auxList = new
|
|
73
|
+
this._auxList = new Map<string, HelmAux | null>();
|
|
74
74
|
this.invalidateGrid();
|
|
75
75
|
this.logger.debug(`${logPrefix}, end`);
|
|
76
76
|
}
|
|
@@ -89,8 +89,8 @@ export class HelmGridCellRendererBack extends CellRendererBackAsyncBase<HelmProp
|
|
|
89
89
|
protected override storeAux(gridCell: DG.GridCell, aux: HelmAux): void {
|
|
90
90
|
const logPrefix = `${this.toLog()}.storeAux()`;
|
|
91
91
|
this.logger.debug(`${logPrefix}, start`);
|
|
92
|
-
if (gridCell.
|
|
93
|
-
this._auxList
|
|
92
|
+
if (!!gridCell.cell?.value)
|
|
93
|
+
this._auxList.set(gridCell.cell.value, aux);
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
/** Renders cell from image data (cache), returns true to update the cell by service.
|
|
@@ -104,9 +104,11 @@ export class HelmGridCellRendererBack extends CellRendererBackAsyncBase<HelmProp
|
|
|
104
104
|
|
|
105
105
|
const gcb = gridCellBounds;
|
|
106
106
|
const dpr = window.devicePixelRatio;
|
|
107
|
-
if (gridCell.
|
|
108
|
-
|
|
109
|
-
|
|
107
|
+
if (!gridCell.cell?.value)
|
|
108
|
+
return false;
|
|
109
|
+
const aux = this._auxList.get(gridCell.cell.value);
|
|
110
|
+
if (!aux)
|
|
111
|
+
return true;
|
|
110
112
|
|
|
111
113
|
const [cellWidth, cellHeight] = [gcb.width * dpr - 2, gcb.height * dpr - 2];
|
|
112
114
|
const cellDScale = Math.min(0.95 * cellWidth / aux.dBox.width, 0.95 * cellHeight / aux.dBox.height);
|
|
@@ -158,8 +160,8 @@ export class HelmGridCellRendererBack extends CellRendererBackAsyncBase<HelmProp
|
|
|
158
160
|
}
|
|
159
161
|
|
|
160
162
|
onMouseMove(gridCell: DG.GridCell, e: MouseEvent): void {
|
|
161
|
-
if (gridCell.
|
|
162
|
-
const aux = this._auxList
|
|
163
|
+
if (!gridCell.cell?.value || !this._auxList || !!e.buttons) return;
|
|
164
|
+
const aux = this._auxList.get(gridCell.cell.value);
|
|
163
165
|
if (!aux) return;
|
|
164
166
|
|
|
165
167
|
const logPrefix = `${this.toLog()}.onMouseMove()`;
|
|
@@ -192,8 +194,11 @@ export class HelmGridCellRendererBack extends CellRendererBackAsyncBase<HelmProp
|
|
|
192
194
|
// Tooltip for missing monomers
|
|
193
195
|
ui.tooltip.hide();
|
|
194
196
|
}
|
|
195
|
-
|
|
196
197
|
execMonomerHoverLinks(gridCell, seqMonomer);
|
|
198
|
+
|
|
199
|
+
e.preventDefault();
|
|
200
|
+
e.stopPropagation();
|
|
201
|
+
|
|
197
202
|
}
|
|
198
203
|
|
|
199
204
|
onMouseLeave(gridCell: DG.GridCell, e: MouseEvent): void {
|
|
@@ -237,9 +242,6 @@ export class HelmGridCellRenderer extends DG.GridCellRenderer {
|
|
|
237
242
|
} catch (err: any) {
|
|
238
243
|
const [errMsg, errStack] = errInfo(err);
|
|
239
244
|
_package.logger.error(errMsg, undefined, errStack);
|
|
240
|
-
} finally {
|
|
241
|
-
e.preventDefault();
|
|
242
|
-
e.stopPropagation();
|
|
243
245
|
}
|
|
244
246
|
}
|
|
245
247
|
|