@datagrok/bio 2.12.16 → 2.12.18
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 +20 -2
- package/dist/79.js.map +1 -1
- package/dist/package-test.js +5 -5
- package/dist/package-test.js.map +1 -1
- package/dist/package.js +3 -3
- package/dist/package.js.map +1 -1
- package/package.json +6 -6
- package/src/package-test.ts +1 -1
- package/src/package.ts +38 -44
- package/src/tests/monomer-libraries-tests.ts +1 -4
- package/src/tests/renderers-monomer-placer-tests.ts +9 -8
- package/src/tests/renderers-test.ts +1 -1
- package/src/tests/scoring.ts +2 -2
- package/src/tests/substructure-filters-tests.ts +4 -2
- package/src/tests/to-atomic-level-tests.ts +1 -1
- package/src/tests/utils.ts +15 -0
- package/src/utils/cell-renderer.ts +45 -70
- package/src/utils/{poly-tool/cyclized.ts → cyclized.ts} +3 -7
- package/src/utils/helm-to-molfile/converter/converter.ts +10 -5
- package/src/utils/helm-to-molfile/converter/monomer-wrapper.ts +9 -9
- package/src/utils/helm-to-molfile/converter/polymer.ts +10 -3
- package/src/utils/monomer-cell-renderer.ts +18 -8
- package/src/utils/monomer-lib/lib-manager.ts +56 -18
- package/src/utils/monomer-lib/library-file-manager/event-manager.ts +15 -9
- package/src/utils/monomer-lib/library-file-manager/file-manager.ts +78 -59
- package/src/utils/monomer-lib/library-file-manager/file-validator.ts +3 -1
- package/src/utils/monomer-lib/library-file-manager/ui.ts +52 -47
- package/src/utils/monomer-lib/monomer-lib.ts +91 -10
- package/src/utils/sequence-to-mol.ts +7 -7
- package/src/widgets/bio-substructure-filter-helm.ts +5 -4
- package/src/widgets/bio-substructure-filter.ts +2 -3
- package/webpack.config.js +3 -0
- package/src/utils/poly-tool/const.ts +0 -40
- package/src/utils/poly-tool/csv-to-json-monomer-lib-converter.ts +0 -40
- package/src/utils/poly-tool/monomer-lib-handler.ts +0 -115
- package/src/utils/poly-tool/transformation.ts +0 -320
- package/src/utils/poly-tool/ui.ts +0 -59
- package/src/utils/poly-tool/utils.ts +0 -20
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.
|
|
8
|
+
"version": "2.12.18",
|
|
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.
|
|
37
|
+
"@datagrok-libraries/bio": "^5.41.2",
|
|
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.
|
|
42
|
+
"@datagrok-libraries/utils": "^4.2.5",
|
|
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.
|
|
59
|
-
"@datagrok/dendrogram": "^1.2.
|
|
60
|
-
"@datagrok/helm": "^2.1.
|
|
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-test.ts
CHANGED
|
@@ -23,7 +23,7 @@ import './tests/WebLogo-project-tests';
|
|
|
23
23
|
import './tests/WebLogo-layout-tests';
|
|
24
24
|
import './tests/checkInputColumn-tests';
|
|
25
25
|
import './tests/similarity-diversity-tests';
|
|
26
|
-
import './tests/substructure-filters-tests';
|
|
26
|
+
// import './tests/substructure-filters-tests';
|
|
27
27
|
import './tests/pepsea-tests';
|
|
28
28
|
import './tests/viewers';
|
|
29
29
|
import './tests/seq-handler-tests';
|
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/
|
|
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
|
|
|
@@ -87,8 +86,8 @@ export const _package = new BioPackage();
|
|
|
87
86
|
//name: getMonomerLibHelper
|
|
88
87
|
//description:
|
|
89
88
|
//output: object result
|
|
90
|
-
export function getMonomerLibHelper(): IMonomerLibHelper {
|
|
91
|
-
return MonomerLibManager.
|
|
89
|
+
export async function getMonomerLibHelper(): Promise<IMonomerLibHelper> {
|
|
90
|
+
return await MonomerLibManager.getInstance();
|
|
92
91
|
}
|
|
93
92
|
|
|
94
93
|
export let hydrophobPalette: SeqPaletteCustom | null = null;
|
|
@@ -105,12 +104,20 @@ export class SeqPaletteCustom implements SeqPalette {
|
|
|
105
104
|
}
|
|
106
105
|
}
|
|
107
106
|
|
|
107
|
+
let monomerLib: IMonomerLib | null = null;
|
|
108
|
+
|
|
108
109
|
//tags: init
|
|
109
110
|
export async function initBio() {
|
|
110
|
-
|
|
111
|
+
const logPrefix = 'Bio: initBio()';
|
|
112
|
+
_package.logger.debug(`${logPrefix}, start`);
|
|
111
113
|
const module = await grok.functions.call('Chem:getRdKitModule');
|
|
114
|
+
const t1: number = window.performance.now();
|
|
112
115
|
await Promise.all([
|
|
113
|
-
(async () => {
|
|
116
|
+
(async () => {
|
|
117
|
+
const monomerLibManager = await MonomerLibManager.getInstance();
|
|
118
|
+
await monomerLibManager.loadLibraries();
|
|
119
|
+
monomerLib = monomerLibManager.getBioLib();
|
|
120
|
+
})(),
|
|
114
121
|
(async () => {
|
|
115
122
|
const pkgProps = await _package.getProperties();
|
|
116
123
|
const bioPkgProps = new BioPackageProperties(pkgProps);
|
|
@@ -118,9 +125,10 @@ export async function initBio() {
|
|
|
118
125
|
})(),
|
|
119
126
|
]).finally(() => {
|
|
120
127
|
_package.completeInit();
|
|
128
|
+
const t2: number = window.performance.now();
|
|
129
|
+
_package.logger.debug(`${logPrefix}, loading ET: ${t2 - t1} ms`);
|
|
121
130
|
});
|
|
122
131
|
|
|
123
|
-
const monomerLib = MonomerLibManager.instance.getBioLib();
|
|
124
132
|
const monomers: string[] = [];
|
|
125
133
|
const logPs: number[] = [];
|
|
126
134
|
|
|
@@ -160,10 +168,16 @@ export function sequenceTooltip(col: DG.Column): DG.Widget<any> {
|
|
|
160
168
|
return resWidget;
|
|
161
169
|
}
|
|
162
170
|
|
|
171
|
+
// Keep for backward compatibility
|
|
163
172
|
//name: getBioLib
|
|
164
173
|
//output: object monomerLib
|
|
165
174
|
export function getBioLib(): IMonomerLib {
|
|
166
|
-
return
|
|
175
|
+
return monomerLib!;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// For sync internal use, on initialized package
|
|
179
|
+
export function getMonomerLib(): IMonomerLib | null {
|
|
180
|
+
return monomerLib!;
|
|
167
181
|
}
|
|
168
182
|
|
|
169
183
|
//name: getSeqHandler
|
|
@@ -572,7 +586,8 @@ export async function sequenceSpaceTopMenu(table: DG.DataFrame, molecules: DG.Co
|
|
|
572
586
|
export async function toAtomicLevel(table: DG.DataFrame, seqCol: DG.Column, nonlinear: boolean): Promise<void> {
|
|
573
587
|
const pi = DG.TaskBarProgressIndicator.create('Converting to atomic level ...');
|
|
574
588
|
try {
|
|
575
|
-
await
|
|
589
|
+
const monomerLib = (await getMonomerLibHelper()).getBioLib();
|
|
590
|
+
await sequenceToMolfile(table, seqCol, nonlinear, monomerLib);
|
|
576
591
|
} finally {
|
|
577
592
|
pi.close();
|
|
578
593
|
}
|
|
@@ -685,19 +700,6 @@ export function convertDialog() {
|
|
|
685
700
|
convert(col);
|
|
686
701
|
}
|
|
687
702
|
|
|
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
703
|
//name: monomerCellRenderer
|
|
702
704
|
//tags: cellRenderer
|
|
703
705
|
//meta.cellType: Monomer
|
|
@@ -1010,25 +1012,6 @@ export async function demoBioHelmMsaSequenceSpace(): Promise<void> {
|
|
|
1010
1012
|
await demoBio05UI();
|
|
1011
1013
|
}
|
|
1012
1014
|
|
|
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
1015
|
//name: SDF to JSON Library
|
|
1033
1016
|
//input: dataframe table
|
|
1034
1017
|
export async function sdfToJsonLib(table: DG.DataFrame) {
|
|
@@ -1048,6 +1031,17 @@ export async function detectMacromoleculeProbe(file: DG.FileInfo, colName: strin
|
|
|
1048
1031
|
await detectMacromoleculeProbeDo(csv, colName, probeCount);
|
|
1049
1032
|
}
|
|
1050
1033
|
|
|
1034
|
+
//name: getMolFromHelm
|
|
1035
|
+
//input: dataframe df
|
|
1036
|
+
//input: column helmCol
|
|
1037
|
+
//input: bool chiralityEngine
|
|
1038
|
+
//output: column result
|
|
1039
|
+
export async function getMolFromHelm(
|
|
1040
|
+
df: DG.DataFrame, helmCol: DG.Column<string>, chiralityEngine?: boolean
|
|
1041
|
+
): Promise<DG.Column<string>> {
|
|
1042
|
+
return getMolColumnFromHelm(df, helmCol, chiralityEngine);
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1051
1045
|
// -- Custom notation providers --
|
|
1052
1046
|
|
|
1053
1047
|
//name: applyNotationProviderForCyclized
|
|
@@ -8,8 +8,6 @@ import {getMonomerLibHelper, IMonomerLibHelper} from '@datagrok-libraries/bio/sr
|
|
|
8
8
|
import {
|
|
9
9
|
getUserLibSettings, setUserLibSettings, setUserLibSettingsForTests
|
|
10
10
|
} from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
|
|
11
|
-
import {MonomerLibFileManager} from '../utils/monomer-lib/library-file-manager/file-manager';
|
|
12
|
-
import {MonomerLibFileEventManager} from '../utils/monomer-lib/library-file-manager/event-manager';
|
|
13
11
|
|
|
14
12
|
|
|
15
13
|
category('monomerLibraries', () => {
|
|
@@ -51,8 +49,7 @@ category('monomerLibraries', () => {
|
|
|
51
49
|
test('empty', async () => {
|
|
52
50
|
// exclude all monomer libraries for empty set
|
|
53
51
|
const libSettings = await getUserLibSettings();
|
|
54
|
-
const
|
|
55
|
-
const libFileManager = await MonomerLibFileManager.getInstance(libFileEventManager);
|
|
52
|
+
const libFileManager = await monomerLibHelper.getFileManager();
|
|
56
53
|
|
|
57
54
|
let libFnList = libFileManager.getValidLibraryPaths();
|
|
58
55
|
if (libFnList.length === 0)
|
|
@@ -8,8 +8,7 @@ import {category, test} from '@datagrok-libraries/utils/src/test';
|
|
|
8
8
|
import {MonomerPlacer} from '@datagrok-libraries/bio/src/utils/cell-renderer-monomer-placer';
|
|
9
9
|
import {monomerToShort} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
10
10
|
import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
|
|
11
|
-
|
|
12
|
-
import {MonomerLibManager} from '../utils/monomer-lib/lib-manager';
|
|
11
|
+
import {getMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
|
|
13
12
|
|
|
14
13
|
import {_package} from '../package-test';
|
|
15
14
|
|
|
@@ -45,7 +44,7 @@ category('renderers: monomerPlacer', () => {
|
|
|
45
44
|
'id1,m1-M-m3-mon4-mon5-N-T-MON8-N9\n' +
|
|
46
45
|
'id2,m1-mon2-m3-mon4-mon5-Num--MON8-N9\n' +
|
|
47
46
|
'id3,\n' + // empty
|
|
48
|
-
'id4,mon1-M-mon3-mon4-mon5---MON8-N9\n',
|
|
47
|
+
'id4,mon1-M-mon3-mon4-mon5---MON8-N9\n', // [ 5, 38, 71, 104, 137, 170, 203, 236, 269, 295 ]
|
|
49
48
|
testList: [
|
|
50
49
|
{src: {row: 0, x: -1}, tgt: {pos: null}},
|
|
51
50
|
{src: {row: 1, x: 0}, tgt: {pos: null}},
|
|
@@ -59,7 +58,7 @@ category('renderers: monomerPlacer', () => {
|
|
|
59
58
|
{src: {row: 2, x: 20}, tgt: {pos: null}}, // empty value
|
|
60
59
|
{src: {row: 3, x: 170}, tgt: {pos: 4}},
|
|
61
60
|
{src: {row: 3, x: 200}, tgt: {pos: 5}},
|
|
62
|
-
{src: {row: 3, x:
|
|
61
|
+
{src: {row: 3, x: 297}, tgt: {pos: null}},
|
|
63
62
|
]
|
|
64
63
|
},
|
|
65
64
|
fastaMsa: {
|
|
@@ -88,6 +87,8 @@ id3,QHIRE--LT
|
|
|
88
87
|
|
|
89
88
|
for (const [testName, testData] of Object.entries(tests)) {
|
|
90
89
|
test(`getPosition-${testName}`, async () => {
|
|
90
|
+
const libHelper = await getMonomerLibHelper();
|
|
91
|
+
const monomerLib = libHelper.getBioLib();
|
|
91
92
|
const df: DG.DataFrame = DG.DataFrame.fromCsv(testData.csv);
|
|
92
93
|
await grok.data.detectSemanticTypes(df);
|
|
93
94
|
const seqCol: DG.Column = df.getCol('seq');
|
|
@@ -95,7 +96,7 @@ id3,QHIRE--LT
|
|
|
95
96
|
const monLength: number = 3;
|
|
96
97
|
const charWidth: number = 7;
|
|
97
98
|
const sepWidth: number = 12;
|
|
98
|
-
const colTemp: MonomerPlacer = new MonomerPlacer(null, seqCol, () => {
|
|
99
|
+
const colTemp: MonomerPlacer = new MonomerPlacer(null, seqCol, _package.logger, () => {
|
|
99
100
|
const sh = SeqHandler.forColumn(seqCol);
|
|
100
101
|
return {
|
|
101
102
|
seqHandler: sh,
|
|
@@ -103,18 +104,18 @@ id3,QHIRE--LT
|
|
|
103
104
|
separatorWidth: sepWidth,
|
|
104
105
|
monomerToShort: monomerToShort,
|
|
105
106
|
monomerLengthLimit: monLength,
|
|
106
|
-
monomerLib: MonomerLibManager.instance.getBioLib(),
|
|
107
107
|
};
|
|
108
108
|
});
|
|
109
109
|
|
|
110
|
+
const width: number = 10000;
|
|
110
111
|
const testList = testData.testList;
|
|
111
112
|
// simulate rendering
|
|
112
113
|
for (let rowI: number = 0; rowI < seqCol.length; ++rowI)
|
|
113
|
-
colTemp.getCellMonomerLengths(rowI);
|
|
114
|
+
colTemp.getCellMonomerLengths(rowI, 10000);
|
|
114
115
|
|
|
115
116
|
const errorList: string[] = [];
|
|
116
117
|
for (const [test, _testI] of wu.enumerate(testList)) {
|
|
117
|
-
const res = {pos: colTemp.getPosition(test.src.row, test.src.x)};
|
|
118
|
+
const res = {pos: colTemp.getPosition(test.src.row, test.src.x, width)};
|
|
118
119
|
if (test.tgt.pos != res.pos) {
|
|
119
120
|
errorList.push(`Test src ${JSON.stringify(test.src)} expected tgt ${JSON.stringify(test.tgt)},` +
|
|
120
121
|
` but get ${JSON.stringify({res})}`);
|
|
@@ -56,7 +56,7 @@ category('renderers', () => {
|
|
|
56
56
|
|
|
57
57
|
test('scatterPlotTooltip', async () => {
|
|
58
58
|
await _testScatterPlotTooltip();
|
|
59
|
-
});
|
|
59
|
+
}, {skipReason: 'GROK-15679'});
|
|
60
60
|
|
|
61
61
|
async function _rendererMacromoleculeFasta() {
|
|
62
62
|
const csv: string = await grok.dapi.files.readAsText('System:AppData/Bio/samples/FASTA.csv');
|
package/src/tests/scoring.ts
CHANGED
|
@@ -4,9 +4,9 @@ import * as DG from 'datagrok-api/dg';
|
|
|
4
4
|
|
|
5
5
|
import {category, test, expectFloat, before, after} from '@datagrok-libraries/utils/src/test';
|
|
6
6
|
import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
7
|
-
import {
|
|
7
|
+
import {IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
|
|
8
8
|
|
|
9
|
-
import {sequenceIdentityScoring, sequenceSimilarityScoring} from '../package';
|
|
9
|
+
import {getMonomerLibHelper, sequenceIdentityScoring, sequenceSimilarityScoring} from '../package';
|
|
10
10
|
import {
|
|
11
11
|
getUserLibSettings, setUserLibSettings, setUserLibSettingsForTests
|
|
12
12
|
} from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
|
|
@@ -185,7 +185,8 @@ category('bio-substructure-filters', async () => {
|
|
|
185
185
|
dlg.close();
|
|
186
186
|
}
|
|
187
187
|
await filter.awaitRendered();
|
|
188
|
-
|
|
188
|
+
await delay(3000); //TODO: await for grid.onLookChanged
|
|
189
|
+
}, {skipReason: 'GROK-15678'});
|
|
189
190
|
|
|
190
191
|
// Generates unhandled exception accessing isFiltering before bioFilter created
|
|
191
192
|
test('helm-view', async () => {
|
|
@@ -308,7 +309,8 @@ category('bio-substructure-filters', async () => {
|
|
|
308
309
|
}
|
|
309
310
|
await Promise.all([f1.awaitRendered(), f2.awaitRendered()]);
|
|
310
311
|
await awaitGrid(view.grid);
|
|
311
|
-
|
|
312
|
+
await delay(3000); //TODO: await for grid.onLookChanged
|
|
313
|
+
}, {skipReason: 'GROK-15678'});
|
|
312
314
|
|
|
313
315
|
// two seq columns
|
|
314
316
|
|
|
@@ -7,7 +7,7 @@ import wu from 'wu';
|
|
|
7
7
|
|
|
8
8
|
import {before, after, category, test, expectArray, expect} from '@datagrok-libraries/utils/src/test';
|
|
9
9
|
import {_toAtomicLevel} from '@datagrok-libraries/bio/src/monomer-works/to-atomic-level';
|
|
10
|
-
import {IMonomerLib} from '@datagrok-libraries/bio/src/types
|
|
10
|
+
import {IMonomerLib} from '@datagrok-libraries/bio/src/types';
|
|
11
11
|
import {ALPHABET, NOTATION, TAGS as bioTAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
12
12
|
import {getMonomerLibHelper, IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
|
|
13
13
|
import {
|
package/src/tests/utils.ts
CHANGED
|
@@ -2,10 +2,12 @@ import * as DG from 'datagrok-api/dg';
|
|
|
2
2
|
import * as grok from 'datagrok-api/grok';
|
|
3
3
|
|
|
4
4
|
import {delay, expect, testEvent} from '@datagrok-libraries/utils/src/test';
|
|
5
|
+
import {asRenderer, IRenderer, isRenderer} from '@datagrok-libraries/bio/src/types/renderer';
|
|
5
6
|
|
|
6
7
|
import {startDockerContainer} from '../utils/docker';
|
|
7
8
|
|
|
8
9
|
import {_package} from '../package-test';
|
|
10
|
+
import {CellRendererBackBase, getGridCellRendererBack} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
|
|
9
11
|
|
|
10
12
|
export async function loadFileAsText(name: string): Promise<string> {
|
|
11
13
|
return await _package.files.readAsText(name);
|
|
@@ -38,4 +40,17 @@ export async function awaitGrid(grid: DG.Grid, timeout: number = 5000): Promise<
|
|
|
38
40
|
await delay(0);
|
|
39
41
|
await testEvent(grid.onAfterDrawContent, () => {},
|
|
40
42
|
() => { grid.invalidate(); }, timeout);
|
|
43
|
+
|
|
44
|
+
const colCount = grid.columns.length;
|
|
45
|
+
for (let colI = 0; colI < colCount; ++colI) {
|
|
46
|
+
const gridCol = grid.columns.byIndex(colI);
|
|
47
|
+
if (gridCol) {
|
|
48
|
+
const gridCell = grid.cell(gridCol.name, 0);
|
|
49
|
+
const [_gridCol, _tableCol, temp] =
|
|
50
|
+
getGridCellRendererBack<void, CellRendererBackBase<void>>(gridCell);
|
|
51
|
+
|
|
52
|
+
const renderer = asRenderer(temp.rendererBack);
|
|
53
|
+
if (renderer) await renderer.awaitRendered();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
41
56
|
}
|
|
@@ -3,7 +3,6 @@ import * as DG from 'datagrok-api/dg';
|
|
|
3
3
|
import * as ui from 'datagrok-api/ui';
|
|
4
4
|
|
|
5
5
|
import wu from 'wu';
|
|
6
|
-
import {Unsubscribable} from 'rxjs';
|
|
7
6
|
|
|
8
7
|
import {printLeftOrCentered, DrawStyle, TAGS as mmcrTAGS} from '@datagrok-libraries/bio/src/utils/cell-renderer';
|
|
9
8
|
import {MonomerPlacer} from '@datagrok-libraries/bio/src/utils/cell-renderer-monomer-placer';
|
|
@@ -22,7 +21,8 @@ import {GapOriginals, SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-ha
|
|
|
22
21
|
import {ISeqSplitted, SeqSplittedBase} from '@datagrok-libraries/bio/src/utils/macromolecule/types';
|
|
23
22
|
import {getSplitter} from '@datagrok-libraries/bio/src/utils/macromolecule/utils';
|
|
24
23
|
import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
|
|
25
|
-
import {alphabetPolymerTypes, IMonomerLib} from '@datagrok-libraries/bio/src/types
|
|
24
|
+
import {alphabetPolymerTypes, IMonomerLib} from '@datagrok-libraries/bio/src/types';
|
|
25
|
+
import {getGridCellRendererBack} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
|
|
26
26
|
|
|
27
27
|
import {
|
|
28
28
|
Temps as mmcrTemps, Tags as mmcrTags,
|
|
@@ -30,14 +30,16 @@ import {
|
|
|
30
30
|
} from '../utils/cell-renderer-consts';
|
|
31
31
|
import * as C from './constants';
|
|
32
32
|
|
|
33
|
-
import {_package,
|
|
33
|
+
import {_package, getMonomerLib} from '../package';
|
|
34
34
|
|
|
35
35
|
type TempType = { [tagName: string]: any };
|
|
36
36
|
|
|
37
37
|
const undefinedColor = 'rgb(100,100,100)';
|
|
38
38
|
const monomerToShortFunction: MonomerToShortFunc = monomerToShort;
|
|
39
39
|
|
|
40
|
-
function getUpdatedWidth(
|
|
40
|
+
function getUpdatedWidth(
|
|
41
|
+
grid: DG.Grid | null | undefined, g: CanvasRenderingContext2D, x: number, w: number, dpr: number
|
|
42
|
+
): number {
|
|
41
43
|
return !!grid ? Math.max(Math.min(grid.canvas.width / dpr - x, w)) : Math.max(g.canvas.width / dpr - x, 0);
|
|
42
44
|
}
|
|
43
45
|
|
|
@@ -63,27 +65,6 @@ type RendererGridCellTemp = {
|
|
|
63
65
|
[mmcrTemps.monomerPlacer]: MonomerPlacer
|
|
64
66
|
}
|
|
65
67
|
|
|
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
68
|
export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
88
69
|
private padding: number = 5;
|
|
89
70
|
|
|
@@ -105,9 +86,9 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
105
86
|
// if (gridCell.cell.column.getTag(bioTAGS.aligned) !== ALIGNMENT.SEQ_MSA)
|
|
106
87
|
// return;
|
|
107
88
|
|
|
108
|
-
const tableCol
|
|
109
|
-
|
|
110
|
-
const seqColTemp: MonomerPlacer =
|
|
89
|
+
const [_gridCol, tableCol, temp] =
|
|
90
|
+
getGridCellRendererBack<string, MonomerPlacer>(gridCell);
|
|
91
|
+
const seqColTemp: MonomerPlacer = temp['rendererBack'];
|
|
111
92
|
if (!seqColTemp) return; // Can do nothing without precalculated data
|
|
112
93
|
|
|
113
94
|
const gridCellBounds: DG.Rect = gridCell.bounds;
|
|
@@ -119,9 +100,9 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
119
100
|
// maxLengthWordsSum[posI] = maxLengthWordsSum[posI - 1] + maxLengthWords[posI];
|
|
120
101
|
// const maxIndex = maxLengthWords.length;
|
|
121
102
|
const argsX = e.offsetX - gridCell.gridColumn.left + (gridCell.gridColumn.left - gridCellBounds.x);
|
|
122
|
-
const left: number | null = seqColTemp.getPosition(gridCell.tableRowIndex!, argsX);
|
|
103
|
+
const left: number | null = seqColTemp.getPosition(gridCell.tableRowIndex!, argsX, gridCellBounds.width);
|
|
123
104
|
|
|
124
|
-
const seqCList: SeqSplittedBase = SeqHandler.forColumn(
|
|
105
|
+
const seqCList: SeqSplittedBase = SeqHandler.forColumn(tableCol)
|
|
125
106
|
.getSplitted(gridCell.tableRowIndex!).canonicals;
|
|
126
107
|
if (left !== null && left < seqCList.length) {
|
|
127
108
|
const monomerSymbol: string = seqCList[left];
|
|
@@ -133,8 +114,8 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
133
114
|
const alphabet = sh.alphabet ?? ALPHABET.UN;
|
|
134
115
|
const polymerType = alphabetPolymerTypes[alphabet as ALPHABET];
|
|
135
116
|
|
|
136
|
-
const lib: IMonomerLib =
|
|
137
|
-
return lib.getTooltip(polymerType, monomerSymbol);
|
|
117
|
+
const lib: IMonomerLib | null = getMonomerLib();
|
|
118
|
+
return lib ? lib.getTooltip(polymerType, monomerSymbol) : ui.divText('Monomer library is not available');
|
|
138
119
|
})();
|
|
139
120
|
}
|
|
140
121
|
tooltipElements.push(monomerDiv);
|
|
@@ -162,23 +143,17 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
162
143
|
_cellStyle: DG.GridCellStyle
|
|
163
144
|
): void {
|
|
164
145
|
const logPrefix: string = 'MacromoleculeSequenceCellRenderer.render()';
|
|
146
|
+
|
|
147
|
+
const dpr = window.devicePixelRatio;
|
|
148
|
+
const [gridCol, tableCol, _temp] =
|
|
149
|
+
getGridCellRendererBack<string, MonomerPlacer>(gridCell);
|
|
150
|
+
if (!tableCol) return;
|
|
151
|
+
const tableColTemp: TempType = tableCol.temp;
|
|
152
|
+
|
|
165
153
|
let gapLength = 0;
|
|
166
154
|
const msaGapLength = 8;
|
|
167
155
|
let maxLengthOfMonomer = 50; // in case of long monomer representation, do not limit max length
|
|
168
156
|
|
|
169
|
-
// TODO: Store temp data to GridColumn
|
|
170
|
-
// Now the renderer requires data frame table Column underlying GridColumn
|
|
171
|
-
let grid: DG.Grid | undefined = undefined;
|
|
172
|
-
try { grid = gridCell.grid; } catch (err: any) {
|
|
173
|
-
grid = undefined;
|
|
174
|
-
const [errMsg, errStack] = errInfo(err);
|
|
175
|
-
_package.logger.error(errMsg, undefined, errStack);
|
|
176
|
-
}
|
|
177
|
-
const tableCol: DG.Column = gridCell.cell.column;
|
|
178
|
-
if (!grid || !tableCol) return;
|
|
179
|
-
|
|
180
|
-
const tableColTemp: TempType = tableCol.temp;
|
|
181
|
-
|
|
182
157
|
// Cell renderer settings
|
|
183
158
|
const tempMonomerWidth: string | null = tableColTemp[tempTAGS.monomerWidth];
|
|
184
159
|
const monomerWidth: string = (tempMonomerWidth != null) ? tempMonomerWidth : 'short';
|
|
@@ -190,44 +165,41 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
190
165
|
(!isNaN(tagMaxMonomerLength) ? tagMaxMonomerLength : _package.properties?.MaxMonomerLength) ?? 4;
|
|
191
166
|
}
|
|
192
167
|
|
|
193
|
-
|
|
168
|
+
const [_gc, _tc, temp] =
|
|
169
|
+
getGridCellRendererBack<string, MonomerPlacer>(gridCell);
|
|
170
|
+
let seqColTemp: MonomerPlacer = temp.rendererBack;
|
|
194
171
|
if (!seqColTemp) {
|
|
195
|
-
seqColTemp = new MonomerPlacer(
|
|
172
|
+
seqColTemp = temp.rendererBack = new MonomerPlacer(gridCol, tableCol, _package.logger,
|
|
196
173
|
() => {
|
|
197
174
|
const sh = SeqHandler.forColumn(tableCol);
|
|
198
175
|
return {
|
|
199
176
|
seqHandler: sh,
|
|
200
177
|
monomerCharWidth: 7, separatorWidth: !sh.isMsa() ? gapLength : msaGapLength,
|
|
201
178
|
monomerToShort: monomerToShortFunction, monomerLengthLimit: maxLengthOfMonomer,
|
|
202
|
-
monomerLib: getBioLib()
|
|
203
179
|
};
|
|
204
180
|
});
|
|
205
181
|
}
|
|
206
182
|
|
|
207
|
-
if (tableCol.tags[mmcrTags.RendererSettingsChanged] === rendererSettingsChangedState.true) {
|
|
208
|
-
gapLength = tableColTemp[mmcrTemps.gapLength] as number ?? gapLength;
|
|
209
|
-
// this event means that the mm renderer settings have changed, particularly monomer representation and max width.
|
|
210
|
-
seqColTemp.setMonomerLengthLimit(maxLengthOfMonomer);
|
|
211
|
-
seqColTemp.setSeparatorWidth(seqColTemp.isMsa() ? msaGapLength : gapLength);
|
|
212
|
-
tableCol.setTag(mmcrTags.RendererSettingsChanged, rendererSettingsChangedState.false);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
const [maxLengthWords, maxLengthWordsSum]: [number[], number[]] =
|
|
216
|
-
seqColTemp.getCellMonomerLengths(gridCell.tableRowIndex!);
|
|
217
|
-
const _maxIndex = maxLengthWords.length;
|
|
218
|
-
|
|
219
|
-
// Store updated seqColTemp to the col temp
|
|
220
|
-
if (seqColTemp.updated) getRendererFridCellTempTemp(gridCell)[mmcrTemps.monomerPlacer] = seqColTemp;
|
|
221
|
-
|
|
222
183
|
g.save();
|
|
223
184
|
try {
|
|
224
|
-
|
|
225
|
-
|
|
185
|
+
if (tableCol.tags[mmcrTags.RendererSettingsChanged] === rendererSettingsChangedState.true) {
|
|
186
|
+
gapLength = tableColTemp[mmcrTemps.gapLength] as number ?? gapLength;
|
|
187
|
+
// this event means that the mm renderer settings have changed,
|
|
188
|
+
// particularly monomer representation and max width.
|
|
189
|
+
seqColTemp.setMonomerLengthLimit(maxLengthOfMonomer);
|
|
190
|
+
seqColTemp.setSeparatorWidth(seqColTemp.isMsa() ? msaGapLength : gapLength);
|
|
191
|
+
tableCol.setTag(mmcrTags.RendererSettingsChanged, rendererSettingsChangedState.false);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const [maxLengthWords, maxLengthWordsSum]: [number[], number[]] =
|
|
195
|
+
seqColTemp.getCellMonomerLengths(gridCell.tableRowIndex!, w);
|
|
196
|
+
const _maxIndex = maxLengthWords.length;
|
|
197
|
+
|
|
226
198
|
const value: any = gridCell.cell.value;
|
|
227
199
|
const rowIdx = gridCell.cell.rowIndex;
|
|
228
200
|
const paletteType = tableCol.getTag(bioTAGS.alphabet);
|
|
229
201
|
const minDistanceRenderer = 50;
|
|
230
|
-
w = getUpdatedWidth(grid, g, x, w, dpr);
|
|
202
|
+
w = getUpdatedWidth(gridCol?.grid, g, x, w, dpr);
|
|
231
203
|
g.beginPath();
|
|
232
204
|
g.rect(x + this.padding, y + this.padding, w - this.padding - 1, h - this.padding * 2);
|
|
233
205
|
g.clip();
|
|
@@ -241,7 +213,8 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
241
213
|
const palette = getPaletteByType(paletteType);
|
|
242
214
|
|
|
243
215
|
const separator = tableCol.getTag(bioTAGS.separator) ?? '';
|
|
244
|
-
const
|
|
216
|
+
const minMonWidth = seqColTemp.props.separatorWidth + 1 * seqColTemp.props.monomerCharWidth;
|
|
217
|
+
const splitLimit = w / minMonWidth;
|
|
245
218
|
const sh = SeqHandler.forColumn(tableCol);
|
|
246
219
|
|
|
247
220
|
const tempReferenceSequence: string | null = tableColTemp[tempTAGS.referenceSequence];
|
|
@@ -265,7 +238,8 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
265
238
|
if (aligned && aligned.includes('MSA') && units == NOTATION.SEPARATOR)
|
|
266
239
|
drawStyle = DrawStyle.MSA;
|
|
267
240
|
|
|
268
|
-
|
|
241
|
+
const visibleSeqLength = Math.min(subParts.length, splitLimit);
|
|
242
|
+
for (let posIdx: number = 0; posIdx < visibleSeqLength; ++posIdx) {
|
|
269
243
|
const amino: string = subParts.getOriginal(posIdx);
|
|
270
244
|
color = palette.get(amino);
|
|
271
245
|
g.fillStyle = undefinedColor;
|
|
@@ -277,8 +251,9 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
277
251
|
if (minDistanceRenderer > w) break;
|
|
278
252
|
}
|
|
279
253
|
} catch (err: any) {
|
|
280
|
-
const errMsg
|
|
281
|
-
|
|
254
|
+
const [errMsg, errStack] = errInfo(err);
|
|
255
|
+
seqColTemp.logger.error(errMsg, undefined, errStack);
|
|
256
|
+
seqColTemp.errors.push(err);
|
|
282
257
|
//throw err; // Do not throw to prevent disabling renderer
|
|
283
258
|
} finally {
|
|
284
259
|
g.restore();
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
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
|
}
|