@datagrok/bio 2.16.8 → 2.17.0
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-test.js +2 -2
- package/dist/package-test.js.map +1 -1
- package/dist/package.js +2 -2
- package/dist/package.js.map +1 -1
- package/files/tests/peptides_with_random_motif_1600.csv +1601 -0
- package/package.json +2 -2
- package/src/package.ts +34 -38
- package/src/tests/activity-cliffs-tests.ts +1 -1
- package/src/tests/sequence-space-test.ts +1 -1
- package/src/utils/cell-renderer-custom.ts +3 -1
- package/src/utils/cell-renderer.ts +62 -14
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"name": "Aleksandr Tanas",
|
|
6
6
|
"email": "atanas@datagrok.ai"
|
|
7
7
|
},
|
|
8
|
-
"version": "2.
|
|
8
|
+
"version": "2.17.0",
|
|
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.7",
|
|
41
41
|
"@datagrok-libraries/chem-meta": "^1.2.7",
|
|
42
42
|
"@datagrok-libraries/math": "^1.2.2",
|
|
43
43
|
"@datagrok-libraries/ml": "^6.7.4",
|
package/src/package.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/* eslint-disable max-params */
|
|
2
|
+
/* eslint-disable max-len */
|
|
1
3
|
/* eslint max-lines: "off" */
|
|
2
4
|
import * as grok from 'datagrok-api/grok';
|
|
3
5
|
import * as ui from 'datagrok-api/ui';
|
|
@@ -9,7 +11,7 @@ import {getActivityCliffs} from '@datagrok-libraries/ml/src/viewers/activity-cli
|
|
|
9
11
|
import {MmDistanceFunctionsNames} from '@datagrok-libraries/ml/src/macromolecule-distance-functions';
|
|
10
12
|
import {BitArrayMetrics, KnownMetrics} from '@datagrok-libraries/ml/src/typed-metrics';
|
|
11
13
|
import {NOTATION, TAGS as bioTAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
12
|
-
import {IMonomerLib
|
|
14
|
+
import {IMonomerLib} from '@datagrok-libraries/bio/src/types';
|
|
13
15
|
import {SeqPalette} from '@datagrok-libraries/bio/src/seq-palettes';
|
|
14
16
|
import {FastaFileHandler} from '@datagrok-libraries/bio/src/utils/fasta-handler';
|
|
15
17
|
import {SCORE} from '@datagrok-libraries/bio/src/utils/macromolecule/scoring';
|
|
@@ -24,14 +26,13 @@ import {ITSNEOptions, IUMAPOptions} from '@datagrok-libraries/ml/src/multi-colum
|
|
|
24
26
|
import {generateLongSequence, generateLongSequence2} from '@datagrok-libraries/bio/src/utils/generator';
|
|
25
27
|
import {getUserLibSettings, setUserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
|
|
26
28
|
import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
27
|
-
import {RDModule} from '@datagrok-libraries/chem-meta/src/rdkit-api';
|
|
29
|
+
import {RDModule as _RDMoule} from '@datagrok-libraries/chem-meta/src/rdkit-api';
|
|
28
30
|
import {getRdKitModule} from '@datagrok-libraries/bio/src/chem/rdkit-module';
|
|
29
31
|
import {ISeqHandler} from '@datagrok-libraries/bio/src/utils/macromolecule/seq-handler';
|
|
30
32
|
import {MmcrTemps} from '@datagrok-libraries/bio/src/utils/cell-renderer-consts';
|
|
31
33
|
|
|
32
34
|
import {getMacromoleculeColumns} from './utils/ui-utils';
|
|
33
35
|
import {MacromoleculeDifferenceCellRenderer, MacromoleculeSequenceCellRenderer,} from './utils/cell-renderer';
|
|
34
|
-
import {MacromoleculeCustomCellRenderer} from './utils/cell-renderer-custom';
|
|
35
36
|
import {VdRegionsViewer} from './viewers/vd-regions-viewer';
|
|
36
37
|
import {SequenceAlignment} from './seq_align';
|
|
37
38
|
import {getEncodedSeqSpaceCol} from './analysis/sequence-space';
|
|
@@ -102,52 +103,46 @@ let initBioPromise: Promise<void> | null = null;
|
|
|
102
103
|
|
|
103
104
|
//tags: init
|
|
104
105
|
export async function initBio(): Promise<void> {
|
|
105
|
-
if (initBioPromise === null)
|
|
106
|
+
if (initBioPromise === null)
|
|
106
107
|
initBioPromise = initBioInt();
|
|
107
|
-
|
|
108
|
+
|
|
108
109
|
await initBioPromise;
|
|
109
110
|
}
|
|
110
111
|
|
|
111
112
|
async function initBioInt() {
|
|
112
113
|
const logPrefix = 'Bio: _package.initBio()';
|
|
113
114
|
_package.logger.debug(`${logPrefix}, start`);
|
|
114
|
-
let monomerLib!: IMonomerLib;
|
|
115
|
-
let monomerSets!: IMonomerSet;
|
|
116
|
-
let rdKitModule!: RDModule;
|
|
117
|
-
let libHelper!: MonomerLibManager;
|
|
118
115
|
const t1: number = window.performance.now();
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
const bioPkgProps = new BioPackageProperties(pkgProps);
|
|
138
|
-
_package.properties = bioPkgProps;
|
|
139
|
-
})(),
|
|
140
|
-
(async () => { rdKitModule = await getRdKitModule(); })(),
|
|
141
|
-
]).finally(() => {
|
|
142
|
-
const t2: number = window.performance.now();
|
|
143
|
-
_package.logger.debug(`${logPrefix}, loading ET: ${t2 - t1} ms`);
|
|
116
|
+
// very important that loading should happen in correct order!
|
|
117
|
+
// first make sure chem and rdkit module are loaded
|
|
118
|
+
const rdKitModule = await getRdKitModule();
|
|
119
|
+
// then load package settings
|
|
120
|
+
const pkgProps = await _package.getProperties();
|
|
121
|
+
const bioPkgProps = new BioPackageProperties(pkgProps);
|
|
122
|
+
_package.properties = bioPkgProps;
|
|
123
|
+
// then load monomer lib
|
|
124
|
+
const libHelper = await MonomerLibManager.getInstance();
|
|
125
|
+
// Fix user lib settings for explicit stuck from a terminated test
|
|
126
|
+
const libSettings = await getUserLibSettings();
|
|
127
|
+
if (libSettings.explicit) {
|
|
128
|
+
libSettings.explicit = [];
|
|
129
|
+
await setUserLibSettings(libSettings);
|
|
130
|
+
}
|
|
131
|
+
libHelper.awaitLoaded(Infinity).then(() => {
|
|
132
|
+
// Do not wait for monomers and sets loaded
|
|
133
|
+
return Promise.all([libHelper.loadMonomerLib(), libHelper.loadMonomerSets()]);
|
|
144
134
|
});
|
|
145
|
-
const
|
|
146
|
-
|
|
135
|
+
const monomerLib = libHelper.getMonomerLib();
|
|
136
|
+
const monomerSets = libHelper.getMonomerSets();
|
|
137
|
+
// finally log
|
|
138
|
+
const t2: number = window.performance.now();
|
|
139
|
+
_package.logger.debug(`${logPrefix}, loading ET: ${t2 - t1} ms`);
|
|
147
140
|
|
|
148
141
|
const monomers: string[] = [];
|
|
149
142
|
const logPs: number[] = [];
|
|
150
143
|
|
|
144
|
+
const seqHelper = new SeqHelper(libHelper, rdKitModule);
|
|
145
|
+
_package.completeInit(seqHelper, monomerLib, monomerSets, rdKitModule);
|
|
151
146
|
const series = monomerLib!.getMonomerMolsByPolymerType('PEPTIDE')!;
|
|
152
147
|
Object.keys(series).forEach((symbol) => {
|
|
153
148
|
monomers.push(symbol);
|
|
@@ -324,7 +319,7 @@ export function SeqActivityCliffsEditor(call: DG.FuncCall) {
|
|
|
324
319
|
//meta.columnTags: quality=Macromolecule, units=custom
|
|
325
320
|
//output: grid_cell_renderer result
|
|
326
321
|
export function customSequenceCellRenderer(): DG.GridCellRenderer {
|
|
327
|
-
return new
|
|
322
|
+
return new MacromoleculeSequenceCellRenderer();
|
|
328
323
|
}
|
|
329
324
|
|
|
330
325
|
//name: fastaSequenceCellRenderer
|
|
@@ -770,7 +765,7 @@ export function convertDialog() {
|
|
|
770
765
|
export async function convertSeqNotation(sequence: string, targetNotation: NOTATION, separator?: string): Promise<string | undefined | null> {
|
|
771
766
|
try {
|
|
772
767
|
const col = DG.Column.fromStrings('sequence', [sequence]);
|
|
773
|
-
const
|
|
768
|
+
const _df = DG.DataFrame.fromColumns([col]);
|
|
774
769
|
const semType = await grok.functions.call('Bio:detectMacromolecule', {col: col});
|
|
775
770
|
if (semType)
|
|
776
771
|
col.semType = semType;
|
|
@@ -1216,6 +1211,7 @@ export async function detectMacromoleculeProbe(file: DG.FileInfo, colName: strin
|
|
|
1216
1211
|
//name: getSeqHelper
|
|
1217
1212
|
//output: object result
|
|
1218
1213
|
export async function getSeqHelper(): Promise<ISeqHelper> {
|
|
1214
|
+
await initBio();
|
|
1219
1215
|
return _package.seqHelper;
|
|
1220
1216
|
}
|
|
1221
1217
|
|
|
@@ -44,7 +44,7 @@ category('activityCliffs', async () => {
|
|
|
44
44
|
test('activityCliffsOpens', async () => {
|
|
45
45
|
const testData = !DG.Test.isInBenchmark ?
|
|
46
46
|
{fileName: 'tests/100_3_clustests.csv', tgt: {cliffCount: 3}} :
|
|
47
|
-
{fileName: 'tests/
|
|
47
|
+
{fileName: 'tests/peptides_with_random_motif_1600.csv', tgt: {cliffCount: 64}};
|
|
48
48
|
const actCliffsDf = await readDataframe(testData.fileName);
|
|
49
49
|
const actCliffsTableView = grok.shell.addTableView(actCliffsDf);
|
|
50
50
|
|
|
@@ -16,7 +16,7 @@ category('sequenceSpace', async () => {
|
|
|
16
16
|
test('sequenceSpaceOpens', async () => {
|
|
17
17
|
const testData = !DG.Test.isInBenchmark ?
|
|
18
18
|
{fileName: 'tests/100_3_clustests.csv'} :
|
|
19
|
-
{fileName: 'tests/
|
|
19
|
+
{fileName: 'tests/peptides_with_random_motif_1600.csv'};
|
|
20
20
|
testFastaDf = await readDataframe(testData.fileName);
|
|
21
21
|
testFastaTableView = grok.shell.addTableView(testFastaDf);
|
|
22
22
|
await _testSequenceSpaceReturnsResult(testFastaDf, DimReductionMethods.UMAP, 'sequence');
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable max-len */
|
|
1
2
|
import * as grok from 'datagrok-api/grok';
|
|
2
3
|
import * as DG from 'datagrok-api/dg';
|
|
3
4
|
import * as ui from 'datagrok-api/ui';
|
|
@@ -8,6 +9,7 @@ import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
|
8
9
|
|
|
9
10
|
import {_package} from '../package';
|
|
10
11
|
|
|
12
|
+
/// NB! UNUSED LEGACY CODE
|
|
11
13
|
export class MacromoleculeCustomCellRenderer extends DG.GridCellRenderer {
|
|
12
14
|
private readonly seqHelper: ISeqHelper;
|
|
13
15
|
|
|
@@ -41,7 +43,7 @@ export class MacromoleculeCustomCellRenderer extends DG.GridCellRenderer {
|
|
|
41
43
|
back?.onMouseEnter(gridCell, e);
|
|
42
44
|
}
|
|
43
45
|
|
|
44
|
-
override onMouseLeave(
|
|
46
|
+
override onMouseLeave(_gridCell: DG.GridCell, _e: MouseEvent) {
|
|
45
47
|
// TODO: We get gridCell from another column here, so we can not get back object from the column rendered.
|
|
46
48
|
ui.tooltip.hide();
|
|
47
49
|
// const back = this.getRendererBack(gridCell);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable max-len */
|
|
1
2
|
/* eslint-disable max-lines */
|
|
2
3
|
/* eslint-disable max-params */
|
|
3
4
|
/* eslint-disable max-lines-per-function */
|
|
@@ -22,7 +23,7 @@ import {getSplitter} from '@datagrok-libraries/bio/src/utils/macromolecule/utils
|
|
|
22
23
|
import {IMonomerLibBase} from '@datagrok-libraries/bio/src/types';
|
|
23
24
|
import {GapOriginals} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
|
|
24
25
|
import {execMonomerHoverLinks} from '@datagrok-libraries/bio/src/monomer-works/monomer-hover';
|
|
25
|
-
import {getGridCellColTemp} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
|
|
26
|
+
import {CellRendererBackBase, getGridCellColTemp} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
|
|
26
27
|
import {HelmTypes} from '@datagrok-libraries/bio/src/helm/consts';
|
|
27
28
|
import {MmcrTemps, rendererSettingsChangedState, tempTAGS} from '@datagrok-libraries/bio/src/utils/cell-renderer-consts';
|
|
28
29
|
|
|
@@ -53,6 +54,7 @@ export function processSequence(subParts: string[]): [string[], boolean] {
|
|
|
53
54
|
return [text, simplified];
|
|
54
55
|
}
|
|
55
56
|
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
56
58
|
type RendererGridCellTemp = {
|
|
57
59
|
[MmcrTemps.monomerPlacer]: MonomerPlacer
|
|
58
60
|
}
|
|
@@ -73,21 +75,58 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
73
75
|
this.seqHelper = _package.seqHelper;
|
|
74
76
|
}
|
|
75
77
|
|
|
76
|
-
|
|
78
|
+
getRendererBack(gridCell: DG.GridCell): CellRendererBackBase<string> | null {
|
|
79
|
+
const [gridCol, tableCol, _temp] = getGridCellColTemp<string, any>(gridCell);
|
|
80
|
+
if (tableCol.meta.units !== NOTATION.CUSTOM)
|
|
81
|
+
return _temp.rendererBack;
|
|
82
|
+
let back: CellRendererBackBase<string> | null = null;
|
|
83
|
+
|
|
84
|
+
if (this.seqHelper) {
|
|
85
|
+
const sh = this.seqHelper.getSeqHandler(tableCol);
|
|
86
|
+
back = sh.getRendererBack(gridCol, tableCol);
|
|
87
|
+
}
|
|
88
|
+
return back;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
override onClick(gridCell: DG.GridCell, _e: MouseEvent): void {
|
|
77
92
|
const colTemp: TempType = gridCell.cell.column.temp;
|
|
78
93
|
colTemp[tempTAGS.currentWord] = gridCell.cell.value;
|
|
79
94
|
gridCell.grid.invalidate();
|
|
95
|
+
if (gridCell.cell.column.meta.units === NOTATION.CUSTOM) {
|
|
96
|
+
const back = this.getRendererBack(gridCell);
|
|
97
|
+
back?.onClick(gridCell, _e);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
override onMouseEnter(gridCell: DG.GridCell, e: MouseEvent) {
|
|
102
|
+
const back = this.getRendererBack(gridCell);
|
|
103
|
+
back?.onMouseEnter(gridCell, e);
|
|
80
104
|
}
|
|
81
105
|
|
|
82
106
|
override onMouseMove(gridCell: DG.GridCell, e: MouseEvent): void {
|
|
83
|
-
const
|
|
84
|
-
|
|
107
|
+
const back = this.getRendererBack(gridCell);
|
|
108
|
+
back?.onMouseMove(gridCell, e);
|
|
85
109
|
}
|
|
86
110
|
|
|
87
|
-
override onMouseLeave(gridCell: DG.GridCell,
|
|
111
|
+
override onMouseLeave(gridCell: DG.GridCell, _e: MouseEvent) {
|
|
88
112
|
execMonomerHoverLinks(gridCell, null);
|
|
89
113
|
}
|
|
90
114
|
|
|
115
|
+
override onDoubleClick(gridCell: DG.GridCell, e: MouseEvent) {
|
|
116
|
+
const back = this.getRendererBack(gridCell);
|
|
117
|
+
back?.onDoubleClick(gridCell, e);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
override onKeyDown(gridCell: DG.GridCell, e: KeyboardEvent) {
|
|
121
|
+
const back = this.getRendererBack(gridCell);
|
|
122
|
+
back?.onKeyDown(gridCell, e);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
override onKeyPress(gridCell: DG.GridCell, e: KeyboardEvent) {
|
|
126
|
+
const back = this.getRendererBack(gridCell);
|
|
127
|
+
back?.onKeyPress(gridCell, e);
|
|
128
|
+
}
|
|
129
|
+
|
|
91
130
|
/**
|
|
92
131
|
* Cell renderer function.
|
|
93
132
|
*
|
|
@@ -99,11 +138,11 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
99
138
|
* @param {DG.GridCell} gridCell Grid cell.
|
|
100
139
|
* @param {DG.GridCellStyle} _cellStyle Cell style.
|
|
101
140
|
*/
|
|
102
|
-
|
|
141
|
+
renderInt(
|
|
103
142
|
g: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, gridCell: DG.GridCell,
|
|
104
143
|
_cellStyle: DG.GridCellStyle
|
|
105
144
|
): void {
|
|
106
|
-
const
|
|
145
|
+
const _logPrefix: string = 'MacromoleculeSequenceCellRenderer.render()';
|
|
107
146
|
|
|
108
147
|
const [gridCol, tableCol, temp] =
|
|
109
148
|
getGridCellColTemp<string, MonomerPlacer>(gridCell);
|
|
@@ -111,7 +150,7 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
111
150
|
const tableColTemp: TempType = tableCol.temp;
|
|
112
151
|
const sh = this.seqHelper.getSeqHandler(tableCol);
|
|
113
152
|
|
|
114
|
-
|
|
153
|
+
const gapLength = 0;
|
|
115
154
|
const msaGapLength = 8;
|
|
116
155
|
|
|
117
156
|
// Cell renderer settings
|
|
@@ -140,6 +179,15 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
|
|
|
140
179
|
|
|
141
180
|
seqColTemp.render(g, x, y, w, h, gridCell, _cellStyle);
|
|
142
181
|
}
|
|
182
|
+
|
|
183
|
+
override render(g: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, gridCell: DG.GridCell, cellStyle: DG.GridCellStyle): void {
|
|
184
|
+
if (gridCell.cell.column?.meta?.units === NOTATION.CUSTOM) {
|
|
185
|
+
const back = this.getRendererBack(gridCell);
|
|
186
|
+
back?.render(g, x, y, w, h, gridCell, cellStyle);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
this.renderInt(g, x, y, w, h, gridCell, cellStyle);
|
|
190
|
+
}
|
|
143
191
|
}
|
|
144
192
|
|
|
145
193
|
export class MacromoleculeDifferenceCellRendererBack extends CellRendererWithMonomerLibBackBase {
|
|
@@ -151,7 +199,7 @@ export class MacromoleculeDifferenceCellRendererBack extends CellRendererWithMon
|
|
|
151
199
|
}
|
|
152
200
|
|
|
153
201
|
render(g: CanvasRenderingContext2D,
|
|
154
|
-
x: number, y: number, w: number, h: number, gridCell: DG.GridCell,
|
|
202
|
+
x: number, y: number, w: number, h: number, gridCell: DG.GridCell, _cellStyle: DG.GridCellStyle
|
|
155
203
|
): void {
|
|
156
204
|
const dpr = window.devicePixelRatio;
|
|
157
205
|
const grid = gridCell.grid;
|
|
@@ -172,7 +220,7 @@ export class MacromoleculeDifferenceCellRendererBack extends CellRendererWithMon
|
|
|
172
220
|
drawMoleculeDifferenceOnCanvas(g, x, y, w, h, subParts1, subParts2, biotype, this.monomerLib, undefined, undefined);
|
|
173
221
|
}
|
|
174
222
|
|
|
175
|
-
async awaitRendered(timeout: number = 10000,
|
|
223
|
+
async awaitRendered(timeout: number = 10000, _reason: string = `${timeout} timeout`): Promise<void> {
|
|
176
224
|
return Promise.resolve();
|
|
177
225
|
}
|
|
178
226
|
|
|
@@ -258,15 +306,15 @@ export function drawMoleculeDifferenceOnCanvas(
|
|
|
258
306
|
const amino2 = subParts2[i];
|
|
259
307
|
|
|
260
308
|
let color1 = undefinedColor;
|
|
261
|
-
if (monomerLib)
|
|
309
|
+
if (monomerLib)
|
|
262
310
|
color1 = monomerLib.getMonomerTextColor(biotype, amino1);
|
|
263
|
-
|
|
311
|
+
|
|
264
312
|
|
|
265
313
|
if (amino1 != amino2) {
|
|
266
314
|
let color2 = undefinedColor;
|
|
267
|
-
if (monomerLib)
|
|
315
|
+
if (monomerLib)
|
|
268
316
|
color2 = monomerLib.getMonomerTextColor(biotype, amino2);
|
|
269
|
-
|
|
317
|
+
|
|
270
318
|
const subX0 = printLeftOrCentered(g, amino1, updatedX, updatedY - vShift, w, h,
|
|
271
319
|
{color: color1, pivot: 0, left: true});
|
|
272
320
|
const subX1 = printLeftOrCentered(g, amino2, updatedX, updatedY + vShift, w, h,
|