jbrowse-plugin-graphgenomeviewer 7.2.0 → 7.3.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.
Files changed (115) hide show
  1. package/dist/chunks/GbzBaseSyntenyAdapter-FXMGIM7Z.js +2 -0
  2. package/dist/chunks/{GbzBaseSyntenyAdapter-NB6WBBZH.js.map → GbzBaseSyntenyAdapter-FXMGIM7Z.js.map} +3 -3
  3. package/dist/chunks/{GraphGenomeView-4O5F5I37.js → GraphGenomeView-WJ3FIDY2.js} +2 -2
  4. package/dist/chunks/{GraphTrackSettingsDialog-WZEJAF7F.js → GraphTrackSettingsDialog-ZW7ALMDV.js} +2 -2
  5. package/dist/chunks/{HighlightColorDialog-SRT2FPXP.js → HighlightColorDialog-VBZRUKD5.js} +2 -2
  6. package/dist/chunks/{LinearGraphDisplay-Z33PVCJL.js → LinearGraphDisplay-SPOPTJEN.js} +2 -2
  7. package/dist/chunks/MinigraphBubbleAdapter-QCOMFPLL.js +2 -0
  8. package/dist/chunks/{MinigraphBubbleAdapter-HDLUZ6YF.js.map → MinigraphBubbleAdapter-QCOMFPLL.js.map} +1 -1
  9. package/dist/chunks/RgfaTabixAdapter-O3NMNRZ2.js +2 -0
  10. package/dist/chunks/RgfaTabixAdapter-O3NMNRZ2.js.map +7 -0
  11. package/dist/chunks/WalkTabixSyntenyAdapter-7VDCNSFD.js +2 -0
  12. package/dist/chunks/WalkTabixSyntenyAdapter-7VDCNSFD.js.map +7 -0
  13. package/dist/chunks/chunk-2M4XYSLG.js +2 -0
  14. package/dist/chunks/chunk-2M4XYSLG.js.map +7 -0
  15. package/dist/chunks/{chunk-JLGPQO5L.js → chunk-2O3YVA2I.js} +2 -2
  16. package/dist/chunks/{chunk-CWNJR5XB.js → chunk-44CJ2N3N.js} +1 -1
  17. package/dist/chunks/{chunk-CWNJR5XB.js.map → chunk-44CJ2N3N.js.map} +1 -1
  18. package/dist/chunks/chunk-6KUHGRHU.js +2 -0
  19. package/dist/chunks/chunk-6KUHGRHU.js.map +7 -0
  20. package/dist/chunks/chunk-6MUBJVBG.js +2 -0
  21. package/dist/chunks/chunk-6MUBJVBG.js.map +7 -0
  22. package/dist/chunks/{chunk-GUXZESDR.js → chunk-7HWHWPRW.js} +1 -1
  23. package/dist/chunks/{chunk-GUXZESDR.js.map → chunk-7HWHWPRW.js.map} +1 -1
  24. package/dist/chunks/chunk-B2EP6FOQ.js +3 -0
  25. package/dist/chunks/chunk-B2EP6FOQ.js.map +7 -0
  26. package/dist/chunks/{chunk-44HZPYGC.js → chunk-BXRTG7FU.js} +2 -2
  27. package/dist/chunks/{chunk-44HZPYGC.js.map → chunk-BXRTG7FU.js.map} +1 -1
  28. package/dist/chunks/{chunk-HLKZCTQ3.js → chunk-DBPEUVUC.js} +1 -1
  29. package/dist/chunks/{chunk-HLKZCTQ3.js.map → chunk-DBPEUVUC.js.map} +1 -1
  30. package/dist/chunks/{chunk-FME624X3.js → chunk-DUR437TH.js} +2 -2
  31. package/dist/chunks/{chunk-FME624X3.js.map → chunk-DUR437TH.js.map} +1 -1
  32. package/dist/chunks/{chunk-6WA6WF6A.js → chunk-FIRQAKMX.js} +1 -1
  33. package/dist/chunks/{chunk-6WA6WF6A.js.map → chunk-FIRQAKMX.js.map} +1 -1
  34. package/dist/chunks/chunk-JCAZTNYG.js +2 -0
  35. package/dist/chunks/chunk-JCAZTNYG.js.map +7 -0
  36. package/dist/chunks/chunk-N74HGPAW.js +3 -0
  37. package/dist/chunks/chunk-N74HGPAW.js.map +7 -0
  38. package/dist/chunks/chunk-PEDWEPNK.js +2 -0
  39. package/dist/chunks/chunk-PEDWEPNK.js.map +7 -0
  40. package/dist/chunks/chunk-PYQG3JHP.js +3 -0
  41. package/dist/chunks/chunk-PYQG3JHP.js.map +7 -0
  42. package/dist/chunks/chunk-RFDSEB2X.js +4 -0
  43. package/dist/chunks/chunk-RFDSEB2X.js.map +7 -0
  44. package/dist/chunks/{chunk-O7Y7LYN6.js → chunk-RW775LQN.js} +2 -2
  45. package/dist/chunks/{chunk-O7Y7LYN6.js.map → chunk-RW775LQN.js.map} +1 -1
  46. package/dist/chunks/{chunk-N4WBX2OS.js → chunk-VQ77X5QU.js} +2 -2
  47. package/dist/chunks/{chunk-N4WBX2OS.js.map → chunk-VQ77X5QU.js.map} +1 -1
  48. package/dist/chunks/{chunk-LXCMWL7B.js → chunk-WUSKVEA6.js} +2 -2
  49. package/dist/chunks/{chunk-LXCMWL7B.js.map → chunk-WUSKVEA6.js.map} +1 -1
  50. package/dist/chunks/{chunk-ZNT7TQLN.js → chunk-YKSUKPYY.js} +2 -2
  51. package/dist/chunks/chunk-YKSUKPYY.js.map +7 -0
  52. package/dist/chunks/{renderSvg-RRWCAEGF.js → renderSvg-WD6YDV2I.js} +2 -2
  53. package/dist/jbrowse-plugin-graphgenomeviewer.esm.js +4 -4
  54. package/dist/jbrowse-plugin-graphgenomeviewer.esm.js.map +4 -4
  55. package/package.json +3 -3
  56. package/src/GbzBaseSyntenyAdapter/GbzBaseSyntenyAdapter.test.ts +2 -2
  57. package/src/GbzBaseSyntenyAdapter/GbzBaseSyntenyAdapter.ts +1 -1
  58. package/src/GetSubgraph.ts +1 -1
  59. package/src/GraphGenomeView/genes/genes.test.ts +20 -2
  60. package/src/GraphGenomeView/legendSections.test.ts +1 -1
  61. package/src/GraphGenomeView/legendSections.ts +1 -7
  62. package/src/GraphGenomeView/model.test.ts +1 -2
  63. package/src/GraphGenomeView/pane/graphViews.ts +24 -35
  64. package/src/GraphGenomeView/pane/loadActions.ts +4 -3
  65. package/src/GraphGenomeView/pane/paneBase.ts +1 -1
  66. package/src/GraphGenomeView/subgraphLoad.test.ts +41 -1
  67. package/src/GraphGenomeView/walkRowsCut.ts +10 -44
  68. package/src/RgfaTabixAdapter/RgfaTabixAdapter.test.ts +23 -4
  69. package/src/RgfaTabixAdapter/RgfaTabixAdapter.ts +2 -3
  70. package/src/RgfaTabixAdapter/bubbleTier.test.ts +1 -1
  71. package/src/RgfaTabixAdapter/test_data/walks3_inversion.GRCh38.walks.bed.gz +0 -0
  72. package/src/RgfaTabixAdapter/test_data/walks3_inversion.GRCh38.walks.bed.gz.tbi +0 -0
  73. package/src/RgfaTabixAdapter/walkCut.ts +20 -0
  74. package/src/RgfaTabixAdapter/walkFiles.test.ts +2 -2
  75. package/src/RgfaTabixAdapter/walkReader.ts +1 -1
  76. package/src/WalkTabixSyntenyAdapter/WalkTabixSyntenyAdapter.test.ts +77 -1
  77. package/src/WalkTabixSyntenyAdapter/WalkTabixSyntenyAdapter.ts +2 -2
  78. package/src/WalkTabixSyntenyAdapter/walkLanes.ts +55 -18
  79. package/src/version.ts +1 -1
  80. package/dist/chunks/GbzBaseSyntenyAdapter-NB6WBBZH.js +0 -2
  81. package/dist/chunks/MinigraphBubbleAdapter-HDLUZ6YF.js +0 -2
  82. package/dist/chunks/RgfaTabixAdapter-XZRTWQMZ.js +0 -3
  83. package/dist/chunks/RgfaTabixAdapter-XZRTWQMZ.js.map +0 -7
  84. package/dist/chunks/WalkTabixSyntenyAdapter-WBHOZLAN.js +0 -2
  85. package/dist/chunks/WalkTabixSyntenyAdapter-WBHOZLAN.js.map +0 -7
  86. package/dist/chunks/chunk-BWP3XYKD.js +0 -2
  87. package/dist/chunks/chunk-BWP3XYKD.js.map +0 -7
  88. package/dist/chunks/chunk-EDSIYH4H.js +0 -2
  89. package/dist/chunks/chunk-EDSIYH4H.js.map +0 -7
  90. package/dist/chunks/chunk-III4GT4G.js +0 -2
  91. package/dist/chunks/chunk-III4GT4G.js.map +0 -7
  92. package/dist/chunks/chunk-N5GYTUIL.js +0 -3
  93. package/dist/chunks/chunk-N5GYTUIL.js.map +0 -7
  94. package/dist/chunks/chunk-PA4HKAUJ.js +0 -2
  95. package/dist/chunks/chunk-PA4HKAUJ.js.map +0 -7
  96. package/dist/chunks/chunk-PFAHNHMM.js +0 -2
  97. package/dist/chunks/chunk-PFAHNHMM.js.map +0 -7
  98. package/dist/chunks/chunk-UFQTIWSN.js +0 -4
  99. package/dist/chunks/chunk-UFQTIWSN.js.map +0 -7
  100. package/dist/chunks/chunk-VDHDEEMF.js +0 -2
  101. package/dist/chunks/chunk-VDHDEEMF.js.map +0 -7
  102. package/dist/chunks/chunk-WGVATZLM.js +0 -3
  103. package/dist/chunks/chunk-WGVATZLM.js.map +0 -7
  104. package/dist/chunks/chunk-ZNT7TQLN.js.map +0 -7
  105. package/src/RgfaTabixAdapter/rgfaBed.test.ts +0 -254
  106. package/src/RgfaTabixAdapter/rgfaBed.ts +0 -314
  107. package/src/RgfaTabixAdapter/rgfaCut.ts +0 -139
  108. package/src/RgfaTabixAdapter/walkRowRuns.test.ts +0 -192
  109. package/src/RgfaTabixAdapter/walkRowRuns.ts +0 -520
  110. /package/dist/chunks/{GraphGenomeView-4O5F5I37.js.map → GraphGenomeView-WJ3FIDY2.js.map} +0 -0
  111. /package/dist/chunks/{GraphTrackSettingsDialog-WZEJAF7F.js.map → GraphTrackSettingsDialog-ZW7ALMDV.js.map} +0 -0
  112. /package/dist/chunks/{HighlightColorDialog-SRT2FPXP.js.map → HighlightColorDialog-VBZRUKD5.js.map} +0 -0
  113. /package/dist/chunks/{LinearGraphDisplay-Z33PVCJL.js.map → LinearGraphDisplay-SPOPTJEN.js.map} +0 -0
  114. /package/dist/chunks/{chunk-JLGPQO5L.js.map → chunk-2O3YVA2I.js.map} +0 -0
  115. /package/dist/chunks/{renderSvg-RRWCAEGF.js.map → renderSvg-WD6YDV2I.js.map} +0 -0
