@datagrok/bio 2.15.13 → 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 +25 -0
- package/detectors.js +16 -11
- package/dist/455.js.map +1 -1
- package/dist/980.js +1 -1
- package/dist/980.js.map +1 -1
- package/dist/package-test.js +6 -6
- package/dist/package-test.js.map +1 -1
- package/dist/package.js +3 -3
- package/dist/package.js.map +1 -1
- package/package.json +14 -14
- package/src/analysis/sequence-activity-cliffs.ts +9 -8
- package/src/analysis/sequence-diversity-viewer.ts +6 -4
- package/src/analysis/sequence-similarity-viewer.ts +9 -6
- package/src/analysis/sequence-space.ts +3 -2
- package/src/calculations/monomerLevelMols.ts +4 -5
- package/src/demo/bio01-similarity-diversity.ts +4 -1
- package/src/package-test.ts +1 -1
- package/src/package-types.ts +34 -2
- package/src/package.ts +60 -76
- package/src/substructure-search/substructure-search.ts +15 -9
- package/src/tests/WebLogo-layout-tests.ts +1 -1
- package/src/tests/WebLogo-positions-test.ts +11 -5
- package/src/tests/WebLogo-project-tests.ts +1 -1
- package/src/tests/activity-cliffs-utils.ts +11 -14
- package/src/tests/bio-tests.ts +85 -79
- package/src/tests/checkInputColumn-tests.ts +15 -10
- package/src/tests/converters-test.ts +12 -5
- package/src/tests/detectors-benchmark-tests.ts +5 -2
- package/src/tests/detectors-tests.ts +51 -44
- package/src/tests/detectors-weak-and-likely-tests.ts +12 -5
- package/src/tests/fasta-export-tests.ts +13 -5
- package/src/tests/helm-tests.ts +85 -0
- package/src/tests/mm-distance-tests.ts +14 -7
- package/src/tests/monomer-libraries-tests.ts +1 -1
- package/src/tests/msa-tests.ts +33 -24
- package/src/tests/renderers-monomer-placer-tests.ts +2 -5
- package/src/tests/renderers-test.ts +15 -9
- package/src/tests/scoring.ts +9 -6
- package/src/tests/seq-handler-get-helm-tests.ts +7 -5
- package/src/tests/seq-handler-get-region-tests.ts +9 -3
- package/src/tests/seq-handler-splitted-tests.ts +11 -5
- package/src/tests/seq-handler-tests.ts +17 -10
- package/src/tests/sequence-space-utils.ts +9 -4
- package/src/tests/splitters-test.ts +5 -4
- package/src/tests/substructure-filters-tests.ts +22 -23
- package/src/tests/to-atomic-level-tests.ts +5 -3
- package/src/tests/to-atomic-level-ui-tests.ts +4 -1
- package/src/tests/utils/detectors-utils.ts +4 -4
- package/src/utils/calculate-scores.ts +11 -9
- package/src/utils/cell-renderer-custom.ts +27 -17
- package/src/utils/cell-renderer.ts +14 -8
- package/src/utils/check-input-column.ts +13 -9
- package/src/utils/context-menu.ts +4 -4
- package/src/utils/convert.ts +21 -14
- package/src/utils/get-region-func-editor.ts +8 -5
- package/src/utils/get-region.ts +4 -5
- package/src/utils/helm-to-molfile/converter/helm.ts +4 -4
- package/src/utils/helm-to-molfile/utils.ts +5 -6
- package/src/utils/macromolecule-column-widget.ts +6 -7
- package/src/utils/monomer-cell-renderer-base.ts +8 -1
- package/src/utils/monomer-lib/lib-manager.ts +3 -2
- package/src/utils/monomer-lib/monomer-colors.ts +10 -10
- package/src/utils/monomer-lib/monomer-lib-base.ts +6 -1
- package/src/utils/monomer-lib/monomer-lib.ts +15 -9
- package/src/utils/multiple-sequence-alignment-ui.ts +30 -30
- package/src/utils/save-as-fasta.ts +19 -12
- package/src/utils/seq-helper/seq-handler.ts +836 -0
- package/src/utils/seq-helper/seq-helper.ts +43 -19
- package/src/utils/sequence-to-mol.ts +7 -8
- package/src/utils/split-to-monomers.ts +7 -2
- package/src/utils/types.ts +8 -7
- package/src/utils/ui-utils.ts +2 -2
- package/src/viewers/web-logo-viewer.ts +18 -16
- package/src/widgets/bio-substructure-filter-helm.ts +5 -2
- package/src/widgets/bio-substructure-filter.ts +14 -24
- package/src/widgets/composition-analysis-widget.ts +6 -6
- package/src/widgets/representations.ts +7 -4
- package/src/tests/detectors-custom-notation-tests.ts +0 -37
- package/src/utils/cyclized.ts +0 -89
- package/src/utils/dimerized.ts +0 -10
|
@@ -15,9 +15,10 @@ import {getMolHighlight} from '@datagrok-libraries/bio/src/monomer-works/seq-to-
|
|
|
15
15
|
import {IMonomerLibBase} from '@datagrok-libraries/bio/src/types/index';
|
|
16
16
|
|
|
17
17
|
import {HelmToMolfileConverter} from '../helm-to-molfile/converter';
|
|
18
|
-
import {
|
|
19
|
-
|
|
20
|
-
import {
|
|
18
|
+
import {ISeqHandler} from '@datagrok-libraries/bio/src/utils/macromolecule/seq-handler';
|
|
19
|
+
import {SeqHandler} from './seq-handler';
|
|
20
|
+
import {Column} from 'datagrok-api/dg';
|
|
21
|
+
import {NOTATION, TAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
21
22
|
|
|
22
23
|
type SeqHelperWindowType = Window & { $seqHelperPromise?: Promise<SeqHelper> };
|
|
23
24
|
declare const window: SeqHelperWindowType;
|
|
@@ -25,12 +26,22 @@ declare const window: SeqHelperWindowType;
|
|
|
25
26
|
export class SeqHelper implements ISeqHelper {
|
|
26
27
|
constructor(
|
|
27
28
|
private readonly libHelper: IMonomerLibHelper,
|
|
28
|
-
private readonly helmHelper: IHelmHelper,
|
|
29
29
|
private readonly rdKitModule: RDModule
|
|
30
30
|
) {}
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
return
|
|
32
|
+
getSeqHandler(seqCol: DG.Column<string>): ISeqHandler {
|
|
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);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// TODO: Move to the Helm package
|
|
42
|
+
async getHelmToMolfileConverter(monomerLib: IMonomerLibBase): Promise<HelmToMolfileConverter> {
|
|
43
|
+
const helmHelper: IHelmHelper = await getHelmHelper();
|
|
44
|
+
return new HelmToMolfileConverter(helmHelper, this.rdKitModule, monomerLib);
|
|
34
45
|
}
|
|
35
46
|
|
|
36
47
|
async helmToAtomicLevel(
|
|
@@ -41,7 +52,7 @@ export class SeqHelper implements ISeqHelper {
|
|
|
41
52
|
const df: DG.DataFrame = helmCol.dataFrame;
|
|
42
53
|
const molColName: string = getMolColName(df, helmCol.name);
|
|
43
54
|
|
|
44
|
-
const converter = this.getHelmToMolfileConverter(monomerLib);
|
|
55
|
+
const converter = await this.getHelmToMolfileConverter(monomerLib);
|
|
45
56
|
|
|
46
57
|
//#region From HelmToMolfileConverter.convertToRdKitBeautifiedMolfileColumn
|
|
47
58
|
|
|
@@ -86,17 +97,30 @@ export class SeqHelper implements ISeqHelper {
|
|
|
86
97
|
return {molCol: molCol, warnings: []};
|
|
87
98
|
}
|
|
88
99
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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);
|
|
101
125
|
}
|
|
102
126
|
}
|
|
@@ -4,24 +4,23 @@ import * as DG from 'datagrok-api/dg';
|
|
|
4
4
|
|
|
5
5
|
import {_toAtomicLevel} from '@datagrok-libraries/bio/src/monomer-works/to-atomic-level';
|
|
6
6
|
import {IMonomerLib} from '@datagrok-libraries/bio/src/types';
|
|
7
|
-
import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
|
|
8
7
|
import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
9
|
-
import {getSeqHelper, ToAtomicLevelRes} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
8
|
+
import {getSeqHelper, ISeqHelper, ToAtomicLevelRes} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
10
9
|
import {RDModule} from '@datagrok-libraries/chem-meta/src/rdkit-api';
|
|
11
10
|
import {ChemTags, ChemTemps} from '@datagrok-libraries/chem-meta/src/consts';
|
|
12
11
|
import {buildMonomerHoverLink} from '@datagrok-libraries/bio/src/monomer-works/monomer-hover';
|
|
13
12
|
|
|
14
|
-
import {checkInputColumnUI} from './check-input-column';
|
|
13
|
+
import {checkInputColumn, checkInputColumnUI} from './check-input-column';
|
|
15
14
|
import {getMolColName} from '@datagrok-libraries/bio/src/monomer-works/utils';
|
|
16
15
|
|
|
17
16
|
export async function sequenceToMolfile(
|
|
18
17
|
df: DG.DataFrame, macroMolecule: DG.Column, nonlinear: boolean, highlight: boolean,
|
|
19
|
-
monomerLib: IMonomerLib, rdKitModule: RDModule
|
|
18
|
+
monomerLib: IMonomerLib, seqHelper: ISeqHelper, rdKitModule: RDModule
|
|
20
19
|
): Promise<ToAtomicLevelRes> {
|
|
21
20
|
let res: ToAtomicLevelRes;
|
|
22
21
|
if (nonlinear) {
|
|
23
22
|
const seqHelper = await getSeqHelper();
|
|
24
|
-
const seqSh =
|
|
23
|
+
const seqSh = seqHelper.getSeqHandler(macroMolecule);
|
|
25
24
|
|
|
26
25
|
let helmCol: DG.Column<string>;
|
|
27
26
|
let seqColName!: string;
|
|
@@ -43,10 +42,10 @@ export async function sequenceToMolfile(
|
|
|
43
42
|
}
|
|
44
43
|
}
|
|
45
44
|
} else { // linear
|
|
46
|
-
if (!
|
|
45
|
+
if (!checkInputColumn(macroMolecule, 'To Atomic Level', seqHelper)[0])
|
|
47
46
|
return {molCol: null, warnings: ['Column is not suitable']};
|
|
48
47
|
|
|
49
|
-
res = await _toAtomicLevel(df, macroMolecule, monomerLib, rdKitModule);
|
|
48
|
+
res = await _toAtomicLevel(df, macroMolecule, monomerLib, seqHelper, rdKitModule);
|
|
50
49
|
}
|
|
51
50
|
|
|
52
51
|
if (res.molCol) {
|
|
@@ -54,7 +53,7 @@ export async function sequenceToMolfile(
|
|
|
54
53
|
res.molCol.name = molColName;
|
|
55
54
|
df.columns.add(res.molCol, true);
|
|
56
55
|
|
|
57
|
-
buildMonomerHoverLink(macroMolecule, res.molCol, monomerLib, rdKitModule);
|
|
56
|
+
buildMonomerHoverLink(macroMolecule, res.molCol, monomerLib, seqHelper, rdKitModule);
|
|
58
57
|
res.molCol.setTag(ChemTags.SEQUENCE_SRC_HL_MONOMERS, String(highlight));
|
|
59
58
|
await grok.data.detectSemanticTypes(df);
|
|
60
59
|
}
|
|
@@ -8,15 +8,20 @@ import {splitAlignedSequences} from '@datagrok-libraries/bio/src/utils/splitter'
|
|
|
8
8
|
import * as C from './constants';
|
|
9
9
|
import {TAGS as bioTAGS} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
|
|
10
10
|
import {SEM_TYPES} from './constants';
|
|
11
|
+
import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
12
|
+
import {_package} from '../package';
|
|
11
13
|
|
|
12
14
|
|
|
13
|
-
export async function splitToMonomersUI(
|
|
15
|
+
export async function splitToMonomersUI(
|
|
16
|
+
table: DG.DataFrame, seqCol: DG.Column<string>
|
|
17
|
+
): Promise<DG.DataFrame> {
|
|
14
18
|
// Delay is required for initial function dialog to close before starting invalidating of molfiles.
|
|
15
19
|
// Otherwise, dialog is freezing
|
|
16
20
|
await delay(10);
|
|
17
21
|
if (!checkInputColumnUI(seqCol, 'Sequence space')) return table;
|
|
18
22
|
|
|
19
|
-
const
|
|
23
|
+
const seqHelper = _package.seqHelper;
|
|
24
|
+
const tempDf = splitAlignedSequences(seqCol, seqHelper);
|
|
20
25
|
tempDf.name = 'splitToMonomers';
|
|
21
26
|
const originalDf = seqCol.dataFrame;
|
|
22
27
|
for (const tempCol of tempDf.columns) {
|
package/src/utils/types.ts
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import * as DG from 'datagrok-api/dg';
|
|
2
2
|
import {pepseaMethods} from './pepsea';
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
export type DataFrameDict = { [key: string]: DG.DataFrame };
|
|
4
5
|
|
|
5
6
|
export namespace BarChart {
|
|
6
|
-
export type BarPart = {colName
|
|
7
|
-
export type BarStatsObject = {name: string, count: number, selectedCount: number};
|
|
7
|
+
export type BarPart = { colName: string, aaName: string };
|
|
8
|
+
export type BarStatsObject = { name: string, count: number, selectedCount: number };
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
export type UTypedArray = Uint8Array | Uint16Array | Uint32Array;
|
|
11
12
|
//AAR: (Position: (index: indexList))
|
|
12
13
|
export type SubstitutionsInfo = Map<string, Map<string, Map<number, number[] | UTypedArray>>>;
|
|
13
|
-
export type SelectionObject = {[
|
|
14
|
+
export type SelectionObject = { [position: string]: string[] };
|
|
14
15
|
|
|
15
|
-
export type
|
|
16
|
+
export type MultipleSequenceAlignmentUIOptions = {
|
|
16
17
|
col?: DG.Column<string> | null, clustersCol?: DG.Column | null,
|
|
17
|
-
pepsea?: {method?: typeof pepseaMethods[number], gapOpen?: number, gapExtend?: number},
|
|
18
|
-
kalign?: {gapOpen?: number, gapExtend?: number, terminalGap?: number}
|
|
18
|
+
pepsea?: { method?: typeof pepseaMethods[number], gapOpen?: number, gapExtend?: number },
|
|
19
|
+
kalign?: { gapOpen?: number, gapExtend?: number, terminalGap?: number }
|
|
19
20
|
};
|
package/src/utils/ui-utils.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as grok from 'datagrok-api/grok';
|
|
2
2
|
import * as DG from 'datagrok-api/dg';
|
|
3
3
|
|
|
4
|
-
export function getMacromoleculeColumns(): DG.Column<
|
|
4
|
+
export function getMacromoleculeColumns(): DG.Column<string>[] {
|
|
5
5
|
const columns = grok.shell.t.columns.bySemTypeAll(DG.SEMTYPE.MACROMOLECULE);
|
|
6
6
|
if (columns === null) {
|
|
7
7
|
grok.shell.error('Current table does not contain macromolecules');
|
|
8
|
-
return;
|
|
8
|
+
return [];
|
|
9
9
|
}
|
|
10
10
|
return columns;
|
|
11
11
|
}
|
|
@@ -6,7 +6,8 @@ import $ from 'cash-dom';
|
|
|
6
6
|
import wu from 'wu';
|
|
7
7
|
import {fromEvent, Observable, Subject, Unsubscribable} from 'rxjs';
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
10
|
+
import {ISeqHandler} from '@datagrok-libraries/bio/src/utils/macromolecule/seq-handler';
|
|
10
11
|
import {
|
|
11
12
|
monomerToShort, pickUpSeqCol, TAGS as bioTAGS, positionSeparator, ALPHABET
|
|
12
13
|
} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
@@ -308,7 +309,8 @@ export class WebLogoViewer extends DG.JsViewer implements IWebLogoViewer {
|
|
|
308
309
|
|
|
309
310
|
private viewed: boolean = false;
|
|
310
311
|
|
|
311
|
-
private
|
|
312
|
+
private seqHelper: ISeqHelper;
|
|
313
|
+
private seqHandler: ISeqHandler | null;
|
|
312
314
|
private initialized: boolean = false;
|
|
313
315
|
|
|
314
316
|
private monomerLib: IMonomerLibBase | null = null;
|
|
@@ -387,6 +389,7 @@ export class WebLogoViewer extends DG.JsViewer implements IWebLogoViewer {
|
|
|
387
389
|
constructor() {
|
|
388
390
|
super();
|
|
389
391
|
|
|
392
|
+
this.seqHelper = _package.seqHelper;
|
|
390
393
|
this.textBaseline = 'top';
|
|
391
394
|
this.seqHandler = null;
|
|
392
395
|
|
|
@@ -606,7 +609,7 @@ export class WebLogoViewer extends DG.JsViewer implements IWebLogoViewer {
|
|
|
606
609
|
}
|
|
607
610
|
if (this.seqCol) {
|
|
608
611
|
try {
|
|
609
|
-
this.seqHandler =
|
|
612
|
+
this.seqHandler = this.seqHelper.getSeqHandler(this.seqCol);
|
|
610
613
|
|
|
611
614
|
this.render(WlRenderLevel.Freqs, 'updateSeqCol()');
|
|
612
615
|
this.error = null;
|
|
@@ -1006,7 +1009,7 @@ export class WebLogoViewer extends DG.JsViewer implements IWebLogoViewer {
|
|
|
1006
1009
|
// endregion updatePositions
|
|
1007
1010
|
|
|
1008
1011
|
const length: number = this.startPosition <= this.endPosition ? this.endPosition - this.startPosition + 1 : 0;
|
|
1009
|
-
this.seqHandler =
|
|
1012
|
+
this.seqHandler = this.seqHelper.getSeqHandler(this.seqCol);
|
|
1010
1013
|
const posCount: number = this.startPosition <= this.endPosition ? this.endPosition - this.startPosition + 1 : 0;
|
|
1011
1014
|
this.positions = new Array(posCount);
|
|
1012
1015
|
for (let jPos = 0; jPos < length; jPos++) {
|
|
@@ -1073,7 +1076,7 @@ export class WebLogoViewer extends DG.JsViewer implements IWebLogoViewer {
|
|
|
1073
1076
|
const absoluteMaxHeight: number = this.canvas.height - positionLabelsHeight * dpr;
|
|
1074
1077
|
let alphabetSizeLog: number;
|
|
1075
1078
|
if (this.valueAggrType === DG.AGG.TOTAL_COUNT) {
|
|
1076
|
-
const alphabetSize: number = this.getAlphabetSize();
|
|
1079
|
+
const alphabetSize: number = this.seqHandler!.getAlphabetSize();
|
|
1077
1080
|
if ((this.positionHeight == PositionHeight.Entropy) && (alphabetSize == null))
|
|
1078
1081
|
grok.shell.error('WebLogo: alphabet is undefined.');
|
|
1079
1082
|
alphabetSizeLog = Math.log2(alphabetSize);
|
|
@@ -1139,8 +1142,7 @@ export class WebLogoViewer extends DG.JsViewer implements IWebLogoViewer {
|
|
|
1139
1142
|
// Hacks to scale uppercase characters to target rectangle
|
|
1140
1143
|
const uppercaseLetterAscent = 0.25;
|
|
1141
1144
|
const uppercaseLetterHeight = 12.2;
|
|
1142
|
-
const
|
|
1143
|
-
const biotype = sh.defaultBiotype;
|
|
1145
|
+
const biotype = this.seqHandler!.defaultBiotype;
|
|
1144
1146
|
for (let jPos = firstPos; jPos <= lastPos; jPos++)
|
|
1145
1147
|
this.positions[jPos].render(g, fontStyle, uppercaseLetterAscent, uppercaseLetterHeight, biotype, this.monomerLib);
|
|
1146
1148
|
} finally {
|
|
@@ -1165,9 +1167,9 @@ export class WebLogoViewer extends DG.JsViewer implements IWebLogoViewer {
|
|
|
1165
1167
|
private _lastWidth: number;
|
|
1166
1168
|
private _lastHeight: number;
|
|
1167
1169
|
|
|
1168
|
-
public getAlphabetSize(): number {
|
|
1169
|
-
|
|
1170
|
-
}
|
|
1170
|
+
// public getAlphabetSize(): number {
|
|
1171
|
+
// return this.seqHandler?.getAlphabetSize() ?? 0;
|
|
1172
|
+
// }
|
|
1171
1173
|
|
|
1172
1174
|
// -- Handle events --
|
|
1173
1175
|
|
|
@@ -1215,7 +1217,8 @@ export class WebLogoViewer extends DG.JsViewer implements IWebLogoViewer {
|
|
|
1215
1217
|
}
|
|
1216
1218
|
}
|
|
1217
1219
|
|
|
1218
|
-
private canvasOnMouseMove(e: MouseEvent) {
|
|
1220
|
+
private canvasOnMouseMove(e: MouseEvent): void {
|
|
1221
|
+
if (!this.monomerLib || !this.seqHandler) return;
|
|
1219
1222
|
const dpr = window.devicePixelRatio;
|
|
1220
1223
|
try {
|
|
1221
1224
|
const args = e as MouseEvent;
|
|
@@ -1224,13 +1227,12 @@ export class WebLogoViewer extends DG.JsViewer implements IWebLogoViewer {
|
|
|
1224
1227
|
const [pi, monomer] = this.getMonomer(cursorP, dpr);
|
|
1225
1228
|
const positionLabelHeight = this.showPositionLabels ? POSITION_LABELS_HEIGHT * dpr : 0;
|
|
1226
1229
|
|
|
1227
|
-
if (pi !== null && monomer === null && 0 <= cursorP.y && cursorP.y <= positionLabelHeight
|
|
1230
|
+
if (pi !== null && monomer === null && 0 <= cursorP.y && cursorP.y <= positionLabelHeight) {
|
|
1228
1231
|
// Position tooltip
|
|
1229
1232
|
|
|
1230
1233
|
const tooltipRows = [ui.divText(`Position ${pi.label}`)];
|
|
1231
1234
|
if (this.valueAggrType === DG.AGG.TOTAL_COUNT) {
|
|
1232
|
-
const
|
|
1233
|
-
const biotype = sh.defaultBiotype;
|
|
1235
|
+
const biotype = this.seqHandler!.defaultBiotype;
|
|
1234
1236
|
tooltipRows.push(pi.buildCompositionTable(biotype, this.monomerLib));
|
|
1235
1237
|
}
|
|
1236
1238
|
const tooltipEl = ui.divV(tooltipRows);
|
|
@@ -1356,7 +1358,7 @@ function renderPositionLabels(g: CanvasRenderingContext2D,
|
|
|
1356
1358
|
}
|
|
1357
1359
|
|
|
1358
1360
|
export function checkSeqForMonomerAtPos(
|
|
1359
|
-
df: DG.DataFrame, sh:
|
|
1361
|
+
df: DG.DataFrame, sh: ISeqHandler, filter: DG.BitSet, rowI: number, monomer: string, at: PositionInfo,
|
|
1360
1362
|
): boolean {
|
|
1361
1363
|
const seqMList: ISeqSplitted = sh.getSplitted(rowI);
|
|
1362
1364
|
const seqCM: string | null = at.pos < seqMList.length ? seqMList.getCanonical(at.pos) : null;
|
|
@@ -1364,7 +1366,7 @@ export function checkSeqForMonomerAtPos(
|
|
|
1364
1366
|
}
|
|
1365
1367
|
|
|
1366
1368
|
export function countForMonomerAtPosition(
|
|
1367
|
-
df: DG.DataFrame, sh:
|
|
1369
|
+
df: DG.DataFrame, sh: ISeqHandler, filter: DG.BitSet, monomer: string, at: PositionInfo
|
|
1368
1370
|
): number {
|
|
1369
1371
|
let count = 0;
|
|
1370
1372
|
let rowI = -1;
|
|
@@ -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`);
|
|
@@ -16,18 +16,16 @@ import {TAGS as bioTAGS, NOTATION} from '@datagrok-libraries/bio/src/utils/macro
|
|
|
16
16
|
import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
|
|
17
17
|
import {delay, testEvent} from '@datagrok-libraries/utils/src/test';
|
|
18
18
|
import {getHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
|
|
19
|
-
import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
|
|
20
19
|
import {IRenderer} from '@datagrok-libraries/bio/src/types/renderer';
|
|
21
20
|
import {ILogger} from '@datagrok-libraries/bio/src/utils/logger';
|
|
22
21
|
import {PromiseSyncer} from '@datagrok-libraries/bio/src/utils/syncer';
|
|
22
|
+
import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
23
23
|
|
|
24
24
|
import {helmSubstructureSearch, linearSubstructureSearch} from '../substructure-search/substructure-search';
|
|
25
25
|
import {updateDivInnerHTML} from '../utils/ui-utils';
|
|
26
26
|
import {BioFilterBase, BioFilterProps, IBioFilter, IFilterProps} from './bio-substructure-filter-types';
|
|
27
27
|
import {HelmBioFilter} from './bio-substructure-filter-helm';
|
|
28
28
|
|
|
29
|
-
import {_package} from '../package';
|
|
30
|
-
|
|
31
29
|
const FILTER_SYNC_EVENT: string = 'bio-substructure-filter';
|
|
32
30
|
|
|
33
31
|
class FilterState {
|
|
@@ -56,7 +54,6 @@ export class BioSubstructureFilter extends DG.Filter implements IRenderer {
|
|
|
56
54
|
readonly loader: HTMLDivElement;
|
|
57
55
|
notation: string | undefined = undefined;
|
|
58
56
|
|
|
59
|
-
readonly logger: ILogger;
|
|
60
57
|
readonly filterSyncer: PromiseSyncer;
|
|
61
58
|
|
|
62
59
|
get calculating(): boolean { return this.loader.style.display == 'initial'; }
|
|
@@ -88,22 +85,15 @@ export class BioSubstructureFilter extends DG.Filter implements IRenderer {
|
|
|
88
85
|
return res;
|
|
89
86
|
}
|
|
90
87
|
|
|
91
|
-
constructor(
|
|
88
|
+
constructor(
|
|
89
|
+
private readonly seqHelper: ISeqHelper,
|
|
90
|
+
private logger: ILogger
|
|
91
|
+
) {
|
|
92
92
|
super();
|
|
93
93
|
this.root = ui.divV([]);
|
|
94
94
|
this.loader = ui.loader();
|
|
95
95
|
this.calculating = false;
|
|
96
|
-
this.filterSyncer = new PromiseSyncer(this.logger
|
|
97
|
-
|
|
98
|
-
return new Proxy(this, {
|
|
99
|
-
set(target: any, key, value) {
|
|
100
|
-
if (key === 'column') {
|
|
101
|
-
const k = 42;
|
|
102
|
-
}
|
|
103
|
-
target[key] = value;
|
|
104
|
-
return true;
|
|
105
|
-
}
|
|
106
|
-
});
|
|
96
|
+
this.filterSyncer = new PromiseSyncer(this.logger);
|
|
107
97
|
}
|
|
108
98
|
|
|
109
99
|
private static filterCounter: number = -1;
|
|
@@ -125,13 +115,13 @@ export class BioSubstructureFilter extends DG.Filter implements IRenderer {
|
|
|
125
115
|
else
|
|
126
116
|
this.column = dataFrame.columns.bySemType(DG.SEMTYPE.MACROMOLECULE);
|
|
127
117
|
}
|
|
128
|
-
const sh =
|
|
118
|
+
const sh = this.seqHelper.getSeqHandler(this.column!);
|
|
129
119
|
this.columnName ??= this.column?.name;
|
|
130
120
|
this.notation ??= this.column?.meta.units!;
|
|
131
121
|
|
|
132
122
|
this.bioFilter = this.notation === NOTATION.FASTA ?
|
|
133
123
|
new FastaBioFilter() : this.notation === NOTATION.SEPARATOR ?
|
|
134
|
-
new SeparatorBioFilter(this.column!.getTag(bioTAGS.separator)) : new HelmBioFilter();
|
|
124
|
+
new SeparatorBioFilter(this.column!.getTag(bioTAGS.separator)) : new HelmBioFilter(this.seqHelper);
|
|
135
125
|
this.root.appendChild(this.bioFilter!.filterPanel);
|
|
136
126
|
this.root.appendChild(this.loader);
|
|
137
127
|
await this.bioFilter.attach(); // may await waitForElementInDom
|
|
@@ -201,7 +191,7 @@ export class BioSubstructureFilter extends DG.Filter implements IRenderer {
|
|
|
201
191
|
|
|
202
192
|
private fireFilterSync(): void {
|
|
203
193
|
const logPrefix = `${this.filterToLog()}.fireFilterSync()`;
|
|
204
|
-
|
|
194
|
+
this.logger.debug(`${logPrefix}, ` +
|
|
205
195
|
`bioFilter = ${!!this.bioFilter ? this.bioFilter.constructor.name : 'null'}` +
|
|
206
196
|
(!!this.bioFilter ? `, props = ${JSON.stringify(this.bioFilter!.saveProps())}` : ''));
|
|
207
197
|
|
|
@@ -219,7 +209,7 @@ export class BioSubstructureFilter extends DG.Filter implements IRenderer {
|
|
|
219
209
|
bioFilterOnChangedDebounced(): void {
|
|
220
210
|
if (!this.dataFrame) return; // Debounced event can be handled postponed
|
|
221
211
|
const logPrefix = `${this.filterToLog()}.bioFilterOnChangedDebounced()`;
|
|
222
|
-
|
|
212
|
+
this.logger.debug(`${logPrefix}, start, ` +
|
|
223
213
|
`isFiltering = ${this.isFiltering}, ` +
|
|
224
214
|
`props = ${JSON.stringify(this.bioFilter!.saveProps())}`);
|
|
225
215
|
|
|
@@ -236,22 +226,22 @@ export class BioSubstructureFilter extends DG.Filter implements IRenderer {
|
|
|
236
226
|
this.filterSyncer.sync(logPrefix, async () => {
|
|
237
227
|
this.calculating = true;
|
|
238
228
|
try {
|
|
239
|
-
|
|
229
|
+
this.logger.debug(`${logPrefix}, before substructureSearch`);
|
|
240
230
|
this.bitset = await this.bioFilter?.substructureSearch(this.column!)!;
|
|
241
|
-
|
|
231
|
+
this.logger.debug(`${logPrefix}, after substructureSearch`);
|
|
242
232
|
this.calculating = false;
|
|
243
233
|
this.fireFilterSync();
|
|
244
234
|
this.dataFrame?.rows.requestFilter();
|
|
245
235
|
} finally {
|
|
246
236
|
this.calculating = false;
|
|
247
|
-
|
|
237
|
+
this.logger.debug(`${logPrefix}, end`);
|
|
248
238
|
}
|
|
249
239
|
});
|
|
250
240
|
}
|
|
251
241
|
|
|
252
242
|
grokEventsOnResetFilterRequest(): void {
|
|
253
243
|
const logPrefix = `${this.filterToLog()}.grokEventsOnResetFilterRequest()`;
|
|
254
|
-
|
|
244
|
+
this.logger.debug(`${logPrefix}`);
|
|
255
245
|
this.bioFilter?.resetFilter();
|
|
256
246
|
}
|
|
257
247
|
|
|
@@ -4,25 +4,25 @@ import * as DG from 'datagrok-api/dg';
|
|
|
4
4
|
|
|
5
5
|
import wu from 'wu';
|
|
6
6
|
|
|
7
|
-
import {TAGS as bioTAGS, ALPHABET
|
|
8
|
-
import {SeqPalette} from '@datagrok-libraries/bio/src/seq-palettes';
|
|
9
|
-
import {UnknownSeqPalettes} from '@datagrok-libraries/bio/src/unknown';
|
|
10
|
-
import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
|
|
7
|
+
import {TAGS as bioTAGS, ALPHABET} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
11
8
|
import {GAP_SYMBOL} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
|
|
12
9
|
import {IMonomerLibBase} from '@datagrok-libraries/bio/src/types';
|
|
13
10
|
import {HelmType} from '@datagrok-libraries/bio/src/helm/types';
|
|
14
11
|
import {HelmTypes} from '@datagrok-libraries/bio/src/helm/consts';
|
|
15
12
|
|
|
16
13
|
import '../../css/composition-analysis.css';
|
|
14
|
+
import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
17
15
|
|
|
18
|
-
export function getCompositionAnalysisWidget(
|
|
16
|
+
export function getCompositionAnalysisWidget(
|
|
17
|
+
val: DG.SemanticValue, monomerLib: IMonomerLibBase, seqHelper: ISeqHelper
|
|
18
|
+
): DG.Widget {
|
|
19
19
|
const host = ui.div();
|
|
20
20
|
host.classList.add('macromolecule-cell-comp-analysis-host');
|
|
21
21
|
const alphabet = val.cell.column.tags[bioTAGS.alphabet];
|
|
22
22
|
const biotype = alphabet === ALPHABET.DNA || alphabet === ALPHABET.RNA ? HelmTypes.NUCLEOTIDE : HelmTypes.AA;
|
|
23
23
|
|
|
24
24
|
const counts: { [m: string]: number } = {};
|
|
25
|
-
const sh =
|
|
25
|
+
const sh = seqHelper.getSeqHandler(val.cell.column as DG.Column<string>);
|
|
26
26
|
const rowIdx = val.cell.rowIndex;
|
|
27
27
|
const seqSS = sh.getSplitted(rowIdx);
|
|
28
28
|
wu.count(0).take(seqSS.length).filter((posIdx) => !seqSS.isGap(posIdx)).forEach((posIdx) => {
|
|
@@ -2,13 +2,13 @@ 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 {getMolfilesFromSingleSeq} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
|
|
6
5
|
import {TAGS as mmcrTAGS} from '@datagrok-libraries/bio/src/utils/cell-renderer';
|
|
7
6
|
|
|
8
7
|
import {MmcrTemps, rendererSettingsChangedState} from '@datagrok-libraries/bio/src/utils/cell-renderer-consts';
|
|
8
|
+
import {ISeqHelper} from '@datagrok-libraries/bio/src/utils/seq-helper';
|
|
9
|
+
import {getMolfilesFromSingleSeq} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
|
|
9
10
|
|
|
10
11
|
import {_package} from '../package';
|
|
11
|
-
import {max} from 'rxjs/operators';
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
/**
|
|
@@ -105,16 +105,19 @@ export function getMacromoleculeColumnPropertyPanel(col: DG.Column): DG.Widget {
|
|
|
105
105
|
* @export
|
|
106
106
|
* @param {DG.Cell} macroMolecule macromolecule cell.
|
|
107
107
|
* @param {any[]} monomersLibObject
|
|
108
|
+
* @param {ISeqHelper} seqHelper
|
|
108
109
|
* @return {Promise<DG.Widget>} Widget.
|
|
109
110
|
*/
|
|
110
|
-
export async function representationsWidget(
|
|
111
|
+
export async function representationsWidget(
|
|
112
|
+
macroMolecule: DG.Cell, monomersLibObject: any[], seqHelper: ISeqHelper
|
|
113
|
+
): Promise<DG.Widget> {
|
|
111
114
|
const pi = DG.TaskBarProgressIndicator.create('Creating 3D view');
|
|
112
115
|
|
|
113
116
|
let widgetHost;
|
|
114
117
|
let molBlock3D = '';
|
|
115
118
|
try {
|
|
116
119
|
try {
|
|
117
|
-
const _atomicCodes = getMolfilesFromSingleSeq(macroMolecule, monomersLibObject);
|
|
120
|
+
const _atomicCodes = getMolfilesFromSingleSeq(macroMolecule, monomersLibObject, seqHelper);
|
|
118
121
|
const result = '';//await getMacroMol(atomicCodes!);
|
|
119
122
|
const molBlock2D = result[0];
|
|
120
123
|
molBlock3D = (await grok.functions.call('Bio:Embed', {molBlock2D})) as unknown as string;
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import * as grok from 'datagrok-api/grok';
|
|
2
|
-
import * as ui from 'datagrok-api/ui';
|
|
3
|
-
import * as DG from 'datagrok-api/dg';
|
|
4
|
-
|
|
5
|
-
import {category, test} from '@datagrok-libraries/utils/src/test';
|
|
6
|
-
import {ALIGNMENT, ALPHABET, NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
|
|
7
|
-
|
|
8
|
-
import {_testNeg, _testPos, DetectorTestData, DfReaderFunc, PosCol} from './utils/detectors-utils';
|
|
9
|
-
|
|
10
|
-
category('detectors: custom', () => {
|
|
11
|
-
const tests: DetectorTestData = {
|
|
12
|
-
'cyclized1': {
|
|
13
|
-
csv: `n,seq
|
|
14
|
-
1,R-F-C(1)-T-G-H-F-Y-G-H-F-Y-G-H-F-Y-P-C(1)-meI
|
|
15
|
-
2,C(1)-T-G-H-F-Y-P-C(1)-meI
|
|
16
|
-
3,R-F-C(1)-T-G-H-F-Y-P-C(1)
|
|
17
|
-
4,C(1)-T-G-H-F-H-P-C(1)
|
|
18
|
-
5,R-F-D(2)-T-G-H-F-Y-P-NH2(2)
|
|
19
|
-
6,R-F-aG(3)-T-G-H-F-Y-P-azG(3)-meI`,
|
|
20
|
-
pos: {'seq': new PosCol(NOTATION.CUSTOM, ALIGNMENT.SEQ, ALPHABET.UN, 13, true, '-')}
|
|
21
|
-
},
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
for (const [testName, testData] of Object.entries(tests)) {
|
|
25
|
-
test(`${testName}`, async () => {
|
|
26
|
-
const reader: DfReaderFunc = async (): Promise<DG.DataFrame> => {
|
|
27
|
-
return DG.DataFrame.fromCsv(testData.csv);
|
|
28
|
-
};
|
|
29
|
-
for (const negColName of testData.neg ?? [])
|
|
30
|
-
await _testNeg(reader, negColName);
|
|
31
|
-
for (const [posColName, posCol] of Object.entries(testData.pos ?? {})) {
|
|
32
|
-
await _testPos(reader, posColName, posCol.units, posCol.aligned,
|
|
33
|
-
posCol.alphabet, posCol.alphabetSize, posCol.alphabetIsMultichar, posCol.separator);
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
});
|