@jbrowse/plugin-alignments 2.2.0 → 2.2.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.
Files changed (210) hide show
  1. package/dist/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +12 -13
  2. package/dist/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js.map +1 -1
  3. package/dist/BamAdapter/BamAdapter.d.ts +1 -1
  4. package/dist/BamAdapter/BamAdapter.js +1 -0
  5. package/dist/BamAdapter/BamAdapter.js.map +1 -1
  6. package/dist/BamAdapter/BamSlightlyLazyFeature.js +1 -0
  7. package/dist/BamAdapter/BamSlightlyLazyFeature.js.map +1 -1
  8. package/dist/BamAdapter/MismatchParser.d.ts +2 -2
  9. package/dist/BamAdapter/MismatchParser.js +4 -7
  10. package/dist/BamAdapter/MismatchParser.js.map +1 -1
  11. package/dist/BamAdapter/configSchema.js +1 -1
  12. package/dist/BamAdapter/configSchema.js.map +1 -1
  13. package/dist/BamAdapter/index.js +7 -5
  14. package/dist/BamAdapter/index.js.map +1 -1
  15. package/dist/CramAdapter/CramSlightlyLazyFeature.d.ts +1 -10
  16. package/dist/CramAdapter/CramSlightlyLazyFeature.js +5 -218
  17. package/dist/CramAdapter/CramSlightlyLazyFeature.js.map +1 -1
  18. package/dist/CramAdapter/CramTestAdapters.d.ts +1 -1
  19. package/dist/CramAdapter/CramTestAdapters.js +3 -2
  20. package/dist/CramAdapter/CramTestAdapters.js.map +1 -1
  21. package/dist/CramAdapter/configSchema.js +2 -2
  22. package/dist/CramAdapter/configSchema.js.map +1 -1
  23. package/dist/CramAdapter/index.js +7 -5
  24. package/dist/CramAdapter/index.js.map +1 -1
  25. package/dist/CramAdapter/util.d.ts +18 -0
  26. package/dist/CramAdapter/util.js +241 -0
  27. package/dist/CramAdapter/util.js.map +1 -0
  28. package/dist/LinearAlignmentsDisplay/components/AlignmentsDisplay.js +1 -1
  29. package/dist/LinearAlignmentsDisplay/components/AlignmentsDisplay.js.map +1 -1
  30. package/dist/LinearAlignmentsDisplay/models/configSchema.d.ts +1 -1
  31. package/dist/LinearAlignmentsDisplay/models/model.d.ts +5 -5
  32. package/dist/LinearAlignmentsDisplay/models/model.js +7 -7
  33. package/dist/LinearAlignmentsDisplay/models/model.js.map +1 -1
  34. package/dist/LinearPileupDisplay/components/ColorByModifications.d.ts +3 -1
  35. package/dist/LinearPileupDisplay/components/ColorByModifications.js +7 -22
  36. package/dist/LinearPileupDisplay/components/ColorByModifications.js.map +1 -1
  37. package/dist/LinearPileupDisplay/components/ColorByTag.js +2 -22
  38. package/dist/LinearPileupDisplay/components/ColorByTag.js.map +1 -1
  39. package/dist/LinearPileupDisplay/components/FilterByTag.js +2 -15
  40. package/dist/LinearPileupDisplay/components/FilterByTag.js.map +1 -1
  41. package/dist/LinearPileupDisplay/components/SetFeatureHeight.js +2 -19
  42. package/dist/LinearPileupDisplay/components/SetFeatureHeight.js.map +1 -1
  43. package/dist/LinearPileupDisplay/components/SetMaxHeight.js +2 -18
  44. package/dist/LinearPileupDisplay/components/SetMaxHeight.js.map +1 -1
  45. package/dist/LinearPileupDisplay/components/SortByTag.js +2 -23
  46. package/dist/LinearPileupDisplay/components/SortByTag.js.map +1 -1
  47. package/dist/LinearPileupDisplay/configSchema.d.ts +4 -4
  48. package/dist/LinearPileupDisplay/configSchema.js +2 -2
  49. package/dist/LinearPileupDisplay/configSchema.js.map +1 -1
  50. package/dist/LinearPileupDisplay/index.d.ts +3 -0
  51. package/dist/LinearPileupDisplay/index.js +3 -0
  52. package/dist/LinearPileupDisplay/index.js.map +1 -1
  53. package/dist/LinearPileupDisplay/model.d.ts +19 -9
  54. package/dist/LinearPileupDisplay/model.js +25 -30
  55. package/dist/LinearPileupDisplay/model.js.map +1 -1
  56. package/dist/LinearSNPCoverageDisplay/components/Tooltip.d.ts +1 -1
  57. package/dist/LinearSNPCoverageDisplay/models/model.d.ts +14 -10
  58. package/dist/LinearSNPCoverageDisplay/models/model.js +8 -6
  59. package/dist/LinearSNPCoverageDisplay/models/model.js.map +1 -1
  60. package/dist/PileupRPC/rpcMethods.d.ts +1 -1
  61. package/dist/PileupRPC/rpcMethods.js +12 -7
  62. package/dist/PileupRPC/rpcMethods.js.map +1 -1
  63. package/dist/PileupRenderer/PileupLayoutSession.d.ts +1 -1
  64. package/dist/PileupRenderer/PileupRenderer.js +32 -28
  65. package/dist/PileupRenderer/PileupRenderer.js.map +1 -1
  66. package/dist/PileupRenderer/configSchema.js +1 -1
  67. package/dist/PileupRenderer/configSchema.js.map +1 -1
  68. package/dist/PileupRenderer/index.js +8 -6
  69. package/dist/PileupRenderer/index.js.map +1 -1
  70. package/dist/SNPCoverageAdapter/SNPCoverageAdapter.d.ts +0 -51
  71. package/dist/SNPCoverageAdapter/SNPCoverageAdapter.js +3 -182
  72. package/dist/SNPCoverageAdapter/SNPCoverageAdapter.js.map +1 -1
  73. package/dist/SNPCoverageAdapter/configSchema.d.ts +2 -3
  74. package/dist/SNPCoverageAdapter/configSchema.js +6 -3
  75. package/dist/SNPCoverageAdapter/configSchema.js.map +1 -1
  76. package/dist/SNPCoverageAdapter/generateCoverageBins.d.ts +53 -0
  77. package/dist/SNPCoverageAdapter/generateCoverageBins.js +185 -0
  78. package/dist/SNPCoverageAdapter/generateCoverageBins.js.map +1 -0
  79. package/dist/SNPCoverageAdapter/index.d.ts +1 -2
  80. package/dist/SNPCoverageAdapter/index.js +17 -14
  81. package/dist/SNPCoverageAdapter/index.js.map +1 -1
  82. package/dist/index.d.ts +3 -2
  83. package/dist/index.js +4 -2
  84. package/dist/index.js.map +1 -1
  85. package/esm/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +12 -13
  86. package/esm/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js.map +1 -1
  87. package/esm/BamAdapter/BamAdapter.d.ts +1 -1
  88. package/esm/BamAdapter/BamAdapter.js +1 -0
  89. package/esm/BamAdapter/BamAdapter.js.map +1 -1
  90. package/esm/BamAdapter/BamSlightlyLazyFeature.js +1 -0
  91. package/esm/BamAdapter/BamSlightlyLazyFeature.js.map +1 -1
  92. package/esm/BamAdapter/MismatchParser.d.ts +2 -2
  93. package/esm/BamAdapter/MismatchParser.js +4 -7
  94. package/esm/BamAdapter/MismatchParser.js.map +1 -1
  95. package/esm/BamAdapter/configSchema.js +1 -1
  96. package/esm/BamAdapter/configSchema.js.map +1 -1
  97. package/esm/BamAdapter/index.js +7 -5
  98. package/esm/BamAdapter/index.js.map +1 -1
  99. package/esm/CramAdapter/CramSlightlyLazyFeature.d.ts +1 -10
  100. package/esm/CramAdapter/CramSlightlyLazyFeature.js +5 -218
  101. package/esm/CramAdapter/CramSlightlyLazyFeature.js.map +1 -1
  102. package/esm/CramAdapter/CramTestAdapters.d.ts +1 -1
  103. package/esm/CramAdapter/CramTestAdapters.js +3 -2
  104. package/esm/CramAdapter/CramTestAdapters.js.map +1 -1
  105. package/esm/CramAdapter/configSchema.js +2 -2
  106. package/esm/CramAdapter/configSchema.js.map +1 -1
  107. package/esm/CramAdapter/index.js +7 -5
  108. package/esm/CramAdapter/index.js.map +1 -1
  109. package/esm/CramAdapter/util.d.ts +18 -0
  110. package/esm/CramAdapter/util.js +236 -0
  111. package/esm/CramAdapter/util.js.map +1 -0
  112. package/esm/LinearAlignmentsDisplay/components/AlignmentsDisplay.js +1 -1
  113. package/esm/LinearAlignmentsDisplay/components/AlignmentsDisplay.js.map +1 -1
  114. package/esm/LinearAlignmentsDisplay/models/configSchema.d.ts +1 -1
  115. package/esm/LinearAlignmentsDisplay/models/model.d.ts +5 -5
  116. package/esm/LinearAlignmentsDisplay/models/model.js +7 -7
  117. package/esm/LinearAlignmentsDisplay/models/model.js.map +1 -1
  118. package/esm/LinearPileupDisplay/components/ColorByModifications.d.ts +3 -1
  119. package/esm/LinearPileupDisplay/components/ColorByModifications.js +8 -23
  120. package/esm/LinearPileupDisplay/components/ColorByModifications.js.map +1 -1
  121. package/esm/LinearPileupDisplay/components/ColorByTag.js +3 -20
  122. package/esm/LinearPileupDisplay/components/ColorByTag.js.map +1 -1
  123. package/esm/LinearPileupDisplay/components/FilterByTag.js +3 -13
  124. package/esm/LinearPileupDisplay/components/FilterByTag.js.map +1 -1
  125. package/esm/LinearPileupDisplay/components/SetFeatureHeight.js +3 -17
  126. package/esm/LinearPileupDisplay/components/SetFeatureHeight.js.map +1 -1
  127. package/esm/LinearPileupDisplay/components/SetMaxHeight.js +3 -16
  128. package/esm/LinearPileupDisplay/components/SetMaxHeight.js.map +1 -1
  129. package/esm/LinearPileupDisplay/components/SortByTag.js +3 -21
  130. package/esm/LinearPileupDisplay/components/SortByTag.js.map +1 -1
  131. package/esm/LinearPileupDisplay/configSchema.d.ts +4 -4
  132. package/esm/LinearPileupDisplay/configSchema.js +2 -2
  133. package/esm/LinearPileupDisplay/configSchema.js.map +1 -1
  134. package/esm/LinearPileupDisplay/index.d.ts +3 -0
  135. package/esm/LinearPileupDisplay/index.js +1 -0
  136. package/esm/LinearPileupDisplay/index.js.map +1 -1
  137. package/esm/LinearPileupDisplay/model.d.ts +19 -9
  138. package/esm/LinearPileupDisplay/model.js +25 -30
  139. package/esm/LinearPileupDisplay/model.js.map +1 -1
  140. package/esm/LinearSNPCoverageDisplay/components/Tooltip.d.ts +1 -1
  141. package/esm/LinearSNPCoverageDisplay/models/model.d.ts +14 -10
  142. package/esm/LinearSNPCoverageDisplay/models/model.js +9 -7
  143. package/esm/LinearSNPCoverageDisplay/models/model.js.map +1 -1
  144. package/esm/PileupRPC/rpcMethods.d.ts +1 -1
  145. package/esm/PileupRPC/rpcMethods.js +12 -7
  146. package/esm/PileupRPC/rpcMethods.js.map +1 -1
  147. package/esm/PileupRenderer/PileupLayoutSession.d.ts +1 -1
  148. package/esm/PileupRenderer/PileupRenderer.js +32 -28
  149. package/esm/PileupRenderer/PileupRenderer.js.map +1 -1
  150. package/esm/PileupRenderer/configSchema.js +1 -1
  151. package/esm/PileupRenderer/configSchema.js.map +1 -1
  152. package/esm/PileupRenderer/index.js +8 -6
  153. package/esm/PileupRenderer/index.js.map +1 -1
  154. package/esm/SNPCoverageAdapter/SNPCoverageAdapter.d.ts +0 -51
  155. package/esm/SNPCoverageAdapter/SNPCoverageAdapter.js +4 -183
  156. package/esm/SNPCoverageAdapter/SNPCoverageAdapter.js.map +1 -1
  157. package/esm/SNPCoverageAdapter/configSchema.d.ts +2 -3
  158. package/esm/SNPCoverageAdapter/configSchema.js +6 -3
  159. package/esm/SNPCoverageAdapter/configSchema.js.map +1 -1
  160. package/esm/SNPCoverageAdapter/generateCoverageBins.d.ts +53 -0
  161. package/esm/SNPCoverageAdapter/generateCoverageBins.js +182 -0
  162. package/esm/SNPCoverageAdapter/generateCoverageBins.js.map +1 -0
  163. package/esm/SNPCoverageAdapter/index.d.ts +1 -2
  164. package/esm/SNPCoverageAdapter/index.js +17 -15
  165. package/esm/SNPCoverageAdapter/index.js.map +1 -1
  166. package/esm/index.d.ts +3 -2
  167. package/esm/index.js +2 -2
  168. package/esm/index.js.map +1 -1
  169. package/package.json +4 -3
  170. package/src/AlignmentsFeatureDetail/AlignmentsFeatureDetail.tsx +17 -16
  171. package/src/AlignmentsFeatureDetail/__snapshots__/index.test.js.snap +1 -473
  172. package/src/AlignmentsFeatureDetail/index.test.js +6 -4
  173. package/src/BamAdapter/BamAdapter.ts +3 -2
  174. package/src/BamAdapter/BamSlightlyLazyFeature.ts +2 -1
  175. package/src/BamAdapter/MismatchParser.test.ts +21 -12
  176. package/src/BamAdapter/MismatchParser.ts +7 -10
  177. package/src/BamAdapter/__snapshots__/BamAdapter.test.ts.snap +135 -135
  178. package/src/BamAdapter/configSchema.ts +1 -1
  179. package/src/BamAdapter/index.ts +7 -8
  180. package/src/CombinationTest.test.ts +107 -0
  181. package/src/CramAdapter/CramSlightlyLazyFeature.ts +10 -219
  182. package/src/CramAdapter/CramTestAdapters.ts +2 -1
  183. package/src/CramAdapter/__snapshots__/CramAdapter.test.ts.snap +31 -31
  184. package/src/CramAdapter/__snapshots__/util.test.ts.snap +14 -0
  185. package/src/CramAdapter/configSchema.ts +2 -3
  186. package/src/CramAdapter/index.ts +7 -8
  187. package/src/CramAdapter/util.test.ts +26 -0
  188. package/src/CramAdapter/util.ts +251 -0
  189. package/src/LinearAlignmentsDisplay/components/AlignmentsDisplay.tsx +3 -1
  190. package/src/LinearAlignmentsDisplay/models/model.tsx +8 -7
  191. package/src/LinearPileupDisplay/components/ColorByModifications.tsx +5 -34
  192. package/src/LinearPileupDisplay/components/ColorByTag.tsx +2 -29
  193. package/src/LinearPileupDisplay/components/FilterByTag.tsx +2 -22
  194. package/src/LinearPileupDisplay/components/SetFeatureHeight.tsx +2 -22
  195. package/src/LinearPileupDisplay/components/SetMaxHeight.tsx +2 -24
  196. package/src/LinearPileupDisplay/components/SortByTag.tsx +2 -31
  197. package/src/LinearPileupDisplay/configSchema.ts +3 -5
  198. package/src/LinearPileupDisplay/index.ts +5 -0
  199. package/src/LinearPileupDisplay/model.ts +31 -30
  200. package/src/LinearSNPCoverageDisplay/models/model.ts +12 -8
  201. package/src/PileupRPC/rpcMethods.ts +15 -20
  202. package/src/PileupRenderer/{PileupRenderer.tsx → PileupRenderer.ts} +48 -54
  203. package/src/PileupRenderer/configSchema.ts +1 -1
  204. package/src/PileupRenderer/index.ts +8 -9
  205. package/src/SNPCoverageAdapter/SNPCoverageAdapter.ts +5 -249
  206. package/src/SNPCoverageAdapter/configSchema.ts +14 -13
  207. package/src/SNPCoverageAdapter/generateCoverageBins.ts +245 -0
  208. package/src/SNPCoverageAdapter/index.ts +17 -18
  209. package/src/__snapshots__/index.test.ts.snap +1 -1
  210. package/src/index.ts +11 -4
