@jbrowse/plugin-variants 3.1.0 → 3.2.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/dist/MultiLinearVariantDisplay/model.d.ts +19 -0
- package/dist/MultiLinearVariantMatrixDisplay/model.d.ts +20 -0
- package/dist/MultiLinearVariantMatrixDisplay/model.js +4 -1
- package/dist/MultiLinearVariantMatrixRenderer/makeImageData.js +9 -1
- package/dist/MultiLinearVariantRenderer/makeImageData.js +9 -1
- package/dist/VariantRPC/MultiVariantClusterGenotypeMatrix.d.ts +28 -0
- package/dist/VariantRPC/MultiVariantClusterGenotypeMatrix.js +33 -0
- package/dist/VariantRPC/MultiVariantGetGenotypeMatrix.d.ts +13 -11
- package/dist/VariantRPC/MultiVariantGetGenotypeMatrix.js +5 -57
- package/dist/VariantRPC/MultiVariantGetSimplifiedFeatures.d.ts +11 -8
- package/dist/VariantRPC/MultiVariantGetSimplifiedFeatures.js +1 -2
- package/dist/VariantRPC/cluster.d.ts +17 -0
- package/dist/VariantRPC/cluster.js +84 -0
- package/dist/VariantRPC/getGenotypeMatrix.d.ts +6 -0
- package/dist/VariantRPC/getGenotypeMatrix.js +55 -0
- package/dist/VariantRPC/types.d.ts +13 -0
- package/dist/VariantRPC/types.js +2 -0
- package/dist/VcfAdapter/VcfAdapter.js +6 -3
- package/dist/VcfFeature/util.js +2 -2
- package/dist/VcfTabixAdapter/VcfTabixAdapter.js +11 -6
- package/dist/index.js +2 -0
- package/dist/shared/MultiVariantBaseModel.d.ts +19 -0
- package/dist/shared/MultiVariantBaseModel.js +27 -35
- package/dist/shared/components/ClusterDialog/ClusterDialog.d.ts +6 -0
- package/dist/shared/components/ClusterDialog/ClusterDialog.js +29 -0
- package/dist/shared/components/ClusterDialog/ClusterDialogAuto.d.ts +7 -0
- package/dist/shared/components/ClusterDialog/ClusterDialogAuto.js +69 -0
- package/dist/shared/components/ClusterDialog/ClusterDialogManual.d.ts +7 -0
- package/dist/shared/components/ClusterDialog/ClusterDialogManual.js +144 -0
- package/dist/shared/components/ClusterDialog/types.d.ts +9 -0
- package/dist/shared/components/ClusterDialog/types.js +2 -0
- package/dist/shared/components/SourcesDataGrid.js +47 -40
- package/dist/shared/components/SourcesGridHeader.js +2 -2
- package/dist/shared/getSources.d.ts +15 -0
- package/dist/shared/getSources.js +34 -0
- package/esm/MultiLinearVariantDisplay/model.d.ts +19 -0
- package/esm/MultiLinearVariantMatrixDisplay/model.d.ts +20 -0
- package/esm/MultiLinearVariantMatrixDisplay/model.js +4 -1
- package/esm/MultiLinearVariantMatrixRenderer/makeImageData.js +9 -1
- package/esm/MultiLinearVariantRenderer/makeImageData.js +9 -1
- package/esm/VariantRPC/MultiVariantClusterGenotypeMatrix.d.ts +28 -0
- package/esm/VariantRPC/MultiVariantClusterGenotypeMatrix.js +26 -0
- package/esm/VariantRPC/MultiVariantGetGenotypeMatrix.d.ts +13 -11
- package/esm/VariantRPC/MultiVariantGetGenotypeMatrix.js +5 -57
- package/esm/VariantRPC/MultiVariantGetSimplifiedFeatures.d.ts +11 -8
- package/esm/VariantRPC/MultiVariantGetSimplifiedFeatures.js +1 -2
- package/esm/VariantRPC/cluster.d.ts +17 -0
- package/esm/VariantRPC/cluster.js +79 -0
- package/esm/VariantRPC/getGenotypeMatrix.d.ts +6 -0
- package/esm/VariantRPC/getGenotypeMatrix.js +52 -0
- package/esm/VariantRPC/types.d.ts +13 -0
- package/esm/VariantRPC/types.js +1 -0
- package/esm/VcfAdapter/VcfAdapter.js +7 -4
- package/esm/VcfFeature/util.js +2 -2
- package/esm/VcfTabixAdapter/VcfTabixAdapter.js +11 -6
- package/esm/index.js +2 -0
- package/esm/shared/MultiVariantBaseModel.d.ts +19 -0
- package/esm/shared/MultiVariantBaseModel.js +27 -35
- package/esm/shared/components/ClusterDialog/ClusterDialog.d.ts +6 -0
- package/esm/shared/components/ClusterDialog/ClusterDialog.js +24 -0
- package/esm/shared/components/ClusterDialog/ClusterDialogAuto.d.ts +7 -0
- package/esm/shared/components/ClusterDialog/ClusterDialogAuto.js +67 -0
- package/esm/shared/components/ClusterDialog/ClusterDialogManual.d.ts +7 -0
- package/esm/shared/components/ClusterDialog/ClusterDialogManual.js +139 -0
- package/esm/shared/components/ClusterDialog/types.d.ts +9 -0
- package/esm/shared/components/ClusterDialog/types.js +1 -0
- package/esm/shared/components/SourcesDataGrid.js +47 -40
- package/esm/shared/components/SourcesGridHeader.js +2 -2
- package/esm/shared/getSources.d.ts +15 -0
- package/esm/shared/getSources.js +31 -0
- package/package.json +6 -6
- package/dist/shared/components/ClusterDialog.d.ts +0 -11
- package/dist/shared/components/ClusterDialog.js +0 -113
- package/esm/shared/components/ClusterDialog.d.ts +0 -11
- package/esm/shared/components/ClusterDialog.js +0 -107
|
@@ -259,6 +259,15 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
259
259
|
setSampleInfo(arg: Record<string, import("../shared/types").SampleInfo>): void;
|
|
260
260
|
} & {
|
|
261
261
|
readonly preSources: import("../shared/types").Source[] | undefined;
|
|
262
|
+
readonly sourcesWithoutLayout: {
|
|
263
|
+
label: string;
|
|
264
|
+
id: string;
|
|
265
|
+
baseUri?: string;
|
|
266
|
+
name: string;
|
|
267
|
+
color?: string;
|
|
268
|
+
group?: string;
|
|
269
|
+
HP?: number;
|
|
270
|
+
}[] | undefined;
|
|
262
271
|
readonly sources: {
|
|
263
272
|
label: string;
|
|
264
273
|
id: string;
|
|
@@ -334,10 +343,20 @@ export declare function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
334
343
|
type?: undefined;
|
|
335
344
|
checked?: undefined;
|
|
336
345
|
onClick?: undefined;
|
|
346
|
+
} | {
|
|
347
|
+
label: string;
|
|
348
|
+
icon: import("@mui/material/OverridableComponent").OverridableComponent<import("@mui/material").SvgIconTypeMap<{}, "svg">> & {
|
|
349
|
+
muiName: string;
|
|
350
|
+
};
|
|
351
|
+
onClick: () => void;
|
|
352
|
+
type?: undefined;
|
|
353
|
+
checked?: undefined;
|
|
354
|
+
subMenu?: undefined;
|
|
337
355
|
})[];
|
|
338
356
|
} & {
|
|
339
357
|
readonly canDisplayLabels: boolean;
|
|
340
358
|
readonly totalHeight: number;
|
|
359
|
+
readonly featuresReady: boolean;
|
|
341
360
|
} & {
|
|
342
361
|
renderProps(): any;
|
|
343
362
|
} & {
|
|
@@ -258,6 +258,15 @@ export default function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
258
258
|
setSampleInfo(arg: Record<string, import("../shared/types").SampleInfo>): void;
|
|
259
259
|
} & {
|
|
260
260
|
readonly preSources: import("../shared/types").Source[] | undefined;
|
|
261
|
+
readonly sourcesWithoutLayout: {
|
|
262
|
+
label: string;
|
|
263
|
+
id: string;
|
|
264
|
+
baseUri?: string;
|
|
265
|
+
name: string;
|
|
266
|
+
color?: string;
|
|
267
|
+
group?: string;
|
|
268
|
+
HP?: number;
|
|
269
|
+
}[] | undefined;
|
|
261
270
|
readonly sources: {
|
|
262
271
|
label: string;
|
|
263
272
|
id: string;
|
|
@@ -333,10 +342,20 @@ export default function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
333
342
|
type?: undefined;
|
|
334
343
|
checked?: undefined;
|
|
335
344
|
onClick?: undefined;
|
|
345
|
+
} | {
|
|
346
|
+
label: string;
|
|
347
|
+
icon: import("@mui/material/OverridableComponent").OverridableComponent<import("@mui/material").SvgIconTypeMap<{}, "svg">> & {
|
|
348
|
+
muiName: string;
|
|
349
|
+
};
|
|
350
|
+
onClick: () => void;
|
|
351
|
+
type?: undefined;
|
|
352
|
+
checked?: undefined;
|
|
353
|
+
subMenu?: undefined;
|
|
336
354
|
})[];
|
|
337
355
|
} & {
|
|
338
356
|
readonly canDisplayLabels: boolean;
|
|
339
357
|
readonly totalHeight: number;
|
|
358
|
+
readonly featuresReady: boolean;
|
|
340
359
|
} & {
|
|
341
360
|
renderProps(): any;
|
|
342
361
|
} & {
|
|
@@ -344,6 +363,7 @@ export default function stateModelFactory(configSchema: AnyConfigurationSchemaTy
|
|
|
344
363
|
readonly blockType: string;
|
|
345
364
|
readonly totalHeight: number;
|
|
346
365
|
readonly rowHeight: number;
|
|
366
|
+
readonly featuresReady: boolean;
|
|
347
367
|
} & {
|
|
348
368
|
renderProps(): any;
|
|
349
369
|
readonly canDisplayLabels: boolean;
|
|
@@ -65,13 +65,16 @@ function stateModelFactory(configSchema) {
|
|
|
65
65
|
? self.totalHeight / this.nrow
|
|
66
66
|
: self.rowHeightSetting;
|
|
67
67
|
},
|
|
68
|
+
get featuresReady() {
|
|
69
|
+
return !!self.featuresVolatile;
|
|
70
|
+
},
|
|
68
71
|
}))
|
|
69
72
|
.views(self => ({
|
|
70
73
|
renderProps() {
|
|
71
74
|
const superProps = self.adapterProps();
|
|
72
75
|
return {
|
|
73
76
|
...superProps,
|
|
74
|
-
notReady: superProps.notReady || !self.sources || !self.
|
|
77
|
+
notReady: superProps.notReady || !self.sources || !self.featuresReady,
|
|
75
78
|
renderingMode: self.renderingMode,
|
|
76
79
|
minorAlleleFrequencyFilter: self.minorAlleleFrequencyFilter,
|
|
77
80
|
height: self.totalHeight,
|
|
@@ -2,21 +2,29 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.makeImageData = makeImageData;
|
|
4
4
|
const util_1 = require("@jbrowse/core/util");
|
|
5
|
+
const stopToken_1 = require("@jbrowse/core/util/stopToken");
|
|
5
6
|
const constants_1 = require("../shared/constants");
|
|
6
7
|
const drawAlleleCount_1 = require("../shared/drawAlleleCount");
|
|
7
8
|
const drawPhased_1 = require("../shared/drawPhased");
|
|
8
9
|
const minorAlleleFrequencyUtils_1 = require("../shared/minorAlleleFrequencyUtils");
|
|
9
10
|
async function makeImageData({ ctx, canvasWidth, canvasHeight, renderArgs, }) {
|
|
10
|
-
const { renderingMode: renderingMode, minorAlleleFrequencyFilter, sources, features, } = renderArgs;
|
|
11
|
+
const { renderingMode: renderingMode, minorAlleleFrequencyFilter, sources, features, stopToken, } = renderArgs;
|
|
11
12
|
const { statusCallback = () => { } } = renderArgs;
|
|
12
13
|
const h = canvasHeight / sources.length;
|
|
14
|
+
(0, stopToken_1.checkStopToken)(stopToken);
|
|
13
15
|
const mafs = (0, minorAlleleFrequencyUtils_1.getFeaturesThatPassMinorAlleleFrequencyFilter)(features.values(), minorAlleleFrequencyFilter);
|
|
16
|
+
(0, stopToken_1.checkStopToken)(stopToken);
|
|
14
17
|
const arr = [];
|
|
15
18
|
const m = mafs.length;
|
|
16
19
|
const w = canvasWidth / m;
|
|
17
20
|
await (0, util_1.updateStatus)('Drawing variant matrix', statusCallback, () => {
|
|
18
21
|
var _a, _b, _c;
|
|
22
|
+
let start = performance.now();
|
|
19
23
|
for (let i = 0; i < m; i++) {
|
|
24
|
+
if (performance.now() - start > 400) {
|
|
25
|
+
(0, stopToken_1.checkStopToken)(stopToken);
|
|
26
|
+
start = performance.now();
|
|
27
|
+
}
|
|
20
28
|
const arr2 = [];
|
|
21
29
|
const { feature, mostFrequentAlt } = mafs[i];
|
|
22
30
|
const hasPhaseSet = (_a = feature.get('FORMAT')) === null || _a === void 0 ? void 0 : _a.includes('PS');
|
|
@@ -5,17 +5,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.makeImageData = makeImageData;
|
|
7
7
|
const util_1 = require("@jbrowse/core/util");
|
|
8
|
+
const stopToken_1 = require("@jbrowse/core/util/stopToken");
|
|
8
9
|
const rbush_1 = __importDefault(require("rbush"));
|
|
9
10
|
const constants_1 = require("../shared/constants");
|
|
10
11
|
const drawAlleleCount_1 = require("../shared/drawAlleleCount");
|
|
11
12
|
const drawPhased_1 = require("../shared/drawPhased");
|
|
12
13
|
const minorAlleleFrequencyUtils_1 = require("../shared/minorAlleleFrequencyUtils");
|
|
13
14
|
async function makeImageData(ctx, props) {
|
|
14
|
-
const { scrollTop, minorAlleleFrequencyFilter, sources, rowHeight, features, regions, bpPerPx, renderingMode, } = props;
|
|
15
|
+
const { scrollTop, minorAlleleFrequencyFilter, sources, rowHeight, features, regions, bpPerPx, renderingMode, stopToken, } = props;
|
|
15
16
|
const region = regions[0];
|
|
17
|
+
(0, stopToken_1.checkStopToken)(stopToken);
|
|
16
18
|
const mafs = (0, minorAlleleFrequencyUtils_1.getFeaturesThatPassMinorAlleleFrequencyFilter)(features.values(), minorAlleleFrequencyFilter);
|
|
19
|
+
(0, stopToken_1.checkStopToken)(stopToken);
|
|
17
20
|
const rbush = new rbush_1.default();
|
|
21
|
+
let start = performance.now();
|
|
18
22
|
for (const { mostFrequentAlt, feature } of mafs) {
|
|
23
|
+
if (performance.now() - start > 400) {
|
|
24
|
+
(0, stopToken_1.checkStopToken)(stopToken);
|
|
25
|
+
start = performance.now();
|
|
26
|
+
}
|
|
19
27
|
const [leftPx, rightPx] = (0, util_1.featureSpanPx)(feature, region, bpPerPx);
|
|
20
28
|
const w = Math.max(Math.round(rightPx - leftPx), 2);
|
|
21
29
|
const samp = feature.get('genotypes');
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import RpcMethodTypeWithFiltersAndRenameRegions from '@jbrowse/core/pluggableElementTypes/RpcMethodTypeWithFiltersAndRenameRegions';
|
|
2
|
+
import type { Source } from '../shared/types';
|
|
3
|
+
import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
|
|
4
|
+
import type { Region } from '@jbrowse/core/util';
|
|
5
|
+
interface Args {
|
|
6
|
+
adapterConfig: AnyConfigurationModel;
|
|
7
|
+
stopToken?: string;
|
|
8
|
+
statusCallback: (arg: string) => void;
|
|
9
|
+
sessionId: string;
|
|
10
|
+
headers?: Record<string, string>;
|
|
11
|
+
regions: Region[];
|
|
12
|
+
bpPerPx: number;
|
|
13
|
+
sources: Source[];
|
|
14
|
+
minorAlleleFrequencyFilter: number;
|
|
15
|
+
}
|
|
16
|
+
export declare class MultiVariantClusterGenotypeMatrix extends RpcMethodTypeWithFiltersAndRenameRegions {
|
|
17
|
+
name: string;
|
|
18
|
+
execute(args: Args, rpcDriverClassName: string): Promise<{
|
|
19
|
+
clusters: {
|
|
20
|
+
height: number;
|
|
21
|
+
indexes: number[];
|
|
22
|
+
} | undefined;
|
|
23
|
+
distances: number[][];
|
|
24
|
+
order: number[];
|
|
25
|
+
clustersGivenK: number[][][];
|
|
26
|
+
}>;
|
|
27
|
+
}
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.MultiVariantClusterGenotypeMatrix = void 0;
|
|
7
|
+
const RpcMethodTypeWithFiltersAndRenameRegions_1 = __importDefault(require("@jbrowse/core/pluggableElementTypes/RpcMethodTypeWithFiltersAndRenameRegions"));
|
|
8
|
+
const cluster_1 = require("./cluster");
|
|
9
|
+
const getGenotypeMatrix_1 = require("./getGenotypeMatrix");
|
|
10
|
+
class MultiVariantClusterGenotypeMatrix extends RpcMethodTypeWithFiltersAndRenameRegions_1.default {
|
|
11
|
+
constructor() {
|
|
12
|
+
super(...arguments);
|
|
13
|
+
this.name = 'MultiVariantClusterGenotypeMatrix';
|
|
14
|
+
}
|
|
15
|
+
async execute(args, rpcDriverClassName) {
|
|
16
|
+
const deserializedArgs = await this.deserializeArguments(args, rpcDriverClassName);
|
|
17
|
+
const matrix = await (0, getGenotypeMatrix_1.getGenotypeMatrix)({
|
|
18
|
+
pluginManager: this.pluginManager,
|
|
19
|
+
args: deserializedArgs,
|
|
20
|
+
});
|
|
21
|
+
return (0, cluster_1.clusterData)({
|
|
22
|
+
data: Object.values(matrix),
|
|
23
|
+
onProgress: a => {
|
|
24
|
+
deserializedArgs.statusCallback(`${toP(a * 100)}%`);
|
|
25
|
+
},
|
|
26
|
+
stopToken: deserializedArgs.stopToken,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.MultiVariantClusterGenotypeMatrix = MultiVariantClusterGenotypeMatrix;
|
|
31
|
+
function toP(n) {
|
|
32
|
+
return Number.parseFloat(n.toPrecision(3));
|
|
33
|
+
}
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import RpcMethodTypeWithFiltersAndRenameRegions from '@jbrowse/core/pluggableElementTypes/RpcMethodTypeWithFiltersAndRenameRegions';
|
|
2
|
+
import type { Source } from '../shared/types';
|
|
2
3
|
import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
|
|
3
4
|
import type { Region } from '@jbrowse/core/util';
|
|
5
|
+
interface Args {
|
|
6
|
+
adapterConfig: AnyConfigurationModel;
|
|
7
|
+
stopToken?: string;
|
|
8
|
+
sessionId: string;
|
|
9
|
+
headers?: Record<string, string>;
|
|
10
|
+
regions: Region[];
|
|
11
|
+
bpPerPx: number;
|
|
12
|
+
sources: Source[];
|
|
13
|
+
minorAlleleFrequencyFilter: number;
|
|
14
|
+
}
|
|
4
15
|
export declare class MultiVariantGetGenotypeMatrix extends RpcMethodTypeWithFiltersAndRenameRegions {
|
|
5
16
|
name: string;
|
|
6
|
-
execute(args:
|
|
7
|
-
adapterConfig: AnyConfigurationModel;
|
|
8
|
-
stopToken?: string;
|
|
9
|
-
sessionId: string;
|
|
10
|
-
headers?: Record<string, string>;
|
|
11
|
-
regions: Region[];
|
|
12
|
-
bpPerPx: number;
|
|
13
|
-
}, rpcDriverClassName: string): Promise<Record<string, {
|
|
14
|
-
name: string;
|
|
15
|
-
genotypes: string[];
|
|
16
|
-
}>>;
|
|
17
|
+
execute(args: Args, rpcDriverClassName: string): Promise<Record<string, number[]>>;
|
|
17
18
|
}
|
|
19
|
+
export {};
|
|
@@ -4,70 +4,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.MultiVariantGetGenotypeMatrix = void 0;
|
|
7
|
-
const dataAdapterCache_1 = require("@jbrowse/core/data_adapters/dataAdapterCache");
|
|
8
7
|
const RpcMethodTypeWithFiltersAndRenameRegions_1 = __importDefault(require("@jbrowse/core/pluggableElementTypes/RpcMethodTypeWithFiltersAndRenameRegions"));
|
|
9
|
-
const
|
|
10
|
-
const minorAlleleFrequencyUtils_1 = require("../shared/minorAlleleFrequencyUtils");
|
|
8
|
+
const getGenotypeMatrix_1 = require("./getGenotypeMatrix");
|
|
11
9
|
class MultiVariantGetGenotypeMatrix extends RpcMethodTypeWithFiltersAndRenameRegions_1.default {
|
|
12
10
|
constructor() {
|
|
13
11
|
super(...arguments);
|
|
14
12
|
this.name = 'MultiVariantGetGenotypeMatrix';
|
|
15
13
|
}
|
|
16
14
|
async execute(args, rpcDriverClassName) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const dataAdapter = adapter.dataAdapter;
|
|
22
|
-
const feats = await (0, rxjs_1.firstValueFrom)(dataAdapter
|
|
23
|
-
.getFeaturesInMultipleRegions(regions, deserializedArgs)
|
|
24
|
-
.pipe((0, rxjs_1.toArray)()));
|
|
25
|
-
const genotypeFactor = new Set();
|
|
26
|
-
const mafs = (0, minorAlleleFrequencyUtils_1.getFeaturesThatPassMinorAlleleFrequencyFilter)(feats, minorAlleleFrequencyFilter);
|
|
27
|
-
for (const { alleleCounts } of mafs) {
|
|
28
|
-
for (const alt of alleleCounts.keys()) {
|
|
29
|
-
genotypeFactor.add(alt);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
const rows = {};
|
|
33
|
-
for (const { feature } of mafs) {
|
|
34
|
-
const genotypes = feature.get('genotypes');
|
|
35
|
-
for (const { name } of sources) {
|
|
36
|
-
if (!rows[name]) {
|
|
37
|
-
rows[name] = {
|
|
38
|
-
name,
|
|
39
|
-
genotypes: [],
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
const val = genotypes[name];
|
|
43
|
-
const alleles = val.split(/[/|]/);
|
|
44
|
-
let genotypeStatus = '0';
|
|
45
|
-
let nonRefCount = 0;
|
|
46
|
-
let uncalledCount = 0;
|
|
47
|
-
for (const l of alleles) {
|
|
48
|
-
if (l === '.') {
|
|
49
|
-
uncalledCount++;
|
|
50
|
-
}
|
|
51
|
-
else if (l !== '0') {
|
|
52
|
-
nonRefCount++;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
if (uncalledCount === alleles.length) {
|
|
56
|
-
genotypeStatus = '-1';
|
|
57
|
-
}
|
|
58
|
-
else if (nonRefCount === 0) {
|
|
59
|
-
genotypeStatus = '0';
|
|
60
|
-
}
|
|
61
|
-
else if (nonRefCount === alleles.length) {
|
|
62
|
-
genotypeStatus = '2';
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
genotypeStatus = '1';
|
|
66
|
-
}
|
|
67
|
-
rows[name].genotypes.push(genotypeStatus);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
return rows;
|
|
15
|
+
return (0, getGenotypeMatrix_1.getGenotypeMatrix)({
|
|
16
|
+
pluginManager: this.pluginManager,
|
|
17
|
+
args: await this.deserializeArguments(args, rpcDriverClassName),
|
|
18
|
+
});
|
|
71
19
|
}
|
|
72
20
|
}
|
|
73
21
|
exports.MultiVariantGetGenotypeMatrix = MultiVariantGetGenotypeMatrix;
|
|
@@ -2,16 +2,18 @@ import RpcMethodTypeWithFiltersAndRenameRegions from '@jbrowse/core/pluggableEle
|
|
|
2
2
|
import type { SampleInfo } from '../shared/types';
|
|
3
3
|
import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
|
|
4
4
|
import type { Region } from '@jbrowse/core/util';
|
|
5
|
+
interface Args {
|
|
6
|
+
adapterConfig: AnyConfigurationModel;
|
|
7
|
+
stopToken?: string;
|
|
8
|
+
sessionId: string;
|
|
9
|
+
headers?: Record<string, string>;
|
|
10
|
+
regions: Region[];
|
|
11
|
+
bpPerPx: number;
|
|
12
|
+
minorAlleleFrequencyFilter: number;
|
|
13
|
+
}
|
|
5
14
|
export declare class MultiVariantGetSimplifiedFeatures extends RpcMethodTypeWithFiltersAndRenameRegions {
|
|
6
15
|
name: string;
|
|
7
|
-
execute(args: {
|
|
8
|
-
adapterConfig: AnyConfigurationModel;
|
|
9
|
-
stopToken?: string;
|
|
10
|
-
sessionId: string;
|
|
11
|
-
headers?: Record<string, string>;
|
|
12
|
-
regions: Region[];
|
|
13
|
-
bpPerPx: number;
|
|
14
|
-
}, rpcDriverClassName: string): Promise<{
|
|
16
|
+
execute(args: Args, rpcDriverClassName: string): Promise<{
|
|
15
17
|
hasPhased: boolean;
|
|
16
18
|
sampleInfo: Record<string, SampleInfo>;
|
|
17
19
|
features: {
|
|
@@ -24,3 +26,4 @@ export declare class MultiVariantGetSimplifiedFeatures extends RpcMethodTypeWith
|
|
|
24
26
|
}[];
|
|
25
27
|
}>;
|
|
26
28
|
}
|
|
29
|
+
export {};
|
|
@@ -15,10 +15,9 @@ class MultiVariantGetSimplifiedFeatures extends RpcMethodTypeWithFiltersAndRenam
|
|
|
15
15
|
}
|
|
16
16
|
async execute(args, rpcDriverClassName) {
|
|
17
17
|
var _a, _b;
|
|
18
|
-
const pm = this.pluginManager;
|
|
19
18
|
const deserializedArgs = await this.deserializeArguments(args, rpcDriverClassName);
|
|
20
19
|
const { minorAlleleFrequencyFilter, regions, adapterConfig, sessionId } = deserializedArgs;
|
|
21
|
-
const { dataAdapter } = await (0, dataAdapterCache_1.getAdapter)(
|
|
20
|
+
const { dataAdapter } = await (0, dataAdapterCache_1.getAdapter)(this.pluginManager, sessionId, adapterConfig);
|
|
22
21
|
const feats = await (0, rxjs_1.firstValueFrom)(dataAdapter
|
|
23
22
|
.getFeaturesInMultipleRegions(regions, deserializedArgs)
|
|
24
23
|
.pipe((0, rxjs_1.toArray)()));
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare function euclideanDistance(a: number[], b: number[]): number;
|
|
2
|
+
export declare function averageDistance(setA: number[], setB: number[], distances: number[][]): number;
|
|
3
|
+
export declare function clusterData({ data, distance, linkage, onProgress, stopToken, }: {
|
|
4
|
+
data: number[][];
|
|
5
|
+
distance?: (a: number[], b: number[]) => number;
|
|
6
|
+
linkage?: (a: number[], b: number[], distances: number[][]) => number;
|
|
7
|
+
onProgress?: (a: number) => void;
|
|
8
|
+
stopToken?: string;
|
|
9
|
+
}): {
|
|
10
|
+
clusters: {
|
|
11
|
+
height: number;
|
|
12
|
+
indexes: number[];
|
|
13
|
+
} | undefined;
|
|
14
|
+
distances: number[][];
|
|
15
|
+
order: number[];
|
|
16
|
+
clustersGivenK: number[][][];
|
|
17
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.euclideanDistance = euclideanDistance;
|
|
4
|
+
exports.averageDistance = averageDistance;
|
|
5
|
+
exports.clusterData = clusterData;
|
|
6
|
+
const stopToken_1 = require("@jbrowse/core/util/stopToken");
|
|
7
|
+
function euclideanDistance(a, b) {
|
|
8
|
+
const size = Math.min(a.length, b.length);
|
|
9
|
+
let sum = 0;
|
|
10
|
+
for (let index = 0; index < size; index++) {
|
|
11
|
+
sum += (a[index] - b[index]) * (a[index] - b[index]);
|
|
12
|
+
}
|
|
13
|
+
return Math.sqrt(sum);
|
|
14
|
+
}
|
|
15
|
+
function averageDistance(setA, setB, distances) {
|
|
16
|
+
let distance = 0;
|
|
17
|
+
for (const a of setA) {
|
|
18
|
+
for (const b of setB) {
|
|
19
|
+
distance += distances[a][b];
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return distance / setA.length / setB.length;
|
|
23
|
+
}
|
|
24
|
+
function updateProgress(stepNumber, stepProgress, onProgress) {
|
|
25
|
+
onProgress(stepNumber / 2 + stepProgress / 2);
|
|
26
|
+
}
|
|
27
|
+
function clusterData({ data, distance = euclideanDistance, linkage = averageDistance, onProgress, stopToken, }) {
|
|
28
|
+
const distances = data.map((datum, index) => {
|
|
29
|
+
if (onProgress) {
|
|
30
|
+
updateProgress(0, index / (data.length - 1), onProgress);
|
|
31
|
+
}
|
|
32
|
+
return data.map(otherDatum => distance(datum, otherDatum));
|
|
33
|
+
});
|
|
34
|
+
const clusters = data.map((_datum, index) => ({
|
|
35
|
+
height: 0,
|
|
36
|
+
indexes: [Number(index)],
|
|
37
|
+
}));
|
|
38
|
+
let clustersGivenK = [];
|
|
39
|
+
let start = performance.now();
|
|
40
|
+
for (let iteration = 0; iteration < data.length; iteration++) {
|
|
41
|
+
if (performance.now() - start > 2000) {
|
|
42
|
+
(0, stopToken_1.checkStopToken)(stopToken);
|
|
43
|
+
start = performance.now();
|
|
44
|
+
}
|
|
45
|
+
if (onProgress) {
|
|
46
|
+
updateProgress(1, (iteration + 1) / data.length, onProgress);
|
|
47
|
+
}
|
|
48
|
+
clustersGivenK.push(clusters.map(cluster => cluster.indexes));
|
|
49
|
+
if (iteration >= data.length - 1) {
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
let nearestDistance = Infinity;
|
|
53
|
+
let nearestRow = 0;
|
|
54
|
+
let nearestCol = 0;
|
|
55
|
+
for (let row = 0; row < clusters.length; row++) {
|
|
56
|
+
for (let col = row + 1; col < clusters.length; col++) {
|
|
57
|
+
const distance = linkage(clusters[row].indexes, clusters[col].indexes, distances);
|
|
58
|
+
if (distance < nearestDistance) {
|
|
59
|
+
nearestDistance = distance;
|
|
60
|
+
nearestRow = row;
|
|
61
|
+
nearestCol = col;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const newCluster = {
|
|
66
|
+
indexes: [
|
|
67
|
+
...clusters[nearestRow].indexes,
|
|
68
|
+
...clusters[nearestCol].indexes,
|
|
69
|
+
],
|
|
70
|
+
height: nearestDistance,
|
|
71
|
+
children: [clusters[nearestRow], clusters[nearestCol]],
|
|
72
|
+
};
|
|
73
|
+
clusters.splice(Math.max(nearestRow, nearestCol), 1);
|
|
74
|
+
clusters.splice(Math.min(nearestRow, nearestCol), 1);
|
|
75
|
+
clusters.push(newCluster);
|
|
76
|
+
}
|
|
77
|
+
clustersGivenK = [[], ...clustersGivenK.reverse()];
|
|
78
|
+
return {
|
|
79
|
+
clusters: clusters[0],
|
|
80
|
+
distances: distances,
|
|
81
|
+
order: clusters[0].indexes,
|
|
82
|
+
clustersGivenK: clustersGivenK,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { GetGenotypeMatrixArgs } from './types';
|
|
2
|
+
import type PluginManager from '@jbrowse/core/PluginManager';
|
|
3
|
+
export declare function getGenotypeMatrix({ pluginManager, args, }: {
|
|
4
|
+
pluginManager: PluginManager;
|
|
5
|
+
args: GetGenotypeMatrixArgs;
|
|
6
|
+
}): Promise<Record<string, number[]>>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getGenotypeMatrix = getGenotypeMatrix;
|
|
4
|
+
const dataAdapterCache_1 = require("@jbrowse/core/data_adapters/dataAdapterCache");
|
|
5
|
+
const rxjs_1 = require("rxjs");
|
|
6
|
+
const minorAlleleFrequencyUtils_1 = require("../shared/minorAlleleFrequencyUtils");
|
|
7
|
+
async function getGenotypeMatrix({ pluginManager, args, }) {
|
|
8
|
+
const { sources, minorAlleleFrequencyFilter, regions, adapterConfig, sessionId, } = args;
|
|
9
|
+
const adapter = await (0, dataAdapterCache_1.getAdapter)(pluginManager, sessionId, adapterConfig);
|
|
10
|
+
const dataAdapter = adapter.dataAdapter;
|
|
11
|
+
const feats = await (0, rxjs_1.firstValueFrom)(dataAdapter.getFeaturesInMultipleRegions(regions, args).pipe((0, rxjs_1.toArray)()));
|
|
12
|
+
const genotypeFactor = new Set();
|
|
13
|
+
const mafs = (0, minorAlleleFrequencyUtils_1.getFeaturesThatPassMinorAlleleFrequencyFilter)(feats, minorAlleleFrequencyFilter);
|
|
14
|
+
for (const { alleleCounts } of mafs) {
|
|
15
|
+
for (const alt of alleleCounts.keys()) {
|
|
16
|
+
genotypeFactor.add(alt);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const rows = {};
|
|
20
|
+
for (const { feature } of mafs) {
|
|
21
|
+
const genotypes = feature.get('genotypes');
|
|
22
|
+
for (const { name } of sources) {
|
|
23
|
+
if (!rows[name]) {
|
|
24
|
+
rows[name] = [];
|
|
25
|
+
}
|
|
26
|
+
const val = genotypes[name];
|
|
27
|
+
const alleles = val.split(/[/|]/);
|
|
28
|
+
let genotypeStatus = 0;
|
|
29
|
+
let nonRefCount = 0;
|
|
30
|
+
let uncalledCount = 0;
|
|
31
|
+
for (const l of alleles) {
|
|
32
|
+
if (l === '.') {
|
|
33
|
+
uncalledCount++;
|
|
34
|
+
}
|
|
35
|
+
else if (l !== '0') {
|
|
36
|
+
nonRefCount++;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (uncalledCount === alleles.length) {
|
|
40
|
+
genotypeStatus = -1;
|
|
41
|
+
}
|
|
42
|
+
else if (nonRefCount === 0) {
|
|
43
|
+
genotypeStatus = 0;
|
|
44
|
+
}
|
|
45
|
+
else if (nonRefCount === alleles.length) {
|
|
46
|
+
genotypeStatus = 2;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
genotypeStatus = 1;
|
|
50
|
+
}
|
|
51
|
+
rows[name].push(genotypeStatus);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return rows;
|
|
55
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Source } from '../shared/types';
|
|
2
|
+
import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
|
|
3
|
+
import type { Region } from '@jbrowse/core/util';
|
|
4
|
+
export interface GetGenotypeMatrixArgs {
|
|
5
|
+
sources: Source[];
|
|
6
|
+
minorAlleleFrequencyFilter: number;
|
|
7
|
+
adapterConfig: AnyConfigurationModel;
|
|
8
|
+
stopToken?: string;
|
|
9
|
+
sessionId: string;
|
|
10
|
+
headers?: Record<string, string>;
|
|
11
|
+
regions: Region[];
|
|
12
|
+
bpPerPx: number;
|
|
13
|
+
}
|
|
@@ -50,7 +50,7 @@ class VcfAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
if (i++ % 10000 === 0) {
|
|
53
|
-
statusCallback(`Loading ${
|
|
53
|
+
statusCallback(`Loading ${(0, util_1.getProgressDisplayStr)(blockStart, buffer.length)}`);
|
|
54
54
|
}
|
|
55
55
|
blockStart = n + 1;
|
|
56
56
|
}
|
|
@@ -101,9 +101,12 @@ class VcfAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
101
101
|
try {
|
|
102
102
|
const { start, end, refName } = region;
|
|
103
103
|
const { intervalTreeMap } = await this.setup();
|
|
104
|
-
(_a = intervalTreeMap[refName]) === null || _a === void 0 ? void 0 : _a.call(intervalTreeMap, opts.statusCallback).search([
|
|
104
|
+
for (const f of ((_a = intervalTreeMap[refName]) === null || _a === void 0 ? void 0 : _a.call(intervalTreeMap, opts.statusCallback).search([
|
|
105
|
+
start,
|
|
106
|
+
end,
|
|
107
|
+
])) || []) {
|
|
105
108
|
observer.next(f);
|
|
106
|
-
}
|
|
109
|
+
}
|
|
107
110
|
observer.complete();
|
|
108
111
|
}
|
|
109
112
|
catch (e) {
|
package/dist/VcfFeature/util.js
CHANGED
|
@@ -22,7 +22,7 @@ function getSOTermAndDescription(ref, alt, parser) {
|
|
|
22
22
|
}
|
|
23
23
|
const soTerms = new Set();
|
|
24
24
|
let descriptions = new Set();
|
|
25
|
-
|
|
25
|
+
for (const a of alt) {
|
|
26
26
|
let [soTerm, description] = getSOAndDescFromAltDefs(a, parser);
|
|
27
27
|
if (!soTerm) {
|
|
28
28
|
;
|
|
@@ -32,7 +32,7 @@ function getSOTermAndDescription(ref, alt, parser) {
|
|
|
32
32
|
soTerms.add(soTerm);
|
|
33
33
|
descriptions.add(description);
|
|
34
34
|
}
|
|
35
|
-
}
|
|
35
|
+
}
|
|
36
36
|
if (descriptions.size > 1) {
|
|
37
37
|
const descs = [...descriptions];
|
|
38
38
|
const prefixes = new Set(descs
|
|
@@ -91,16 +91,21 @@ class VcfTabixAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
91
91
|
const header = lines[0].split('\t');
|
|
92
92
|
const { parser } = await this.configure();
|
|
93
93
|
const s = new Set(parser.samples);
|
|
94
|
-
|
|
94
|
+
const ret = lines
|
|
95
95
|
.slice(1)
|
|
96
|
+
.filter(f => !!f)
|
|
96
97
|
.map(line => {
|
|
97
|
-
const
|
|
98
|
+
const [name, ...rest] = line.split('\t');
|
|
98
99
|
return {
|
|
99
|
-
|
|
100
|
-
|
|
100
|
+
...Object.fromEntries(rest.map((c, idx) => [header[idx + 1], c])),
|
|
101
|
+
name: name,
|
|
101
102
|
};
|
|
102
|
-
})
|
|
103
|
-
|
|
103
|
+
});
|
|
104
|
+
const missing = ret.filter(f => !s.has(f.name));
|
|
105
|
+
if (missing.length) {
|
|
106
|
+
console.warn('Samples in metadata file not in VCF:', ret.filter(f => !s.has(f.name)));
|
|
107
|
+
}
|
|
108
|
+
return ret.filter(f => s.has(f.name));
|
|
104
109
|
}
|
|
105
110
|
}
|
|
106
111
|
freeResources() { }
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,7 @@ const MultiLinearVariantRenderer_1 = __importDefault(require("./MultiLinearVaria
|
|
|
14
14
|
const SplitVcfTabixAdapter_1 = __importDefault(require("./SplitVcfTabixAdapter"));
|
|
15
15
|
const StructuralVariantChordRenderer_1 = __importDefault(require("./StructuralVariantChordRenderer"));
|
|
16
16
|
const VariantFeatureWidget_1 = __importDefault(require("./VariantFeatureWidget"));
|
|
17
|
+
const MultiVariantClusterGenotypeMatrix_1 = require("./VariantRPC/MultiVariantClusterGenotypeMatrix");
|
|
17
18
|
const MultiVariantGetGenotypeMatrix_1 = require("./VariantRPC/MultiVariantGetGenotypeMatrix");
|
|
18
19
|
const MultiVariantGetSimplifiedFeatures_1 = require("./VariantRPC/MultiVariantGetSimplifiedFeatures");
|
|
19
20
|
const MultiVariantGetSources_1 = require("./VariantRPC/MultiVariantGetSources");
|
|
@@ -42,6 +43,7 @@ class VariantsPlugin extends Plugin_1.default {
|
|
|
42
43
|
(0, ChordVariantDisplay_1.default)(pluginManager);
|
|
43
44
|
pluginManager.addRpcMethod(() => new MultiVariantGetSources_1.MultiVariantGetSources(pluginManager));
|
|
44
45
|
pluginManager.addRpcMethod(() => new MultiVariantGetGenotypeMatrix_1.MultiVariantGetGenotypeMatrix(pluginManager));
|
|
46
|
+
pluginManager.addRpcMethod(() => new MultiVariantClusterGenotypeMatrix_1.MultiVariantClusterGenotypeMatrix(pluginManager));
|
|
45
47
|
pluginManager.addRpcMethod(() => new MultiVariantGetSimplifiedFeatures_1.MultiVariantGetSimplifiedFeatures(pluginManager));
|
|
46
48
|
}
|
|
47
49
|
}
|