@jbrowse/plugin-alignments 1.7.7 → 1.7.10
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/dist/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +13 -3
- package/dist/AlignmentsFeatureDetail/index.d.ts +28 -3
- package/dist/AlignmentsFeatureDetail/index.js +6 -17
- package/dist/BamAdapter/BamAdapter.d.ts +1 -1
- package/dist/BamAdapter/BamAdapter.js +3 -3
- package/dist/BamAdapter/MismatchParser.d.ts +2 -5
- package/dist/BamAdapter/MismatchParser.js +108 -46
- package/dist/BamAdapter/MismatchParser.test.js +6 -14
- package/dist/CramAdapter/CramAdapter.d.ts +10 -9
- package/dist/CramAdapter/CramAdapter.js +6 -6
- package/dist/CramAdapter/CramSlightlyLazyFeature.js +35 -30
- package/dist/LinearPileupDisplay/model.d.ts +6 -3
- package/dist/LinearPileupDisplay/model.js +132 -51
- package/dist/LinearSNPCoverageDisplay/components/Tooltip.js +37 -17
- package/dist/LinearSNPCoverageDisplay/models/model.d.ts +2 -2
- package/dist/LinearSNPCoverageDisplay/models/model.js +1 -1
- package/dist/PileupRenderer/PileupLayoutSession.d.ts +3 -0
- package/dist/PileupRenderer/PileupLayoutSession.js +3 -1
- package/dist/PileupRenderer/PileupRenderer.d.ts +66 -9
- package/dist/PileupRenderer/PileupRenderer.js +296 -258
- package/dist/PileupRenderer/configSchema.js +2 -2
- package/dist/SNPCoverageAdapter/SNPCoverageAdapter.d.ts +6 -6
- package/dist/SNPCoverageAdapter/SNPCoverageAdapter.js +95 -96
- package/dist/SNPCoverageRenderer/configSchema.d.ts +1 -1
- package/package.json +3 -3
- package/src/AlignmentsFeatureDetail/AlignmentsFeatureDetail.tsx +14 -3
- package/src/AlignmentsFeatureDetail/index.ts +7 -17
- package/src/BamAdapter/BamAdapter.ts +3 -3
- package/src/BamAdapter/MismatchParser.test.ts +5 -7
- package/src/BamAdapter/MismatchParser.ts +72 -59
- package/src/CramAdapter/CramAdapter.ts +14 -10
- package/src/CramAdapter/CramSlightlyLazyFeature.ts +84 -91
- package/src/LinearPileupDisplay/model.ts +76 -24
- package/src/LinearSNPCoverageDisplay/components/Tooltip.tsx +41 -20
- package/src/LinearSNPCoverageDisplay/models/model.ts +1 -1
- package/src/PileupRenderer/PileupLayoutSession.ts +6 -1
- package/src/PileupRenderer/PileupRenderer.tsx +413 -225
- package/src/PileupRenderer/configSchema.ts +2 -2
- package/src/SNPCoverageAdapter/SNPCoverageAdapter.ts +89 -76
|
@@ -31,8 +31,8 @@ export default ConfigurationSchema(
|
|
|
31
31
|
minSubfeatureWidth: {
|
|
32
32
|
type: 'number',
|
|
33
33
|
description:
|
|
34
|
-
'the minimum width in px for a pileup mismatch feature. use for increasing mismatch marker widths when zoomed out
|
|
35
|
-
defaultValue: 0,
|
|
34
|
+
'the minimum width in px for a pileup mismatch feature. use for increasing/decreasing mismatch marker widths when zoomed out, e.g. 0 or 1',
|
|
35
|
+
defaultValue: 0.7,
|
|
36
36
|
},
|
|
37
37
|
maxHeight: {
|
|
38
38
|
type: 'integer',
|
|
@@ -30,22 +30,16 @@ function isInterbase(type: string) {
|
|
|
30
30
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
31
31
|
function inc(bin: any, strand: number, type: string, field: string) {
|
|
32
32
|
let thisBin = bin[type][field]
|
|
33
|
-
if (
|
|
33
|
+
if (thisBin === undefined) {
|
|
34
34
|
thisBin = bin[type][field] = {
|
|
35
35
|
total: 0,
|
|
36
|
-
|
|
36
|
+
'-1': 0,
|
|
37
|
+
'0': 0,
|
|
38
|
+
'1': 0,
|
|
37
39
|
}
|
|
38
40
|
}
|
|
39
41
|
thisBin.total++
|
|
40
|
-
thisBin
|
|
41
|
-
}
|
|
42
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
43
|
-
function dec(bin: any, strand: number, type: string, field: string) {
|
|
44
|
-
if (!bin[type][field]) {
|
|
45
|
-
bin[type][field] = { total: 0, strands: { '-1': 0, '0': 0, '1': 0 } }
|
|
46
|
-
}
|
|
47
|
-
bin[type][field].total--
|
|
48
|
-
bin[type][field].strands[strand]--
|
|
42
|
+
thisBin[strand]++
|
|
49
43
|
}
|
|
50
44
|
|
|
51
45
|
export default class SNPCoverageAdapter extends BaseFeatureDataAdapter {
|
|
@@ -172,43 +166,56 @@ export default class SNPCoverageAdapter extends BaseFeatureDataAdapter {
|
|
|
172
166
|
: undefined
|
|
173
167
|
|
|
174
168
|
const bins = [] as {
|
|
169
|
+
refbase?: string
|
|
175
170
|
total: number
|
|
171
|
+
all: number
|
|
172
|
+
ref: number
|
|
173
|
+
'-1': 0
|
|
174
|
+
'0': 0
|
|
175
|
+
'1': 0
|
|
176
176
|
lowqual: BinType
|
|
177
177
|
cov: BinType
|
|
178
178
|
delskips: BinType
|
|
179
179
|
noncov: BinType
|
|
180
|
-
ref: BinType
|
|
181
180
|
}[]
|
|
182
181
|
|
|
183
182
|
for (let i = 0; i < features.length; i++) {
|
|
184
183
|
const feature = features[i]
|
|
185
|
-
const ops = parseCigar(feature.get('CIGAR'))
|
|
186
184
|
const fstart = feature.get('start')
|
|
187
185
|
const fend = feature.get('end')
|
|
188
|
-
const fstrand = feature.get('strand')
|
|
186
|
+
const fstrand = feature.get('strand') as -1 | 0 | 1
|
|
189
187
|
|
|
190
|
-
for (let j = fstart; j < fend; j++) {
|
|
188
|
+
for (let j = fstart; j < fend + 1; j++) {
|
|
191
189
|
const i = j - region.start
|
|
192
190
|
if (i >= 0 && i < binMax) {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
191
|
+
if (bins[i] === undefined) {
|
|
192
|
+
bins[i] = {
|
|
193
|
+
total: 0,
|
|
194
|
+
all: 0,
|
|
195
|
+
ref: 0,
|
|
196
|
+
'-1': 0,
|
|
197
|
+
'0': 0,
|
|
198
|
+
'1': 0,
|
|
199
|
+
lowqual: {} as BinType,
|
|
200
|
+
cov: {} as BinType,
|
|
201
|
+
delskips: {} as BinType,
|
|
202
|
+
noncov: {} as BinType,
|
|
203
|
+
}
|
|
200
204
|
}
|
|
201
205
|
if (j !== fend) {
|
|
202
|
-
|
|
203
|
-
|
|
206
|
+
bins[i].total++
|
|
207
|
+
bins[i].all++
|
|
208
|
+
bins[i].ref++
|
|
209
|
+
bins[i][fstrand]++
|
|
204
210
|
}
|
|
205
|
-
bins[i] = bin
|
|
206
211
|
}
|
|
207
212
|
}
|
|
208
213
|
|
|
209
214
|
if (colorBy?.type === 'modifications') {
|
|
210
215
|
const seq = feature.get('seq') as string
|
|
211
216
|
const mm = (getTagAlt(feature, 'MM', 'Mm') as string) || ''
|
|
217
|
+
const ops = parseCigar(feature.get('CIGAR'))
|
|
218
|
+
const fend = feature.get('end')
|
|
212
219
|
|
|
213
220
|
getModificationPositions(mm, seq, fstrand).forEach(
|
|
214
221
|
({ type, positions }) => {
|
|
@@ -217,7 +224,13 @@ export default class SNPCoverageAdapter extends BaseFeatureDataAdapter {
|
|
|
217
224
|
const epos = pos + fstart - region.start
|
|
218
225
|
if (epos >= 0 && epos < bins.length && pos + fstart < fend) {
|
|
219
226
|
const bin = bins[epos]
|
|
220
|
-
|
|
227
|
+
if (bin) {
|
|
228
|
+
inc(bin, fstrand, 'cov', mod)
|
|
229
|
+
} else {
|
|
230
|
+
console.warn(
|
|
231
|
+
'Undefined position in modifications snpcoverage encountered',
|
|
232
|
+
)
|
|
233
|
+
}
|
|
221
234
|
}
|
|
222
235
|
}
|
|
223
236
|
},
|
|
@@ -235,6 +248,7 @@ export default class SNPCoverageAdapter extends BaseFeatureDataAdapter {
|
|
|
235
248
|
const seq = feature.get('seq')
|
|
236
249
|
const mm = getTagAlt(feature, 'MM', 'Mm') || ''
|
|
237
250
|
const methBins = new Array(region.end - region.start).fill(0)
|
|
251
|
+
const ops = parseCigar(feature.get('CIGAR'))
|
|
238
252
|
|
|
239
253
|
getModificationPositions(mm, seq, fstrand).forEach(
|
|
240
254
|
({ type, positions }) => {
|
|
@@ -263,13 +277,17 @@ export default class SNPCoverageAdapter extends BaseFeatureDataAdapter {
|
|
|
263
277
|
if (methBins[i] || methBins[i + 1]) {
|
|
264
278
|
inc(bin, fstrand, 'cov', 'meth')
|
|
265
279
|
inc(bin1, fstrand, 'cov', 'meth')
|
|
266
|
-
|
|
267
|
-
|
|
280
|
+
bins[i].ref--
|
|
281
|
+
bins[i][fstrand]--
|
|
282
|
+
bins[i + 1].ref--
|
|
283
|
+
bins[i + 1][fstrand]--
|
|
268
284
|
} else {
|
|
269
285
|
inc(bin, fstrand, 'cov', 'unmeth')
|
|
270
286
|
inc(bin1, fstrand, 'cov', 'unmeth')
|
|
271
|
-
|
|
272
|
-
|
|
287
|
+
bins[i].ref--
|
|
288
|
+
bins[i][fstrand]--
|
|
289
|
+
bins[i + 1].ref--
|
|
290
|
+
bins[i + 1][fstrand]--
|
|
273
291
|
}
|
|
274
292
|
}
|
|
275
293
|
}
|
|
@@ -277,56 +295,51 @@ export default class SNPCoverageAdapter extends BaseFeatureDataAdapter {
|
|
|
277
295
|
}
|
|
278
296
|
|
|
279
297
|
// normal SNP based coloring
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
+
const mismatches = (feature.get('mismatches') as Mismatch[]) || []
|
|
299
|
+
const colorSNPs =
|
|
300
|
+
colorBy?.type !== 'modifications' && colorBy?.type !== 'methylation'
|
|
301
|
+
|
|
302
|
+
for (let i = 0; i < mismatches.length; i++) {
|
|
303
|
+
const mismatch = mismatches[i]
|
|
304
|
+
const mstart = fstart + mismatch.start
|
|
305
|
+
const mlen = mismatchLen(mismatch)
|
|
306
|
+
const mend = mstart + mlen
|
|
307
|
+
for (let j = mstart; j < mstart + mlen; j++) {
|
|
308
|
+
const epos = j - region.start
|
|
309
|
+
if (epos >= 0 && epos < bins.length) {
|
|
310
|
+
const bin = bins[epos]
|
|
311
|
+
const { base, type } = mismatch
|
|
312
|
+
const interbase = isInterbase(type)
|
|
313
|
+
if (!interbase) {
|
|
314
|
+
bin.ref--
|
|
315
|
+
bin[fstrand]--
|
|
316
|
+
} else {
|
|
317
|
+
inc(bin, fstrand, 'noncov', type)
|
|
318
|
+
}
|
|
298
319
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
}
|
|
320
|
+
if (type === 'deletion' || type === 'skip') {
|
|
321
|
+
inc(bin, fstrand, 'delskips', type)
|
|
322
|
+
bin.total--
|
|
323
|
+
} else if (!interbase && colorSNPs) {
|
|
324
|
+
inc(bin, fstrand, 'cov', base)
|
|
325
|
+
bin.refbase = mismatch.altbase
|
|
306
326
|
}
|
|
307
327
|
}
|
|
328
|
+
}
|
|
308
329
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
strand,
|
|
323
|
-
xs: getTag(feature, 'XS') || getTag(feature, 'TS'),
|
|
324
|
-
score: 1,
|
|
325
|
-
}
|
|
326
|
-
} else {
|
|
327
|
-
skipmap[hash].score++
|
|
328
|
-
}
|
|
329
|
-
})
|
|
330
|
+
if (mismatch.type === 'skip') {
|
|
331
|
+
const hash = `${mstart}_${mend}_${fstrand}`
|
|
332
|
+
if (skipmap[hash] === undefined) {
|
|
333
|
+
skipmap[hash] = {
|
|
334
|
+
feature: feature,
|
|
335
|
+
start: mstart,
|
|
336
|
+
end: mend,
|
|
337
|
+
strand: fstrand,
|
|
338
|
+
xs: getTag(feature, 'XS') || getTag(feature, 'TS'),
|
|
339
|
+
score: 0,
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
skipmap[hash].score++
|
|
330
343
|
}
|
|
331
344
|
}
|
|
332
345
|
}
|