@jbrowse/plugin-variants 4.0.3 → 4.1.1
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/esm/ChordVariantDisplay/models/stateModelFactory.d.ts +9 -0
- package/esm/LDDisplay/SharedLDConfigSchema.d.ts +102 -0
- package/esm/LDDisplay/SharedLDConfigSchema.js +83 -0
- package/esm/LDDisplay/afterAttach.d.ts +2 -0
- package/esm/LDDisplay/afterAttach.js +123 -0
- package/esm/LDDisplay/components/BaseDisplayComponent.d.ts +15 -0
- package/esm/LDDisplay/components/BaseDisplayComponent.js +39 -0
- package/esm/LDDisplay/components/LDColorLegend.d.ts +15 -0
- package/esm/LDDisplay/components/LDColorLegend.js +75 -0
- package/esm/LDDisplay/components/LDDisplayComponent.d.ts +5 -0
- package/esm/LDDisplay/components/LDDisplayComponent.js +203 -0
- package/esm/LDDisplay/components/LinesConnectingMatrixToGenomicPosition.d.ts +16 -0
- package/esm/LDDisplay/components/LinesConnectingMatrixToGenomicPosition.js +109 -0
- package/esm/LDDisplay/configSchema1.d.ts +115 -0
- package/esm/LDDisplay/configSchema1.js +16 -0
- package/esm/LDDisplay/configSchema2.d.ts +115 -0
- package/esm/LDDisplay/configSchema2.js +16 -0
- package/esm/LDDisplay/index.d.ts +2 -0
- package/esm/LDDisplay/index.js +35 -0
- package/esm/LDDisplay/renderSvg.d.ts +3 -0
- package/esm/LDDisplay/renderSvg.js +36 -0
- package/esm/LDDisplay/shared.d.ts +367 -0
- package/esm/LDDisplay/shared.js +467 -0
- package/esm/LDDisplay/stateModel1.d.ts +365 -0
- package/esm/LDDisplay/stateModel1.js +10 -0
- package/esm/LDDisplay/stateModel2.d.ts +365 -0
- package/esm/LDDisplay/stateModel2.js +10 -0
- package/esm/LDRenderer/LDRenderer.d.ts +30 -0
- package/esm/LDRenderer/LDRenderer.js +109 -0
- package/esm/LDRenderer/components/LDRendering.d.ts +2 -0
- package/esm/LDRenderer/components/LDRendering.js +4 -0
- package/esm/LDRenderer/configSchema.d.ts +8 -0
- package/esm/LDRenderer/configSchema.js +10 -0
- package/esm/LDRenderer/index.d.ts +2 -0
- package/esm/LDRenderer/index.js +11 -0
- package/esm/LDRenderer/makeImageData.d.ts +20 -0
- package/esm/LDRenderer/makeImageData.js +158 -0
- package/esm/LDRenderer/types.d.ts +8 -0
- package/esm/LDRenderer/types.js +1 -0
- package/esm/LDTrack/configSchema.d.ts +85 -0
- package/esm/LDTrack/configSchema.js +7 -0
- package/esm/LDTrack/index.d.ts +2 -0
- package/esm/LDTrack/index.js +14 -0
- package/esm/LinearVariantDisplay/model.d.ts +139 -42
- package/esm/LinearVariantDisplay/model.js +46 -8
- package/esm/MultiLinearVariantDisplay/configSchema.d.ts +27 -1
- package/esm/MultiLinearVariantDisplay/model.d.ts +2647 -58
- package/esm/MultiLinearVariantDisplay/model.js +6 -0
- package/esm/MultiLinearVariantDisplay/renderSvg.d.ts +10 -2
- package/esm/MultiLinearVariantMatrixDisplay/configSchema.d.ts +25 -0
- package/esm/MultiLinearVariantMatrixDisplay/configSchema.js +26 -0
- package/esm/MultiLinearVariantMatrixDisplay/model.d.ts +2648 -59
- package/esm/MultiLinearVariantMatrixDisplay/model.js +6 -0
- package/esm/MultiLinearVariantMatrixRenderer/MultiLinearVariantMatrixRenderer.d.ts +2 -2
- package/esm/MultiLinearVariantMatrixRenderer/MultiLinearVariantMatrixRenderer.js +11 -9
- package/esm/MultiLinearVariantMatrixRenderer/components/MultiLinearVariantMatrixRendering.d.ts +8 -0
- package/esm/MultiLinearVariantMatrixRenderer/components/MultiLinearVariantMatrixRendering.js +14 -2
- package/esm/MultiLinearVariantMatrixRenderer/makeImageData.js +14 -8
- package/esm/MultiLinearVariantRenderer/MultiVariantRenderer.d.ts +2 -2
- package/esm/MultiLinearVariantRenderer/MultiVariantRenderer.js +4 -3
- package/esm/MultiLinearVariantRenderer/components/MultiLinearVariantRendering.d.ts +4 -0
- package/esm/MultiLinearVariantRenderer/components/MultiLinearVariantRendering.js +23 -2
- package/esm/MultiLinearVariantRenderer/makeImageData.js +8 -3
- package/esm/PlinkLDAdapter/PlinkLDAdapter.d.ts +25 -0
- package/esm/PlinkLDAdapter/PlinkLDAdapter.js +147 -0
- package/esm/PlinkLDAdapter/PlinkLDTabixAdapter.d.ts +24 -0
- package/esm/PlinkLDAdapter/PlinkLDTabixAdapter.js +156 -0
- package/esm/PlinkLDAdapter/configSchema.d.ts +10 -0
- package/esm/PlinkLDAdapter/configSchema.js +25 -0
- package/esm/PlinkLDAdapter/configSchemaTabix.d.ts +24 -0
- package/esm/PlinkLDAdapter/configSchemaTabix.js +46 -0
- package/esm/PlinkLDAdapter/index.d.ts +2 -0
- package/esm/PlinkLDAdapter/index.js +25 -0
- package/esm/PlinkLDAdapter/types.d.ts +29 -0
- package/esm/PlinkLDAdapter/types.js +1 -0
- package/esm/VariantFeatureWidget/VariantSampleGrid/VariantSampleGrid.js +1 -1
- package/esm/VariantRPC/MultiVariantGetFeatureDetails.d.ts +14 -0
- package/esm/VariantRPC/MultiVariantGetFeatureDetails.js +15 -0
- package/esm/VariantRPC/executeClusterGenotypeMatrix.d.ts +3 -1
- package/esm/VariantRPC/executeClusterGenotypeMatrix.js +8 -4
- package/esm/VariantRPC/getLDMatrix.d.ts +48 -0
- package/esm/VariantRPC/getLDMatrix.js +388 -0
- package/esm/VariantRPC/getLDMatrixFromPlink.d.ts +16 -0
- package/esm/VariantRPC/getLDMatrixFromPlink.js +105 -0
- package/esm/VariantRPC/getPhasedGenotypeMatrix.d.ts +20 -0
- package/esm/VariantRPC/getPhasedGenotypeMatrix.js +50 -0
- package/esm/VariantRPC/types.d.ts +3 -0
- package/esm/VcfAdapter/VcfAdapter.d.ts +1 -1
- package/esm/VcfAdapter/VcfAdapter.js +1 -2
- package/esm/VcfExtensionPoints/index.js +29 -3
- package/esm/VcfFeature/index.d.ts +2 -1
- package/esm/VcfFeature/index.js +4 -2
- package/esm/index.d.ts +1 -0
- package/esm/index.js +23 -0
- package/esm/shared/MultiVariantBaseModel.d.ts +2638 -53
- package/esm/shared/MultiVariantBaseModel.js +100 -47
- package/esm/shared/SharedVariantConfigSchema.d.ts +27 -1
- package/esm/shared/SharedVariantConfigSchema.js +28 -1
- package/esm/shared/VariantFeatureCache.d.ts +27 -0
- package/esm/shared/VariantFeatureCache.js +48 -0
- package/esm/shared/VariantRendererType.d.ts +23 -0
- package/esm/shared/VariantRendererType.js +15 -0
- package/esm/shared/applyColorPalette.d.ts +9 -0
- package/esm/shared/applyColorPalette.js +23 -0
- package/esm/shared/colorByAutorun.d.ts +10 -0
- package/esm/shared/colorByAutorun.js +39 -0
- package/esm/shared/components/AddFiltersDialog.d.ts +3 -3
- package/esm/shared/components/AddFiltersDialog.js +29 -22
- package/esm/shared/components/LDFilterDialog.d.ts +13 -0
- package/esm/shared/components/LDFilterDialog.js +102 -0
- package/esm/shared/components/MAFFilterDialog.js +23 -16
- package/esm/shared/components/MultiVariantClusterDialog/ClusterDialogAuto.js +19 -6
- package/esm/shared/components/MultiVariantClusterDialog/types.d.ts +4 -1
- package/esm/shared/components/MultiVariantColorLegend.js +4 -4
- package/esm/shared/components/MultiVariantLegendBar.js +1 -1
- package/esm/shared/components/MultiVariantTooltip.d.ts +1 -0
- package/esm/shared/components/MultiVariantTooltip.js +2 -2
- package/esm/shared/components/RecombinationTrack.d.ts +21 -0
- package/esm/shared/components/RecombinationTrack.js +54 -0
- package/esm/shared/components/RecombinationYScaleBar.d.ts +7 -0
- package/esm/shared/components/RecombinationYScaleBar.js +34 -0
- package/esm/shared/components/RectBg.js +1 -1
- package/esm/shared/components/SetColorDialogRowPalettizer.d.ts +3 -8
- package/esm/shared/components/SetColorDialogRowPalettizer.js +2 -14
- package/esm/shared/components/SourcesDataGrid.js +4 -4
- package/esm/shared/components/TreeSidebar.js +11 -1
- package/esm/shared/drawAlleleCount.js +9 -0
- package/esm/shared/drawPhased.d.ts +1 -1
- package/esm/shared/drawPhased.js +31 -2
- package/esm/shared/getMultiVariantFeaturesAutorun.d.ts +1 -0
- package/esm/shared/getMultiVariantFeaturesAutorun.js +3 -0
- package/esm/shared/getMultiVariantSourcesAutorun.d.ts +1 -0
- package/esm/shared/getMultiVariantSourcesAutorun.js +3 -0
- package/esm/shared/getSources.d.ts +5 -9
- package/esm/shared/getSources.js +30 -25
- package/esm/shared/mafFilterUtils.d.ts +5 -0
- package/esm/shared/mafFilterUtils.js +17 -0
- package/esm/shared/minorAlleleFrequencyUtils.d.ts +2 -0
- package/esm/shared/minorAlleleFrequencyUtils.js +259 -17
- package/esm/shared/setupMultiVariantAutoruns.js +2 -0
- package/esm/shared/treeDrawingAutorun.d.ts +1 -0
- package/esm/shared/treeDrawingAutorun.js +7 -1
- package/esm/shared/types.d.ts +1 -2
- package/package.json +12 -11
|
@@ -14,6 +14,12 @@ export default function stateModelFactory(configSchema) {
|
|
|
14
14
|
get prefersOffset() {
|
|
15
15
|
return true;
|
|
16
16
|
},
|
|
17
|
+
get featureWidgetType() {
|
|
18
|
+
return {
|
|
19
|
+
type: 'VariantFeatureWidget',
|
|
20
|
+
id: 'variantFeature',
|
|
21
|
+
};
|
|
22
|
+
},
|
|
17
23
|
}))
|
|
18
24
|
.views(self => ({
|
|
19
25
|
renderProps() {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import VariantRendererType from '../shared/VariantRendererType.ts';
|
|
2
2
|
import type { RenderArgsDeserialized } from './types.ts';
|
|
3
|
-
export default class LinearVariantMatrixRenderer extends
|
|
3
|
+
export default class LinearVariantMatrixRenderer extends VariantRendererType {
|
|
4
4
|
supportsSVG: boolean;
|
|
5
5
|
render(renderProps: RenderArgsDeserialized): Promise<import("librpc-web-mod").RpcResult>;
|
|
6
6
|
}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import FeatureRendererType from '@jbrowse/core/pluggableElementTypes/renderers/FeatureRendererType';
|
|
2
1
|
import { renderToAbstractCanvas } from '@jbrowse/core/util';
|
|
3
2
|
import { rpcResult } from '@jbrowse/core/util/librpc';
|
|
4
3
|
import { collectTransferables } from '@jbrowse/core/util/offscreenCanvasPonyfill';
|
|
5
|
-
|
|
4
|
+
import VariantRendererType from "../shared/VariantRendererType.js";
|
|
5
|
+
export default class LinearVariantMatrixRenderer extends VariantRendererType {
|
|
6
6
|
supportsSVG = true;
|
|
7
7
|
async render(renderProps) {
|
|
8
8
|
const features = await this.getFeatures(renderProps);
|
|
9
|
-
const { height, regions, bpPerPx, scrollTop, rowHeight } = renderProps;
|
|
9
|
+
const { height, regions, bpPerPx, scrollTop, rowHeight, sessionId, trackInstanceId, } = renderProps;
|
|
10
10
|
const region = regions[0];
|
|
11
11
|
const width = (region.end - region.start) / bpPerPx;
|
|
12
|
+
this.cacheFeatures({ sessionId, trackInstanceId }, region.refName, features);
|
|
12
13
|
const { makeImageData } = await import("./makeImageData.js");
|
|
13
14
|
const { mafs, ...rest } = await renderToAbstractCanvas(width, height, renderProps, ctx => makeImageData({
|
|
14
15
|
ctx,
|
|
@@ -16,14 +17,15 @@ export default class LinearVariantMatrixRenderer extends FeatureRendererType {
|
|
|
16
17
|
canvasHeight: height,
|
|
17
18
|
renderArgs: { ...renderProps, features },
|
|
18
19
|
}));
|
|
20
|
+
const simplifiedFeatures = mafs.map(({ feature }) => ({
|
|
21
|
+
uniqueId: feature.id(),
|
|
22
|
+
start: feature.get('start'),
|
|
23
|
+
end: feature.get('end'),
|
|
24
|
+
refName: feature.get('refName'),
|
|
25
|
+
}));
|
|
19
26
|
const serialized = {
|
|
20
27
|
...rest,
|
|
21
|
-
simplifiedFeatures
|
|
22
|
-
uniqueId: feature.id(),
|
|
23
|
-
start: feature.get('start'),
|
|
24
|
-
end: feature.get('end'),
|
|
25
|
-
refName: feature.get('refName'),
|
|
26
|
-
})),
|
|
28
|
+
simplifiedFeatures,
|
|
27
29
|
height,
|
|
28
30
|
width,
|
|
29
31
|
origScrollTop: scrollTop,
|
package/esm/MultiLinearVariantMatrixRenderer/components/MultiLinearVariantMatrixRendering.d.ts
CHANGED
|
@@ -6,6 +6,12 @@ interface FeatureData {
|
|
|
6
6
|
description: string;
|
|
7
7
|
length: number;
|
|
8
8
|
}
|
|
9
|
+
interface SimplifiedFeature {
|
|
10
|
+
uniqueId: string;
|
|
11
|
+
}
|
|
12
|
+
interface RenderingProps {
|
|
13
|
+
onFeatureClick?: (event: React.MouseEvent, featureId: string) => void;
|
|
14
|
+
}
|
|
9
15
|
declare const MultiLinearVariantMatrixRendering: (props: {
|
|
10
16
|
width: number;
|
|
11
17
|
height: number;
|
|
@@ -15,5 +21,7 @@ declare const MultiLinearVariantMatrixRendering: (props: {
|
|
|
15
21
|
rowHeight: number;
|
|
16
22
|
origScrollTop: number;
|
|
17
23
|
totalHeight: number;
|
|
24
|
+
simplifiedFeatures?: SimplifiedFeature[];
|
|
25
|
+
renderingProps?: RenderingProps;
|
|
18
26
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
19
27
|
export default MultiLinearVariantMatrixRendering;
|
package/esm/MultiLinearVariantMatrixRenderer/components/MultiLinearVariantMatrixRendering.js
CHANGED
|
@@ -5,7 +5,7 @@ import { getBpDisplayStr } from '@jbrowse/core/util';
|
|
|
5
5
|
import { observer } from 'mobx-react';
|
|
6
6
|
import { makeSimpleAltString } from "../../VcfFeature/util.js";
|
|
7
7
|
const MultiLinearVariantMatrixRendering = observer(function MultiLinearVariantMatrixRendering(props) {
|
|
8
|
-
const { arr, width, displayModel, featureData, totalHeight, origScrollTop, rowHeight, } = props;
|
|
8
|
+
const { arr, width, displayModel, featureData, totalHeight, origScrollTop, rowHeight, simplifiedFeatures, renderingProps, } = props;
|
|
9
9
|
const ref = useRef(null);
|
|
10
10
|
const lastHoveredRef = useRef(undefined);
|
|
11
11
|
const getFeatureUnderMouse = useCallback((eventClientX, eventClientY) => {
|
|
@@ -52,7 +52,19 @@ const MultiLinearVariantMatrixRendering = observer(function MultiLinearVariantMa
|
|
|
52
52
|
displayModel.setHoveredGenotype(undefined);
|
|
53
53
|
}
|
|
54
54
|
}, [displayModel]);
|
|
55
|
-
|
|
55
|
+
const handleClick = useCallback((e) => {
|
|
56
|
+
if (!ref.current || !simplifiedFeatures) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const r = ref.current.getBoundingClientRect();
|
|
60
|
+
const offsetX = e.clientX - r.left;
|
|
61
|
+
const featureIdx = Math.floor((offsetX / width) * arr.length);
|
|
62
|
+
const feature = simplifiedFeatures[featureIdx];
|
|
63
|
+
if (feature) {
|
|
64
|
+
renderingProps?.onFeatureClick?.(e, feature.uniqueId);
|
|
65
|
+
}
|
|
66
|
+
}, [arr.length, width, simplifiedFeatures, renderingProps]);
|
|
67
|
+
return (_jsx("div", { ref: ref, onMouseMove: handleMouseMove, onMouseLeave: handleMouseLeave, onMouseOut: handleMouseLeave, onClick: handleClick, style: {
|
|
56
68
|
overflow: 'visible',
|
|
57
69
|
position: 'relative',
|
|
58
70
|
height: totalHeight,
|
|
@@ -17,8 +17,10 @@ function drawPhasedMode(drawCtx, mafs) {
|
|
|
17
17
|
const samp = feature.get('samples');
|
|
18
18
|
for (let j = startRow; j < endRow; j++) {
|
|
19
19
|
const y = j * h - scrollTop;
|
|
20
|
-
const
|
|
21
|
-
const
|
|
20
|
+
const source = sources[j];
|
|
21
|
+
const { name, HP, baseName } = source;
|
|
22
|
+
const sampleName = baseName ?? name;
|
|
23
|
+
const s = samp[sampleName];
|
|
22
24
|
if (s) {
|
|
23
25
|
const genotype = s.GT?.[0];
|
|
24
26
|
if (genotype) {
|
|
@@ -47,8 +49,10 @@ function drawPhasedMode(drawCtx, mafs) {
|
|
|
47
49
|
}
|
|
48
50
|
for (let j = startRow; j < endRow; j++) {
|
|
49
51
|
const y = j * h - scrollTop;
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
+
const source = sources[j];
|
|
53
|
+
const { name, HP, baseName } = source;
|
|
54
|
+
const sampleName = baseName ?? name;
|
|
55
|
+
const genotype = samp[sampleName];
|
|
52
56
|
if (genotype) {
|
|
53
57
|
arr2.push(genotype);
|
|
54
58
|
const isPhased = genotype.includes('|');
|
|
@@ -82,8 +86,9 @@ function drawAlleleCountMode(drawCtx, mafs) {
|
|
|
82
86
|
const samp = feature.get('samples');
|
|
83
87
|
for (let j = startRow; j < endRow; j++) {
|
|
84
88
|
const y = j * h - scrollTop;
|
|
85
|
-
const
|
|
86
|
-
const
|
|
89
|
+
const source = sources[j];
|
|
90
|
+
const sampleName = source.baseName ?? source.name;
|
|
91
|
+
const s = samp[sampleName];
|
|
87
92
|
if (s) {
|
|
88
93
|
const genotype = s.GT?.[0];
|
|
89
94
|
if (genotype) {
|
|
@@ -105,8 +110,9 @@ function drawAlleleCountMode(drawCtx, mafs) {
|
|
|
105
110
|
}
|
|
106
111
|
for (let j = startRow; j < endRow; j++) {
|
|
107
112
|
const y = j * h - scrollTop;
|
|
108
|
-
const
|
|
109
|
-
const
|
|
113
|
+
const source = sources[j];
|
|
114
|
+
const sampleName = source.baseName ?? source.name;
|
|
115
|
+
const genotype = samp[sampleName];
|
|
110
116
|
if (genotype) {
|
|
111
117
|
arr2.push(genotype);
|
|
112
118
|
const c = getAlleleColor(genotype, mostFrequentAlt, colorCache, splitCache, true);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import VariantRendererType from '../shared/VariantRendererType.ts';
|
|
2
2
|
import type { MultiRenderArgsDeserialized } from './types.ts';
|
|
3
|
-
export default class MultiVariantRenderer extends
|
|
3
|
+
export default class MultiVariantRenderer extends VariantRendererType {
|
|
4
4
|
supportsSVG: boolean;
|
|
5
5
|
render(renderProps: MultiRenderArgsDeserialized): Promise<import("librpc-web-mod").RpcResult>;
|
|
6
6
|
}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import FeatureRendererType from '@jbrowse/core/pluggableElementTypes/renderers/FeatureRendererType';
|
|
2
1
|
import { renderToAbstractCanvas } from '@jbrowse/core/util';
|
|
3
2
|
import { rpcResult } from '@jbrowse/core/util/librpc';
|
|
4
3
|
import { collectTransferables } from '@jbrowse/core/util/offscreenCanvasPonyfill';
|
|
5
|
-
|
|
4
|
+
import VariantRendererType from "../shared/VariantRendererType.js";
|
|
5
|
+
export default class MultiVariantRenderer extends VariantRendererType {
|
|
6
6
|
supportsSVG = true;
|
|
7
7
|
async render(renderProps) {
|
|
8
8
|
const features = await this.getFeatures(renderProps);
|
|
9
|
-
const { height, referenceDrawingMode, regions, bpPerPx, scrollTop } = renderProps;
|
|
9
|
+
const { height, referenceDrawingMode, regions, bpPerPx, scrollTop, sessionId, trackInstanceId, } = renderProps;
|
|
10
10
|
const region = regions[0];
|
|
11
11
|
const width = (region.end - region.start) / bpPerPx;
|
|
12
|
+
this.cacheFeatures({ sessionId, trackInstanceId }, region.refName, features);
|
|
12
13
|
const { makeImageData } = await import("./makeImageData.js");
|
|
13
14
|
const ret = await renderToAbstractCanvas(width, height, renderProps, ctx => {
|
|
14
15
|
if (referenceDrawingMode === 'skip') {
|
|
@@ -17,6 +17,9 @@ interface MinimizedVariantRecord {
|
|
|
17
17
|
interface MultiVariantDisplayModel {
|
|
18
18
|
setHoveredGenotype?: (genotype?: Record<string, unknown>) => void;
|
|
19
19
|
}
|
|
20
|
+
interface RenderingProps {
|
|
21
|
+
onFeatureClick?: (event: React.MouseEvent, featureId: string) => void;
|
|
22
|
+
}
|
|
20
23
|
declare const MultiVariantRendering: (props: {
|
|
21
24
|
regions: Region[];
|
|
22
25
|
features: Map<string, Feature>;
|
|
@@ -30,5 +33,6 @@ declare const MultiVariantRendering: (props: {
|
|
|
30
33
|
flatbush: any;
|
|
31
34
|
items: Item[];
|
|
32
35
|
displayModel: MultiVariantDisplayModel;
|
|
36
|
+
renderingProps?: RenderingProps;
|
|
33
37
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
34
38
|
export default MultiVariantRendering;
|
|
@@ -7,7 +7,7 @@ import { observer } from 'mobx-react';
|
|
|
7
7
|
import { minElt } from "./util.js";
|
|
8
8
|
import { makeSimpleAltString } from "../../VcfFeature/util.js";
|
|
9
9
|
const MultiVariantRendering = observer(function MultiVariantRendering(props) {
|
|
10
|
-
const { flatbush, items, displayModel, featureGenotypeMap, totalHeight, origScrollTop, } = props;
|
|
10
|
+
const { flatbush, items, displayModel, featureGenotypeMap, totalHeight, origScrollTop, renderingProps, } = props;
|
|
11
11
|
const ref = useRef(null);
|
|
12
12
|
const lastHoveredRef = useRef(undefined);
|
|
13
13
|
const flatbush2 = useMemo(() => Flatbush.from(flatbush), [flatbush]);
|
|
@@ -53,7 +53,28 @@ const MultiVariantRendering = observer(function MultiVariantRendering(props) {
|
|
|
53
53
|
displayModel.setHoveredGenotype?.(undefined);
|
|
54
54
|
}
|
|
55
55
|
}, [displayModel]);
|
|
56
|
-
|
|
56
|
+
const getFeatureIdUnderMouse = useCallback((eventClientX, eventClientY) => {
|
|
57
|
+
if (!ref.current) {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
const rect = ref.current.getBoundingClientRect();
|
|
61
|
+
const offsetX = eventClientX - rect.left;
|
|
62
|
+
const offsetY = eventClientY - rect.top;
|
|
63
|
+
const canvasOffsetY = offsetY - origScrollTop;
|
|
64
|
+
const x = flatbush2.search(offsetX, canvasOffsetY, offsetX + 1, canvasOffsetY + 1);
|
|
65
|
+
if (x.length) {
|
|
66
|
+
const res = minElt(x, idx => items[idx]?.bpLen ?? 0);
|
|
67
|
+
return items[res]?.featureId;
|
|
68
|
+
}
|
|
69
|
+
return undefined;
|
|
70
|
+
}, [flatbush2, items, origScrollTop]);
|
|
71
|
+
const handleClick = useCallback((e) => {
|
|
72
|
+
const featureId = getFeatureIdUnderMouse(e.clientX, e.clientY);
|
|
73
|
+
if (featureId) {
|
|
74
|
+
renderingProps?.onFeatureClick?.(e, featureId);
|
|
75
|
+
}
|
|
76
|
+
}, [getFeatureIdUnderMouse, renderingProps]);
|
|
77
|
+
return (_jsx("div", { ref: ref, onMouseMove: handleMouseMove, onMouseLeave: handleMouseLeave, onMouseOut: handleMouseLeave, onClick: handleClick, style: {
|
|
57
78
|
overflow: 'visible',
|
|
58
79
|
position: 'relative',
|
|
59
80
|
height: totalHeight,
|
|
@@ -20,15 +20,20 @@ function drawPhasedMode(drawCtx, itemData, mafs) {
|
|
|
20
20
|
samp = feature.get('genotypes');
|
|
21
21
|
genotypesCache.set(featureId, samp);
|
|
22
22
|
}
|
|
23
|
+
const featureType = feature.get('type');
|
|
24
|
+
const featureStrand = feature.get('strand');
|
|
25
|
+
const alpha = bpLen > 5 ? 0.75 : 1;
|
|
23
26
|
for (let j = startRow; j < endRow; j++) {
|
|
24
27
|
const y = j * h - scrollTop;
|
|
25
|
-
const
|
|
26
|
-
const
|
|
28
|
+
const source = sources[j];
|
|
29
|
+
const { name, HP, baseName } = source;
|
|
30
|
+
const sampleName = baseName ?? name;
|
|
31
|
+
const genotype = samp[sampleName];
|
|
27
32
|
if (genotype) {
|
|
28
33
|
const isPhased = genotype.includes('|');
|
|
29
34
|
if (isPhased) {
|
|
30
35
|
const alleles = splitCache[genotype] ?? (splitCache[genotype] = genotype.split('|'));
|
|
31
|
-
if (drawPhased(alleles, ctx, x, y, w, drawH, HP, undefined, drawRef)) {
|
|
36
|
+
if (drawPhased(alleles, ctx, x, y, w, drawH, HP, undefined, drawRef, alpha, featureType, featureStrand)) {
|
|
32
37
|
items.push({ name, genotype, featureId, bpLen });
|
|
33
38
|
coords.push(x, y, x + w, y + drawH);
|
|
34
39
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { BaseAdapter } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
2
|
+
import type { PlinkLDHeader, PlinkLDRecord } from './types.ts';
|
|
3
|
+
import type { BaseOptions } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
4
|
+
import type { NoAssemblyRegion } from '@jbrowse/core/util/types';
|
|
5
|
+
export default class PlinkLDAdapter extends BaseAdapter {
|
|
6
|
+
private configured?;
|
|
7
|
+
private configurePre;
|
|
8
|
+
private parseHeader;
|
|
9
|
+
protected configurePre2(opts?: BaseOptions): Promise<{
|
|
10
|
+
records: PlinkLDRecord[];
|
|
11
|
+
header: PlinkLDHeader;
|
|
12
|
+
refNames: string[];
|
|
13
|
+
}>;
|
|
14
|
+
configure(opts?: BaseOptions): Promise<{
|
|
15
|
+
records: PlinkLDRecord[];
|
|
16
|
+
header: PlinkLDHeader;
|
|
17
|
+
refNames: string[];
|
|
18
|
+
}>;
|
|
19
|
+
getRefNames(opts?: BaseOptions): Promise<string[]>;
|
|
20
|
+
getHeader(opts?: BaseOptions): Promise<PlinkLDHeader>;
|
|
21
|
+
getLDRecords(query: NoAssemblyRegion, opts?: BaseOptions): Promise<PlinkLDRecord[]>;
|
|
22
|
+
getLDRecordsInRegion(query: NoAssemblyRegion, opts?: BaseOptions): Promise<PlinkLDRecord[]>;
|
|
23
|
+
private parseLine;
|
|
24
|
+
freeResources(): void;
|
|
25
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { BaseAdapter } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
2
|
+
import { fetchAndMaybeUnzipText, updateStatus } from '@jbrowse/core/util';
|
|
3
|
+
export default class PlinkLDAdapter extends BaseAdapter {
|
|
4
|
+
configured;
|
|
5
|
+
async configurePre(opts) {
|
|
6
|
+
const ldLocation = this.getConf('ldLocation');
|
|
7
|
+
const text = await fetchAndMaybeUnzipText(ldLocation, opts);
|
|
8
|
+
const lines = text.split('\n').filter(line => line.trim());
|
|
9
|
+
if (lines.length === 0) {
|
|
10
|
+
throw new Error('Empty LD file');
|
|
11
|
+
}
|
|
12
|
+
const header = this.parseHeader(lines[0]);
|
|
13
|
+
const records = [];
|
|
14
|
+
const refNamesSet = new Set();
|
|
15
|
+
for (let i = 1; i < lines.length; i++) {
|
|
16
|
+
const record = this.parseLine(lines[i], header);
|
|
17
|
+
if (record) {
|
|
18
|
+
records.push(record);
|
|
19
|
+
refNamesSet.add(record.chrA);
|
|
20
|
+
refNamesSet.add(record.chrB);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
const refNames = [...refNamesSet].sort();
|
|
24
|
+
return { records, header, refNames };
|
|
25
|
+
}
|
|
26
|
+
parseHeader(headerLine) {
|
|
27
|
+
const columns = headerLine.trim().split(/\s+/);
|
|
28
|
+
const findIdx = (names) => {
|
|
29
|
+
for (const name of names) {
|
|
30
|
+
const idx = columns.indexOf(name);
|
|
31
|
+
if (idx !== -1) {
|
|
32
|
+
return idx;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return -1;
|
|
36
|
+
};
|
|
37
|
+
const chrAIdx = findIdx(['CHR_A', 'CHR1']);
|
|
38
|
+
const bpAIdx = findIdx(['BP_A', 'BP1', 'POS_A', 'POS1']);
|
|
39
|
+
const snpAIdx = findIdx(['SNP_A', 'SNP1', 'ID_A', 'ID1']);
|
|
40
|
+
const chrBIdx = findIdx(['CHR_B', 'CHR2']);
|
|
41
|
+
const bpBIdx = findIdx(['BP_B', 'BP2', 'POS_B', 'POS2']);
|
|
42
|
+
const snpBIdx = findIdx(['SNP_B', 'SNP2', 'ID_B', 'ID2']);
|
|
43
|
+
const r2Idx = findIdx(['R2', 'R^2', 'RSQ']);
|
|
44
|
+
const dprimeIdx = findIdx(['DP', 'DPRIME', "D'"]);
|
|
45
|
+
const mafAIdx = findIdx(['MAF_A', 'MAF1']);
|
|
46
|
+
const mafBIdx = findIdx(['MAF_B', 'MAF2']);
|
|
47
|
+
if (chrAIdx === -1 || bpAIdx === -1 || chrBIdx === -1 || bpBIdx === -1) {
|
|
48
|
+
throw new Error(`Invalid PLINK LD header. Expected columns CHR_A, BP_A, CHR_B, BP_B. Got: ${columns.join(', ')}`);
|
|
49
|
+
}
|
|
50
|
+
if (r2Idx === -1 && dprimeIdx === -1) {
|
|
51
|
+
throw new Error(`Invalid PLINK LD header. Expected at least R2 or DP column. Got: ${columns.join(', ')}`);
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
columns,
|
|
55
|
+
hasR2: r2Idx !== -1,
|
|
56
|
+
hasDprime: dprimeIdx !== -1,
|
|
57
|
+
hasMafA: mafAIdx !== -1,
|
|
58
|
+
hasMafB: mafBIdx !== -1,
|
|
59
|
+
chrAIdx,
|
|
60
|
+
bpAIdx,
|
|
61
|
+
snpAIdx,
|
|
62
|
+
chrBIdx,
|
|
63
|
+
bpBIdx,
|
|
64
|
+
snpBIdx,
|
|
65
|
+
r2Idx,
|
|
66
|
+
dprimeIdx,
|
|
67
|
+
mafAIdx,
|
|
68
|
+
mafBIdx,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
async configurePre2(opts) {
|
|
72
|
+
if (!this.configured) {
|
|
73
|
+
this.configured = this.configurePre(opts).catch((e) => {
|
|
74
|
+
this.configured = undefined;
|
|
75
|
+
throw e;
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return this.configured;
|
|
79
|
+
}
|
|
80
|
+
async configure(opts) {
|
|
81
|
+
const { statusCallback = () => { } } = opts || {};
|
|
82
|
+
return updateStatus('Loading LD data', statusCallback, () => this.configurePre2(opts));
|
|
83
|
+
}
|
|
84
|
+
async getRefNames(opts = {}) {
|
|
85
|
+
const { refNames } = await this.configure(opts);
|
|
86
|
+
return refNames;
|
|
87
|
+
}
|
|
88
|
+
async getHeader(opts) {
|
|
89
|
+
const { header } = await this.configure(opts);
|
|
90
|
+
return header;
|
|
91
|
+
}
|
|
92
|
+
async getLDRecords(query, opts = {}) {
|
|
93
|
+
const { refName, start, end } = query;
|
|
94
|
+
const { records } = await this.configure(opts);
|
|
95
|
+
const filtered = records.filter(r => r.chrA === refName && r.bpA >= start && r.bpA <= end);
|
|
96
|
+
return filtered;
|
|
97
|
+
}
|
|
98
|
+
async getLDRecordsInRegion(query, opts = {}) {
|
|
99
|
+
const { refName, start, end } = query;
|
|
100
|
+
const records = await this.getLDRecords(query, opts);
|
|
101
|
+
const filtered = records.filter(r => r.chrB === refName &&
|
|
102
|
+
r.bpB >= start &&
|
|
103
|
+
r.bpB <= end &&
|
|
104
|
+
r.chrA === refName &&
|
|
105
|
+
r.bpA >= start &&
|
|
106
|
+
r.bpA <= end);
|
|
107
|
+
return filtered;
|
|
108
|
+
}
|
|
109
|
+
parseLine(line, header) {
|
|
110
|
+
const fields = line.trim().split(/\s+/);
|
|
111
|
+
const chrA = fields[header.chrAIdx];
|
|
112
|
+
const bpA = Number.parseInt(fields[header.bpAIdx] ?? '', 10);
|
|
113
|
+
const snpA = header.snpAIdx >= 0 ? fields[header.snpAIdx] : `${chrA}:${bpA}`;
|
|
114
|
+
const chrB = fields[header.chrBIdx];
|
|
115
|
+
const bpB = Number.parseInt(fields[header.bpBIdx] ?? '', 10);
|
|
116
|
+
const snpB = header.snpBIdx >= 0 ? fields[header.snpBIdx] : `${chrB}:${bpB}`;
|
|
117
|
+
if (!chrA || !chrB || Number.isNaN(bpA) || Number.isNaN(bpB)) {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
const r2 = header.r2Idx >= 0
|
|
121
|
+
? Number.parseFloat(fields[header.r2Idx] ?? '')
|
|
122
|
+
: undefined;
|
|
123
|
+
const dprime = header.dprimeIdx >= 0
|
|
124
|
+
? Number.parseFloat(fields[header.dprimeIdx] ?? '')
|
|
125
|
+
: undefined;
|
|
126
|
+
const mafA = header.mafAIdx >= 0
|
|
127
|
+
? Number.parseFloat(fields[header.mafAIdx] ?? '')
|
|
128
|
+
: undefined;
|
|
129
|
+
const mafB = header.mafBIdx >= 0
|
|
130
|
+
? Number.parseFloat(fields[header.mafBIdx] ?? '')
|
|
131
|
+
: undefined;
|
|
132
|
+
return {
|
|
133
|
+
chrA,
|
|
134
|
+
bpA,
|
|
135
|
+
snpA: snpA ?? `${chrA}:${bpA}`,
|
|
136
|
+
chrB,
|
|
137
|
+
bpB,
|
|
138
|
+
snpB: snpB ?? `${chrB}:${bpB}`,
|
|
139
|
+
r2: r2 ?? 0,
|
|
140
|
+
dprime,
|
|
141
|
+
mafA,
|
|
142
|
+
mafB,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
freeResources() {
|
|
146
|
+
}
|
|
147
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { TabixIndexedFile } from '@gmod/tabix';
|
|
2
|
+
import { BaseAdapter } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
3
|
+
import type { PlinkLDHeader, PlinkLDRecord } from './types.ts';
|
|
4
|
+
import type { BaseOptions } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
5
|
+
import type { NoAssemblyRegion } from '@jbrowse/core/util/types';
|
|
6
|
+
export default class PlinkLDTabixAdapter extends BaseAdapter {
|
|
7
|
+
private configured?;
|
|
8
|
+
private configurePre;
|
|
9
|
+
private parseHeader;
|
|
10
|
+
protected configurePre2(): Promise<{
|
|
11
|
+
ld: TabixIndexedFile;
|
|
12
|
+
header: PlinkLDHeader;
|
|
13
|
+
}>;
|
|
14
|
+
configure(opts?: BaseOptions): Promise<{
|
|
15
|
+
ld: TabixIndexedFile;
|
|
16
|
+
header: PlinkLDHeader;
|
|
17
|
+
}>;
|
|
18
|
+
getRefNames(opts?: BaseOptions): Promise<string[]>;
|
|
19
|
+
getHeader(opts?: BaseOptions): Promise<PlinkLDHeader>;
|
|
20
|
+
getLDRecords(query: NoAssemblyRegion, opts?: BaseOptions): Promise<PlinkLDRecord[]>;
|
|
21
|
+
getLDRecordsInRegion(query: NoAssemblyRegion, opts?: BaseOptions): Promise<PlinkLDRecord[]>;
|
|
22
|
+
private parseLine;
|
|
23
|
+
freeResources(): void;
|
|
24
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { TabixIndexedFile } from '@gmod/tabix';
|
|
2
|
+
import { BaseAdapter } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
3
|
+
import { updateStatus } from '@jbrowse/core/util';
|
|
4
|
+
import { openLocation } from '@jbrowse/core/util/io';
|
|
5
|
+
export default class PlinkLDTabixAdapter extends BaseAdapter {
|
|
6
|
+
configured;
|
|
7
|
+
async configurePre(_opts) {
|
|
8
|
+
const ldLocation = this.getConf('ldLocation');
|
|
9
|
+
const location = this.getConf(['index', 'location']);
|
|
10
|
+
const indexType = this.getConf(['index', 'indexType']);
|
|
11
|
+
const filehandle = openLocation(ldLocation, this.pluginManager);
|
|
12
|
+
const isCSI = indexType === 'CSI';
|
|
13
|
+
const ld = new TabixIndexedFile({
|
|
14
|
+
filehandle,
|
|
15
|
+
csiFilehandle: isCSI
|
|
16
|
+
? openLocation(location, this.pluginManager)
|
|
17
|
+
: undefined,
|
|
18
|
+
tbiFilehandle: !isCSI
|
|
19
|
+
? openLocation(location, this.pluginManager)
|
|
20
|
+
: undefined,
|
|
21
|
+
chunkCacheSize: 50 * 2 ** 20,
|
|
22
|
+
});
|
|
23
|
+
const headerLine = await ld.getHeader();
|
|
24
|
+
const header = this.parseHeader(headerLine);
|
|
25
|
+
return { ld, header };
|
|
26
|
+
}
|
|
27
|
+
parseHeader(headerLine) {
|
|
28
|
+
const columns = headerLine.trim().split(/\s+/);
|
|
29
|
+
const findIdx = (names) => {
|
|
30
|
+
for (const name of names) {
|
|
31
|
+
const idx = columns.indexOf(name);
|
|
32
|
+
if (idx !== -1) {
|
|
33
|
+
return idx;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return -1;
|
|
37
|
+
};
|
|
38
|
+
const chrAIdx = findIdx(['CHR_A', 'CHR1']);
|
|
39
|
+
const bpAIdx = findIdx(['BP_A', 'BP1', 'POS_A', 'POS1']);
|
|
40
|
+
const snpAIdx = findIdx(['SNP_A', 'SNP1', 'ID_A', 'ID1']);
|
|
41
|
+
const chrBIdx = findIdx(['CHR_B', 'CHR2']);
|
|
42
|
+
const bpBIdx = findIdx(['BP_B', 'BP2', 'POS_B', 'POS2']);
|
|
43
|
+
const snpBIdx = findIdx(['SNP_B', 'SNP2', 'ID_B', 'ID2']);
|
|
44
|
+
const r2Idx = findIdx(['R2', 'R^2', 'RSQ']);
|
|
45
|
+
const dprimeIdx = findIdx(['DP', 'DPRIME', "D'"]);
|
|
46
|
+
const mafAIdx = findIdx(['MAF_A', 'MAF1']);
|
|
47
|
+
const mafBIdx = findIdx(['MAF_B', 'MAF2']);
|
|
48
|
+
if (chrAIdx === -1 || bpAIdx === -1 || chrBIdx === -1 || bpBIdx === -1) {
|
|
49
|
+
throw new Error(`Invalid PLINK LD header. Expected columns CHR_A, BP_A, CHR_B, BP_B. Got: ${columns.join(', ')}`);
|
|
50
|
+
}
|
|
51
|
+
if (r2Idx === -1 && dprimeIdx === -1) {
|
|
52
|
+
throw new Error(`Invalid PLINK LD header. Expected at least R2 or DP column. Got: ${columns.join(', ')}`);
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
columns,
|
|
56
|
+
hasR2: r2Idx !== -1,
|
|
57
|
+
hasDprime: dprimeIdx !== -1,
|
|
58
|
+
hasMafA: mafAIdx !== -1,
|
|
59
|
+
hasMafB: mafBIdx !== -1,
|
|
60
|
+
chrAIdx,
|
|
61
|
+
bpAIdx,
|
|
62
|
+
snpAIdx,
|
|
63
|
+
chrBIdx,
|
|
64
|
+
bpBIdx,
|
|
65
|
+
snpBIdx,
|
|
66
|
+
r2Idx,
|
|
67
|
+
dprimeIdx,
|
|
68
|
+
mafAIdx,
|
|
69
|
+
mafBIdx,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
async configurePre2() {
|
|
73
|
+
if (!this.configured) {
|
|
74
|
+
this.configured = this.configurePre().catch((e) => {
|
|
75
|
+
this.configured = undefined;
|
|
76
|
+
throw e;
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
return this.configured;
|
|
80
|
+
}
|
|
81
|
+
async configure(opts) {
|
|
82
|
+
const { statusCallback = () => { } } = opts || {};
|
|
83
|
+
return updateStatus('Downloading index', statusCallback, () => this.configurePre2());
|
|
84
|
+
}
|
|
85
|
+
async getRefNames(opts = {}) {
|
|
86
|
+
const { ld } = await this.configure(opts);
|
|
87
|
+
return ld.getReferenceSequenceNames(opts);
|
|
88
|
+
}
|
|
89
|
+
async getHeader(opts) {
|
|
90
|
+
const { header } = await this.configure(opts);
|
|
91
|
+
return header;
|
|
92
|
+
}
|
|
93
|
+
async getLDRecords(query, opts = {}) {
|
|
94
|
+
const { refName, start, end } = query;
|
|
95
|
+
const { ld, header } = await this.configure(opts);
|
|
96
|
+
const records = [];
|
|
97
|
+
await ld.getLines(refName, start, end, {
|
|
98
|
+
lineCallback: (line) => {
|
|
99
|
+
const record = this.parseLine(line, header);
|
|
100
|
+
if (record) {
|
|
101
|
+
records.push(record);
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
...opts,
|
|
105
|
+
});
|
|
106
|
+
return records;
|
|
107
|
+
}
|
|
108
|
+
async getLDRecordsInRegion(query, opts = {}) {
|
|
109
|
+
const { refName, start, end } = query;
|
|
110
|
+
const records = await this.getLDRecords(query, opts);
|
|
111
|
+
return records.filter(r => r.chrB === refName &&
|
|
112
|
+
r.bpB >= start &&
|
|
113
|
+
r.bpB <= end &&
|
|
114
|
+
r.chrA === refName &&
|
|
115
|
+
r.bpA >= start &&
|
|
116
|
+
r.bpA <= end);
|
|
117
|
+
}
|
|
118
|
+
parseLine(line, header) {
|
|
119
|
+
const fields = line.trim().split(/\s+/);
|
|
120
|
+
const chrA = fields[header.chrAIdx];
|
|
121
|
+
const bpA = Number.parseInt(fields[header.bpAIdx] ?? '', 10);
|
|
122
|
+
const snpA = header.snpAIdx >= 0 ? fields[header.snpAIdx] : `${chrA}:${bpA}`;
|
|
123
|
+
const chrB = fields[header.chrBIdx];
|
|
124
|
+
const bpB = Number.parseInt(fields[header.bpBIdx] ?? '', 10);
|
|
125
|
+
const snpB = header.snpBIdx >= 0 ? fields[header.snpBIdx] : `${chrB}:${bpB}`;
|
|
126
|
+
if (!chrA || !chrB || Number.isNaN(bpA) || Number.isNaN(bpB)) {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
const r2 = header.r2Idx >= 0
|
|
130
|
+
? Number.parseFloat(fields[header.r2Idx] ?? '')
|
|
131
|
+
: undefined;
|
|
132
|
+
const dprime = header.dprimeIdx >= 0
|
|
133
|
+
? Number.parseFloat(fields[header.dprimeIdx] ?? '')
|
|
134
|
+
: undefined;
|
|
135
|
+
const mafA = header.mafAIdx >= 0
|
|
136
|
+
? Number.parseFloat(fields[header.mafAIdx] ?? '')
|
|
137
|
+
: undefined;
|
|
138
|
+
const mafB = header.mafBIdx >= 0
|
|
139
|
+
? Number.parseFloat(fields[header.mafBIdx] ?? '')
|
|
140
|
+
: undefined;
|
|
141
|
+
return {
|
|
142
|
+
chrA,
|
|
143
|
+
bpA,
|
|
144
|
+
snpA: snpA ?? `${chrA}:${bpA}`,
|
|
145
|
+
chrB,
|
|
146
|
+
bpB,
|
|
147
|
+
snpB: snpB ?? `${chrB}:${bpB}`,
|
|
148
|
+
r2: r2 ?? 0,
|
|
149
|
+
dprime,
|
|
150
|
+
mafA,
|
|
151
|
+
mafB,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
freeResources() {
|
|
155
|
+
}
|
|
156
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
declare const PlinkLDAdapter: import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaType<{
|
|
2
|
+
ldLocation: {
|
|
3
|
+
type: string;
|
|
4
|
+
defaultValue: {
|
|
5
|
+
uri: string;
|
|
6
|
+
locationType: string;
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
}, import("node_modules/@jbrowse/core/src/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
|
|
10
|
+
export default PlinkLDAdapter;
|