@@ -5,12 +5,11 @@ import AdapterType from '@jbrowse/core/pluggableElementTypes/AdapterType'
5
5
  import configSchema from './configSchema'
6
6
 
7
7
  export default (pluginManager: PluginManager) => {
8
- pluginManager.addAdapterType(
9
- () =>
10
- new AdapterType({
11
- name: 'CramAdapter',
12
- configSchema,
13
- getAdapterClass: () => import('./CramAdapter').then(r => r.default),
14
- }),
15
- )
8
+ pluginManager.addAdapterType(() => {
9
+ return new AdapterType({
10
+ name: 'CramAdapter',
11
+ configSchema,
12
+ getAdapterClass: () => import('./CramAdapter').then(r => r.default),
13
+ })
14
+ })
16
15
  }
@@ -0,0 +1,26 @@
1
+ import { readFeaturesToCIGAR, readFeaturesToMismatches } from './util'
2
+
3
+ test('cram read features mismatches', () => {
4
+ expect(
5
+ // from ctgA_15140_15565_0:0:1_1:0:0_2e8 in volvox-sorted.cram
6
+ readFeaturesToMismatches(
7
+ [{ code: 'i', data: 'C', pos: 25, refPos: 15164 }],
8
+ 15139,
9
+ ),
10
+ ).toMatchSnapshot()
11
+ })
12
+
13
+ test('cram read features to CIGAR', () => {
14
+ expect(
15
+ // from ctgA_15140_15565_0:0:1_1:0:0_2e8 in volvox-sorted.cram
16
+ readFeaturesToCIGAR(
17
+ [{ code: 'i', data: 'C', pos: 25, refPos: 15164 }],
18
+ 15140,
19
+ 100,
20
+ {
21
+ start: 14998,
22
+ seq: 'agaccacattcagctctcggtaacatgggaggcttgtggttgcaccgtaaaagggggatagcccatccatcctgtaaacctacaatcgcgcgtagcttaatacgctcacattagacattcgatcgagagacctggtttcaagagccttcccttttgctttagtgggccaaatcgcaaccctgctcccctcccttacgccttatacacttcagtgcaaattcatgcgttcagcgaacaactggacttctgttgtacgtagtccacgggggcttattcattatagaaagccccctactgtcaccgttatatggttcacacatgagctgatcacctagagagtcgtcatgcacattcgcctaacaaggacatatgagtaaccg',
23
+ },
24
+ ),
25
+ ).toMatchSnapshot()
26
+ })
@@ -0,0 +1,251 @@
1
+ import { CramRecord } from '@gmod/cram'
2
+
3
+ type ReadFeatures = CramRecord['readFeatures']
4
+
5
+ export interface Mismatch {
6
+ qual?: number
7
+ start: number
8
+ length: number
9
+ type: string
10
+ base: string | undefined
11
+ altbase?: string
12
+ seq?: string
13
+ cliplen?: number
14
+ }
15
+
16
+ export function readFeaturesToMismatches(
17
+ readFeatures: ReadFeatures,
18
+ start: number,
19
+ qual?: number[] | null,
20
+ ) {
21
+ if (!readFeatures) {
22
+ return []
23
+ }
24
+ const mismatches: Mismatch[] = new Array(readFeatures.length)
25
+ let j = 0
26
+ let insLen = 0
27
+ let refPos = 0
28
+ let sublen = 0
29
+ let lastPos = start
30
+
31
+ for (let i = 0; i < readFeatures.length; i++) {
32
+ const f = readFeatures[i]
33
+ const { code, pos, data, sub, ref } = f
34
+ sublen = refPos - lastPos
35
+ lastPos = refPos
36
+
37
+ if (sublen && insLen > 0) {
38
+ mismatches[j++] = {
39
+ start: refPos,
40
+ type: 'insertion',
41
+ base: `${insLen}`,
42
+ length: 0,
43
+ }
44
+ insLen = 0
45
+ }
46
+ refPos = f.refPos - 1 - start
47
+
48
+ if (code === 'X') {
49
+ // substitution
50
+ mismatches[j++] = {
51
+ start: refPos,
52
+ length: 1,
53
+ base: sub,
54
+ qual: qual?.[pos - 1],
55
+ altbase: ref?.toUpperCase(),
56
+ type: 'mismatch',
57
+ }
58
+ } else if (code === 'I') {
59
+ // insertion
60
+ mismatches[j++] = {
61
+ start: refPos,
62
+ type: 'insertion',
63
+ base: `${data.length}`,
64
+ length: 0,
65
+ }
66
+ } else if (code === 'N') {
67
+ // reference skip
68
+ mismatches[j++] = {
69
+ type: 'skip',
70
+ length: data,
71
+ start: refPos,
72
+ base: 'N',
73
+ }
74
+ } else if (code === 'S') {
75
+ // soft clip
76
+ const len = data.length
77
+ mismatches[j++] = {
78
+ start: refPos,
79
+ type: 'softclip',
80
+ base: `S${len}`,
81
+ cliplen: len,
82
+ length: 1,
83
+ }
84
+ } else if (code === 'P') {
85
+ // padding
86
+ } else if (code === 'H') {
87
+ // hard clip
88
+ const len = data
89
+ mismatches[j++] = {
90
+ start: refPos,
91
+ type: 'hardclip',
92
+ base: `H${len}`,
93
+ cliplen: len,
94
+ length: 1,
95
+ }
96
+ } else if (code === 'D') {
97
+ // deletion
98
+ mismatches[j++] = {
99
+ type: 'deletion',
100
+ length: data,
101
+ start: refPos,
102
+ base: '*',
103
+ }
104
+ } else if (code === 'b') {
105
+ // stretch of bases
106
+ } else if (code === 'q') {
107
+ // stretch of qual scores
108
+ } else if (code === 'B') {
109
+ // a pair of [base, qual]
110
+ } else if (code === 'i') {
111
+ // single-base insertion, we collect these if there are multiple in a row
112
+ // into a single insertion entry
113
+ insLen++
114
+ } else if (code === 'Q') {
115
+ // single quality value
116
+ }
117
+ }
118
+
119
+ if (sublen && insLen > 0) {
120
+ mismatches[j++] = {
121
+ start: refPos,
122
+ type: 'insertion',
123
+ base: `${insLen}`,
124
+ length: 0,
125
+ }
126
+ insLen = 0
127
+ }
128
+
129
+ return mismatches.slice(0, j)
130
+ }
131
+
132
+ export function readFeaturesToCIGAR(
133
+ readFeatures: ReadFeatures,
134
+ alignmentStart: number,
135
+ readLen: number,
136
+ refRegion?: { seq: string; start: number },
137
+ ) {
138
+ let seq = ''
139
+ let cigar = ''
140
+ let op = 'M'
141
+ let oplen = 0
142
+ if (!refRegion) {
143
+ return ''
144
+ }
145
+
146
+ // not sure I should access these, but...
147
+ const ref = refRegion.seq
148
+ const refStart = refRegion.start
149
+ let lastPos = alignmentStart
150
+ let sublen = 0
151
+ let insLen = 0
152
+ if (readFeatures !== undefined) {
153
+ for (let i = 0; i < readFeatures.length; i++) {
154
+ const { code, refPos, sub, data } = readFeatures[i]
155
+ sublen = refPos - lastPos
156
+ seq += ref.substring(lastPos - refStart, refPos - refStart)
157
+ lastPos = refPos
158
+
159
+ if (insLen > 0 && sublen) {
160
+ cigar += `${insLen}I`
161
+ insLen = 0
162
+ }
163
+ if (oplen && op !== 'M') {
164
+ cigar += oplen + op
165
+ oplen = 0
166
+ }
167
+ if (sublen) {
168
+ op = 'M'
169
+ oplen += sublen
170
+ }
171
+
172
+ if (code === 'b') {
173
+ // An array of bases stored verbatim
174
+ const ret = data.split(',')
175
+ const added = String.fromCharCode(...ret)
176
+ seq += added
177
+ lastPos += added.length
178
+ oplen += added.length
179
+ } else if (code === 'B') {
180
+ // Single base (+ qual score)
181
+ seq += sub
182
+ lastPos++
183
+ oplen++
184
+ } else if (code === 'X') {
185
+ // Substitution
186
+ seq += sub
187
+ lastPos++
188
+ oplen++
189
+ } else if (code === 'D' || code === 'N') {
190
+ // Deletion or Ref Skip
191
+ lastPos += data
192
+ if (oplen) {
193
+ cigar += oplen + op
194
+ }
195
+ cigar += data + code
196
+ oplen = 0
197
+ } else if (code === 'I' || code === 'S') {
198
+ // Insertion or soft-clip
199
+ seq += data
200
+ if (oplen) {
201
+ cigar += oplen + op
202
+ }
203
+ cigar += data.length + code
204
+ oplen = 0
205
+ } else if (code === 'i') {
206
+ // Single base insertion
207
+ // seq += data
208
+ if (oplen) {
209
+ cigar += oplen + op
210
+ }
211
+ insLen++
212
+ seq += data
213
+ oplen = 0
214
+ } else if (code === 'P') {
215
+ // Padding
216
+ if (oplen) {
217
+ cigar += oplen + op
218
+ }
219
+ cigar += `${data}P`
220
+ } else if (code === 'H') {
221
+ // Hard clip
222
+ if (oplen) {
223
+ cigar += oplen + op
224
+ }
225
+ cigar += `${data}H`
226
+ oplen = 0
227
+ } // else q or Q
228
+ }
229
+ } else {
230
+ sublen = readLen - seq.length
231
+ }
232
+ if (seq.length !== readLen) {
233
+ sublen = readLen - seq.length
234
+ seq += ref.substring(lastPos - refStart, lastPos - refStart + sublen)
235
+
236
+ if (oplen && op !== 'M') {
237
+ cigar += oplen + op
238
+ oplen = 0
239
+ }
240
+ op = 'M'
241
+ oplen += sublen
242
+ }
243
+ if (sublen && insLen > 0) {
244
+ cigar += `${insLen}I`
245
+ }
246
+ if (oplen) {
247
+ cigar += oplen + op
248
+ }
249
+
250
+ return cigar
251
+ }
@@ -1,8 +1,10 @@
1
1
  import React from 'react'
