@jbrowse/plugin-alignments 2.1.7 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (226) hide show
  1. package/dist/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +12 -13
  2. package/dist/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js.map +1 -1
  3. package/dist/AlignmentsTrack/index.d.ts +1 -1
  4. package/dist/AlignmentsTrack/index.js +16 -6
  5. package/dist/AlignmentsTrack/index.js.map +1 -1
  6. package/dist/BamAdapter/BamAdapter.d.ts +7 -3
  7. package/dist/BamAdapter/BamAdapter.js +36 -31
  8. package/dist/BamAdapter/BamAdapter.js.map +1 -1
  9. package/dist/BamAdapter/BamSlightlyLazyFeature.js +1 -0
  10. package/dist/BamAdapter/BamSlightlyLazyFeature.js.map +1 -1
  11. package/dist/BamAdapter/MismatchParser.d.ts +2 -2
  12. package/dist/BamAdapter/MismatchParser.js +4 -7
  13. package/dist/BamAdapter/MismatchParser.js.map +1 -1
  14. package/dist/BamAdapter/configSchema.d.ts +2 -2
  15. package/dist/BamAdapter/configSchema.js +27 -2
  16. package/dist/BamAdapter/configSchema.js.map +1 -1
  17. package/dist/BamAdapter/index.js +7 -5
  18. package/dist/BamAdapter/index.js.map +1 -1
  19. package/dist/CramAdapter/CramAdapter.d.ts +13 -7
  20. package/dist/CramAdapter/CramAdapter.js +56 -61
  21. package/dist/CramAdapter/CramAdapter.js.map +1 -1
  22. package/dist/CramAdapter/CramSlightlyLazyFeature.d.ts +15 -23
  23. package/dist/CramAdapter/CramSlightlyLazyFeature.js +10 -217
  24. package/dist/CramAdapter/CramSlightlyLazyFeature.js.map +1 -1
  25. package/dist/CramAdapter/CramTestAdapters.d.ts +1 -1
  26. package/dist/CramAdapter/CramTestAdapters.js +1 -1
  27. package/dist/CramAdapter/CramTestAdapters.js.map +1 -1
  28. package/dist/CramAdapter/configSchema.d.ts +2 -3
  29. package/dist/CramAdapter/configSchema.js +44 -22
  30. package/dist/CramAdapter/configSchema.js.map +1 -1
  31. package/dist/CramAdapter/index.js +7 -5
  32. package/dist/CramAdapter/index.js.map +1 -1
  33. package/dist/CramAdapter/util.d.ts +18 -0
  34. package/dist/CramAdapter/util.js +241 -0
  35. package/dist/CramAdapter/util.js.map +1 -0
  36. package/dist/HtsgetBamAdapter/HtsgetBamAdapter.d.ts +5 -2
  37. package/dist/HtsgetBamAdapter/HtsgetBamAdapter.js +15 -20
  38. package/dist/HtsgetBamAdapter/HtsgetBamAdapter.js.map +1 -1
  39. package/dist/HtsgetBamAdapter/configSchema.d.ts +2 -2
  40. package/dist/HtsgetBamAdapter/configSchema.js +20 -3
  41. package/dist/HtsgetBamAdapter/configSchema.js.map +1 -1
  42. package/dist/LinearAlignmentsDisplay/components/AlignmentsDisplay.js +1 -1
  43. package/dist/LinearAlignmentsDisplay/components/AlignmentsDisplay.js.map +1 -1
  44. package/dist/LinearAlignmentsDisplay/models/configSchema.d.ts +2 -2
  45. package/dist/LinearAlignmentsDisplay/models/configSchema.js +23 -6
  46. package/dist/LinearAlignmentsDisplay/models/configSchema.js.map +1 -1
  47. package/dist/LinearAlignmentsDisplay/models/model.d.ts +77 -10
  48. package/dist/LinearAlignmentsDisplay/models/model.js +102 -9
  49. package/dist/LinearAlignmentsDisplay/models/model.js.map +1 -1
  50. package/dist/LinearPileupDisplay/configSchema.d.ts +4 -4
  51. package/dist/LinearPileupDisplay/configSchema.js +22 -5
  52. package/dist/LinearPileupDisplay/configSchema.js.map +1 -1
  53. package/dist/LinearPileupDisplay/index.d.ts +3 -0
  54. package/dist/LinearPileupDisplay/index.js +3 -0
  55. package/dist/LinearPileupDisplay/index.js.map +1 -1
  56. package/dist/LinearPileupDisplay/model.d.ts +100 -6
  57. package/dist/LinearPileupDisplay/model.js +611 -503
  58. package/dist/LinearPileupDisplay/model.js.map +1 -1
  59. package/dist/LinearSNPCoverageDisplay/components/Tooltip.d.ts +1 -1
  60. package/dist/LinearSNPCoverageDisplay/models/configSchema.js +33 -4
  61. package/dist/LinearSNPCoverageDisplay/models/configSchema.js.map +1 -1
  62. package/dist/LinearSNPCoverageDisplay/models/model.d.ts +87 -4
  63. package/dist/LinearSNPCoverageDisplay/models/model.js +240 -159
  64. package/dist/LinearSNPCoverageDisplay/models/model.js.map +1 -1
  65. package/dist/PileupRPC/rpcMethods.d.ts +1 -1
  66. package/dist/PileupRPC/rpcMethods.js +12 -7
  67. package/dist/PileupRPC/rpcMethods.js.map +1 -1
  68. package/dist/PileupRenderer/PileupLayoutSession.d.ts +1 -1
  69. package/dist/PileupRenderer/PileupRenderer.d.ts +1 -1
  70. package/dist/PileupRenderer/PileupRenderer.js +37 -34
  71. package/dist/PileupRenderer/PileupRenderer.js.map +1 -1
  72. package/dist/PileupRenderer/configSchema.d.ts +2 -2
  73. package/dist/PileupRenderer/configSchema.js +37 -2
  74. package/dist/PileupRenderer/configSchema.js.map +1 -1
  75. package/dist/PileupRenderer/index.js +8 -6
  76. package/dist/PileupRenderer/index.js.map +1 -1
  77. package/dist/SNPCoverageAdapter/configSchema.d.ts +2 -3
  78. package/dist/SNPCoverageAdapter/configSchema.js +15 -4
  79. package/dist/SNPCoverageAdapter/configSchema.js.map +1 -1
  80. package/dist/SNPCoverageAdapter/index.d.ts +1 -2
  81. package/dist/SNPCoverageAdapter/index.js +17 -14
  82. package/dist/SNPCoverageAdapter/index.js.map +1 -1
  83. package/dist/SNPCoverageRenderer/configSchema.d.ts +2 -2
  84. package/dist/SNPCoverageRenderer/configSchema.js +21 -1
  85. package/dist/SNPCoverageRenderer/configSchema.js.map +1 -1
  86. package/dist/SNPCoverageRenderer/index.d.ts +0 -1
  87. package/dist/SNPCoverageRenderer/index.js +1 -4
  88. package/dist/SNPCoverageRenderer/index.js.map +1 -1
  89. package/dist/index.d.ts +3 -2
  90. package/dist/index.js +4 -2
  91. package/dist/index.js.map +1 -1
  92. package/esm/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +12 -13
  93. package/esm/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js.map +1 -1
  94. package/esm/AlignmentsTrack/index.d.ts +1 -1
  95. package/esm/AlignmentsTrack/index.js +16 -6
  96. package/esm/AlignmentsTrack/index.js.map +1 -1
  97. package/esm/BamAdapter/BamAdapter.d.ts +7 -3
  98. package/esm/BamAdapter/BamAdapter.js +36 -31
  99. package/esm/BamAdapter/BamAdapter.js.map +1 -1
  100. package/esm/BamAdapter/BamSlightlyLazyFeature.js +1 -0
  101. package/esm/BamAdapter/BamSlightlyLazyFeature.js.map +1 -1
  102. package/esm/BamAdapter/MismatchParser.d.ts +2 -2
  103. package/esm/BamAdapter/MismatchParser.js +4 -7
  104. package/esm/BamAdapter/MismatchParser.js.map +1 -1
  105. package/esm/BamAdapter/configSchema.d.ts +2 -2
  106. package/esm/BamAdapter/configSchema.js +27 -2
  107. package/esm/BamAdapter/configSchema.js.map +1 -1
  108. package/esm/BamAdapter/index.js +7 -5
  109. package/esm/BamAdapter/index.js.map +1 -1
  110. package/esm/CramAdapter/CramAdapter.d.ts +13 -7
  111. package/esm/CramAdapter/CramAdapter.js +56 -61
  112. package/esm/CramAdapter/CramAdapter.js.map +1 -1
  113. package/esm/CramAdapter/CramSlightlyLazyFeature.d.ts +15 -23
  114. package/esm/CramAdapter/CramSlightlyLazyFeature.js +10 -217
  115. package/esm/CramAdapter/CramSlightlyLazyFeature.js.map +1 -1
  116. package/esm/CramAdapter/CramTestAdapters.d.ts +1 -1
  117. package/esm/CramAdapter/CramTestAdapters.js +1 -1
  118. package/esm/CramAdapter/CramTestAdapters.js.map +1 -1
  119. package/esm/CramAdapter/configSchema.d.ts +2 -3
  120. package/esm/CramAdapter/configSchema.js +44 -22
  121. package/esm/CramAdapter/configSchema.js.map +1 -1
  122. package/esm/CramAdapter/index.js +8 -6
  123. package/esm/CramAdapter/index.js.map +1 -1
  124. package/esm/CramAdapter/util.d.ts +18 -0
  125. package/esm/CramAdapter/util.js +236 -0
  126. package/esm/CramAdapter/util.js.map +1 -0
  127. package/esm/HtsgetBamAdapter/HtsgetBamAdapter.d.ts +5 -2
  128. package/esm/HtsgetBamAdapter/HtsgetBamAdapter.js +15 -20
  129. package/esm/HtsgetBamAdapter/HtsgetBamAdapter.js.map +1 -1
  130. package/esm/HtsgetBamAdapter/configSchema.d.ts +2 -2
  131. package/esm/HtsgetBamAdapter/configSchema.js +20 -3
  132. package/esm/HtsgetBamAdapter/configSchema.js.map +1 -1
  133. package/esm/LinearAlignmentsDisplay/components/AlignmentsDisplay.js +1 -1
  134. package/esm/LinearAlignmentsDisplay/components/AlignmentsDisplay.js.map +1 -1
  135. package/esm/LinearAlignmentsDisplay/models/configSchema.d.ts +2 -2
  136. package/esm/LinearAlignmentsDisplay/models/configSchema.js +23 -6
  137. package/esm/LinearAlignmentsDisplay/models/configSchema.js.map +1 -1
  138. package/esm/LinearAlignmentsDisplay/models/model.d.ts +77 -10
  139. package/esm/LinearAlignmentsDisplay/models/model.js +102 -9
  140. package/esm/LinearAlignmentsDisplay/models/model.js.map +1 -1
  141. package/esm/LinearPileupDisplay/configSchema.d.ts +4 -4
  142. package/esm/LinearPileupDisplay/configSchema.js +22 -5
  143. package/esm/LinearPileupDisplay/configSchema.js.map +1 -1
  144. package/esm/LinearPileupDisplay/index.d.ts +3 -0
  145. package/esm/LinearPileupDisplay/index.js +1 -0
  146. package/esm/LinearPileupDisplay/index.js.map +1 -1
  147. package/esm/LinearPileupDisplay/model.d.ts +100 -6
  148. package/esm/LinearPileupDisplay/model.js +611 -503
  149. package/esm/LinearPileupDisplay/model.js.map +1 -1
  150. package/esm/LinearSNPCoverageDisplay/components/Tooltip.d.ts +1 -1
  151. package/esm/LinearSNPCoverageDisplay/models/configSchema.js +33 -4
  152. package/esm/LinearSNPCoverageDisplay/models/configSchema.js.map +1 -1
  153. package/esm/LinearSNPCoverageDisplay/models/model.d.ts +87 -4
  154. package/esm/LinearSNPCoverageDisplay/models/model.js +240 -159
  155. package/esm/LinearSNPCoverageDisplay/models/model.js.map +1 -1
  156. package/esm/PileupRPC/rpcMethods.d.ts +1 -1
  157. package/esm/PileupRPC/rpcMethods.js +12 -7
  158. package/esm/PileupRPC/rpcMethods.js.map +1 -1
  159. package/esm/PileupRenderer/PileupLayoutSession.d.ts +1 -1
  160. package/esm/PileupRenderer/PileupRenderer.d.ts +1 -1
  161. package/esm/PileupRenderer/PileupRenderer.js +37 -34
  162. package/esm/PileupRenderer/PileupRenderer.js.map +1 -1
  163. package/esm/PileupRenderer/configSchema.d.ts +2 -2
  164. package/esm/PileupRenderer/configSchema.js +37 -2
  165. package/esm/PileupRenderer/configSchema.js.map +1 -1
  166. package/esm/PileupRenderer/index.js +8 -6
  167. package/esm/PileupRenderer/index.js.map +1 -1
  168. package/esm/SNPCoverageAdapter/configSchema.d.ts +2 -3
  169. package/esm/SNPCoverageAdapter/configSchema.js +15 -4
  170. package/esm/SNPCoverageAdapter/configSchema.js.map +1 -1
  171. package/esm/SNPCoverageAdapter/index.d.ts +1 -2
  172. package/esm/SNPCoverageAdapter/index.js +17 -15
  173. package/esm/SNPCoverageAdapter/index.js.map +1 -1
  174. package/esm/SNPCoverageRenderer/configSchema.d.ts +2 -2
  175. package/esm/SNPCoverageRenderer/configSchema.js +21 -1
  176. package/esm/SNPCoverageRenderer/configSchema.js.map +1 -1
  177. package/esm/SNPCoverageRenderer/index.d.ts +0 -1
  178. package/esm/SNPCoverageRenderer/index.js +1 -3
  179. package/esm/SNPCoverageRenderer/index.js.map +1 -1
  180. package/esm/index.d.ts +3 -2
  181. package/esm/index.js +2 -2
  182. package/esm/index.js.map +1 -1
  183. package/package.json +4 -3
  184. package/src/AlignmentsFeatureDetail/AlignmentsFeatureDetail.tsx +17 -16
  185. package/src/AlignmentsFeatureDetail/__snapshots__/index.test.js.snap +41 -513
  186. package/src/AlignmentsFeatureDetail/index.test.js +6 -4
  187. package/src/AlignmentsTrack/index.ts +18 -12
  188. package/src/BamAdapter/BamAdapter.ts +42 -41
  189. package/src/BamAdapter/BamSlightlyLazyFeature.ts +2 -1
  190. package/src/BamAdapter/MismatchParser.test.ts +21 -12
  191. package/src/BamAdapter/MismatchParser.ts +7 -10
  192. package/src/BamAdapter/__snapshots__/BamAdapter.test.ts.snap +135 -135
  193. package/src/BamAdapter/configSchema.ts +57 -29
  194. package/src/BamAdapter/index.ts +7 -8
  195. package/src/CombinationTest.test.ts +107 -0
  196. package/src/CramAdapter/CramAdapter.test.ts +1 -2
  197. package/src/CramAdapter/CramAdapter.ts +83 -84
  198. package/src/CramAdapter/CramSlightlyLazyFeature.ts +18 -218
  199. package/src/CramAdapter/CramTestAdapters.ts +1 -1
  200. package/src/CramAdapter/__snapshots__/CramAdapter.test.ts.snap +31 -31
  201. package/src/CramAdapter/__snapshots__/util.test.ts.snap +14 -0
  202. package/src/CramAdapter/configSchema.ts +54 -30
  203. package/src/CramAdapter/index.ts +8 -9
  204. package/src/CramAdapter/util.test.ts +26 -0
  205. package/src/CramAdapter/util.ts +251 -0
  206. package/src/HtsgetBamAdapter/HtsgetBamAdapter.ts +14 -21
  207. package/src/HtsgetBamAdapter/configSchema.ts +36 -19
  208. package/src/LinearAlignmentsDisplay/components/AlignmentsDisplay.tsx +3 -1
  209. package/src/LinearAlignmentsDisplay/models/configSchema.ts +23 -10
  210. package/src/LinearAlignmentsDisplay/models/model.tsx +107 -11
  211. package/src/LinearPileupDisplay/configSchema.ts +25 -9
  212. package/src/LinearPileupDisplay/index.ts +5 -0
  213. package/src/LinearPileupDisplay/model.ts +151 -34
  214. package/src/LinearSNPCoverageDisplay/models/configSchema.ts +36 -9
  215. package/src/LinearSNPCoverageDisplay/models/model.ts +83 -4
  216. package/src/PileupRPC/rpcMethods.ts +15 -20
  217. package/src/PileupRenderer/{PileupRenderer.tsx → PileupRenderer.ts} +53 -63
  218. package/src/PileupRenderer/configSchema.ts +39 -2
  219. package/src/PileupRenderer/index.ts +8 -9
  220. package/src/SNPCoverageAdapter/configSchema.ts +21 -12
  221. package/src/SNPCoverageAdapter/index.ts +17 -18
  222. package/src/SNPCoverageRenderer/configSchema.ts +23 -1
  223. package/src/SNPCoverageRenderer/index.ts +1 -8
  224. package/src/__snapshots__/index.test.ts.snap +1 -1
  225. package/src/index.ts +11 -4
  226. package/src/declare.d.ts +0 -1
