jbrowse-plugin-graphgenomeviewer 7.1.0 → 7.1.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/README.md +17 -8
- package/dist/chunks/AddTrackWorkflow-RPH4ZFSX.js +2 -0
- package/dist/chunks/{AddTrackWorkflow-Q6RY23LF.js.map → AddTrackWorkflow-RPH4ZFSX.js.map} +2 -2
- package/dist/chunks/{ChooseSamplesDialog-BNVYBGJQ.js → ChooseSamplesDialog-JRN4YLBY.js} +2 -2
- package/dist/chunks/{ChooseWalksDialog-EN3C6AQA.js → ChooseWalksDialog-UXLFZTZJ.js} +2 -2
- package/dist/chunks/GbzBaseSyntenyAdapter-LRECKL74.js +2 -0
- package/dist/chunks/GbzBaseSyntenyAdapter-LRECKL74.js.map +7 -0
- package/dist/chunks/{GraphGenomeView-Z2WZKEEO.js → GraphGenomeView-NJ5XCREB.js} +2 -2
- package/dist/chunks/GraphTrackSettingsDialog-47PQ6LM7.js +6 -0
- package/dist/chunks/GraphTrackSettingsDialog-47PQ6LM7.js.map +7 -0
- package/dist/chunks/{HighlightColorDialog-EYBKFSJU.js → HighlightColorDialog-UK5VDDV6.js} +2 -2
- package/dist/chunks/{LinearGraphDisplay-WIBVWRQE.js → LinearGraphDisplay-TXTKAACH.js} +2 -2
- package/dist/chunks/MinigraphBubbleAdapter-HW7XQMAI.js +2 -0
- package/dist/chunks/MinigraphBubbleAdapter-HW7XQMAI.js.map +7 -0
- package/dist/chunks/RgfaTabixAdapter-PSKYWD2X.js +3 -0
- package/dist/chunks/RgfaTabixAdapter-PSKYWD2X.js.map +7 -0
- package/dist/chunks/{TrackWarningsDialog-QT4YEXGD.js → TrackWarningsDialog-TRYBOIHX.js} +2 -2
- package/dist/chunks/WalkTabixSyntenyAdapter-U53JLYVU.js +2 -0
- package/dist/chunks/WalkTabixSyntenyAdapter-U53JLYVU.js.map +7 -0
- package/dist/chunks/chunk-2MCOY3YG.js +3 -0
- package/dist/chunks/chunk-2MCOY3YG.js.map +7 -0
- package/dist/chunks/{chunk-EWFJBQDV.js → chunk-5O6YRJHL.js} +2 -2
- package/dist/chunks/{chunk-EWFJBQDV.js.map → chunk-5O6YRJHL.js.map} +1 -1
- package/dist/chunks/chunk-BUY2PV7D.js +2 -0
- package/dist/chunks/chunk-BUY2PV7D.js.map +7 -0
- package/dist/chunks/chunk-DVCZ3BOC.js +2 -0
- package/dist/chunks/chunk-DVCZ3BOC.js.map +7 -0
- package/dist/chunks/{chunk-SAMJE6GH.js → chunk-EGDLEQ47.js} +3 -3
- package/dist/chunks/{chunk-SAMJE6GH.js.map → chunk-EGDLEQ47.js.map} +4 -4
- package/dist/chunks/chunk-FHZXW7IG.js +2 -0
- package/dist/chunks/chunk-FHZXW7IG.js.map +7 -0
- package/dist/chunks/{chunk-DZ4OUKQV.js → chunk-FITPB5X6.js} +2 -2
- package/dist/chunks/{chunk-DZ4OUKQV.js.map → chunk-FITPB5X6.js.map} +1 -1
- package/dist/chunks/chunk-FVK2THE4.js +2 -0
- package/dist/chunks/chunk-FVK2THE4.js.map +7 -0
- package/dist/chunks/{chunk-AHFQHYJI.js → chunk-IBWORBGY.js} +2 -2
- package/dist/chunks/chunk-MND7GAOG.js +2 -0
- package/dist/chunks/chunk-MND7GAOG.js.map +7 -0
- package/dist/chunks/chunk-MURN3JPK.js +2 -0
- package/dist/chunks/chunk-MURN3JPK.js.map +7 -0
- package/dist/chunks/{chunk-3Q4RBDCL.js → chunk-N6PQZSAX.js} +1 -1
- package/dist/chunks/{chunk-3Q4RBDCL.js.map → chunk-N6PQZSAX.js.map} +1 -1
- package/dist/chunks/chunk-NWJYLP6Z.js +4 -0
- package/dist/chunks/chunk-NWJYLP6Z.js.map +7 -0
- package/dist/chunks/{chunk-YJHYBDYF.js → chunk-S75W27NT.js} +2 -2
- package/dist/chunks/{chunk-YJHYBDYF.js.map → chunk-S75W27NT.js.map} +1 -1
- package/dist/chunks/{chunk-IXQK7JAW.js → chunk-T4HOC6O3.js} +1 -1
- package/dist/chunks/{chunk-IXQK7JAW.js.map → chunk-T4HOC6O3.js.map} +1 -1
- package/dist/chunks/{chunk-AU73K7LX.js → chunk-TUKJRVBS.js} +1 -1
- package/dist/chunks/{chunk-AU73K7LX.js.map → chunk-TUKJRVBS.js.map} +1 -1
- package/dist/chunks/chunk-UGCNPRKC.js +2 -0
- package/dist/chunks/{chunk-E3WYW7Z6.js.map → chunk-UGCNPRKC.js.map} +2 -2
- package/dist/chunks/{chunk-YSTMDXXX.js → chunk-VJ3SO4CH.js} +1 -1
- package/dist/chunks/{chunk-YSTMDXXX.js.map → chunk-VJ3SO4CH.js.map} +1 -1
- package/dist/chunks/{chunk-XT766CZ5.js → chunk-W6EQLQ6H.js} +1 -1
- package/dist/chunks/{chunk-XT766CZ5.js.map → chunk-W6EQLQ6H.js.map} +1 -1
- package/dist/chunks/chunk-WAMBI7OX.js +2 -0
- package/dist/chunks/chunk-WAMBI7OX.js.map +7 -0
- package/dist/chunks/chunk-WCGVUZWP.js +2 -0
- package/dist/chunks/chunk-WCGVUZWP.js.map +7 -0
- package/dist/chunks/chunk-WEGWTC52.js +2 -0
- package/dist/chunks/chunk-WEGWTC52.js.map +7 -0
- package/dist/chunks/chunk-YU7T5WOQ.js +2 -0
- package/dist/chunks/{chunk-6OPB7FOJ.js.map → chunk-YU7T5WOQ.js.map} +2 -2
- package/dist/chunks/{chunk-446RWIA3.js → chunk-ZMOMFU2B.js} +1 -1
- package/dist/chunks/{chunk-446RWIA3.js.map → chunk-ZMOMFU2B.js.map} +1 -1
- package/dist/chunks/renderSvg-KSQI5DH6.js +2 -0
- package/dist/chunks/renderSvg-KSQI5DH6.js.map +7 -0
- package/dist/jbrowse-plugin-graphgenomeviewer.esm.js +4 -4
- package/dist/jbrowse-plugin-graphgenomeviewer.esm.js.map +4 -4
- package/package.json +8 -9
- package/src/GbzBaseSyntenyAdapter/GbzBaseSyntenyAdapter.test.ts +12 -10
- package/src/GbzBaseSyntenyAdapter/GbzBaseSyntenyAdapter.ts +31 -39
- package/src/GbzBaseSyntenyAdapter/configSchema.ts +5 -29
- package/src/GetGraphHaplotypes.ts +6 -15
- package/src/GetGraphReads.ts +7 -14
- package/src/GetSubgraph.ts +11 -20
- package/src/GraphAddTrackWorkflow/AddTrackWorkflow.test.tsx +73 -0
- package/src/GraphAddTrackWorkflow/AddTrackWorkflow.tsx +1 -0
- package/src/GraphAddTrackWorkflow/buildTrackConfig.test.ts +3 -2
- package/src/GraphAddTrackWorkflow/buildTrackConfig.ts +2 -11
- package/src/GraphAddTrackWorkflow/graphManifest.ts +15 -3
- package/src/GraphGenomeView/components/BubbleHalos.tsx +5 -24
- package/src/GraphGenomeView/components/ElTree.tsx +6 -1
- package/src/GraphGenomeView/components/FacetPanels.test.tsx +65 -0
- package/src/GraphGenomeView/components/FacetPanels.tsx +17 -12
- package/src/GraphGenomeView/components/GenePins.tsx +5 -22
- package/src/GraphGenomeView/components/GraphCanvas.tsx +40 -234
- package/src/GraphGenomeView/components/GraphSettingsDialog.tsx +102 -108
- package/src/GraphGenomeView/components/GraphToolbar.tsx +5 -6
- package/src/GraphGenomeView/components/HoverLayer.tsx +3 -7
- package/src/GraphGenomeView/components/HoverTooltip.test.tsx +39 -0
- package/src/GraphGenomeView/components/HoverTooltip.tsx +122 -0
- package/src/GraphGenomeView/components/LabelChip.tsx +3 -5
- package/src/GraphGenomeView/components/LabelLayer.tsx +4 -17
- package/src/GraphGenomeView/components/LabelledSelect.tsx +1 -1
- package/src/GraphGenomeView/components/Legend.tsx +14 -23
- package/src/GraphGenomeView/components/PaneContextMenu.test.tsx +48 -0
- package/src/GraphGenomeView/components/PaneContextMenu.tsx +144 -0
- package/src/GraphGenomeView/components/PaneLayer.tsx +91 -0
- package/src/GraphGenomeView/components/PaneSvg.tsx +32 -50
- package/src/GraphGenomeView/components/ReferenceStripOverlay.test.tsx +48 -0
- package/src/GraphGenomeView/components/ReferenceStripOverlay.tsx +13 -42
- package/src/GraphGenomeView/components/SettingsMenu.test.tsx +29 -0
- package/src/GraphGenomeView/components/SettingsMenu.tsx +56 -65
- package/src/GraphGenomeView/components/TubeMapOverlay.tsx +15 -46
- package/src/GraphGenomeView/components/WalkRowsOverlay.tsx +58 -132
- package/src/GraphGenomeView/components/WalkStrip.tsx +17 -20
- package/src/GraphGenomeView/components/WalkStripLocator.tsx +8 -15
- package/src/GraphGenomeView/components/usePaneGestures.test.tsx +35 -0
- package/src/GraphGenomeView/components/usePaneGestures.ts +88 -91
- package/src/GraphGenomeView/genes/geneFeatures.ts +27 -45
- package/src/GraphGenomeView/graphLayers.ts +4 -4
- package/src/GraphGenomeView/host.ts +1 -1
- package/src/GraphGenomeView/legendSections.test.ts +23 -1
- package/src/GraphGenomeView/legendSections.ts +68 -74
- package/src/GraphGenomeView/model.test.ts +373 -39
- package/src/GraphGenomeView/model.ts +67 -11
- package/src/GraphGenomeView/pane/fitViews.ts +57 -514
- package/src/GraphGenomeView/pane/graphViews.ts +219 -160
- package/src/GraphGenomeView/pane/hostViews.ts +2 -10
- package/src/GraphGenomeView/pane/keepInView.ts +5 -4
- package/src/GraphGenomeView/pane/launchActions.ts +117 -139
- package/src/GraphGenomeView/pane/launchViews.ts +8 -27
- package/src/GraphGenomeView/pane/loadActions.ts +208 -187
- package/src/GraphGenomeView/pane/morph.ts +3 -9
- package/src/GraphGenomeView/pane/paneBase.ts +22 -11
- package/src/GraphGenomeView/pane/renderingActions.ts +65 -11
- package/src/GraphGenomeView/pane/settingActions.ts +17 -42
- package/src/GraphGenomeView/pane/tubeMapViews.ts +445 -0
- package/src/GraphGenomeView/pane/walkRowViews.ts +29 -37
- package/src/GraphGenomeView/renderPipeline.test.ts +1 -1
- package/src/GraphGenomeView/repeats/repeatFeatures.test.ts +23 -0
- package/src/GraphGenomeView/repeats/repeatFeatures.ts +16 -23
- package/src/GraphGenomeView/repeats/walkCalls.test.ts +18 -0
- package/src/GraphGenomeView/repeats/walkCalls.ts +46 -38
- package/src/GraphGenomeView/subgraphLoad.test.ts +67 -3
- package/src/GraphGenomeView/trackFeatures.ts +24 -0
- package/src/GraphGenomeView/tubeMapPanels.ts +28 -36
- package/src/GraphGenomeView/viewModel.ts +8 -56
- package/src/GraphGenomeView/walkRowGroups.ts +104 -30
- package/src/GraphGenomeView/walkRowSpans.test.ts +6 -0
- package/src/GraphGenomeView/walkRowSpans.ts +22 -31
- package/src/GraphGenomeView/walkRowsCut.ts +8 -17
- package/src/LinearGraphDisplay/LinearGraphDisplay.test.ts +173 -26
- package/src/LinearGraphDisplay/components/SubgraphContextSelect.test.tsx +1 -1
- package/src/LinearGraphDisplay/components/SubgraphContextSelect.tsx +3 -3
- package/src/LinearGraphDisplay/components/SubgraphHaplotypesField.test.tsx +3 -3
- package/src/LinearGraphDisplay/components/SubgraphHaplotypesField.tsx +7 -10
- package/src/LinearGraphDisplay/configSchema.ts +0 -3
- package/src/LinearGraphDisplay/denseWindow.ts +8 -11
- package/src/LinearGraphDisplay/model.ts +89 -82
- package/src/MinigraphBubbleAdapter/MinigraphBubbleAdapter.test.ts +21 -0
- package/src/MinigraphBubbleAdapter/MinigraphBubbleAdapter.ts +6 -14
- package/src/MinigraphBubbleAdapter/configSchema.ts +3 -9
- package/src/MinigraphBubbleAdapter/index.ts +1 -2
- package/src/RgfaTabixAdapter/RgfaTabixAdapter.test.ts +45 -1
- package/src/RgfaTabixAdapter/RgfaTabixAdapter.ts +111 -276
- package/src/RgfaTabixAdapter/configSchema.ts +15 -49
- package/src/RgfaTabixAdapter/index.ts +1 -2
- package/src/RgfaTabixAdapter/rgfaBed.ts +25 -15
- package/src/RgfaTabixAdapter/rgfaCut.ts +139 -0
- package/src/RgfaTabixAdapter/test_data/walks2_twopart.GRCh38.walks.bed.gz +0 -0
- package/src/RgfaTabixAdapter/test_data/walks2_twopart.GRCh38.walks.bed.gz.tbi +0 -0
- package/src/RgfaTabixAdapter/walkFiles.test.ts +33 -0
- package/src/RgfaTabixAdapter/walkReader.ts +103 -27
- package/src/RgfaTabixAdapter/walkRowRuns.test.ts +53 -0
- package/src/RgfaTabixAdapter/walkRowRuns.ts +42 -24
- package/src/WalkTabixSyntenyAdapter/WalkTabixSyntenyAdapter.test.ts +37 -6
- package/src/WalkTabixSyntenyAdapter/WalkTabixSyntenyAdapter.ts +23 -45
- package/src/WalkTabixSyntenyAdapter/configSchema.ts +11 -24
- package/src/WalkTabixSyntenyAdapter/index.ts +1 -2
- package/src/WalkTabixSyntenyAdapter/walkLanes.ts +35 -43
- package/src/adapterImplementing.ts +27 -0
- package/src/graphTrackDefaults/index.ts +14 -20
- package/src/hoverSync/lgvHover.ts +2 -4
- package/src/launchFromGraph/contributors.ts +1 -5
- package/src/launchFromGraph/graphMenuItems.ts +3 -4
- package/src/launchFromGraph/launchFromGraph.test.ts +0 -1
- package/src/launchFromGraph/launchFromGraph.ts +8 -13
- package/src/panSNTabix.test.ts +1 -26
- package/src/panSNTabix.ts +54 -51
- package/src/synteny/lanePairs.ts +8 -0
- package/src/synteny/matchFeature.ts +52 -0
- package/src/tabixRange.ts +13 -10
- package/src/version.ts +1 -1
- package/dist/chunks/AddTrackWorkflow-Q6RY23LF.js +0 -2
- package/dist/chunks/GbzBaseSyntenyAdapter-TIXR4Y3J.js +0 -2
- package/dist/chunks/GbzBaseSyntenyAdapter-TIXR4Y3J.js.map +0 -7
- package/dist/chunks/GraphTrackSettingsDialog-TAM6PMXD.js +0 -6
- package/dist/chunks/GraphTrackSettingsDialog-TAM6PMXD.js.map +0 -7
- package/dist/chunks/MinigraphBubbleAdapter-AGI2UYQR.js +0 -2
- package/dist/chunks/MinigraphBubbleAdapter-AGI2UYQR.js.map +0 -7
- package/dist/chunks/RgfaTabixAdapter-2OL5X3HF.js +0 -3
- package/dist/chunks/RgfaTabixAdapter-2OL5X3HF.js.map +0 -7
- package/dist/chunks/WalkTabixSyntenyAdapter-UKFHCFOF.js +0 -2
- package/dist/chunks/WalkTabixSyntenyAdapter-UKFHCFOF.js.map +0 -7
- package/dist/chunks/chunk-5SFGHDQA.js +0 -2
- package/dist/chunks/chunk-5SFGHDQA.js.map +0 -7
- package/dist/chunks/chunk-6OPB7FOJ.js +0 -2
- package/dist/chunks/chunk-AMFIBQVR.js +0 -2
- package/dist/chunks/chunk-AMFIBQVR.js.map +0 -7
- package/dist/chunks/chunk-BJMRBVG3.js +0 -2
- package/dist/chunks/chunk-BJMRBVG3.js.map +0 -7
- package/dist/chunks/chunk-E3WYW7Z6.js +0 -2
- package/dist/chunks/chunk-EHCF6AXH.js +0 -2
- package/dist/chunks/chunk-EHCF6AXH.js.map +0 -7
- package/dist/chunks/chunk-GOFS7BXK.js +0 -3
- package/dist/chunks/chunk-GOFS7BXK.js.map +0 -7
- package/dist/chunks/chunk-IJQTSJGT.js +0 -4
- package/dist/chunks/chunk-IJQTSJGT.js.map +0 -7
- package/dist/chunks/chunk-J6NZIAZF.js +0 -2
- package/dist/chunks/chunk-J6NZIAZF.js.map +0 -7
- package/dist/chunks/chunk-LUTMKRXY.js +0 -2
- package/dist/chunks/chunk-LUTMKRXY.js.map +0 -7
- package/dist/chunks/chunk-MHPJB22Z.js +0 -2
- package/dist/chunks/chunk-MHPJB22Z.js.map +0 -7
- package/dist/chunks/chunk-TXI43PEN.js +0 -2
- package/dist/chunks/chunk-TXI43PEN.js.map +0 -7
- package/dist/chunks/chunk-WRH2EJKX.js +0 -2
- package/dist/chunks/chunk-WRH2EJKX.js.map +0 -7
- package/dist/chunks/chunk-WX26KTZM.js +0 -2
- package/dist/chunks/chunk-WX26KTZM.js.map +0 -7
- package/dist/chunks/renderSvg-ST2GBBOC.js +0 -2
- package/dist/chunks/renderSvg-ST2GBBOC.js.map +0 -7
- package/src/GraphGenomeView/components/WalkRowContextMenu.tsx +0 -105
- /package/dist/chunks/{ChooseSamplesDialog-BNVYBGJQ.js.map → ChooseSamplesDialog-JRN4YLBY.js.map} +0 -0
- /package/dist/chunks/{ChooseWalksDialog-EN3C6AQA.js.map → ChooseWalksDialog-UXLFZTZJ.js.map} +0 -0
- /package/dist/chunks/{GraphGenomeView-Z2WZKEEO.js.map → GraphGenomeView-NJ5XCREB.js.map} +0 -0
- /package/dist/chunks/{HighlightColorDialog-EYBKFSJU.js.map → HighlightColorDialog-UK5VDDV6.js.map} +0 -0
- /package/dist/chunks/{LinearGraphDisplay-WIBVWRQE.js.map → LinearGraphDisplay-TXTKAACH.js.map} +0 -0
- /package/dist/chunks/{TrackWarningsDialog-QT4YEXGD.js.map → TrackWarningsDialog-TRYBOIHX.js.map} +0 -0
- /package/dist/chunks/{chunk-AHFQHYJI.js.map → chunk-IBWORBGY.js.map} +0 -0
|
@@ -26,25 +26,18 @@ import { reaction } from 'mobx'
|
|
|
26
26
|
import { denseCovers, isNodeLimitError } from './denseWindow'
|
|
27
27
|
import { cutHolds, hostCut, hostWindow } from '../GraphGenomeView/host'
|
|
28
28
|
import { lenientOptionalEnum } from '../GraphGenomeView/lenientEnum'
|
|
29
|
-
import {
|
|
30
|
-
GraphPaneMixin,
|
|
31
|
-
MAX_GRAPH_REGION_BP,
|
|
32
|
-
formatSpanBp,
|
|
33
|
-
} from '../GraphGenomeView/model'
|
|
29
|
+
import { GraphPane, formatSpanBp } from '../GraphGenomeView/model'
|
|
34
30
|
import { FACET_KEY_PX } from '../GraphGenomeView/pane/fitViews'
|
|
31
|
+
import { paneBase } from '../GraphGenomeView/pane/paneBase'
|
|
35
32
|
import {
|
|
36
33
|
configHaplotypes,
|
|
37
34
|
cutsByHaplotype,
|
|
38
|
-
graphReferenceAssembly,
|
|
39
|
-
offReferenceProblem,
|
|
40
35
|
trackLanes,
|
|
41
36
|
walkIndexed,
|
|
42
37
|
} from '../graphTrackConfig'
|
|
43
38
|
import { pushLaunchItem } from '../launchFromGraph/pushLaunchItem'
|
|
44
|
-
import { trackAdapterConfig } from '../panSNAliases/trackAdapterConfig'
|
|
45
39
|
|
|
46
40
|
import type { LinearGraphDisplayConfigModel } from './configSchema'
|
|
47
|
-
import type { DenseWindow } from './denseWindow'
|
|
48
41
|
import type { SubgraphRegion, SubgraphTier } from '../GetSubgraph'
|
|
49
42
|
import type { GraphLayers } from '../GraphGenomeView/graphLayers'
|
|
50
43
|
import type { HostWindow } from '../GraphGenomeView/host'
|
|
@@ -53,11 +46,27 @@ import type { LaunchGraphGenomeViewArgs } from '../LaunchGraphGenomeView'
|
|
|
53
46
|
import type { LayoutModeValue } from '@jbrowse/bandage-core/layoutModes'
|
|
54
47
|
import type { MenuItem } from '@jbrowse/core/ui'
|
|
55
48
|
import type { ExportSvgDisplayOptions } from '@jbrowse/display-kit/types'
|
|
56
|
-
import type { Instance } from '@jbrowse/mobx-state-tree'
|
|
49
|
+
import type { Instance, SnapshotOut } from '@jbrowse/mobx-state-tree'
|
|
57
50
|
import type { DisplayStatusPhase } from '@jbrowse/render-core/displayPhase'
|
|
58
51
|
|
|
59
52
|
type GraphViewSpec = Omit<LaunchGraphGenomeViewArgs, 'session'>
|
|
60
53
|
|
|
54
|
+
// the pane's viewport, which a new graph view fits to its drawing
|
|
55
|
+
const VIEWPORT_PROPS = new Set(['scale', 'translateX', 'translateY'])
|
|
56
|
+
|
|
57
|
+
type PaneSettings = Omit<
|
|
58
|
+
SnapshotOut<typeof paneBase>,
|
|
59
|
+
'scale' | 'translateX' | 'translateY'
|
|
60
|
+
>
|
|
61
|
+
|
|
62
|
+
function paneSettings(pane: Instance<typeof paneBase>) {
|
|
63
|
+
return Object.fromEntries(
|
|
64
|
+
Object.keys(paneBase.properties)
|
|
65
|
+
.filter(key => !VIEWPORT_PROPS.has(key))
|
|
66
|
+
.map(key => [key, pane[key as keyof typeof pane]]),
|
|
67
|
+
) as PaneSettings
|
|
68
|
+
}
|
|
69
|
+
|
|
61
70
|
// A variant under this many of the linear view's pixels folds into the
|
|
62
71
|
// reference before layout, so the drawing gains detail as the view zooms in.
|
|
63
72
|
// It is the width `gfa-to-tabix build` gives a backbone node at the zoom a
|
|
@@ -89,7 +98,7 @@ export function stateModelFactory(configSchema: LinearGraphDisplayConfigModel) {
|
|
|
89
98
|
'LinearGraphDisplay',
|
|
90
99
|
BaseDisplay,
|
|
91
100
|
TrackHeightMixin(),
|
|
92
|
-
|
|
101
|
+
GraphPane,
|
|
93
102
|
types.model({
|
|
94
103
|
type: types.literal('LinearGraphDisplay'),
|
|
95
104
|
configuration: ConfigurationReference(configSchema),
|
|
@@ -102,35 +111,20 @@ export function stateModelFactory(configSchema: LinearGraphDisplayConfigModel) {
|
|
|
102
111
|
// whether that cut came from the track's coarse pair
|
|
103
112
|
// (RgfaTabixAdapter), on which no bp cap applies
|
|
104
113
|
coarseCut: types.optional(types.boolean, false),
|
|
105
|
-
// The bp ceiling on a fine cut, a proxy for node count that only
|
|
106
|
-
// holds at fine granularity; `maxGraphNodes` counts what came back.
|
|
107
|
-
maxRegionBp: types.optional(types.number, MAX_GRAPH_REGION_BP),
|
|
108
|
-
// How far the cut follows links past the region's own segments. At
|
|
109
|
-
// 0 a detour that leaves the backbone before the window and rejoins
|
|
110
|
-
// after it arrives as a fragment, since its interior is indexed only
|
|
111
|
-
// under its own sequence, so one bubble draws as two unrelated
|
|
112
|
-
// insertions. A hop follows alleles only, so it never walks the
|
|
113
|
-
// backbone out of the window.
|
|
114
|
-
subgraphContext: types.optional(types.number, 1),
|
|
115
|
-
// the haplotypes a GBZ or walk-indexed cut is for; unset is the
|
|
116
|
-
// config's defaultHaplotypes, else the lanes the track names
|
|
117
|
-
subgraphHaplotypes: types.maybe(types.frozen<string[]>()),
|
|
118
114
|
}),
|
|
119
115
|
)
|
|
120
116
|
.volatile(() => ({
|
|
121
117
|
recuts: 0,
|
|
122
118
|
// the host window the settle clock last woke on
|
|
123
119
|
settledWindow: undefined as HostWindow | undefined,
|
|
124
|
-
|
|
120
|
+
// where a cut came back over its node limit (denseCovers)
|
|
121
|
+
dense: undefined as SubgraphRegion | undefined,
|
|
125
122
|
// the haplotypes a walk-indexed graph's header names, once read
|
|
126
123
|
haplotypeNames: undefined as string[] | undefined,
|
|
127
124
|
// the fold the latest cut asked for
|
|
128
125
|
cutFoldBp: 0,
|
|
129
126
|
}))
|
|
130
127
|
.views(self => ({
|
|
131
|
-
get adapterConfig() {
|
|
132
|
-
return trackAdapterConfig(self, self.parentTrack.configuration)
|
|
133
|
-
},
|
|
134
128
|
get grammar(): GraphGrammar {
|
|
135
129
|
return {
|
|
136
130
|
layoutMode: getConf(self, 'layoutMode'),
|
|
@@ -152,17 +146,18 @@ export function stateModelFactory(configSchema: LinearGraphDisplayConfigModel) {
|
|
|
152
146
|
get canRetryLoad() {
|
|
153
147
|
return self.cutRegion !== undefined
|
|
154
148
|
},
|
|
155
|
-
|
|
149
|
+
// the config's defaultHaplotypes, else the lanes the track names
|
|
150
|
+
get trackHaplotypes() {
|
|
151
|
+
const adapter = self.sourceAdapter
|
|
152
|
+
const track = self.sourceTrack
|
|
156
153
|
return (
|
|
157
|
-
|
|
158
|
-
configHaplotypes(this.adapterConfig) ??
|
|
159
|
-
trackLanes(self.parentTrack.configuration)
|
|
154
|
+
(adapter && configHaplotypes(adapter)) ?? (track && trackLanes(track))
|
|
160
155
|
)
|
|
161
156
|
},
|
|
162
157
|
// the linear view's zoom past which the track's coarse pair is cut, or
|
|
163
158
|
// undefined for a track with none
|
|
164
159
|
get coarseAboveBpPerPx() {
|
|
165
|
-
return coarseHandover(self.
|
|
160
|
+
return coarseHandover(self.sourceAdapter?.coarse)
|
|
166
161
|
},
|
|
167
162
|
}))
|
|
168
163
|
.views(self => ({
|
|
@@ -175,13 +170,13 @@ export function stateModelFactory(configSchema: LinearGraphDisplayConfigModel) {
|
|
|
175
170
|
},
|
|
176
171
|
// Whether a zoom has moved far enough from the one the drawing was
|
|
177
172
|
// folded for that folding again would show or hide more. A graph with
|
|
178
|
-
// walks is never folded.
|
|
173
|
+
// walks is never folded, and a fold rounded to 0 bp counts as 1 bp.
|
|
179
174
|
foldDrifted(bpPerPx: number) {
|
|
180
175
|
const want = FOLD_PX * bpPerPx
|
|
181
176
|
const had = self.cutFoldBp
|
|
182
177
|
return (
|
|
183
178
|
!self.graph?.paths?.length &&
|
|
184
|
-
(want >= 2 * had ||
|
|
179
|
+
(want >= 2 * Math.max(had, 1) ||
|
|
185
180
|
(self.foldedBelowBp !== undefined && want <= had / 2))
|
|
186
181
|
)
|
|
187
182
|
},
|
|
@@ -267,15 +262,16 @@ export function stateModelFactory(configSchema: LinearGraphDisplayConfigModel) {
|
|
|
267
262
|
setConf(self, slot as keyof GraphGrammar, value)
|
|
268
263
|
}
|
|
269
264
|
},
|
|
270
|
-
// The setters describe the next cut
|
|
265
|
+
// The setters describe the next cut, which recut makes
|
|
271
266
|
setSubgraphContext(hops: number) {
|
|
272
267
|
self.subgraphContext = hops
|
|
268
|
+
self.dense = undefined
|
|
273
269
|
},
|
|
274
270
|
setSubgraphHaplotypes(haplotypes: string[] | undefined) {
|
|
275
271
|
self.subgraphHaplotypes = haplotypes
|
|
276
272
|
self.dense = undefined
|
|
277
273
|
},
|
|
278
|
-
setDense(window:
|
|
274
|
+
setDense(window: SubgraphRegion | undefined) {
|
|
279
275
|
self.dense = window
|
|
280
276
|
},
|
|
281
277
|
setHaplotypeNames(names: string[] | undefined) {
|
|
@@ -288,13 +284,11 @@ export function stateModelFactory(configSchema: LinearGraphDisplayConfigModel) {
|
|
|
288
284
|
// a fine one does, since a tier is the same graph folded.
|
|
289
285
|
cut() {
|
|
290
286
|
const region = self.cutRegion
|
|
291
|
-
|
|
287
|
+
const adapterConfig = self.sourceAdapter
|
|
288
|
+
if (!region || !adapterConfig) {
|
|
292
289
|
return
|
|
293
290
|
}
|
|
294
|
-
const problem =
|
|
295
|
-
graphReferenceAssembly(self.parentTrack.configuration),
|
|
296
|
-
region.assemblyName,
|
|
297
|
-
)
|
|
291
|
+
const problem = self.offReference(region)
|
|
298
292
|
if (problem) {
|
|
299
293
|
self.clearGraph()
|
|
300
294
|
self.setError(new Error(problem))
|
|
@@ -305,17 +299,9 @@ export function stateModelFactory(configSchema: LinearGraphDisplayConfigModel) {
|
|
|
305
299
|
FOLD_PX * (self.settledWindow?.bpPerPx ?? self.host?.bpPerPx ?? 0),
|
|
306
300
|
)
|
|
307
301
|
return self.cutSubgraph(
|
|
308
|
-
|
|
302
|
+
adapterConfig,
|
|
309
303
|
region,
|
|
310
|
-
{
|
|
311
|
-
hops: self.subgraphContext,
|
|
312
|
-
haplotypes: self.cutHaplotypes,
|
|
313
|
-
tier: coarse ? 'coarse' : undefined,
|
|
314
|
-
...(self.chosenLayoutMode === 'walkrows' ? { walkRows: true } : {}),
|
|
315
|
-
...(layoutModeByValue(self.chosenLayoutMode).wholeWalks
|
|
316
|
-
? { snarls: 'overlapping' as const }
|
|
317
|
-
: {}),
|
|
318
|
-
},
|
|
304
|
+
{ ...self.cutOptions, tier: coarse ? 'coarse' : undefined },
|
|
319
305
|
self.cutFoldBp,
|
|
320
306
|
)
|
|
321
307
|
},
|
|
@@ -353,10 +339,16 @@ export function stateModelFactory(configSchema: LinearGraphDisplayConfigModel) {
|
|
|
353
339
|
) {
|
|
354
340
|
return false
|
|
355
341
|
}
|
|
356
|
-
//
|
|
357
|
-
//
|
|
358
|
-
|
|
359
|
-
|
|
342
|
+
// An outrun cut resolves without touching the error, so the error
|
|
343
|
+
// is this cut's only while no later one has started
|
|
344
|
+
const cut = self.recutAt(seen)
|
|
345
|
+
const recut = self.recuts
|
|
346
|
+
void Promise.resolve(cut).then(() => {
|
|
347
|
+
if (
|
|
348
|
+
isAlive(self) &&
|
|
349
|
+
self.recuts === recut &&
|
|
350
|
+
isNodeLimitError(self.error)
|
|
351
|
+
) {
|
|
360
352
|
this.refuseDenseCut(seen)
|
|
361
353
|
}
|
|
362
354
|
})
|
|
@@ -369,16 +361,23 @@ export function stateModelFactory(configSchema: LinearGraphDisplayConfigModel) {
|
|
|
369
361
|
self.cutRegion = undefined
|
|
370
362
|
this.settleOn(self.settledWindow ?? seen)
|
|
371
363
|
},
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
364
|
+
// Cut the region again with the current options, or the window on
|
|
365
|
+
// screen where a refused cut left no region
|
|
366
|
+
recut() {
|
|
367
|
+
if (self.cutRegion) {
|
|
368
|
+
void self.cut()
|
|
369
|
+
} else if (self.settledWindow) {
|
|
370
|
+
this.settleOn(self.settledWindow)
|
|
371
|
+
}
|
|
372
|
+
},
|
|
373
|
+
relayoutFrom(from: LayoutModeValue) {
|
|
375
374
|
const seen = self.host ? hostWindow(self.host) : undefined
|
|
376
375
|
if (
|
|
377
376
|
seen &&
|
|
378
377
|
!self.regionTooLarge &&
|
|
379
|
-
(
|
|
380
|
-
|
|
381
|
-
|
|
378
|
+
(self.cutChangedFrom(from) ||
|
|
379
|
+
layoutModeByValue(from).cutMargins !==
|
|
380
|
+
layoutModeByValue(self.chosenLayoutMode).cutMargins)
|
|
382
381
|
) {
|
|
383
382
|
return self.recutAt(seen)
|
|
384
383
|
}
|
|
@@ -396,18 +395,23 @@ export function stateModelFactory(configSchema: LinearGraphDisplayConfigModel) {
|
|
|
396
395
|
}))
|
|
397
396
|
.actions(self => ({
|
|
398
397
|
// A failed read leaves the picker taking typed names
|
|
399
|
-
async fetchHaplotypeNames(
|
|
398
|
+
async fetchHaplotypeNames(
|
|
399
|
+
adapterConfig: Record<string, unknown>,
|
|
400
|
+
signal?: AbortSignal,
|
|
401
|
+
) {
|
|
400
402
|
try {
|
|
401
403
|
const names = await getSession(self).rpcManager.call(
|
|
402
404
|
getRpcSessionId(self),
|
|
403
405
|
'GetGraphHaplotypes',
|
|
404
|
-
{ adapterConfig },
|
|
406
|
+
{ adapterConfig, signal },
|
|
405
407
|
)
|
|
406
|
-
if (isAlive(self) && self.
|
|
408
|
+
if (isAlive(self) && self.sourceAdapter === adapterConfig) {
|
|
407
409
|
self.setHaplotypeNames(names)
|
|
408
410
|
}
|
|
409
411
|
} catch (e) {
|
|
410
|
-
|
|
412
|
+
if (!signal?.aborted) {
|
|
413
|
+
console.warn('[LinearGraphDisplay] no haplotype names', e)
|
|
414
|
+
}
|
|
411
415
|
}
|
|
412
416
|
},
|
|
413
417
|
}))
|
|
@@ -456,15 +460,24 @@ export function stateModelFactory(configSchema: LinearGraphDisplayConfigModel) {
|
|
|
456
460
|
if (self.cutRegion && !self.graph) {
|
|
457
461
|
void self.cut()
|
|
458
462
|
}
|
|
463
|
+
let namesRead: AbortController | undefined
|
|
464
|
+
addDisposer(self, () => {
|
|
465
|
+
namesRead?.abort()
|
|
466
|
+
})
|
|
459
467
|
addDisposer(
|
|
460
468
|
self,
|
|
461
469
|
reaction(
|
|
462
|
-
() =>
|
|
463
|
-
|
|
470
|
+
() => {
|
|
471
|
+
const adapter = self.sourceAdapter
|
|
472
|
+
return adapter && walkIndexed(adapter) ? adapter : undefined
|
|
473
|
+
},
|
|
464
474
|
adapterConfig => {
|
|
475
|
+
namesRead?.abort()
|
|
476
|
+
namesRead = undefined
|
|
465
477
|
self.setHaplotypeNames(undefined)
|
|
466
478
|
if (adapterConfig) {
|
|
467
|
-
|
|
479
|
+
namesRead = new AbortController()
|
|
480
|
+
void self.fetchHaplotypeNames(adapterConfig, namesRead.signal)
|
|
468
481
|
}
|
|
469
482
|
},
|
|
470
483
|
{ fireImmediately: true, name: 'GraphHaplotypeNames' },
|
|
@@ -579,6 +592,7 @@ export function stateModelFactory(configSchema: LinearGraphDisplayConfigModel) {
|
|
|
579
592
|
const start = Math.floor(seen.start)
|
|
580
593
|
const end = Math.ceil(seen.end)
|
|
581
594
|
return {
|
|
595
|
+
...paneSettings(self),
|
|
582
596
|
loadedTrackId: trackId,
|
|
583
597
|
loadedRegion: {
|
|
584
598
|
refName: seen.refName,
|
|
@@ -586,19 +600,10 @@ export function stateModelFactory(configSchema: LinearGraphDisplayConfigModel) {
|
|
|
586
600
|
start,
|
|
587
601
|
end,
|
|
588
602
|
},
|
|
589
|
-
subgraphContext: self.subgraphContext,
|
|
590
603
|
subgraphHaplotypes: self.cutHaplotypes,
|
|
591
604
|
maxRegionBp: Math.max(self.maxRegionBp, end - start),
|
|
592
605
|
...self.grammar,
|
|
593
606
|
layoutMode: self.chosenLayoutMode,
|
|
594
|
-
referencePath: self.referencePath,
|
|
595
|
-
geneTrackId: self.geneTrackId,
|
|
596
|
-
walkLayers: self.walkLayers,
|
|
597
|
-
layoutEngine: self.layoutEngine,
|
|
598
|
-
layoutQuality: self.layoutQuality,
|
|
599
|
-
bubbleSpread: self.bubbleSpread,
|
|
600
|
-
linearLayout: self.linearLayout,
|
|
601
|
-
maxGraphNodes: self.maxGraphNodes,
|
|
602
607
|
connectedViewId: self.host?.id,
|
|
603
608
|
} satisfies GraphViewSpec
|
|
604
609
|
},
|
|
@@ -616,16 +621,18 @@ export function stateModelFactory(configSchema: LinearGraphDisplayConfigModel) {
|
|
|
616
621
|
// graph, the config's default set or the assemblies the track names,
|
|
617
622
|
// or a list chosen in Graph settings
|
|
618
623
|
cutMenuItems(): MenuItem[] {
|
|
619
|
-
|
|
624
|
+
const adapter = self.sourceAdapter
|
|
625
|
+
const track = self.sourceTrack
|
|
626
|
+
if (!adapter || !track || !cutsByHaplotype(adapter)) {
|
|
620
627
|
return []
|
|
621
628
|
}
|
|
622
|
-
const defaults = configHaplotypes(
|
|
623
|
-
const lanes = trackLanes(
|
|
629
|
+
const defaults = configHaplotypes(adapter)
|
|
630
|
+
const lanes = trackLanes(track)
|
|
624
631
|
const names = self.haplotypeNames
|
|
625
632
|
const chosen = self.subgraphHaplotypes
|
|
626
633
|
const recut = (haplotypes: string[] | undefined) => {
|
|
627
634
|
self.setSubgraphHaplotypes(haplotypes)
|
|
628
|
-
|
|
635
|
+
self.recut()
|
|
629
636
|
}
|
|
630
637
|
return [
|
|
631
638
|
{ type: 'subHeader', label: 'Load' },
|
|
@@ -4,11 +4,13 @@ import {
|
|
|
4
4
|
bubbleLabel,
|
|
5
5
|
parseBubbleLine,
|
|
6
6
|
} from '@jbrowse/bandage-core/bubbles/bubbleLine'
|
|
7
|
+
import PluginManager from '@jbrowse/core/PluginManager'
|
|
7
8
|
import { firstValueFrom } from 'rxjs'
|
|
8
9
|
import { toArray } from 'rxjs/operators'
|
|
9
10
|
|
|
10
11
|
import Adapter from './MinigraphBubbleAdapter.ts'
|
|
11
12
|
import configSchema from './configSchema.ts'
|
|
13
|
+
import MinigraphBubbleAdapterF from './index.ts'
|
|
12
14
|
|
|
13
15
|
// Unmodified `gfatools bubble` output cut to chr6:32.4-32.7 Mb, so the column
|
|
14
16
|
// order here is the real one. Its stable names are bare (`chr6`) rather than
|
|
@@ -36,6 +38,12 @@ const mhc = {
|
|
|
36
38
|
end: 32420000,
|
|
37
39
|
}
|
|
38
40
|
|
|
41
|
+
test("the byte gate measures a region from the bubble file's index", async () => {
|
|
42
|
+
const adapter = makeAdapter()
|
|
43
|
+
expect(await adapter.getRegionByteSize([mhc])).toBeGreaterThan(0)
|
|
44
|
+
expect(await adapter.getRegionByteSize([{ ...mhc, refName: 'chr7' }])).toBe(0)
|
|
45
|
+
})
|
|
46
|
+
|
|
39
47
|
test('getRefNames lists the sequences the bubbles sit on', async () => {
|
|
40
48
|
expect(await makeAdapter().getRefNames()).toEqual(['chr6'])
|
|
41
49
|
})
|
|
@@ -155,3 +163,16 @@ test('reports assembly-facing contigs for a PanSN-named file', async () => {
|
|
|
155
163
|
const adapter = makeAdapter()
|
|
156
164
|
expect(await adapter.getRefNames({ assemblyName: 'hg38' })).toEqual(['chr6'])
|
|
157
165
|
})
|
|
166
|
+
|
|
167
|
+
test("the adapter type expands the uri shorthand with the schema's preprocessor", () => {
|
|
168
|
+
const pluginManager = new PluginManager()
|
|
169
|
+
MinigraphBubbleAdapterF(pluginManager)
|
|
170
|
+
pluginManager.createPluggableElements()
|
|
171
|
+
const { normalizeSnapshot } = pluginManager.getAdapterType(
|
|
172
|
+
'MinigraphBubbleAdapter',
|
|
173
|
+
)
|
|
174
|
+
expect(normalizeSnapshot?.({ uri: 'bb.bed.gz' })).toMatchObject({
|
|
175
|
+
bubblesLocation: { uri: 'bb.bed.gz' },
|
|
176
|
+
index: { location: { uri: 'bb.bed.gz.tbi' } },
|
|
177
|
+
})
|
|
178
|
+
})
|
|
@@ -11,36 +11,28 @@ import { PanSNRefNames, openTabixSlot } from '../panSNTabix.ts'
|
|
|
11
11
|
import { getLines } from '../tabixRange.ts'
|
|
12
12
|
|
|
13
13
|
import type { MinigraphBubbleAdapterConfig } from './configSchema.ts'
|
|
14
|
-
import type PluginManager from '@jbrowse/core/PluginManager'
|
|
15
14
|
import type { BaseOptions } from '@jbrowse/core/data_adapters/BaseAdapter'
|
|
16
|
-
import type { getSubAdapterType } from '@jbrowse/core/data_adapters/dataAdapterCache'
|
|
17
15
|
import type { Feature } from '@jbrowse/core/util'
|
|
18
16
|
import type { Region } from '@jbrowse/core/util/types'
|
|
19
17
|
|
|
20
18
|
export default class MinigraphBubbleAdapter extends BaseFeatureDataAdapter<MinigraphBubbleAdapterConfig> {
|
|
21
19
|
public static capabilities = ['getFeatures', 'getRefNames']
|
|
22
20
|
|
|
23
|
-
private readonly bubbles
|
|
21
|
+
private readonly bubbles = openTabixSlot(this, ['bubblesLocation'], ['index'])
|
|
24
22
|
// `gfatools bubble` names each row after the graph's stable sequence, so a
|
|
25
23
|
// Minigraph-Cactus graph produces PanSN rows (`GRCh38#0#chr6`) where a plain
|
|
26
24
|
// minigraph graph produces bare ones (`chr6`). Same resolution the segment
|
|
27
25
|
// adapter does, through the same `assemblyNameToPanSN` slot.
|
|
28
|
-
private readonly refNames
|
|
29
|
-
|
|
30
|
-
public constructor(
|
|
31
|
-
config: MinigraphBubbleAdapterConfig,
|
|
32
|
-
getSubAdapter?: getSubAdapterType,
|
|
33
|
-
pluginManager?: PluginManager,
|
|
34
|
-
) {
|
|
35
|
-
super(config, getSubAdapter, pluginManager)
|
|
36
|
-
this.bubbles = openTabixSlot(this, ['bubblesLocation'], ['index'])
|
|
37
|
-
this.refNames = new PanSNRefNames(this.bubbles, this)
|
|
38
|
-
}
|
|
26
|
+
private readonly refNames = new PanSNRefNames(this.bubbles, this)
|
|
39
27
|
|
|
40
28
|
async getRefNames(opts: BaseOptions = {}) {
|
|
41
29
|
return this.refNames.assemblyRefNames(opts)
|
|
42
30
|
}
|
|
43
31
|
|
|
32
|
+
async getRegionByteSize(regions: Region[], opts: BaseOptions = {}) {
|
|
33
|
+
return this.refNames.regionBytes(regions, opts)
|
|
34
|
+
}
|
|
35
|
+
|
|
44
36
|
public async hasDataForRefName() {
|
|
45
37
|
return true
|
|
46
38
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ConfigurationSchema } from '@jbrowse/core/configuration'
|
|
2
2
|
|
|
3
|
-
import { tabixIndexSchema, tbiBeside } from '../panSNTabix.ts'
|
|
3
|
+
import { fileLocationSlot, tabixIndexSchema, tbiBeside } from '../panSNTabix.ts'
|
|
4
4
|
|
|
5
5
|
import type { Instance } from '@jbrowse/mobx-state-tree'
|
|
6
6
|
|
|
@@ -25,7 +25,7 @@ import type { Instance } from '@jbrowse/mobx-state-tree'
|
|
|
25
25
|
* ```
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
function normalizeSnapshot(snap: Record<string, unknown>) {
|
|
29
29
|
const { uri, baseUri, csi } = snap
|
|
30
30
|
return typeof uri === 'string'
|
|
31
31
|
? {
|
|
@@ -42,13 +42,7 @@ const MinigraphBubbleAdapter = ConfigurationSchema(
|
|
|
42
42
|
/**
|
|
43
43
|
* #slot
|
|
44
44
|
*/
|
|
45
|
-
bubblesLocation:
|
|
46
|
-
type: 'fileLocation',
|
|
47
|
-
defaultValue: {
|
|
48
|
-
uri: '/path/to/graph.bb.bed.gz',
|
|
49
|
-
locationType: 'UriLocation',
|
|
50
|
-
},
|
|
51
|
-
},
|
|
45
|
+
bubblesLocation: fileLocationSlot('/path/to/graph.bb.bed.gz'),
|
|
52
46
|
/**
|
|
53
47
|
* #slot
|
|
54
48
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import AdapterType from '@jbrowse/core/pluggableElementTypes/AdapterType'
|
|
2
2
|
|
|
3
|
-
import configSchema
|
|
3
|
+
import configSchema from './configSchema.ts'
|
|
4
4
|
|
|
5
5
|
import type PluginManager from '@jbrowse/core/PluginManager'
|
|
6
6
|
|
|
@@ -10,7 +10,6 @@ export default function MinigraphBubbleAdapterF(pluginManager: PluginManager) {
|
|
|
10
10
|
new AdapterType({
|
|
11
11
|
name: 'MinigraphBubbleAdapter',
|
|
12
12
|
displayName: 'Minigraph bubble BED adapter',
|
|
13
|
-
normalizeSnapshot,
|
|
14
13
|
configSchema,
|
|
15
14
|
adapterMetadata: {
|
|
16
15
|
category: 'Graph adapters',
|
|
@@ -1,14 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { execFileSync } from 'node:child_process'
|
|
2
|
+
import { mkdtempSync, readFileSync } from 'node:fs'
|
|
3
|
+
import { tmpdir } from 'node:os'
|
|
4
|
+
import { join } from 'node:path'
|
|
2
5
|
import { gunzipSync } from 'node:zlib'
|
|
3
6
|
|
|
4
7
|
import { TabixIndexedFile } from '@gmod/tabix'
|
|
5
8
|
import { parseGFA } from '@jbrowse/bandage-core/gfa-core/index'
|
|
9
|
+
import PluginManager from '@jbrowse/core/PluginManager'
|
|
6
10
|
import { readConfObject } from '@jbrowse/core/configuration'
|
|
7
11
|
import { firstValueFrom } from 'rxjs'
|
|
8
12
|
import { toArray } from 'rxjs/operators'
|
|
9
13
|
|
|
10
14
|
import Adapter from './RgfaTabixAdapter.ts'
|
|
11
15
|
import configSchema from './configSchema.ts'
|
|
16
|
+
import RgfaTabixAdapterF from './index.ts'
|
|
12
17
|
import { linkKey, parseLinkLine } from './rgfaBed.ts'
|
|
13
18
|
|
|
14
19
|
import type { WalkCut } from './walkRowRuns.ts'
|
|
@@ -79,6 +84,16 @@ test('getFeatures returns the segments on a stable sequence', async () => {
|
|
|
79
84
|
])
|
|
80
85
|
})
|
|
81
86
|
|
|
87
|
+
test("the byte gate measures a region from the segment file's index", async () => {
|
|
88
|
+
const bytes = vi.spyOn(TabixIndexedFile.prototype, 'bytesForRegions')
|
|
89
|
+
const size = await makeAdapter().getRegionByteSize([k12])
|
|
90
|
+
expect(size).toBeGreaterThan(0)
|
|
91
|
+
expect(bytes.mock.calls.map(call => call[0])).toEqual([
|
|
92
|
+
[{ refName: 'K12#1#chr', start: k12.start, end: k12.end }],
|
|
93
|
+
])
|
|
94
|
+
bytes.mockRestore()
|
|
95
|
+
})
|
|
96
|
+
|
|
82
97
|
test('getFeatures resolves a PanSN name given unqualified', async () => {
|
|
83
98
|
const qualified = await firstValueFrom(
|
|
84
99
|
makeAdapter()
|
|
@@ -119,6 +134,24 @@ test('getSubgraph reaches off-reference neighbours', async () => {
|
|
|
119
134
|
)
|
|
120
135
|
})
|
|
121
136
|
|
|
137
|
+
// node runs the script with type stripping, which refuses a parameter property
|
|
138
|
+
// or an enum anywhere among the cut's imports
|
|
139
|
+
test('scripts/dump-subgraph.ts writes the cut getSubgraph makes', async () => {
|
|
140
|
+
const out = join(mkdtempSync(join(tmpdir(), 'dump-subgraph-')), 'cut.gfa')
|
|
141
|
+
const window = { ...k12, start: 1_000_000, end: 1_100_000 }
|
|
142
|
+
execFileSync(process.execPath, [
|
|
143
|
+
require.resolve('../../scripts/dump-subgraph.ts'),
|
|
144
|
+
prefix,
|
|
145
|
+
'K12',
|
|
146
|
+
'chr',
|
|
147
|
+
String(window.start),
|
|
148
|
+
String(window.end),
|
|
149
|
+
out,
|
|
150
|
+
])
|
|
151
|
+
const cut = gfaText(await makeAdapter().getSubgraph(window, { hops: 1 }))
|
|
152
|
+
expect(readFileSync(out, 'utf8')).toBe(`${cut}\n`)
|
|
153
|
+
})
|
|
154
|
+
|
|
122
155
|
test('getSubgraph is byte-identical across calls', async () => {
|
|
123
156
|
const adapter = makeAdapter()
|
|
124
157
|
expect(await adapter.getSubgraph(k12)).toBe(await adapter.getSubgraph(k12))
|
|
@@ -407,6 +440,17 @@ test("getSubgraph with tier: 'coarse' cuts the coarse pair", async () => {
|
|
|
407
440
|
expect(bubbles.every(n => fineIds.has(n.id))).toBe(true)
|
|
408
441
|
})
|
|
409
442
|
|
|
443
|
+
test("the adapter type expands the uri shorthand with the schema's preprocessor", () => {
|
|
444
|
+
const pluginManager = new PluginManager()
|
|
445
|
+
RgfaTabixAdapterF(pluginManager)
|
|
446
|
+
pluginManager.createPluggableElements()
|
|
447
|
+
const { normalizeSnapshot } = pluginManager.getAdapterType('RgfaTabixAdapter')
|
|
448
|
+
expect(normalizeSnapshot?.({ uri: 'hprc', walksUri: 'w' })).toMatchObject({
|
|
449
|
+
segmentsLocation: { uri: 'hprc.segs.bed.gz' },
|
|
450
|
+
walksLocation: { uri: 'w.walks.bed.gz' },
|
|
451
|
+
})
|
|
452
|
+
})
|
|
453
|
+
|
|
410
454
|
test('the coarse uri shorthand resolves a pair against the adapter baseUri', () => {
|
|
411
455
|
const config = configSchema.create({
|
|
412
456
|
uri: 'hprc',
|