@datagrok/bio 2.16.0 → 2.16.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 +12 -0
- package/dist/package-test.js +6 -6
- package/dist/package-test.js.map +1 -1
- package/dist/package.js +1 -1
- package/dist/package.js.map +1 -1
- package/package.json +11 -11
- package/src/analysis/sequence-activity-cliffs.ts +6 -4
- package/src/analysis/sequence-diversity-viewer.ts +1 -1
- package/src/analysis/sequence-similarity-viewer.ts +1 -1
- package/src/calculations/monomerLevelMols.ts +4 -5
- package/src/package-types.ts +0 -1
- package/src/package.ts +4 -6
- package/src/substructure-search/substructure-search.ts +15 -9
- package/src/tests/substructure-filters-tests.ts +27 -31
- package/src/utils/seq-helper/seq-handler.ts +11 -34
- package/src/utils/seq-helper/seq-helper.ts +35 -1
- package/src/widgets/bio-substructure-filter-helm.ts +5 -2
- package/src/widgets/bio-substructure-filter.ts +14 -23
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"name": "Aleksandr Tanas",
|
|
6
6
|
"email": "atanas@datagrok.ai"
|
|
7
7
|
},
|
|
8
|
-
"version": "2.16.
|
|
8
|
+
"version": "2.16.2",
|
|
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",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@biowasm/aioli": "^3.1.0",
|
|
40
|
-
"@datagrok-libraries/bio": "^5.45.
|
|
40
|
+
"@datagrok-libraries/bio": "^5.45.2",
|
|
41
41
|
"@datagrok-libraries/chem-meta": "^1.2.7",
|
|
42
42
|
"@datagrok-libraries/math": "^1.2.1",
|
|
43
43
|
"@datagrok-libraries/ml": "^6.7.4",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"rxjs": "^6.5.5",
|
|
56
56
|
"style-loader": "^3.3.1",
|
|
57
57
|
"umap-js": "^1.3.3",
|
|
58
|
-
"wu": "
|
|
58
|
+
"wu": "^2.1.0"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@datagrok-libraries/helm-web-editor": "^1.1.12",
|
|
@@ -64,18 +64,18 @@
|
|
|
64
64
|
"@datagrok/dendrogram": "^1.2.33",
|
|
65
65
|
"@datagrok/helm": "^2.5.3",
|
|
66
66
|
"@types/node": "^17.0.24",
|
|
67
|
-
"@types/wu": "
|
|
68
|
-
"@typescript-eslint/eslint-plugin": "
|
|
69
|
-
"@typescript-eslint/parser": "
|
|
67
|
+
"@types/wu": "^2.1.44",
|
|
68
|
+
"@typescript-eslint/eslint-plugin": "^8.8.1",
|
|
69
|
+
"@typescript-eslint/parser": "^8.8.1",
|
|
70
70
|
"datagrok-tools": "latest",
|
|
71
|
-
"eslint": "
|
|
72
|
-
"eslint-config-google": "
|
|
73
|
-
"eslint-plugin-rxjs": "
|
|
74
|
-
"source-map-loader": "
|
|
71
|
+
"eslint": "^9.12.0",
|
|
72
|
+
"eslint-config-google": "^0.14.0",
|
|
73
|
+
"eslint-plugin-rxjs": "^5.0.3",
|
|
74
|
+
"source-map-loader": "^5.0.0",
|
|
75
75
|
"ts-loader": "^9.5.1",
|
|
76
76
|
"typescript": "^5.5.3",
|
|
77
77
|
"webpack": "^5.92.1",
|
|
78
|
-
"webpack-bundle-analyzer": "
|
|
78
|
+
"webpack-bundle-analyzer": "^4.10.2",
|
|
79
79
|
"webpack-cli": "^5.1.4"
|
|
80
80
|
},
|
|
81
81
|
"scripts": {
|
|
@@ -6,13 +6,15 @@ import wu from 'wu';
|
|
|
6
6
|
|
|
7
7
|
import {ITooltipAndPanelParams} from '@datagrok-libraries/ml/src/viewers/activity-cliffs';
|
|
8
8
|
import {getSimilarityFromDistance} from '@datagrok-libraries/ml/src/distance-metrics-methods';
|
|
9
|
+
import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
9
10
|
import {AvailableMetrics, DistanceMetricsSubjects, StringMetricsNames} from '@datagrok-libraries/ml/src/typed-metrics';
|
|
10
|
-
import {drawMoleculeDifferenceOnCanvas} from '../utils/cell-renderer';
|
|
11
|
-
import {invalidateMols, MONOMERIC_COL_TAGS} from '../substructure-search/substructure-search';
|
|
12
11
|
import {TAGS as bioTAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
13
12
|
import {ISeqSplitted} from '@datagrok-libraries/bio/src/utils/macromolecule/types';
|
|
14
13
|
import {HelmType} from '@datagrok-libraries/bio/src/helm/types';
|
|
15
14
|
|
|
15
|
+
import {drawMoleculeDifferenceOnCanvas} from '../utils/cell-renderer';
|
|
16
|
+
import {invalidateMols, MONOMERIC_COL_TAGS} from '../substructure-search/substructure-search';
|
|
17
|
+
|
|
16
18
|
import {_package} from '../package';
|
|
17
19
|
|
|
18
20
|
export async function getDistances(col: DG.Column, seq: string): Promise<Array<number>> {
|
|
@@ -46,11 +48,11 @@ export async function getSimilaritiesMatrix(
|
|
|
46
48
|
return simArr;
|
|
47
49
|
}
|
|
48
50
|
|
|
49
|
-
export async function getChemSimilaritiesMatrix(dim: number, seqCol: DG.Column,
|
|
51
|
+
export async function getChemSimilaritiesMatrix(dim: number, seqCol: DG.Column, seqHelper: ISeqHelper,
|
|
50
52
|
df: DG.DataFrame, colName: string, simArr: (DG.Column | null)[])
|
|
51
53
|
: Promise<(DG.Column | null)[]> {
|
|
52
54
|
if (seqCol.version !== seqCol.temp[MONOMERIC_COL_TAGS.LAST_INVALIDATED_VERSION])
|
|
53
|
-
await invalidateMols(seqCol, false);
|
|
55
|
+
await invalidateMols(seqCol, seqHelper, false);
|
|
54
56
|
const fpDf = DG.DataFrame.create(seqCol.length);
|
|
55
57
|
fpDf.columns.addNewString(colName).init((i) => seqCol.temp[MONOMERIC_COL_TAGS.MONOMERIC_MOLS].get(i));
|
|
56
58
|
const res = await grok.functions.call('Chem:getChemSimilaritiesMatrix', {
|
|
@@ -50,7 +50,7 @@ export class SequenceDiversityViewer extends SequenceSearchBaseViewer {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
private async computeByChem() {
|
|
53
|
-
const monomericMols = await getMonomericMols(this.moleculeColumn
|
|
53
|
+
const monomericMols = await getMonomericMols(this.moleculeColumn!, this.seqHelper);
|
|
54
54
|
//need to create df to calculate fingerprints
|
|
55
55
|
const _monomericMolsDf = DG.DataFrame.fromColumns([monomericMols]);
|
|
56
56
|
this.renderMolIds = await grok.functions.call('Chem:callChemDiversitySearch', {
|
|
@@ -86,7 +86,7 @@ export class SequenceSimilarityViewer extends SequenceSearchBaseViewer {
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
private async computeByChem() {
|
|
89
|
-
const monomericMols = await getMonomericMols(this.moleculeColumn
|
|
89
|
+
const monomericMols = await getMonomericMols(this.moleculeColumn!, this.seqHelper);
|
|
90
90
|
//need to create df to calculate fingerprints
|
|
91
91
|
const _monomericMolsDf = DG.DataFrame.fromColumns([monomericMols]);
|
|
92
92
|
const df = await grok.functions.call('Chem:callChemSimilaritySearch', {
|
|
@@ -6,19 +6,18 @@ import wu from 'wu';
|
|
|
6
6
|
|
|
7
7
|
import {ISeqSplitted} from '@datagrok-libraries/bio/src/utils/macromolecule/types';
|
|
8
8
|
import {GAP_SYMBOL} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
|
|
9
|
-
|
|
10
|
-
import {_package, getHelmMonomers} from '../package';
|
|
9
|
+
import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
11
10
|
|
|
12
11
|
const V2000_ATOM_NAME_POS = 31;
|
|
13
12
|
|
|
14
13
|
export async function getMonomericMols(
|
|
15
|
-
mcol: DG.Column<string>, pattern: boolean = false, monomersDict?: Map<string, string>
|
|
14
|
+
mcol: DG.Column<string>, seqHelper: ISeqHelper, pattern: boolean = false, monomersDict?: Map<string, string>
|
|
16
15
|
): Promise<DG.Column> {
|
|
17
|
-
const sh =
|
|
16
|
+
const sh = seqHelper.getSeqHandler(mcol);
|
|
18
17
|
let molV3000Array;
|
|
19
18
|
monomersDict ??= new Map();
|
|
20
19
|
const monomers = sh.isHelm() ?
|
|
21
|
-
|
|
20
|
+
seqHelper.getSeqMonomers(mcol) : Object.keys(sh.stats.freq).filter((it) => it !== '');
|
|
22
21
|
|
|
23
22
|
for (let i = 0; i < monomers.length; i++) {
|
|
24
23
|
if (!monomersDict.has(monomers[i]))
|
package/src/package-types.ts
CHANGED
|
@@ -7,7 +7,6 @@ import {Observable, Subject} from 'rxjs';
|
|
|
7
7
|
import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
|
|
8
8
|
import {LoggerWrapper} from '@datagrok-libraries/bio/src/utils/logger';
|
|
9
9
|
import {RDModule} from '@datagrok-libraries/chem-meta/src/rdkit-api';
|
|
10
|
-
import {SeqHelper} from './utils/seq-helper';
|
|
11
10
|
import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
12
11
|
import {IMonomerLib, IMonomerLibBase, IMonomerSet} from '@datagrok-libraries/bio/src/types';
|
|
13
12
|
|
package/src/package.ts
CHANGED
|
@@ -562,7 +562,7 @@ export async function macromoleculePreprocessingFunction(
|
|
|
562
562
|
export async function helmPreprocessingFunction(
|
|
563
563
|
col: DG.Column<string>, _metric: BitArrayMetrics): Promise<PreprocessFunctionReturnType> {
|
|
564
564
|
if (col.version !== col.temp[MONOMERIC_COL_TAGS.LAST_INVALIDATED_VERSION])
|
|
565
|
-
await invalidateMols(col, false);
|
|
565
|
+
await invalidateMols(col, _package.seqHelper, false);
|
|
566
566
|
const molCol = col.temp[MONOMERIC_COL_TAGS.MONOMERIC_MOLS];
|
|
567
567
|
const fingerPrints: DG.Column<DG.BitSet | null> =
|
|
568
568
|
await grok.functions.call('Chem:getMorganFingerprints', {molColumn: molCol});
|
|
@@ -858,9 +858,7 @@ export async function splitToMonomersTopMenu(table: DG.DataFrame, sequence: DG.C
|
|
|
858
858
|
//input: column sequence {semType: Macromolecule}
|
|
859
859
|
//output: object result
|
|
860
860
|
export function getHelmMonomers(sequence: DG.Column<string>): string[] {
|
|
861
|
-
|
|
862
|
-
const stats = sh.stats;
|
|
863
|
-
return Object.keys(stats.freq);
|
|
861
|
+
return _package.seqHelper.getSeqMonomers(sequence);
|
|
864
862
|
}
|
|
865
863
|
|
|
866
864
|
|
|
@@ -908,7 +906,7 @@ export function searchSubsequenceEditor(call: DG.FuncCall) {
|
|
|
908
906
|
if (columns.length === 1)
|
|
909
907
|
call.func.prepare({macromolecules: columns[0]}).call(true);
|
|
910
908
|
else
|
|
911
|
-
new SubstructureSearchDialog(columns);
|
|
909
|
+
new SubstructureSearchDialog(columns, _package.seqHelper);
|
|
912
910
|
}
|
|
913
911
|
|
|
914
912
|
//top-menu: Bio | Search | Subsequence Search ...
|
|
@@ -980,7 +978,7 @@ export function saveAsFasta() {
|
|
|
980
978
|
//output: filter result
|
|
981
979
|
//meta.semType: Macromolecule
|
|
982
980
|
export function bioSubstructureFilter(): BioSubstructureFilter {
|
|
983
|
-
return new BioSubstructureFilter();
|
|
981
|
+
return new BioSubstructureFilter(_package.seqHelper, _package.logger);
|
|
984
982
|
}
|
|
985
983
|
|
|
986
984
|
// -- Test apps --
|
|
@@ -2,10 +2,12 @@ import * as grok from 'datagrok-api/grok';
|
|
|
2
2
|
import * as ui from 'datagrok-api/ui';
|
|
3
3
|
import * as DG from 'datagrok-api/dg';
|
|
4
4
|
|
|
5
|
-
import {getMonomericMols} from '../calculations/monomerLevelMols';
|
|
6
|
-
import {updateDivInnerHTML} from '../utils/ui-utils';
|
|
7
5
|
import {delay} from '@datagrok-libraries/utils/src/test';
|
|
8
6
|
import {TAGS as bioTAGS, NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
7
|
+
import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
8
|
+
|
|
9
|
+
import {getMonomericMols} from '../calculations/monomerLevelMols';
|
|
10
|
+
import {updateDivInnerHTML} from '../utils/ui-utils';
|
|
9
11
|
|
|
10
12
|
export const MONOMER_MOLS_COL = 'monomeric-mols';
|
|
11
13
|
|
|
@@ -29,7 +31,9 @@ export class SubstructureSearchDialog {
|
|
|
29
31
|
col: DG.Column;
|
|
30
32
|
dialog: DG.Dialog;
|
|
31
33
|
|
|
32
|
-
constructor(columns: DG.Column<string>[]
|
|
34
|
+
constructor(columns: DG.Column<string>[],
|
|
35
|
+
private readonly seqHelper: ISeqHelper
|
|
36
|
+
) {
|
|
33
37
|
this.col = columns[0];
|
|
34
38
|
this.createUI();
|
|
35
39
|
}
|
|
@@ -96,7 +100,7 @@ export class SubstructureSearchDialog {
|
|
|
96
100
|
substructure = substructure.replaceAll(this.separatorInput.value, this.separator);
|
|
97
101
|
let matches: DG.BitSet;
|
|
98
102
|
if (this.units === NOTATION.HELM)
|
|
99
|
-
matches = await helmSubstructureSearch(substructure, this.col);
|
|
103
|
+
matches = await helmSubstructureSearch(substructure, this.col, this.seqHelper);
|
|
100
104
|
else
|
|
101
105
|
matches = linearSubstructureSearch(substructure, this.col);
|
|
102
106
|
this.col.dataFrame.filter.and(matches);
|
|
@@ -129,14 +133,16 @@ function prepareSubstructureRegex(substructure: string, separator: string) {
|
|
|
129
133
|
return re;
|
|
130
134
|
}
|
|
131
135
|
|
|
132
|
-
export async function helmSubstructureSearch(
|
|
136
|
+
export async function helmSubstructureSearch(
|
|
137
|
+
substructure: string, col: DG.Column<string>, seqHelper: ISeqHelper
|
|
138
|
+
): Promise<DG.BitSet> {
|
|
133
139
|
if (col.version !== col.temp[MONOMERIC_COL_TAGS.LAST_INVALIDATED_VERSION])
|
|
134
|
-
await invalidateMols(col, true);
|
|
140
|
+
await invalidateMols(col, seqHelper, true);
|
|
135
141
|
const substructureCol: DG.Column<string> = DG.Column.string('helm', 1).init((_i) => substructure);
|
|
136
142
|
substructureCol.semType = DG.SEMTYPE.MACROMOLECULE;
|
|
137
143
|
substructureCol.meta.units = NOTATION.HELM;
|
|
138
144
|
const substructureMolsCol =
|
|
139
|
-
await getMonomericMols(substructureCol, true, col.temp[MONOMERIC_COL_TAGS.MONOMERS_DICT]);
|
|
145
|
+
await getMonomericMols(substructureCol, seqHelper, true, col.temp[MONOMERIC_COL_TAGS.MONOMERS_DICT]);
|
|
140
146
|
const matchesCol = await grok.functions.call('Chem:searchSubstructure', {
|
|
141
147
|
molStringsColumn: col.temp[MONOMERIC_COL_TAGS.MONOMERIC_MOLS],
|
|
142
148
|
molString: substructureMolsCol.get(0),
|
|
@@ -145,12 +151,12 @@ export async function helmSubstructureSearch(substructure: string, col: DG.Colum
|
|
|
145
151
|
return matchesCol.get(0);
|
|
146
152
|
}
|
|
147
153
|
|
|
148
|
-
export async function invalidateMols(col: DG.Column<string>, pattern: boolean) {
|
|
154
|
+
export async function invalidateMols(col: DG.Column<string>, seqHelper: ISeqHelper, pattern: boolean): Promise<void> {
|
|
149
155
|
const progressBar = DG.TaskBarProgressIndicator.create(`Invalidating molfiles for ${col.name}`);
|
|
150
156
|
try {
|
|
151
157
|
await delay(10);
|
|
152
158
|
const monomersDict = new Map();
|
|
153
|
-
const monomericMolsCol = await getMonomericMols(col, pattern, monomersDict);
|
|
159
|
+
const monomericMolsCol = await getMonomericMols(col, seqHelper, pattern, monomersDict);
|
|
154
160
|
col.temp[MONOMERIC_COL_TAGS.MONOMERIC_MOLS] = monomericMolsCol;
|
|
155
161
|
col.temp[MONOMERIC_COL_TAGS.MONOMERS_DICT] = monomersDict;
|
|
156
162
|
col.temp[MONOMERIC_COL_TAGS.LAST_INVALIDATED_VERSION] = col.version;
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
getUserLibSettings, setUserLibSettings
|
|
12
12
|
} from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
|
|
13
13
|
import {UserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/types';
|
|
14
|
-
import {
|
|
14
|
+
import {getSeqHelper, ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
15
15
|
|
|
16
16
|
import {awaitGrid, readDataframe} from './utils';
|
|
17
17
|
|
|
@@ -24,13 +24,13 @@ import {HelmBioFilter} from '../widgets/bio-substructure-filter-helm';
|
|
|
24
24
|
import {_package} from '../package-test';
|
|
25
25
|
|
|
26
26
|
category('bio-substructure-filters', async () => {
|
|
27
|
-
let
|
|
27
|
+
let seqHelper: ISeqHelper;
|
|
28
28
|
let monomerLibHelper: IMonomerLibHelper;
|
|
29
29
|
/** Backup actual user's monomer libraries settings */
|
|
30
30
|
let userLibSettings: UserLibSettings;
|
|
31
31
|
|
|
32
32
|
before(async () => {
|
|
33
|
-
|
|
33
|
+
seqHelper = await getSeqHelper();
|
|
34
34
|
monomerLibHelper = await getMonomerLibHelper();
|
|
35
35
|
userLibSettings = await getUserLibSettings();
|
|
36
36
|
|
|
@@ -51,7 +51,7 @@ category('bio-substructure-filters', async () => {
|
|
|
51
51
|
const fSubStr: string = 'MD';
|
|
52
52
|
const fTrueCount: number = 3;
|
|
53
53
|
|
|
54
|
-
const filter =
|
|
54
|
+
const filter = new BioSubstructureFilter(seqHelper, _package.logger);
|
|
55
55
|
filter.attach(df);
|
|
56
56
|
await filter.awaitRendered();
|
|
57
57
|
try {
|
|
@@ -68,11 +68,11 @@ category('bio-substructure-filters', async () => {
|
|
|
68
68
|
filter.detach();
|
|
69
69
|
}
|
|
70
70
|
await filter.awaitRendered();
|
|
71
|
-
}
|
|
71
|
+
});
|
|
72
72
|
|
|
73
73
|
test('separator', async () => {
|
|
74
74
|
const msa = await readDataframe('tests/filter_MSA.csv');
|
|
75
|
-
const filter =
|
|
75
|
+
const filter = new BioSubstructureFilter(seqHelper, _package.logger);
|
|
76
76
|
await grok.data.detectSemanticTypes(msa);
|
|
77
77
|
filter.attach(msa);
|
|
78
78
|
await filter.awaitRendered();
|
|
@@ -101,7 +101,7 @@ category('bio-substructure-filters', async () => {
|
|
|
101
101
|
filter.detach();
|
|
102
102
|
}
|
|
103
103
|
await filter.awaitRendered();
|
|
104
|
-
}
|
|
104
|
+
});
|
|
105
105
|
|
|
106
106
|
// test('helm', async () => {
|
|
107
107
|
// const df = await readDataframe('tests/filter_HELM.csv');
|
|
@@ -156,7 +156,7 @@ category('bio-substructure-filters', async () => {
|
|
|
156
156
|
const view = grok.shell.addTableView(df);
|
|
157
157
|
|
|
158
158
|
_package.logger.debug(`${logPrefix}, filter attaching.`);
|
|
159
|
-
const filter =
|
|
159
|
+
const filter = new BioSubstructureFilter(seqHelper, _package.logger);
|
|
160
160
|
filter.attach(df);
|
|
161
161
|
const dlg = ui.dialog('Test filters').add(filter.root).show(); // to waitForElementInDom
|
|
162
162
|
await filter.awaitRendered();
|
|
@@ -187,7 +187,7 @@ category('bio-substructure-filters', async () => {
|
|
|
187
187
|
}
|
|
188
188
|
await filter.awaitRendered();
|
|
189
189
|
await delay(3000); //TODO: await for grid.onLookChanged
|
|
190
|
-
}
|
|
190
|
+
});
|
|
191
191
|
|
|
192
192
|
// Generates unhandled exception accessing isFiltering before bioFilter created
|
|
193
193
|
test('helm-view', async () => {
|
|
@@ -234,7 +234,7 @@ category('bio-substructure-filters', async () => {
|
|
|
234
234
|
f2.detach();
|
|
235
235
|
}
|
|
236
236
|
await Promise.all([f1.awaitRendered(), f2.awaitRendered()]);
|
|
237
|
-
}
|
|
237
|
+
});
|
|
238
238
|
|
|
239
239
|
// MSA filter has the second input field for separator
|
|
240
240
|
test('sync-msa', async () => {
|
|
@@ -268,7 +268,7 @@ category('bio-substructure-filters', async () => {
|
|
|
268
268
|
f2.detach();
|
|
269
269
|
}
|
|
270
270
|
await Promise.all([f1.awaitRendered(), f2.awaitRendered()]);
|
|
271
|
-
}
|
|
271
|
+
});
|
|
272
272
|
|
|
273
273
|
test('sync-helm', async () => {
|
|
274
274
|
const df = await _package.files.readCsv('tests/filter_HELM.csv');
|
|
@@ -311,7 +311,7 @@ category('bio-substructure-filters', async () => {
|
|
|
311
311
|
await Promise.all([f1.awaitRendered(), f2.awaitRendered()]);
|
|
312
312
|
await awaitGrid(view.grid);
|
|
313
313
|
await delay(3000); //TODO: await for grid.onLookChanged
|
|
314
|
-
}
|
|
314
|
+
});
|
|
315
315
|
|
|
316
316
|
// two seq columns
|
|
317
317
|
|
|
@@ -449,24 +449,20 @@ category('bio-substructure-filters', async () => {
|
|
|
449
449
|
await delay(100);
|
|
450
450
|
await awaitGrid(view.grid);
|
|
451
451
|
});
|
|
452
|
+
|
|
453
|
+
async function createFilter(colName: string, df: DG.DataFrame): Promise<BioSubstructureFilter> {
|
|
454
|
+
if (!df.columns.names().includes(colName)) {
|
|
455
|
+
throw new Error(`The column '${colName}' not found. ` +
|
|
456
|
+
`Available in data frame are ${JSON.stringify(df.columns.names())}`);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
const filter = new BioSubstructureFilter(seqHelper, _package.logger);
|
|
460
|
+
filter.attach(df);
|
|
461
|
+
filter.applyState({columnName: colName});
|
|
462
|
+
filter.column = df.col(colName);
|
|
463
|
+
filter.columnName = colName;
|
|
464
|
+
//filter.tableName = df.name;
|
|
465
|
+
return filter;
|
|
466
|
+
};
|
|
452
467
|
});
|
|
453
468
|
|
|
454
|
-
async function createFilter(colName: string, df: DG.DataFrame): Promise<BioSubstructureFilter> {
|
|
455
|
-
if (!df.columns.names().includes(colName)) {
|
|
456
|
-
throw new Error(`The column '${colName}' not found. ` +
|
|
457
|
-
`Available in data frame are ${JSON.stringify(df.columns.names())}`);
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
const filter = await createBioSubstructureFilter();
|
|
461
|
-
filter.attach(df);
|
|
462
|
-
filter.applyState({columnName: colName});
|
|
463
|
-
filter.column = df.col(colName);
|
|
464
|
-
filter.columnName = colName;
|
|
465
|
-
//filter.tableName = df.name;
|
|
466
|
-
return filter;
|
|
467
|
-
};
|
|
468
|
-
|
|
469
|
-
async function createBioSubstructureFilter(): Promise<BioSubstructureFilter> {
|
|
470
|
-
const filter = await grok.functions.call('Bio:bioSubstructureFilter');
|
|
471
|
-
return filter.dart.jsFilter as BioSubstructureFilter;
|
|
472
|
-
}
|
|
@@ -16,6 +16,8 @@ import {HelmTypes} from '@datagrok-libraries/bio/src/helm/consts';
|
|
|
16
16
|
import {HelmType} from '@datagrok-libraries/bio/src/helm/types';
|
|
17
17
|
import {ISeqHandler, ConvertFunc, JoinerFunc, SeqTemps} from '@datagrok-libraries/bio/src/utils/macromolecule/seq-handler';
|
|
18
18
|
|
|
19
|
+
import {SeqHelper} from './seq-helper';
|
|
20
|
+
|
|
19
21
|
/* eslint-enable max-len */
|
|
20
22
|
|
|
21
23
|
/** Class for handling notation units in Macromolecule columns and
|
|
@@ -30,7 +32,9 @@ export class SeqHandler implements ISeqHandler {
|
|
|
30
32
|
|
|
31
33
|
private _splitter: SplitterFunc | null = null;
|
|
32
34
|
|
|
33
|
-
protected constructor(col: DG.Column<string
|
|
35
|
+
protected constructor(col: DG.Column<string>,
|
|
36
|
+
private readonly seqHelper: SeqHelper,
|
|
37
|
+
) {
|
|
34
38
|
if (col.type !== DG.TYPE.STRING)
|
|
35
39
|
throw new Error(`Unexpected column type '${col.type}', must be '${DG.TYPE.STRING}'.`);
|
|
36
40
|
this._column = col;
|
|
@@ -50,12 +54,12 @@ export class SeqHandler implements ISeqHandler {
|
|
|
50
54
|
// The following detectors and setters are to be called because the column is likely
|
|
51
55
|
// as the UnitsHandler constructor was called on the column.
|
|
52
56
|
if (this.isFasta())
|
|
53
|
-
|
|
57
|
+
this.seqHelper.setUnitsToFastaColumn(this);
|
|
54
58
|
else if (this.isSeparator()) {
|
|
55
59
|
const separator = col.getTag(TAGS.separator);
|
|
56
|
-
|
|
60
|
+
this.seqHelper.setUnitsToSeparatorColumn(this, separator);
|
|
57
61
|
} else if (this.isHelm())
|
|
58
|
-
|
|
62
|
+
this.seqHelper.setUnitsToHelmColumn(this);
|
|
59
63
|
else
|
|
60
64
|
throw new Error(`Unexpected units '${this.column.meta.units}'.`);
|
|
61
65
|
}
|
|
@@ -85,33 +89,6 @@ export class SeqHandler implements ISeqHandler {
|
|
|
85
89
|
this.columnVersion = this.column.version;
|
|
86
90
|
}
|
|
87
91
|
|
|
88
|
-
public static setUnitsToFastaColumn(uh: SeqHandler) {
|
|
89
|
-
if (uh.column.semType !== DG.SEMTYPE.MACROMOLECULE || uh.column.meta.units !== NOTATION.FASTA)
|
|
90
|
-
throw new Error(`The column of notation '${NOTATION.FASTA}' must be '${DG.SEMTYPE.MACROMOLECULE}'.`);
|
|
91
|
-
|
|
92
|
-
uh.column.meta.units = NOTATION.FASTA;
|
|
93
|
-
SeqHandler.setTags(uh);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
public static setUnitsToSeparatorColumn(uh: SeqHandler, separator?: string) {
|
|
97
|
-
if (uh.column.semType !== DG.SEMTYPE.MACROMOLECULE || uh.column.meta.units !== NOTATION.SEPARATOR)
|
|
98
|
-
throw new Error(`The column of notation '${NOTATION.SEPARATOR}' must be '${DG.SEMTYPE.MACROMOLECULE}'.`);
|
|
99
|
-
if (!separator)
|
|
100
|
-
throw new Error(`The column of notation '${NOTATION.SEPARATOR}' must have the separator tag.`);
|
|
101
|
-
|
|
102
|
-
uh.column.meta.units = NOTATION.SEPARATOR;
|
|
103
|
-
uh.column.setTag(TAGS.separator, separator);
|
|
104
|
-
SeqHandler.setTags(uh);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
public static setUnitsToHelmColumn(uh: SeqHandler) {
|
|
108
|
-
if (uh.column.semType !== DG.SEMTYPE.MACROMOLECULE)
|
|
109
|
-
throw new Error(`The column of notation '${NOTATION.HELM}' must be '${DG.SEMTYPE.MACROMOLECULE}'`);
|
|
110
|
-
|
|
111
|
-
uh.column.meta.units = NOTATION.HELM;
|
|
112
|
-
SeqHandler.setTags(uh);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
92
|
/** From detectMacromolecule */
|
|
116
93
|
public static setTags(uh: SeqHandler): void {
|
|
117
94
|
const units = uh.column.meta.units as NOTATION;
|
|
@@ -141,7 +118,7 @@ export class SeqHandler implements ISeqHandler {
|
|
|
141
118
|
}
|
|
142
119
|
}
|
|
143
120
|
|
|
144
|
-
|
|
121
|
+
get column(): DG.Column { return this._column; }
|
|
145
122
|
|
|
146
123
|
public get length(): number { return this._column.length; }
|
|
147
124
|
|
|
@@ -741,11 +718,11 @@ export class SeqHandler implements ISeqHandler {
|
|
|
741
718
|
}
|
|
742
719
|
|
|
743
720
|
/** Gets a column's UnitsHandler object from temp slot or creates a new and stores it to the temp slot. */
|
|
744
|
-
public static forColumn(col: DG.Column<string
|
|
721
|
+
public static forColumn(col: DG.Column<string>, seqHelper: SeqHelper): SeqHandler {
|
|
745
722
|
// TODO: Invalidate col.temp[Temps.uh] checking column's metadata
|
|
746
723
|
let res = col.temp[SeqTemps.seqHandler];
|
|
747
724
|
if (!res || res.columnVersion !== col.version)
|
|
748
|
-
res = col.temp[SeqTemps.seqHandler] = new SeqHandler(col);
|
|
725
|
+
res = col.temp[SeqTemps.seqHandler] = new SeqHandler(col, seqHelper);
|
|
749
726
|
return res;
|
|
750
727
|
}
|
|
751
728
|
|
|
@@ -17,6 +17,8 @@ import {IMonomerLibBase} from '@datagrok-libraries/bio/src/types/index';
|
|
|
17
17
|
import {HelmToMolfileConverter} from '../helm-to-molfile/converter';
|
|
18
18
|
import {ISeqHandler} from '@datagrok-libraries/bio/src/utils/macromolecule/seq-handler';
|
|
19
19
|
import {SeqHandler} from './seq-handler';
|
|
20
|
+
import {Column} from 'datagrok-api/dg';
|
|
21
|
+
import {NOTATION, TAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
20
22
|
|
|
21
23
|
type SeqHelperWindowType = Window & { $seqHelperPromise?: Promise<SeqHelper> };
|
|
22
24
|
declare const window: SeqHelperWindowType;
|
|
@@ -28,7 +30,12 @@ export class SeqHelper implements ISeqHelper {
|
|
|
28
30
|
) {}
|
|
29
31
|
|
|
30
32
|
getSeqHandler(seqCol: DG.Column<string>): ISeqHandler {
|
|
31
|
-
return SeqHandler.forColumn(seqCol);
|
|
33
|
+
return SeqHandler.forColumn(seqCol, this);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
getSeqMonomers(seqCol: Column<string>): string[] {
|
|
37
|
+
const sh = this.getSeqHandler(seqCol);
|
|
38
|
+
return Object.keys(sh.stats.freq);
|
|
32
39
|
}
|
|
33
40
|
|
|
34
41
|
// TODO: Move to the Helm package
|
|
@@ -89,4 +96,31 @@ export class SeqHelper implements ISeqHelper {
|
|
|
89
96
|
|
|
90
97
|
return {molCol: molCol, warnings: []};
|
|
91
98
|
}
|
|
99
|
+
|
|
100
|
+
public setUnitsToFastaColumn(uh: SeqHandler) {
|
|
101
|
+
if (uh.column.semType !== DG.SEMTYPE.MACROMOLECULE || uh.column.meta.units !== NOTATION.FASTA)
|
|
102
|
+
throw new Error(`The column of notation '${NOTATION.FASTA}' must be '${DG.SEMTYPE.MACROMOLECULE}'.`);
|
|
103
|
+
|
|
104
|
+
uh.column.meta.units = NOTATION.FASTA;
|
|
105
|
+
SeqHandler.setTags(uh);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
public setUnitsToSeparatorColumn(uh: SeqHandler, separator?: string) {
|
|
109
|
+
if (uh.column.semType !== DG.SEMTYPE.MACROMOLECULE || uh.column.meta.units !== NOTATION.SEPARATOR)
|
|
110
|
+
throw new Error(`The column of notation '${NOTATION.SEPARATOR}' must be '${DG.SEMTYPE.MACROMOLECULE}'.`);
|
|
111
|
+
if (!separator)
|
|
112
|
+
throw new Error(`The column of notation '${NOTATION.SEPARATOR}' must have the separator tag.`);
|
|
113
|
+
|
|
114
|
+
uh.column.meta.units = NOTATION.SEPARATOR;
|
|
115
|
+
uh.column.setTag(TAGS.separator, separator);
|
|
116
|
+
SeqHandler.setTags(uh);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
public setUnitsToHelmColumn(uh: SeqHandler) {
|
|
120
|
+
if (uh.column.semType !== DG.SEMTYPE.MACROMOLECULE)
|
|
121
|
+
throw new Error(`The column of notation '${NOTATION.HELM}' must be '${DG.SEMTYPE.MACROMOLECULE}'`);
|
|
122
|
+
|
|
123
|
+
uh.column.meta.units = NOTATION.HELM;
|
|
124
|
+
SeqHandler.setTags(uh);
|
|
125
|
+
}
|
|
92
126
|
}
|
|
@@ -10,6 +10,7 @@ import {getHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
|
|
|
10
10
|
import {ILogger} from '@datagrok-libraries/bio/src/utils/logger';
|
|
11
11
|
import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
|
|
12
12
|
import {delay} from '@datagrok-libraries/utils/src/test';
|
|
13
|
+
import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
13
14
|
|
|
14
15
|
import {updateDivInnerHTML} from '../utils/ui-utils';
|
|
15
16
|
import {helmSubstructureSearch} from '../substructure-search/substructure-search';
|
|
@@ -32,7 +33,9 @@ export class HelmBioFilter extends BioFilterBase<BioFilterProps> /* implements I
|
|
|
32
33
|
|
|
33
34
|
get type(): string { return 'HelmBioFilter'; }
|
|
34
35
|
|
|
35
|
-
constructor(
|
|
36
|
+
constructor(
|
|
37
|
+
private readonly seqHelper: ISeqHelper,
|
|
38
|
+
) {
|
|
36
39
|
super();
|
|
37
40
|
this.logger = _package.logger;
|
|
38
41
|
}
|
|
@@ -138,7 +141,7 @@ export class HelmBioFilter extends BioFilterBase<BioFilterProps> /* implements I
|
|
|
138
141
|
_package.logger.debug(`${logPrefix}, start`);
|
|
139
142
|
try {
|
|
140
143
|
await delay(10);
|
|
141
|
-
const res = await helmSubstructureSearch(this.props.substructure, column);
|
|
144
|
+
const res = await helmSubstructureSearch(this.props.substructure, column, this.seqHelper);
|
|
142
145
|
return res;
|
|
143
146
|
} finally {
|
|
144
147
|
_package.logger.debug(`${logPrefix}, end`);
|