@@ -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,31 +1,24 @@
1
1
  import { BamFile, HtsgetFile } from '@gmod/bam'
2
- import { readConfObject } from '@jbrowse/core/configuration'
3
2
  import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter'
4
3
  import BamAdapter from '../BamAdapter/BamAdapter'
5
4
 
6
5
  export default class HtsgetBamAdapter extends BamAdapter {
7
- protected async configure() {
8
- if (!this.configured) {
9
- const htsgetBase = readConfObject(this.config, 'htsgetBase')
10
- const htsgetTrackId = readConfObject(this.config, 'htsgetTrackId')
11
- const bam = new HtsgetFile({
12
- baseUrl: htsgetBase,
13
- trackId: htsgetTrackId,
14
- }) as unknown as BamFile
6
+ protected async configurePre() {
7
+ const htsgetBase = this.getConf('htsgetBase')
8
+ const htsgetTrackId = this.getConf('htsgetTrackId')
9
+ const bam = new HtsgetFile({
10
+ baseUrl: htsgetBase,
11
+ trackId: htsgetTrackId,
12
+ }) as unknown as BamFile
15
13
 
16
- const adapterConfig = readConfObject(this.config, 'sequenceAdapter')
17
- if (adapterConfig && this.getSubAdapter) {
18
- this.configured = this.getSubAdapter(adapterConfig).then(
19
- ({ dataAdapter }) => {
20
- return {
21
- bam,
22
- sequenceAdapter: dataAdapter as BaseFeatureDataAdapter,
23
- }
24
- },
25
- )
14
+ const adapterConfig = this.getConf('sequenceAdapter')
15
+ if (adapterConfig && this.getSubAdapter) {
16
+ const adapter = await this.getSubAdapter(adapterConfig)
17
+ return {
18
+ bam,
19
+ sequenceAdapter: adapter.dataAdapter as BaseFeatureDataAdapter,
26
20
  }
27
- this.configured = Promise.resolve({ bam })
28
21
  }
29
- return this.configured
22
+ return { bam }
30
23
  }
31
24
  }
@@ -1,23 +1,40 @@
1
1
  import { ConfigurationSchema } from '@jbrowse/core/configuration'
2
- import { types } from 'mobx-state-tree'
2
+ /**
3
+ * #config HtsgetBamAdapter
4
+ * Used to fetch data from Htsget endpoints in BAM format, using the gmod/bam library
5
+ */
6
+ function x() {} // eslint-disable-line @typescript-eslint/no-unused-vars
3
7
 
4
- export default types.late(() =>
5
- ConfigurationSchema(
6
- 'HtsgetBamAdapter',
7
- {
8
- htsgetBase: {
9
- type: 'string',
10
- defaultValue: '',
11
- },
12
- htsgetTrackId: {
13
- type: 'string',
14
- defaultValue: '',
15
- },
16
- sequenceAdapter: {
17
- type: 'frozen',
18
- defaultValue: null,
19
- },
8
+ const HtsgetBamAdapter = ConfigurationSchema(
9
+ 'HtsgetBamAdapter',
10
+ {
11
+ /**
12
+ * #slot
13
+ */
14
+ htsgetBase: {
15
+ type: 'string',
16
+ description: 'the base URL to fetch from',
17
+ defaultValue: '',
20
18
  },
21
- { explicitlyTyped: true },
22
- ),
19
+ /**
20
+ * #slot
21
+ */
22
+ htsgetTrackId: {
23
+ type: 'string',
24
+ description: 'the trackId, which is appended to the base URL',
25
+ defaultValue: '',
26
+ },
27
+ /**
28
+ * #slot
29
+ */
30
+ sequenceAdapter: {
31
+ type: 'frozen',
32
+ description:
33
+ 'sequence data adapter, used to calculate SNPs when BAM reads lacking MD tags',
34
+ defaultValue: null,
35
+ },
36
+ },
37
+ { explicitlyTyped: true },
23
38
  )
39
+
40
+ export default HtsgetBamAdapter
@@ -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()(() => ({
@@ -2,21 +2,34 @@ import { ConfigurationSchema } from '@jbrowse/core/configuration'
2
2
  import { baseLinearDisplayConfigSchema } from '@jbrowse/plugin-linear-genome-view'
3
3
  import PluginManager from '@jbrowse/core/PluginManager'
4
4
 
5
- const configModelFactory = (pluginManager: PluginManager) => {
6
- const PileupDisplayConfigSchema = pluginManager.getDisplayType(
7
- 'LinearPileupDisplay',
8
- ).configSchema
9
- const SNPCoverageDisplayConfigSchema = pluginManager.getDisplayType(
10
- 'LinearSNPCoverageDisplay',
11
- ).configSchema
5
+ /**
6
+ * #config LinearAlignmentsDisplay
7
+ * has a "pileup" sub-display, where you can see individual reads and a
8
+ * quantitative "snpcoverage" sub-display track showing SNP frequencies
9
+ */
10
+ function x() {} // eslint-disable-line @typescript-eslint/no-unused-vars
12
11
 
12
+ const configModelFactory = (pm: PluginManager) => {
13
13
  return ConfigurationSchema(
14
14
  'LinearAlignmentsDisplay',
15
15
  {
16
- pileupDisplay: PileupDisplayConfigSchema,
17
- snpCoverageDisplay: SNPCoverageDisplayConfigSchema,
16
+ /**
17
+ * #slot
18
+ */
19
+ pileupDisplay: pm.getDisplayType('LinearPileupDisplay').configSchema,
20
+ /**
21
+ * #slot
22
+ */
23
+ snpCoverageDisplay: pm.getDisplayType('LinearSNPCoverageDisplay')
24
+ .configSchema,
25
+ },
26
+ {
27
+ /**
28
+ * #baseConfiguration
29
+ */
30
+ baseConfiguration: baseLinearDisplayConfigSchema,
31
+ explicitlyTyped: true,
18
32
  },
19
- { baseConfiguration: baseLinearDisplayConfigSchema, explicitlyTyped: true },
20
33
  )
21
34
  }
22
35
 
@@ -2,6 +2,7 @@ import React from 'react'
2
2
  import {
3
3
  ConfigurationReference,
4
4
  AnyConfigurationModel,
5
+ AnyConfigurationSchemaType,
5
6
  getConf,
6
7
  } from '@jbrowse/core/configuration'
7
8
  import { BaseDisplay } from '@jbrowse/core/pluggableElementTypes/models'
@@ -11,30 +12,63 @@ import { autorun, when } from 'mobx'
11
12
  import { addDisposer, getSnapshot, Instance, types } from 'mobx-state-tree'
12
13
  import { getContainingTrack } from '@jbrowse/core/util'
13
14
  import deepEqual from 'fast-deep-equal'
14
- import { AlignmentsConfigModel } from './configSchema'
15
15
 
16
16
  const minDisplayHeight = 20
17
- const stateModelFactory = (
17
+
18
+ /**
19
+ * #stateModel LinearAlignmentsDisplay
20
+ * extends `BaseDisplay`
21
+ */
22
+ function stateModelFactory(
18
23
  pluginManager: PluginManager,
19
- configSchema: AlignmentsConfigModel,
20
- ) => {
24
+ configSchema: AnyConfigurationSchemaType,
25
+ ) {
21
26
  return types
22
27
  .compose(
23
28
  'LinearAlignmentsDisplay',
24
29
  BaseDisplay,
25
30
  types.model({
31
+ /**
32
+ * #property
33
+ * refers to LinearPileupDisplay sub-display model
34
+ */
26
35
  PileupDisplay: types.maybe(
27
36
  pluginManager.getDisplayType('LinearPileupDisplay').stateModel,
28
37
  ),
38
+ /**
39
+ * #property
40
+ * refers to LinearSNPCoverageDisplay sub-display model
41
+ */
29
42
  SNPCoverageDisplay: types.maybe(
30
43
  pluginManager.getDisplayType('LinearSNPCoverageDisplay').stateModel,
31
44
  ),
45
+ /**
46
+ * #property
47
+ */
32
48
  snpCovHeight: 45,
49
+ /**
50
+ * #property
51
+ */
33
52
  type: types.literal('LinearAlignmentsDisplay'),
53
+ /**
54
+ * #property
55
+ */
34
56
  configuration: ConfigurationReference(configSchema),
57
+ /**
58
+ * #property
59
+ */
35
60
  height: 250,
61
+ /**
62
+ * #property
63
+ */
36
64
  showCoverage: true,
65
+ /**
66
+ * #property
67
+ */
37
68
  showPileup: true,
69
+ /**
70
+ * #property
71
+ */
38
72
  userFeatureScreenDensity: types.maybe(types.number),
39
73
  }),
40
74
  )
@@ -42,15 +76,28 @@ const stateModelFactory = (
42
76
  scrollTop: 0,
43
77
  }))
44
78
  .actions(self => ({
79
+ /**
80
+ * #action
81
+ */
45
82
  toggleCoverage() {
46
83
  self.showCoverage = !self.showCoverage
47
84
  },
85
+ /**
86
+ * #action
87
+ */
48
88
  togglePileup() {
49
89
  self.showPileup = !self.showPileup
50
90
  },
91
+ /**
92
+ * #action
93
+ */
51
94
  setScrollTop(scrollTop: number) {
52
95
  self.scrollTop = scrollTop
53
96
  },
97
+
98
+ /**
99
+ * #action
100
+ */
54
101
  setSNPCoverageHeight(n: number) {
55
102
  self.snpCovHeight = n
56
103
  },
@@ -58,6 +105,9 @@ const stateModelFactory = (
58
105
  .views(self => {
59
106
  const { trackMenuItems: superTrackMenuItems } = self
60
107
  return {
108
+ /**
109
+ * #getter
110
+ */
61
111
  get pileupDisplayConfig() {
62
112
  const conf = getConf(self, 'pileupDisplay')
63
113
  const track = getContainingTrack(self)
@@ -69,31 +119,55 @@ const stateModelFactory = (
69
119
  }
70
120
  },
71
121
 
122
+ /**
123
+ * #method
124
+ */
72
125
  getFeatureByID(blockKey: string, id: string) {
73
126
  return self.PileupDisplay.getFeatureByID(blockKey, id)
74
127
  },
128
+ /**
129
+ * #method
130
+ */
75
131
  searchFeatureByID(id: string) {
76
132
  return self.PileupDisplay.searchFeatureByID(id)
77
133
  },
78
134
 
135
+ /**
136
+ * #getter
137
+ */
79
138
  get features() {
80
139
  return self.PileupDisplay.features
81
140
  },
82
141
 
142
+ /**
143
+ * #getter
144
+ */
83
145
  get DisplayBlurb() {
84
146
  return self.PileupDisplay?.DisplayBlurb
85
147
  },
86
148
 
149
+ /**
150
+ * #getter
151
+ */
87
152
  get sortedBy() {
88
153
  return self.PileupDisplay.sortedBy
89
154
  },
155
+ /**
156
+ * #getter
157
+ */
90
158
  get sortedByPosition() {
91
159
  return self.PileupDisplay.sortedByPosition
92
160
  },
161
+ /**
162
+ * #getter
163
+ */
93
164
  get sortedByRefName() {
94
165
  return self.PileupDisplay.sortedByRefName
95
166
  },
96
167
 
168
+ /**
169
+ * #getter
170
+ */
97
171
  get snpCoverageDisplayConfig() {
98
172
  const conf = getConf(self, 'snpCoverageDisplay')
99
173
  const track = getContainingTrack(self)
@@ -105,6 +179,9 @@ const stateModelFactory = (
105
179
  }
106
180
  },
107
181
 
182
+ /**
183
+ * #method
184
+ */
108
185
  trackMenuItems(): MenuItem[] {
109
186
  return [
110
187
  ...superTrackMenuItems(),
@@ -123,23 +200,36 @@ const stateModelFactory = (
123
200
  }
124
201
  })
125
202
  .actions(self => ({
126
- setSNPCoverageDisplay(displayConfig: AnyConfigurationModel) {
203
+ /**
204
+ * #action
205
+ */
206
+ setSNPCoverageDisplay(configuration: AnyConfigurationModel) {
127
207
  self.SNPCoverageDisplay = {
128
208
  type: 'LinearSNPCoverageDisplay',
129
- configuration: displayConfig,
209
+ configuration,
130
210
  height: self.snpCovHeight,
131
211
  }
132
212
  },
133
- setUserFeatureScreenDensity(limit: number) {
134
- self.PileupDisplay.setUserFeatureScreenDensity(limit)
135
- self.SNPCoverageDisplay.setUserFeatureScreenDensity(limit)
213
+ /**
214
+ * #action
215
+ */
216
+ updateStatsLimit(stats: unknown) {
217
+ self.PileupDisplay.updateStatsLimit(stats)
218
+ self.SNPCoverageDisplay.updateStatsLimit(stats)
136
219
  },
137
- setPileupDisplay(displayConfig: AnyConfigurationModel) {
220
+
221
+ /**
222
+ * #action
223
+ */
224
+ setPileupDisplay(configuration: AnyConfigurationModel) {
138
225
  self.PileupDisplay = {
139
226
  type: 'LinearPileupDisplay',
140
- configuration: displayConfig,
227
+ configuration,
141
228
  }
142
229
  },
230
+ /**
231
+ * #action
232
+ */
143
233
  setHeight(displayHeight: number) {
144
234
  if (displayHeight > minDisplayHeight) {
145
235
  self.height = displayHeight
@@ -148,6 +238,9 @@ const stateModelFactory = (
148
238
  }
149
239
  return self.height
150
240
  },
241
+ /**
242
+ * #action
243
+ */
151
244
  resizeHeight(distance: number) {
152
245
  const oldHeight = self.height
153
246
  const newHeight = this.setHeight(self.height + distance)
@@ -218,6 +311,9 @@ const stateModelFactory = (
218
311
  }),
219
312
  )
220
313
  },
314
+ /**
315
+ * #action
316
+ */
221
317
  async renderSvg(opts: { rasterizeLayers?: boolean }) {
222
318
  const pileupHeight = self.height - self.SNPCoverageDisplay.height
223
319
  await when(() => self.PileupDisplay.ready)