@@ -1,139 +0,0 @@
1
- import {
2
- addLink,
3
- anchoredCut,
4
- closingLinks,
5
- closingSpans,
6
- formatSubgraph,
7
- parseLinkLine,
8
- parseSegmentRow,
9
- } from './rgfaBed.ts'
10
- import { getLines } from '../tabixRange.ts'
11
-
12
- import type { RgfaLink, RgfaSegment, StableSpan } from './rgfaBed.ts'
13
- import type { TabixIndexedFile } from '@gmod/tabix'
14
-
15
- // What a hop follows: alleles, never the backbone. A rank-0 segment reached
16
- // through a link is flanking backbone, usually outside the window, so querying
17
- // its links walks the reference away from the region, brings back more backbone,
18
- // and closes nothing. Every segment that closes a bubble is an allele interior,
19
- // and an allele interior is rank > 0 in both index formats (rGFA's SR tag, and
20
- // pggb's rank 0-or-1 against the anchor path). Reached backbone still becomes a
21
- // node and its edge still draws; it is only not walked through.
22
- //
23
- // This is gfabase's rule, arrived at from the other end. `gfabase sub` expands
24
- // from a seed either to the whole connected component (`--connected`, which its
25
- // own README calls overkill) or with `--cutpoints 1`, which takes the biconnected
26
- // component by *stopping at cutpoints*, the segments every end-to-end walk of
27
- // the chromosome must traverse. In a reference-anchored pangenome the cutpoints
28
- // are the backbone, and rank is what the index already states about it, so
29
- // `rank > 0` is that stopping rule without a connectivity index to build. The
30
- // third tool is the same shape again: `gfatools view -R` maps the region onto its
31
- // precomputed bubble decomposition and returns whole overlapping bubbles
32
- // (gfa_query_by_reg), which is complete for the same reason. Bandage's own
33
- // `--distance` is a node-step radius, but Bandage holds the entire graph in
34
- // memory, so its scope is a drawing filter rather than a fetch strategy.
35
- //
36
- // Measured with this rule: the E. coli paa window converges at one hop (17
37
- // segments at 1 and at 2), so the cut closes and stays closed. HPRC's amylase
38
- // window keeps growing (63 at 0, 78 at 1, 92 at 2) because its alleles have
39
- // alleles, and wall-clock is flat across all three, since a hop's queries go out
40
- // together and the remote index dominates.
41
- //
42
- // The exact version, when a graph ships a bubble index beside its segments:
43
- // gfatools' bubble rows carry the member segment ids of every bubble, so the
44
- // bubbles overlapping the region state which segments a complete cut must
45
- // contain. That turns the hop count into a termination condition rather than a
46
- // setting, and MinigraphBubbleAdapter already parses those rows.
47
- function offReference(segments: RgfaSegment[]) {
48
- return segments.filter(segment => segment.rank > 0)
49
- }
50
-
51
- export interface RgfaFiles {
52
- segments: TabixIndexedFile
53
- links: TabixIndexedFile
54
- }
55
-
56
- async function linksOver(
57
- file: TabixIndexedFile,
58
- span: StableSpan,
59
- signal?: AbortSignal,
60
- ) {
61
- const found: RgfaLink[] = []
62
- await getLines(file, span.refName, span.start, span.end, {
63
- signal,
64
- lineCallback: line => {
65
- found.push(parseLinkLine(line))
66
- },
67
- })
68
- return found
69
- }
70
-
71
- /**
72
- * The graph around a window of one stable sequence, as GFA text. The window's
73
- * own segments come from the segment file; the link file supplies the edges
74
- * incident to them *and* the coordinates of the segments on the other end,
75
- * which typically sit on a different stable sequence (a rank>0 bubble) and so
76
- * are not reachable by any coordinate query on this window.
77
- *
78
- * `hops` is extra rounds of link-following past the window's own segments and
79
- * their immediate neighbours, each costing one tabix query per off-reference
80
- * segment newly reached. After the last round, one more read per stretch of
81
- * stable sequence the cut holds closes it (closingSpans), so an allele reached
82
- * from both ends draws whole. The view asks for one hop; a hopless cut stays
83
- * as cheap as it was. `signal` goes to every one of those queries, so a cut
84
- * the view has replaced stops.
85
- */
86
- export async function rgfaCut(
87
- files: RgfaFiles,
88
- window: StableSpan,
89
- { hops = 0, signal }: { hops?: number; signal?: AbortSignal } = {},
90
- ) {
91
- const segments = new Map<string, RgfaSegment>()
92
- const links = new Map<string, RgfaLink>()
93
- const layout = { anchored: false }
94
- await getLines(files.segments, window.refName, window.start, window.end, {
95
- signal,
96
- lineCallback: line => {
97
- const row = parseSegmentRow(line)
98
- layout.anchored ||= row.anchored
99
- segments.set(row.segment.id, row.segment)
100
- },
101
- })
102
- // An anchored index files every allele and every link under the reference
103
- // interval its bubble hangs from, so one read of each file holds the whole
104
- // graph under the window and there is nothing to hop to or close.
105
- if (layout.anchored) {
106
- const cut = anchoredCut(
107
- segments,
108
- await linksOver(files.links, window, signal),
109
- window,
110
- )
111
- return formatSubgraph(cut.segments, cut.links)
112
- }
113
- const addLinksOver = async (span: StableSpan) =>
114
- (await linksOver(files.links, span, signal)).flatMap(link =>
115
- addLink(segments, links, link),
116
- )
117
- let frontier = offReference(await addLinksOver(window))
118
- for (let hop = 0; hop < hops; hop++) {
119
- // One hop's queries are independent of each other, so they go out
120
- // together rather than one round-trip at a time, and the output is sorted
121
- // at the end regardless of the order they arrive in.
122
- const reached = await Promise.all(frontier.map(addLinksOver))
123
- frontier = offReference(reached.flat())
124
- }
125
- if (hops > 0) {
126
- const spans = closingSpans(
127
- [...segments.values()],
128
- new Set(frontier.map(segment => segment.id)),
129
- window,
130
- )
131
- const found = await Promise.all(
132
- spans.map(span => linksOver(files.links, span, signal)),
133
- )
134
- for (const link of closingLinks(found.flat(), segments, spans)) {
135
- addLink(segments, links, link)
136
- }
137
- }
138
- return formatSubgraph(segments, links)
139
- }
@@ -1,192 +0,0 @@
1
- import { gfaTables } from '@jbrowse/bandage-core/gfa/gfaTables'
2
- import { walkRows } from '@jbrowse/bandage-core/layout/walkRows'
3
- import { loadGraph } from '@jbrowse/bandage-core/pipeline'
4
-
5
- import { walkRowRuns, walkRowsOf } from './walkRowRuns.ts'
6
-
7
- import type { GraphTables } from '@jbrowse/bandage-core/gfa/graphTables'
8
- import type { WalkRow } from '@jbrowse/bandage-core/layout/walkRows'
9
-
10
- // GRCh38 runs 0..4 over chr1:0-5000, a kb a node, with node 5 (300 bp) an
11
- // expansion off it. The repeat is node 2, chr1:2000-3000. A has the
12
- // reference's left flank from 0 and ends inside the repeat, B the same from
13
- // 1000, and C runs against the reference from its right flank and ends
14
- // inside too, each off the reference. D's contig ends on the repeat's node
15
- // and E's on the left flank.
16
- const tables: GraphTables = {
17
- nodes: {
18
- names: ['0', '1', '2', '3', '4', '5'],
19
- lengths: Int32Array.of(1000, 1000, 1000, 1000, 1000, 300),
20
- refs: Int32Array.of(0, 0, 0, 0, 0, 1),
21
- starts: Float64Array.of(0, 1000, 2000, 3000, 4000, 0),
22
- ranks: Int32Array.of(0, 0, 0, 0, 0, 1),
23
- refNames: ['chr1', 'alt'],
24
- },
25
- links: {
26
- from: new Int32Array(0),
27
- to: new Int32Array(0),
28
- strands: new Uint8Array(0),
29
- },
30
- walks: {
31
- names: ['GRCh38#0#chr1', 'A#1#a', 'B#1#b', 'C#1#c', 'D#1#d', 'E#1#e'],
32
- starts: Float64Array.of(0, 0, 0, 0, 0, 0),
33
- ends: Float64Array.of(5000, 3300, 2300, 2300, 3000, 2000),
34
- offsets: Int32Array.of(0, 5, 9, 12, 15, 18, 20),
35
- steps: Int32Array.of(
36
- ...[0, 1, 2, 3, 4],
37
- ...[0, 1, 2, 5],
38
- ...[1, 2, 5],
39
- ...[4, 3, 5],
40
- ...[0, 1, 2],
41
- ...[0, 1],
42
- ),
43
- reversed: Uint8Array.of(
44
- ...[0, 0, 0, 0, 0],
45
- ...[0, 0, 0, 0],
46
- ...[0, 0, 0],
47
- ...[1, 1, 1],
48
- ...[0, 0, 0],
49
- ...[0, 0],
50
- ),
51
- },
52
- }
53
- const repeat = { start: 2000, end: 3000 }
54
-
55
- test('a walk that ends inside the repeat measures from the flank it enters by', () => {
56
- const rows = walkRowsOf(walkRowRuns(tables, repeat)!).rows
57
- const byLabel = Object.fromEntries(rows.map(r => [r.label, r]))
58
- expect(byLabel['A#1']).toMatchObject({ bp: 1300, complete: false })
59
- expect(byLabel['B#1']).toMatchObject({ bp: 1300, complete: false })
60
- expect(byLabel['C#1']).toMatchObject({ bp: 300, complete: false })
61
- for (const label of ['A#1', 'B#1', 'C#1']) {
62
- expect(byLabel[label]!.stop).toEqual({ contigEnds: false, shortBp: 0 })
63
- }
64
- expect(byLabel['D#1']).toMatchObject({
65
- bp: 1000,
66
- complete: false,
67
- stop: { contigEnds: true, shortBp: 0 },
68
- })
69
- expect(byLabel['E#1']).toMatchObject({
70
- bp: 0,
71
- complete: false,
72
- stop: { contigEnds: true, shortBp: 0 },
73
- })
74
- expect(byLabel['A#1']!.axis).toEqual({
75
- contig: 'a',
76
- start: 2000,
77
- reversed: false,
78
- })
79
- expect(byLabel['C#1']!.axis).toEqual({
80
- contig: 'c',
81
- start: 2300,
82
- reversed: true,
83
- })
84
- })
85
-
86
- test('walkRows measures and stops the same walks', () => {
87
- for (const region of [repeat, { start: 2500, end: 3000 }]) {
88
- const fields = ({ label, bp, complete, stop }: WalkRow) => ({
89
- label,
90
- bp,
91
- complete,
92
- stop,
93
- })
94
- const ours = walkRowsOf(walkRowRuns(tables, region)!).rows.map(fields)
95
- const theirs = walkRows(loadGraph(tables, 'cut'), region)!.rows.map(fields)
96
- expect(ours).toEqual(theirs)
97
- }
98
- const short = walkRowsOf(
99
- walkRowRuns(tables, { start: 2500, end: 3000 })!,
100
- ).rows.find(r => r.label === 'E#1')!
101
- expect(short.stop).toEqual({ contigEnds: true, shortBp: 500 })
102
- })
103
-
104
- test('walks named without a haplotype field are rows of their own, on their contigs', () => {
105
- const twoPart: GraphTables = {
106
- ...tables,
107
- walks: {
108
- ...tables.walks,
109
- names: ['GRCh38#0#chr1', 'A#a', 'A#b', 'C#1#c', 'D#1#d', 'E#1#e'],
110
- },
111
- }
112
- const rows = walkRowsOf(walkRowRuns(twoPart, repeat)!).rows
113
- expect(
114
- rows
115
- .filter(r => r.sample === 'A')
116
- .map(({ name, label, haplotype, axis }) => ({
117
- name,
118
- label,
119
- haplotype,
120
- contig: axis?.contig,
121
- }))
122
- .sort((x, y) => x.name.localeCompare(y.name)),
123
- ).toEqual([
124
- { name: 'A#a', label: 'A', haplotype: undefined, contig: 'a' },
125
- { name: 'A#b', label: 'A', haplotype: undefined, contig: 'b' },
126
- ])
127
- })
128
-
129
- test('a reference cut into pieces is one reference row, as walkRows reads it', () => {
130
- const split: GraphTables = {
131
- ...tables,
132
- walks: {
133
- names: ['GRCh38#0#chr1', 'GRCh38#0#chr1', 'A#1#a'],
134
- starts: Float64Array.of(0, 3000, 0),
135
- ends: Float64Array.of(2000, 5000, 5000),
136
- offsets: Int32Array.of(0, 2, 4, 9),
137
- steps: Int32Array.of(...[0, 1], ...[3, 4], ...[0, 1, 2, 3, 4]),
138
- reversed: new Uint8Array(9),
139
- },
140
- }
141
- const region = { start: 2200, end: 2800 }
142
- const fields = ({ label, bp, offReferenceBp, complete }: WalkRow) => ({
143
- label,
144
- bp,
145
- offReferenceBp,
146
- complete,
147
- })
148
- const ours = walkRowsOf(walkRowRuns(split, region)!)
149
- const graph = loadGraph(split, 'cut')
150
- const theirs = walkRows({ ...graph, referencePath: 'GRCh38#0#chr1' }, region)!
151
- expect(ours.rows.map(fields)).toEqual(theirs.rows.map(fields))
152
- expect(fields(ours.reference)).toEqual(fields(theirs.reference))
153
- expect(ours.rows.map(r => r.label)).toEqual(['A#1'])
154
- expect(ours.rows[0]).toMatchObject({ bp: 1000, complete: true })
155
- })
156
-
157
- test("a gap's parts cross from the worker with their causes, as walkRows splits them", () => {
158
- const S = [1, 2, 3, 4, 5, 6, 7].map(id => `S\t${id}\t*\tLN:i:1000`)
159
- const L = [1, 2, 3, 4, 5, 6].map(id => `L\t${id}\t+\t${id + 1}\t+\t0M`)
160
- const text = [
161
- 'H\tVN:Z:1.1',
162
- ...S,
163
- ...L,
164
- 'W\tGRCh38\t0\tchr1\t0\t7000\t>1>2>3>4>5>6>7\tws:Z:end\twe:Z:end',
165
- 'W\tA\t1\ta\t0\t3000\t>1>2>3\tws:Z:end\twe:Z:break,bp=600,trimmed=400',
166
- 'W\tA\t1\ta\t4000\t7000\t>5>6>7\tws:Z:break,bp=600\twe:Z:end',
167
- 'W\tB\t1\tb\t0\t3000\t<7<6<5\tws:Z:end\twe:Z:elsewhere,chunk=GRCh38#0#chr1:20316160',
168
- 'W\tB\t1\tb\t4000\t7000\t<3<2<1\tws:Z:break,bp=300\twe:Z:end',
169
- ].join('\n')
170
- const region = { start: 1000, end: 6000 }
171
- const gaps = (rows: WalkRow[]) =>
172
- rows.map(r => [
173
- r.label,
174
- r.runs
175
- .filter(run => run.gap)
176
- .map(({ bp, cause, chunk }) => ({ bp, cause, chunk })),
177
- ])
178
- const ours = walkRowsOf(walkRowRuns(gfaTables(text)!, region)!).rows
179
- const graph = loadGraph(text, 'cut', { referencePath: 'GRCh38#0#chr1' })
180
- expect(gaps(ours)).toEqual(gaps(walkRows(graph, region)!.rows))
181
- const chunk = { refName: 'GRCh38#0#chr1', start: 20316160 }
182
- expect(Object.fromEntries(gaps(ours))).toEqual({
183
- 'A#1': [
184
- { bp: 400, cause: undefined, chunk: undefined },
185
- { bp: 600, cause: 'missing', chunk: undefined },
186
- ],
187
- 'B#1': [
188
- { bp: 300, cause: 'missing', chunk: undefined },
189
- { bp: 700, cause: 'elsewhere', chunk },
190
- ],
191
- })
192
- })