@datagrok/bio 2.11.22 → 2.11.24
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 +1 -0
- package/dist/356.js +1 -1
- package/dist/356.js.map +1 -1
- package/dist/796.js +1 -1
- package/dist/796.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/package.json +4 -3
- package/src/demo/bio01a-hierarchical-clustering-and-sequence-space.ts +6 -10
- package/src/demo/bio01b-hierarchical-clustering-and-activity-cliffs.ts +7 -9
- package/src/viewers/web-logo-viewer.ts +5 -1
- package/src/widgets/bio-substructure-filter.ts +51 -24
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"name": "Leonid Stolbov",
|
|
6
6
|
"email": "lstolbov@datagrok.ai"
|
|
7
7
|
},
|
|
8
|
-
"version": "2.11.
|
|
8
|
+
"version": "2.11.24",
|
|
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,11 +34,12 @@
|
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@biowasm/aioli": "^3.1.0",
|
|
37
|
-
"@datagrok-libraries/bio": "^5.39.
|
|
37
|
+
"@datagrok-libraries/bio": "^5.39.18",
|
|
38
38
|
"@datagrok-libraries/chem-meta": "^1.2.1",
|
|
39
39
|
"@datagrok-libraries/ml": "^6.3.68",
|
|
40
40
|
"@datagrok-libraries/tutorials": "^1.3.11",
|
|
41
41
|
"@datagrok-libraries/utils": "^4.1.36",
|
|
42
|
+
"@datagrok-libraries/math": "^1.0.7",
|
|
42
43
|
"cash-dom": "^8.0.0",
|
|
43
44
|
"css-loader": "^6.7.3",
|
|
44
45
|
"datagrok-api": "^1.16.0",
|
|
@@ -65,7 +66,7 @@
|
|
|
65
66
|
"webpack-bundle-analyzer": "latest",
|
|
66
67
|
"webpack-cli": "^4.9.1",
|
|
67
68
|
"@datagrok/chem": "^1.8.8",
|
|
68
|
-
"@datagrok/helm": "^2.1.
|
|
69
|
+
"@datagrok/helm": "^2.1.24",
|
|
69
70
|
"@datagrok/dendrogram": "^1.2.22"
|
|
70
71
|
},
|
|
71
72
|
"scripts": {
|
|
@@ -3,13 +3,11 @@ import * as ui from 'datagrok-api/ui';
|
|
|
3
3
|
import * as DG from 'datagrok-api/dg';
|
|
4
4
|
|
|
5
5
|
import {_package} from '../package';
|
|
6
|
-
|
|
7
|
-
import * as lev from 'fastest-levenshtein';
|
|
8
|
-
import {DistanceMatrix} from '@datagrok-libraries/ml/src/distance-matrix';
|
|
9
6
|
import {getTreeHelper, ITreeHelper} from '@datagrok-libraries/bio/src/trees/tree-helper';
|
|
10
7
|
import {getDendrogramService, IDendrogramService} from '@datagrok-libraries/bio/src/trees/dendrogram';
|
|
11
8
|
import {demoSequenceSpace, handleError} from './utils';
|
|
12
9
|
import {DemoScript} from '@datagrok-libraries/tutorials/src/demo-script';
|
|
10
|
+
import {getClusterMatrixWorker} from '@datagrok-libraries/math';
|
|
13
11
|
|
|
14
12
|
const dataFn = 'data/sample_FASTA_PT_activity.csv';
|
|
15
13
|
const seqColName = 'sequence';
|
|
@@ -55,13 +53,11 @@ export async function demoBio01aUI() {
|
|
|
55
53
|
delay: 2000,
|
|
56
54
|
})
|
|
57
55
|
.step('Cluster sequences', async () => {
|
|
58
|
-
const
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
});
|
|
64
|
-
const treeRoot = await treeHelper.hierarchicalClusteringByDistance(distance, 'ward');
|
|
56
|
+
const distance = await treeHelper.calcDistanceMatrix(df, [seqColName]);
|
|
57
|
+
const clusterMatrix = await getClusterMatrixWorker(
|
|
58
|
+
distance!.data, df.rowCount, 1,
|
|
59
|
+
);
|
|
60
|
+
const treeRoot = treeHelper.parseClusterMatrix(clusterMatrix);
|
|
65
61
|
dendrogramSvc.injectTreeForGrid(view.grid, treeRoot, undefined, 150, undefined);
|
|
66
62
|
}, {
|
|
67
63
|
description: `Perform hierarchical clustering to reveal relationships between sequences.`,
|
|
@@ -6,14 +6,13 @@ import {_package, activityCliffs} from '../package';
|
|
|
6
6
|
import $ from 'cash-dom';
|
|
7
7
|
|
|
8
8
|
import {TEMPS as acTEMPS} from '@datagrok-libraries/ml/src/viewers/activity-cliffs';
|
|
9
|
-
import * as lev from 'fastest-levenshtein';
|
|
10
|
-
import {DistanceMatrix} from '@datagrok-libraries/ml/src/distance-matrix';
|
|
11
9
|
import {getTreeHelper, ITreeHelper} from '@datagrok-libraries/bio/src/trees/tree-helper';
|
|
12
10
|
import {getDendrogramService, IDendrogramService} from '@datagrok-libraries/bio/src/trees/dendrogram';
|
|
13
11
|
import {handleError} from './utils';
|
|
14
12
|
import {DemoScript} from '@datagrok-libraries/tutorials/src/demo-script';
|
|
15
13
|
import {DimReductionMethods} from '@datagrok-libraries/ml/src/reduce-dimensionality';
|
|
16
14
|
import {MmDistanceFunctionsNames} from '@datagrok-libraries/ml/src/macromolecule-distance-functions';
|
|
15
|
+
import {getClusterMatrixWorker} from '@datagrok-libraries/math';
|
|
17
16
|
|
|
18
17
|
const dataFn: string = 'data/sample_FASTA_PT_activity.csv';
|
|
19
18
|
|
|
@@ -67,13 +66,12 @@ export async function demoBio01bUI() {
|
|
|
67
66
|
})
|
|
68
67
|
.step('Cluster sequences', async () => {
|
|
69
68
|
const progressBar = DG.TaskBarProgressIndicator.create(`Running sequence clustering...`);
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const treeRoot = await treeHelper.hierarchicalClusteringByDistance(distance, 'ward');
|
|
69
|
+
|
|
70
|
+
const distance = await treeHelper.calcDistanceMatrix(df, ['sequence']);
|
|
71
|
+
const clusterMatrix = await getClusterMatrixWorker(
|
|
72
|
+
distance!.data, df.rowCount, 1,
|
|
73
|
+
);
|
|
74
|
+
const treeRoot = treeHelper.parseClusterMatrix(clusterMatrix);
|
|
77
75
|
progressBar.close();
|
|
78
76
|
dendrogramSvc.injectTreeForGrid(view.grid, treeRoot, undefined, 150, undefined);
|
|
79
77
|
|
|
@@ -294,6 +294,10 @@ enum WlRenderLevel {
|
|
|
294
294
|
Freqs = 2,
|
|
295
295
|
}
|
|
296
296
|
|
|
297
|
+
export const Debounces = new class {
|
|
298
|
+
render: number = 20;
|
|
299
|
+
}();
|
|
300
|
+
|
|
297
301
|
const POSITION_LABELS_HEIGHT: number = 12;
|
|
298
302
|
|
|
299
303
|
export class WebLogoViewer extends DG.JsViewer implements IWebLogoViewer {
|
|
@@ -507,7 +511,7 @@ export class WebLogoViewer extends DG.JsViewer implements IWebLogoViewer {
|
|
|
507
511
|
const dataFrameTxt: string = this.dataFrame ? 'data' : 'null';
|
|
508
512
|
_package.logger.debug(`Bio: WebLogoViewer<${this.viewerId}>.buildView( dataFrame = ${dataFrameTxt} ) start`);
|
|
509
513
|
const dpr = window.devicePixelRatio;
|
|
510
|
-
this.viewSubs.push(DG.debounce(this.renderRequest)
|
|
514
|
+
this.viewSubs.push(DG.debounce(this.renderRequest, Debounces.render)
|
|
511
515
|
.subscribe(this.renderRequestOnDebounce.bind(this)));
|
|
512
516
|
|
|
513
517
|
this.helpUrl = '/help/visualize/viewers/web-logo.md';
|
|
@@ -6,17 +6,21 @@
|
|
|
6
6
|
|
|
7
7
|
import * as ui from 'datagrok-api/ui';
|
|
8
8
|
import * as DG from 'datagrok-api/dg';
|
|
9
|
-
|
|
10
9
|
import * as grok from 'datagrok-api/grok';
|
|
10
|
+
|
|
11
11
|
import wu from 'wu';
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
|
|
12
|
+
import {fromEvent, Subject, Subscription, Unsubscribable} from 'rxjs';
|
|
13
|
+
import {debounceTime} from 'rxjs/operators';
|
|
14
|
+
|
|
15
15
|
import {TAGS as bioTAGS, NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
16
|
+
import {errInfo, errStack} from '@datagrok-libraries/bio/src/utils/err-info';
|
|
16
17
|
import {delay} from '@datagrok-libraries/utils/src/test';
|
|
17
|
-
import {
|
|
18
|
+
import {IHelmWebEditor} from '@datagrok-libraries/bio/src/types/editor';
|
|
18
19
|
|
|
19
|
-
import {
|
|
20
|
+
import {helmSubstructureSearch, linearSubstructureSearch} from '../substructure-search/substructure-search';
|
|
21
|
+
import {updateDivInnerHTML} from '../utils/ui-utils';
|
|
22
|
+
|
|
23
|
+
import {_package} from '../package';
|
|
20
24
|
|
|
21
25
|
export class BioSubstructureFilter extends DG.Filter {
|
|
22
26
|
bioFilter: BioFilterBase | null = null;
|
|
@@ -84,6 +88,7 @@ export class BioSubstructureFilter extends DG.Filter {
|
|
|
84
88
|
}
|
|
85
89
|
|
|
86
90
|
detach() {
|
|
91
|
+
if (this.bioFilter) this.bioFilter.detach();
|
|
87
92
|
super.detach();
|
|
88
93
|
}
|
|
89
94
|
|
|
@@ -147,18 +152,16 @@ abstract class BioFilterBase {
|
|
|
147
152
|
return new HTMLElement();
|
|
148
153
|
}
|
|
149
154
|
|
|
150
|
-
get substructure()
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
set substructure(s: string) {
|
|
155
|
-
}
|
|
155
|
+
abstract get substructure(): string;
|
|
156
|
+
abstract set substructure(s: string);
|
|
156
157
|
|
|
157
158
|
async substructureSearch(_column: DG.Column): Promise<DG.BitSet | null> {
|
|
158
159
|
return null;
|
|
159
160
|
}
|
|
160
161
|
|
|
161
162
|
abstract resetFilter(): void;
|
|
163
|
+
|
|
164
|
+
abstract detach(): void;
|
|
162
165
|
}
|
|
163
166
|
|
|
164
167
|
class FastaFilter extends BioFilterBase {
|
|
@@ -191,6 +194,8 @@ class FastaFilter extends BioFilterBase {
|
|
|
191
194
|
resetFilter(): void {
|
|
192
195
|
this.substructureInput.value = '';
|
|
193
196
|
}
|
|
197
|
+
|
|
198
|
+
detach(): void { }
|
|
194
199
|
}
|
|
195
200
|
|
|
196
201
|
export class SeparatorFilter extends FastaFilter {
|
|
@@ -227,10 +232,12 @@ export class SeparatorFilter extends FastaFilter {
|
|
|
227
232
|
async substructureSearch(column: DG.Column): Promise<DG.BitSet | null> {
|
|
228
233
|
return linearSubstructureSearch(this.substructure, column, this.colSeparator);
|
|
229
234
|
}
|
|
235
|
+
|
|
236
|
+
detach(): void { }
|
|
230
237
|
}
|
|
231
238
|
|
|
232
239
|
export class HelmFilter extends BioFilterBase {
|
|
233
|
-
helmEditor:
|
|
240
|
+
helmEditor: IHelmWebEditor;
|
|
234
241
|
_filterPanel = ui.div('', {style: {cursor: 'pointer'}});
|
|
235
242
|
helmSubstructure = '';
|
|
236
243
|
|
|
@@ -239,14 +246,18 @@ export class HelmFilter extends BioFilterBase {
|
|
|
239
246
|
this.init();
|
|
240
247
|
}
|
|
241
248
|
|
|
249
|
+
viewSubs: Unsubscribable[] = [];
|
|
250
|
+
|
|
242
251
|
async init() {
|
|
243
|
-
this.helmEditor = await grok.functions.call('
|
|
252
|
+
this.helmEditor = await grok.functions.call('Helm:helmWebEditor');
|
|
244
253
|
await ui.tools.waitForElementInDom(this._filterPanel);
|
|
245
254
|
this.updateFilterPanel();
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
255
|
+
let editorDiv: HTMLDivElement | undefined;
|
|
256
|
+
let webEditor: any | undefined;
|
|
257
|
+
// TODO: Unsubscribe 'click' and 'sizeChanged'
|
|
258
|
+
this.viewSubs.push(fromEvent(this._filterPanel, 'click').subscribe(() => {
|
|
259
|
+
({editorDiv, webEditor} = this.helmEditor.createWebEditor(this.helmSubstructure));
|
|
260
|
+
const dlg = ui.dialog({showHeader: false, showFooter: true})
|
|
250
261
|
.add(editorDiv)
|
|
251
262
|
.onOK(() => {
|
|
252
263
|
const helmString = webEditor.canvas.getHelm(true)
|
|
@@ -255,12 +266,24 @@ export class HelmFilter extends BioFilterBase {
|
|
|
255
266
|
this.updateFilterPanel(this.substructure);
|
|
256
267
|
setTimeout(() => { this.onChanged.next(); }, 10);
|
|
257
268
|
}).show({modal: true, fullScreen: true});
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
});
|
|
269
|
+
const onCloseSub = dlg.onClose.subscribe(() => {
|
|
270
|
+
onCloseSub.unsubscribe();
|
|
271
|
+
editorDiv = undefined;
|
|
272
|
+
webEditor = undefined;
|
|
273
|
+
});
|
|
274
|
+
}));
|
|
275
|
+
this.viewSubs.push(ui.onSizeChanged(this._filterPanel).subscribe((_) => {
|
|
276
|
+
try {
|
|
277
|
+
if (!!webEditor) {
|
|
278
|
+
const helmString = webEditor.canvas.getHelm(true)
|
|
279
|
+
.replace(/<\/span>/g, '').replace(/<span style='background:#bbf;'>/g, '');
|
|
280
|
+
this.updateFilterPanel(helmString);
|
|
281
|
+
}
|
|
282
|
+
} catch (err: any) {
|
|
283
|
+
const [errMsg, errStack] = errInfo(err);
|
|
284
|
+
_package.logger.error(errMsg, undefined, errStack);
|
|
285
|
+
}
|
|
286
|
+
}));
|
|
264
287
|
}
|
|
265
288
|
|
|
266
289
|
get filterPanel() {
|
|
@@ -302,4 +325,8 @@ export class HelmFilter extends BioFilterBase {
|
|
|
302
325
|
this.helmSubstructure = '';
|
|
303
326
|
this.updateFilterPanel(this.substructure);
|
|
304
327
|
}
|
|
328
|
+
|
|
329
|
+
detach(): void {
|
|
330
|
+
for (const sub of this.viewSubs) sub.unsubscribe();
|
|
331
|
+
}
|
|
305
332
|
}
|