2
2
  import { observer } from 'mobx-react'
3
+ import { makeStyles } from 'tss-react/mui'
3
4
  import { getConf } from '@jbrowse/core/configuration'
4
5
  import { ResizeHandle } from '@jbrowse/core/ui'
5
- import { makeStyles } from 'tss-react/mui'
6
+
7
+ // locals
6
8
  import { AlignmentsDisplayModel } from '../models/model'
7
9
 
8
10
  const useStyles = makeStyles()(() => ({
@@ -203,27 +203,28 @@ function stateModelFactory(
203
203
  /**
204
204
  * #action
205
205
  */
206
- setSNPCoverageDisplay(displayConfig: AnyConfigurationModel) {
206
+ setSNPCoverageDisplay(configuration: AnyConfigurationModel) {
207
207
  self.SNPCoverageDisplay = {
208
208
  type: 'LinearSNPCoverageDisplay',
209
- configuration: displayConfig,
209
+ configuration,
210
210
  height: self.snpCovHeight,
211
211
  }
212
212
  },
213
213
  /**
214
214
  * #action
215
215
  */
216
- setUserFeatureScreenDensity(limit: number) {
217
- self.PileupDisplay.setUserFeatureScreenDensity(limit)
218
- self.SNPCoverageDisplay.setUserFeatureScreenDensity(limit)
216
+ updateStatsLimit(stats: unknown) {
217
+ self.PileupDisplay.updateStatsLimit(stats)
218
+ self.SNPCoverageDisplay.updateStatsLimit(stats)
219
219
  },
220
+
220
221
  /**
221
222
  * #action
222
223
  */
223
- setPileupDisplay(displayConfig: AnyConfigurationModel) {
224
+ setPileupDisplay(configuration: AnyConfigurationModel) {
224
225
  self.PileupDisplay = {
225
226
  type: 'LinearPileupDisplay',
226
- configuration: displayConfig,
227
+ configuration,
227
228
  }
228
229
  },
229
230
  /**
@@ -4,23 +4,14 @@ import { ObservableMap } from 'mobx'
4
4
  import {
5
5
  Button,
6
6
  CircularProgress,
7
- Dialog,
8
7
  DialogActions,
9
8
  DialogContent,
10
- DialogTitle,
11
- IconButton,
12
9
  Typography,
13
10
  } from '@mui/material'
11
+ import { Dialog } from '@jbrowse/core/ui'
14
12
  import { makeStyles } from 'tss-react/mui'
15
- import CloseIcon from '@mui/icons-material/Close'
16
13
 
17
14
  const useStyles = makeStyles()(theme => ({
18
- closeButton: {
19
- position: 'absolute',
20
- right: theme.spacing(1),
21
- top: theme.spacing(1),
22
- color: theme.palette.grey[500],
23
- },
24
15
  table: {
25
16
  border: '1px solid #888',
26
17
  margin: theme.spacing(4),
@@ -58,30 +49,19 @@ function ModificationTable({
58
49
 
59
50
  function ColorByTagDlg(props: {
60
51
  model: {
61
- setColorScheme: Function
52
+ setColorScheme: (arg: { type: string }) => void
62
53
  modificationTagMap: ObservableMap<string, string>
63
54
  colorBy?: { type: string }
64
55
  }
65
56
  handleClose: () => void
66
57
  }) {
67
- const { classes } = useStyles()
68
58
  const { model, handleClose } = props
69
59
  const { colorBy, modificationTagMap } = model
70
60
 
71
61
  const modifications = [...modificationTagMap.entries()]
72
62
 
73
63
  return (
74
- <Dialog open onClose={handleClose}>
75
- <DialogTitle>
76
- Color by modifications
77
- <IconButton
78
- aria-label="close"
79
- className={classes.closeButton}
80
- onClick={handleClose}
81
- >
82
- <CloseIcon />
83
- </IconButton>
84
- </DialogTitle>
64
+ <Dialog open onClose={handleClose} title="Color by modifications">
85
65
  <DialogContent>
86
66
  <Typography>
87
67
  You can choose to color the modifications in the BAM/CRAM MM/ML
@@ -126,12 +106,8 @@ function ColorByTagDlg(props: {
126
106
  <DialogActions>
127
107
  <Button
128
108
  variant="contained"
129
- color="primary"
130
- style={{ margin: 5 }}
131
109
  onClick={() => {
132
- model.setColorScheme({
133
- type: 'modifications',
134
- })
110
+ model.setColorScheme({ type: 'modifications' })
135
111
  handleClose()
136
112
  }}
137
113
  >
@@ -139,12 +115,8 @@ function ColorByTagDlg(props: {
139
115
  </Button>
140
116
  <Button
141
117
  variant="contained"
142
- color="primary"
143
- style={{ margin: 5 }}
144
118
  onClick={() => {
145
- model.setColorScheme({
146
- type: 'methylation',
147
- })
119
+ model.setColorScheme({ type: 'methylation' })
148
120
  handleClose()
149
121
  }}
150
122
  >
@@ -153,7 +125,6 @@ function ColorByTagDlg(props: {
153
125
  <Button
154
126
  variant="contained"
155
127
  color="secondary"
156
- style={{ margin: 5 }}
157
128
  onClick={() => handleClose()}
158
129
  >
159
130
  Cancel
@@ -2,50 +2,23 @@ import React, { useState } from 'react'
2
2
  import { observer } from 'mobx-react'
3
3
  import {
4
4
  Button,
5
- Dialog,
6
5
  DialogContent,
7
6
  DialogActions,
8
- DialogTitle,
9
- IconButton,
10
7
  TextField,
11
8
  Typography,
12
9
  } from '@mui/material'
13
- import { makeStyles } from 'tss-react/mui'
14
- import CloseIcon from '@mui/icons-material/Close'
15
-
16
- const useStyles = makeStyles()(theme => ({
17
- root: {
18
- width: 300,
19
- },
20
- closeButton: {
21
- position: 'absolute',
22
- right: theme.spacing(1),
23
- top: theme.spacing(1),
24
- color: theme.palette.grey[500],
25
- },
26
- }))
10
+ import { Dialog } from '@jbrowse/core/ui'
27
11
 
28
12
  function ColorByTagDlg(props: {
29
13
  model: { setColorScheme: Function }
30
14
  handleClose: () => void
31
15
  }) {
32
- const { classes } = useStyles()
33
16
  const { model, handleClose } = props
34
17
  const [tag, setTag] = useState('')
35
18
  const validTag = tag.match(/^[A-Za-z][A-Za-z0-9]$/)
36
19
 
37
20
  return (
38
- <Dialog open onClose={handleClose}>
39
- <DialogTitle>
40
- Color by tag
41
- <IconButton
42
- aria-label="close"
43
- className={classes.closeButton}
44
- onClick={handleClose}
45
- >
46
- <CloseIcon />
47
- </IconButton>
48
- </DialogTitle>
21
+ <Dialog open onClose={handleClose} title="Color by tag">
49
22
  <DialogContent style={{ overflowX: 'hidden' }}>
50
23
  <Typography>Enter tag to color by: </Typography>
51
24
  <Typography color="textSecondary">
@@ -2,31 +2,21 @@ import React, { useState } from 'react'
2
2
  import { observer } from 'mobx-react'
3
3
  import {
4
4
  Button,
5
- Dialog,
6
5
  DialogActions,
7
6
  DialogContent,
8
- DialogTitle,
9
- IconButton,
10
7
  Link,
11
8
  Paper,
12
9
  TextField,
13
10
  Typography,
14
11
  } from '@mui/material'
12
+ import { Dialog } from '@jbrowse/core/ui'
15
13
  import { makeStyles } from 'tss-react/mui'
16
14
 
17
- import CloseIcon from '@mui/icons-material/Close'
18
-
19
15
  const useStyles = makeStyles()(theme => ({
20
16
  paper: {
21
17
  padding: theme.spacing(2),
22
18
  margin: theme.spacing(2),
23
19
  },
24
- closeButton: {
25
- position: 'absolute',
26
- right: theme.spacing(1),
27
- top: theme.spacing(1),
28
- color: theme.palette.grey[500],
29
- },
30
20
  field: {
31
21
  margin: theme.spacing(2),
32
22
  },
@@ -105,17 +95,7 @@ function FilterByTagDlg(props: {
105
95
  const site = 'https://broadinstitute.github.io/picard/explain-flags.html'
106
96
 
107
97
  return (
108
- <Dialog open onClose={handleClose}>
109
- <DialogTitle>
110
- Filter options
111
- <IconButton
112
- aria-label="close"
113
- className={classes.closeButton}
114
- onClick={handleClose}
115
- >
116
- <CloseIcon />
117
- </IconButton>
118
- </DialogTitle>
98
+ <Dialog open onClose={handleClose} title="Filter options">
119
99
  <DialogContent>
120
100
  <Typography>
121
101
  Set filter bitmask options. Refer to <Link href={site}>{site}</Link>{' '}
@@ -3,26 +3,13 @@ import { observer } from 'mobx-react'
3
3
  import {
4
4
  Button,
5
5
  Checkbox,
6
- Dialog,
7
6
  DialogActions,
8
7
  DialogContent,
9
- DialogTitle,
10
8
  FormControlLabel,
11
- IconButton,
12
9
  TextField,
13
10
  Typography,
14
11
  } from '@mui/material'
15
- import { makeStyles } from 'tss-react/mui'
16
- import CloseIcon from '@mui/icons-material/Close'
17
-
18
- const useStyles = makeStyles()(theme => ({
19
- closeButton: {
20
- position: 'absolute',
21
- right: theme.spacing(1),
22
- top: theme.spacing(1),
23
- color: theme.palette.grey[500],
24
- },
25
- }))
12
+ import { Dialog } from '@jbrowse/core/ui'
26
13
 
27
14
  function SetFeatureHeightDlg(props: {
28
15
  model: {
@@ -33,7 +20,6 @@ function SetFeatureHeightDlg(props: {
33
20
  }
34
21
  handleClose: () => void
35
22
  }) {
36
- const { classes } = useStyles()
37
23
  const { model, handleClose } = props
38
24
  const { featureHeightSetting, noSpacing: noSpacingSetting } = model
39
25
  const [height, setHeight] = useState(`${featureHeightSetting}`)
@@ -42,13 +28,7 @@ function SetFeatureHeightDlg(props: {
42
28
  const ok = height !== '' && !Number.isNaN(+height)
43
29
 
44
30
  return (
45
- <Dialog open onClose={handleClose}>
46
- <DialogTitle>
47
- Set feature height
48
- <IconButton className={classes.closeButton} onClick={handleClose}>
49
- <CloseIcon />
50
- </IconButton>
51
- </DialogTitle>
31
+ <Dialog open onClose={handleClose} title={'Set feature height'}>
52
32
  <DialogContent>
53
33
  <Typography>
54
34
  Adjust the feature height and whether there is any spacing between
@@ -2,30 +2,18 @@ import React, { useState } from 'react'
2
2
  import { observer } from 'mobx-react'
3
3
  import {
4
4
  Button,
5
- Dialog,
6
5
  DialogActions,
7
6
  DialogContent,
8
- DialogTitle,
9
- IconButton,
10
7
  TextField,
11
8
  Typography,
12
9
  } from '@mui/material'
10
+ import { Dialog } from '@jbrowse/core/ui'
13
11
  import { makeStyles } from 'tss-react/mui'
14
- import CloseIcon from '@mui/icons-material/Close'
15
12
 
16
13
  const useStyles = makeStyles()(theme => ({
17
14
  root: {
18
15
  width: 500,
19
16
  },
20
- closeButton: {
21
- position: 'absolute',
22
- right: theme.spacing(1),
23
- top: theme.spacing(1),
24
- color: theme.palette.grey[500],
25
- },
26
- field: {
27
- margin: theme.spacing(2),
28
- },
29
17
  }))
30
18
 
31
19
  function SetMaxHeightDlg(props: {
@@ -41,17 +29,7 @@ function SetMaxHeightDlg(props: {
41
29
  const [max, setMax] = useState(`${maxHeight}`)
42
30
 
43
31
  return (
44
- <Dialog open onClose={handleClose}>
45
- <DialogTitle>
46
- Filter options
47
- <IconButton
48
- aria-label="close"
49
- className={classes.closeButton}
50
- onClick={handleClose}
51
- >
52
- <CloseIcon />
53
- </IconButton>
54
- </DialogTitle>
32
+ <Dialog open onClose={handleClose} title="Filter options">
55
33
  <DialogContent className={classes.root}>
56
34
  <Typography>
57
35
  Set max height for the track. For example, you can increase this if
@@ -2,51 +2,22 @@ import React, { useState } from 'react'
2
2
  import { observer } from 'mobx-react'
3
3
  import {
4
4
  Button,
5
- Dialog,
6
5
  DialogActions,
7
6
  DialogContent,
8
- DialogTitle,
9
- IconButton,
10
7
  TextField,
11
8
  Typography,
12
9
  } from '@mui/material'
13
- import { makeStyles } from 'tss-react/mui'
14
-
15
- import CloseIcon from '@mui/icons-material/Close'
16
-
17
- const useStyles = makeStyles()(theme => ({
18
- root: {
19
- margin: 0,
20
- padding: theme.spacing(2),
21
- },
22
- closeButton: {
23
- position: 'absolute',
24
- right: theme.spacing(1),
25
- top: theme.spacing(1),
26
- color: theme.palette.grey[500],
27
- },
28
- }))
10
+ import { Dialog } from '@jbrowse/core/ui'
29
11
 
30
12
  function SortByTagDlg(props: {
31
13
  model: { setSortedBy: Function }
32
14
  handleClose: () => void
33
15
  }) {
34
- const { classes } = useStyles()
35
16
  const { model, handleClose } = props
36
17
  const [tag, setTag] = useState('')
37
18
  const validTag = tag.match(/^[A-Za-z][A-Za-z0-9]$/)
38
19
  return (
39
- <Dialog open onClose={handleClose}>
40
- <DialogTitle>
41
- Sort by tag
42
- <IconButton
43
- aria-label="close"
44
- className={classes.closeButton}
45
- onClick={handleClose}
46
- >
47
- <CloseIcon />
48
- </IconButton>
49
- </DialogTitle>
20
+ <Dialog open onClose={handleClose} title="Sort by tag">
50
21
  <DialogContent>
51
22
  <Typography>Set the tag to sort by</Typography>
52
23
  <Typography color="textSecondary">