@jbrowse/plugin-alignments 1.5.1 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AlignmentsFeatureDetail/index.d.ts +7 -4
- package/dist/AlignmentsTrack/index.d.ts +2 -0
- package/dist/BamAdapter/index.d.ts +2 -4
- package/dist/CramAdapter/index.d.ts +1 -4
- package/dist/HtsgetBamAdapter/HtsgetBamAdapter.d.ts +2 -1
- package/dist/HtsgetBamAdapter/index.d.ts +2 -4
- package/dist/LinearAlignmentsDisplay/index.d.ts +2 -3
- package/dist/LinearPileupDisplay/index.d.ts +2 -2
- package/dist/LinearPileupDisplay/model.d.ts +1 -2
- package/dist/LinearSNPCoverageDisplay/components/Tooltip.d.ts +1 -1
- package/dist/LinearSNPCoverageDisplay/index.d.ts +2 -2
- package/dist/LinearSNPCoverageDisplay/models/model.d.ts +1 -0
- package/dist/PileupRenderer/PileupRenderer.d.ts +20 -7
- package/dist/PileupRenderer/index.d.ts +2 -3
- package/dist/SNPCoverageAdapter/SNPCoverageAdapter.d.ts +38 -26
- package/dist/SNPCoverageAdapter/index.d.ts +1 -5
- package/dist/SNPCoverageRenderer/index.d.ts +3 -3
- package/dist/plugin-alignments.cjs.development.js +3750 -3644
- package/dist/plugin-alignments.cjs.development.js.map +1 -1
- package/dist/plugin-alignments.cjs.production.min.js +1 -1
- package/dist/plugin-alignments.cjs.production.min.js.map +1 -1
- package/dist/plugin-alignments.esm.js +3753 -3647
- package/dist/plugin-alignments.esm.js.map +1 -1
- package/package.json +4 -4
- package/src/AlignmentsFeatureDetail/{index.js → index.ts} +19 -3
- package/src/AlignmentsTrack/index.ts +36 -0
- package/src/BamAdapter/BamSlightlyLazyFeature.ts +9 -19
- package/src/BamAdapter/MismatchParser.test.ts +20 -0
- package/src/BamAdapter/MismatchParser.ts +6 -5
- package/src/BamAdapter/index.ts +11 -5
- package/src/CramAdapter/index.ts +11 -4
- package/src/HtsgetBamAdapter/HtsgetBamAdapter.ts +2 -2
- package/src/HtsgetBamAdapter/index.ts +18 -5
- package/src/LinearAlignmentsDisplay/index.ts +20 -3
- package/src/LinearAlignmentsDisplay/models/configSchema.test.js +8 -68
- package/src/LinearPileupDisplay/configSchema.test.js +2 -13
- package/src/LinearPileupDisplay/index.ts +19 -2
- package/src/LinearPileupDisplay/model.ts +15 -20
- package/src/LinearSNPCoverageDisplay/components/Tooltip.tsx +17 -12
- package/src/LinearSNPCoverageDisplay/index.ts +19 -2
- package/src/LinearSNPCoverageDisplay/models/configSchema.test.js +2 -13
- package/src/LinearSNPCoverageDisplay/models/model.ts +21 -0
- package/src/PileupRenderer/PileupRenderer.tsx +154 -128
- package/src/PileupRenderer/configSchema.ts +2 -2
- package/src/PileupRenderer/index.ts +16 -3
- package/src/SNPCoverageAdapter/SNPCoverageAdapter.ts +95 -25
- package/src/SNPCoverageAdapter/index.ts +17 -5
- package/src/SNPCoverageRenderer/SNPCoverageRenderer.ts +60 -13
- package/src/SNPCoverageRenderer/configSchema.js +5 -0
- package/src/SNPCoverageRenderer/index.ts +24 -0
- package/src/index.ts +39 -204
- package/src/SNPCoverageAdapter/SNPCoverageAdapter.test.ts +0 -275
- package/src/SNPCoverageAdapter/__snapshots__/SNPCoverageAdapter.test.ts.snap +0 -579
- package/src/SNPCoverageRenderer/index.js +0 -11
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
BaseFeatureDataAdapter,
|
|
3
3
|
BaseOptions,
|
|
4
4
|
} from '@jbrowse/core/data_adapters/BaseAdapter'
|
|
5
|
-
import { Region } from '@jbrowse/core/util/types'
|
|
5
|
+
import { AugmentedRegion as Region } from '@jbrowse/core/util/types'
|
|
6
6
|
import SimpleFeature, { Feature } from '@jbrowse/core/util/simpleFeature'
|
|
7
7
|
import { readConfObject } from '@jbrowse/core/configuration'
|
|
8
8
|
import SerializableFilterChain from '@jbrowse/core/pluggableElementTypes/renderers/util/serializableFilterChain'
|
|
@@ -81,7 +81,11 @@ export default class SNPCoverageAdapter extends BaseFeatureDataAdapter {
|
|
|
81
81
|
stream = stream.pipe(filter(f => filters.passes(f, opts)))
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
const bins = await this.generateCoverageBins(
|
|
84
|
+
const { bins, skipmap } = await this.generateCoverageBins(
|
|
85
|
+
stream,
|
|
86
|
+
region,
|
|
87
|
+
opts,
|
|
88
|
+
)
|
|
85
89
|
|
|
86
90
|
bins.forEach((bin, index) => {
|
|
87
91
|
if (bin.total) {
|
|
@@ -100,6 +104,23 @@ export default class SNPCoverageAdapter extends BaseFeatureDataAdapter {
|
|
|
100
104
|
}
|
|
101
105
|
})
|
|
102
106
|
|
|
107
|
+
// make fake features from the coverage
|
|
108
|
+
Object.entries(skipmap).forEach(([key, skip]) => {
|
|
109
|
+
observer.next(
|
|
110
|
+
new SimpleFeature({
|
|
111
|
+
id: key,
|
|
112
|
+
data: {
|
|
113
|
+
type: 'skip',
|
|
114
|
+
start: skip.start,
|
|
115
|
+
end: skip.end,
|
|
116
|
+
strand: skip.strand,
|
|
117
|
+
score: skip.score,
|
|
118
|
+
xs: skip.xs,
|
|
119
|
+
},
|
|
120
|
+
}),
|
|
121
|
+
)
|
|
122
|
+
})
|
|
123
|
+
|
|
103
124
|
observer.complete()
|
|
104
125
|
}, opts.signal)
|
|
105
126
|
}
|
|
@@ -126,9 +147,20 @@ export default class SNPCoverageAdapter extends BaseFeatureDataAdapter {
|
|
|
126
147
|
) {
|
|
127
148
|
const { colorBy } = opts
|
|
128
149
|
const { sequenceAdapter } = await this.configure()
|
|
129
|
-
const { refName, start, end } = region
|
|
150
|
+
const { originalRefName, refName, start, end } = region
|
|
130
151
|
const binMax = Math.ceil(region.end - region.start)
|
|
131
152
|
|
|
153
|
+
const skipmap = {} as {
|
|
154
|
+
[key: string]: {
|
|
155
|
+
score: number
|
|
156
|
+
feature: unknown
|
|
157
|
+
start: number
|
|
158
|
+
end: number
|
|
159
|
+
strand: number
|
|
160
|
+
xs: string
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
132
164
|
// bins contain cov feature if they contribute to coverage, or noncov which
|
|
133
165
|
// are interbase or other features that don't contribute to coverage.
|
|
134
166
|
// delskips are elements that don't contribute to coverage, but should be
|
|
@@ -148,13 +180,18 @@ export default class SNPCoverageAdapter extends BaseFeatureDataAdapter {
|
|
|
148
180
|
|
|
149
181
|
if (sequenceAdapter) {
|
|
150
182
|
const [feat] = await sequenceAdapter
|
|
151
|
-
.getFeatures({
|
|
183
|
+
.getFeatures({
|
|
184
|
+
refName: originalRefName || refName,
|
|
185
|
+
start,
|
|
186
|
+
end: end + 1,
|
|
187
|
+
assemblyName: 'na',
|
|
188
|
+
})
|
|
152
189
|
.pipe(toArray())
|
|
153
190
|
.toPromise()
|
|
154
191
|
regionSeq = feat?.get('seq')
|
|
155
192
|
}
|
|
156
193
|
|
|
157
|
-
|
|
194
|
+
const bins = await features
|
|
158
195
|
.pipe(
|
|
159
196
|
reduce((bins, feature) => {
|
|
160
197
|
const cigar = feature.get('CIGAR')
|
|
@@ -262,30 +299,61 @@ export default class SNPCoverageAdapter extends BaseFeatureDataAdapter {
|
|
|
262
299
|
|
|
263
300
|
// normal SNP based coloring
|
|
264
301
|
else {
|
|
265
|
-
const mismatches = feature.get('mismatches')
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
const
|
|
275
|
-
if (
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
302
|
+
const mismatches = feature.get('mismatches') as
|
|
303
|
+
| Mismatch[]
|
|
304
|
+
| undefined
|
|
305
|
+
|
|
306
|
+
if (mismatches) {
|
|
307
|
+
for (let i = 0; i < mismatches.length; i++) {
|
|
308
|
+
const mismatch = mismatches[i]
|
|
309
|
+
const mstart = fstart + mismatch.start
|
|
310
|
+
for (let j = mstart; j < mstart + mismatchLen(mismatch); j++) {
|
|
311
|
+
const epos = j - region.start
|
|
312
|
+
if (epos >= 0 && epos < bins.length) {
|
|
313
|
+
const bin = bins[epos]
|
|
314
|
+
const { base, type } = mismatch
|
|
315
|
+
const interbase = isInterbase(type)
|
|
316
|
+
if (!interbase) {
|
|
317
|
+
dec(bin, fstrand, 'ref', 'ref')
|
|
318
|
+
} else {
|
|
319
|
+
inc(bin, fstrand, 'noncov', type)
|
|
320
|
+
}
|
|
280
321
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
322
|
+
if (type === 'deletion' || type === 'skip') {
|
|
323
|
+
inc(bin, fstrand, 'delskips', type)
|
|
324
|
+
bin.total--
|
|
325
|
+
} else if (!interbase) {
|
|
326
|
+
inc(bin, fstrand, 'cov', base)
|
|
327
|
+
}
|
|
286
328
|
}
|
|
287
329
|
}
|
|
288
330
|
}
|
|
331
|
+
|
|
332
|
+
mismatches
|
|
333
|
+
.filter(mismatch => mismatch.type === 'skip')
|
|
334
|
+
.forEach(mismatch => {
|
|
335
|
+
const mstart = feature.get('start') + mismatch.start
|
|
336
|
+
const start = mstart
|
|
337
|
+
const end = mstart + mismatch.length
|
|
338
|
+
const strand = feature.get('strand')
|
|
339
|
+
const hash = `${start}_${end}_${strand}`
|
|
340
|
+
if (!skipmap[hash]) {
|
|
341
|
+
skipmap[hash] = {
|
|
342
|
+
feature: feature,
|
|
343
|
+
start,
|
|
344
|
+
end,
|
|
345
|
+
strand,
|
|
346
|
+
xs:
|
|
347
|
+
feature.get('xs') ||
|
|
348
|
+
feature.get('ts') ||
|
|
349
|
+
feature.get('tags').XS ||
|
|
350
|
+
feature.get('tags').TS,
|
|
351
|
+
score: 1,
|
|
352
|
+
}
|
|
353
|
+
} else {
|
|
354
|
+
skipmap[hash].score++
|
|
355
|
+
}
|
|
356
|
+
})
|
|
289
357
|
}
|
|
290
358
|
}
|
|
291
359
|
|
|
@@ -293,6 +361,8 @@ export default class SNPCoverageAdapter extends BaseFeatureDataAdapter {
|
|
|
293
361
|
}, initBins),
|
|
294
362
|
)
|
|
295
363
|
.toPromise()
|
|
364
|
+
|
|
365
|
+
return { bins, skipmap }
|
|
296
366
|
}
|
|
297
367
|
}
|
|
298
368
|
|
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
import PluginManager from '@jbrowse/core/PluginManager'
|
|
2
|
+
import AdapterType from '@jbrowse/core/pluggableElementTypes/AdapterType'
|
|
2
3
|
import configSchemaFactory from './configSchema'
|
|
3
4
|
import { capabilities } from './SNPCoverageAdapter'
|
|
4
5
|
|
|
5
6
|
export default (pluginManager: PluginManager) => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
pluginManager.addAdapterType(
|
|
8
|
+
() =>
|
|
9
|
+
new AdapterType({
|
|
10
|
+
name: 'SNPCoverageAdapter',
|
|
11
|
+
adapterMetadata: {
|
|
12
|
+
category: null,
|
|
13
|
+
displayName: null,
|
|
14
|
+
hiddenFromGUI: true,
|
|
15
|
+
description: null,
|
|
16
|
+
},
|
|
17
|
+
getAdapterClass: () =>
|
|
18
|
+
import('./SNPCoverageAdapter').then(r => r.default),
|
|
19
|
+
configSchema: configSchemaFactory(pluginManager),
|
|
20
|
+
adapterCapabilities: capabilities,
|
|
21
|
+
}),
|
|
22
|
+
)
|
|
11
23
|
}
|
|
@@ -2,6 +2,7 @@ import { createJBrowseTheme } from '@jbrowse/core/ui'
|
|
|
2
2
|
import { featureSpanPx } from '@jbrowse/core/util'
|
|
3
3
|
import { Feature } from '@jbrowse/core/util/simpleFeature'
|
|
4
4
|
import { readConfObject } from '@jbrowse/core/configuration'
|
|
5
|
+
import { bpSpanPx } from '@jbrowse/core/util'
|
|
5
6
|
import { RenderArgsDeserialized as FeatureRenderArgsDeserialized } from '@jbrowse/core/pluggableElementTypes/renderers/FeatureRendererType'
|
|
6
7
|
import {
|
|
7
8
|
getOrigin,
|
|
@@ -26,6 +27,16 @@ export interface RenderArgsDeserializedWithFeatures
|
|
|
26
27
|
modificationTagMap: Record<string, string>
|
|
27
28
|
}
|
|
28
29
|
|
|
30
|
+
type Counts = {
|
|
31
|
+
[key: string]: { total: number; strands: { [key: string]: number } }
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface SNPInfo {
|
|
35
|
+
cov: Counts
|
|
36
|
+
noncov: Counts
|
|
37
|
+
total: number
|
|
38
|
+
}
|
|
39
|
+
|
|
29
40
|
export default class SNPCoverageRenderer extends WiggleBaseRenderer {
|
|
30
41
|
// note: the snps are drawn on linear scale even if the data is drawn in log
|
|
31
42
|
// scape hence the two different scales being used
|
|
@@ -37,13 +48,13 @@ export default class SNPCoverageRenderer extends WiggleBaseRenderer {
|
|
|
37
48
|
features,
|
|
38
49
|
regions,
|
|
39
50
|
bpPerPx,
|
|
51
|
+
displayCrossHatches,
|
|
52
|
+
modificationTagMap,
|
|
40
53
|
scaleOpts,
|
|
41
54
|
height: unadjustedHeight,
|
|
42
55
|
theme: configTheme,
|
|
43
56
|
config: cfg,
|
|
44
|
-
displayCrossHatches,
|
|
45
57
|
ticks: { values },
|
|
46
|
-
modificationTagMap,
|
|
47
58
|
} = props
|
|
48
59
|
const theme = createJBrowseTheme(configTheme)
|
|
49
60
|
const [region] = regions
|
|
@@ -63,6 +74,7 @@ export default class SNPCoverageRenderer extends WiggleBaseRenderer {
|
|
|
63
74
|
|
|
64
75
|
const indicatorThreshold = readConfObject(cfg, 'indicatorThreshold')
|
|
65
76
|
const drawInterbaseCounts = readConfObject(cfg, 'drawInterbaseCounts')
|
|
77
|
+
const drawArcs = readConfObject(cfg, 'drawArcs')
|
|
66
78
|
const drawIndicators = readConfObject(cfg, 'drawIndicators')
|
|
67
79
|
|
|
68
80
|
// get the y coordinate that we are plotting at, this can be log scale
|
|
@@ -87,15 +99,19 @@ export default class SNPCoverageRenderer extends WiggleBaseRenderer {
|
|
|
87
99
|
ref: 'lightgrey',
|
|
88
100
|
}
|
|
89
101
|
|
|
102
|
+
const feats = [...features.values()]
|
|
103
|
+
const coverage = feats.filter(f => f.get('type') !== 'skip')
|
|
104
|
+
const skips = feats.filter(f => f.get('type') === 'skip')
|
|
105
|
+
|
|
90
106
|
// Use two pass rendering, which helps in visualizing the SNPs at higher
|
|
91
107
|
// bpPerPx First pass: draw the gray background
|
|
92
108
|
ctx.fillStyle = colorForBase.total
|
|
93
|
-
|
|
109
|
+
coverage.forEach(feature => {
|
|
94
110
|
const [leftPx, rightPx] = featureSpanPx(feature, region, bpPerPx)
|
|
95
111
|
const w = rightPx - leftPx + 0.3
|
|
96
112
|
const score = feature.get('score') as number
|
|
97
113
|
ctx.fillRect(leftPx, toY(score), w, toHeight(score))
|
|
98
|
-
}
|
|
114
|
+
})
|
|
99
115
|
ctx.fillStyle = 'grey'
|
|
100
116
|
ctx.beginPath()
|
|
101
117
|
ctx.lineTo(0, 0)
|
|
@@ -105,16 +121,10 @@ export default class SNPCoverageRenderer extends WiggleBaseRenderer {
|
|
|
105
121
|
// Second pass: draw the SNP data, and add a minimum feature width of 1px
|
|
106
122
|
// which can be wider than the actual bpPerPx This reduces overdrawing of
|
|
107
123
|
// the grey background over the SNPs
|
|
108
|
-
|
|
124
|
+
coverage.forEach(feature => {
|
|
109
125
|
const [leftPx, rightPx] = featureSpanPx(feature, region, bpPerPx)
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
113
|
-
const snpinfo = feature.get('snpinfo') as {
|
|
114
|
-
cov: Counts
|
|
115
|
-
noncov: Counts
|
|
116
|
-
total: number
|
|
117
|
-
}
|
|
126
|
+
|
|
127
|
+
const snpinfo = feature.get('snpinfo') as SNPInfo
|
|
118
128
|
const w = Math.max(rightPx - leftPx + 0.3, 1)
|
|
119
129
|
const totalScore = snpinfo.total
|
|
120
130
|
|
|
@@ -175,6 +185,43 @@ export default class SNPCoverageRenderer extends WiggleBaseRenderer {
|
|
|
175
185
|
ctx.fill()
|
|
176
186
|
}
|
|
177
187
|
}
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
ctx.globalAlpha = 0.7
|
|
191
|
+
|
|
192
|
+
if (drawArcs) {
|
|
193
|
+
skips.forEach(f => {
|
|
194
|
+
const [left, right] = bpSpanPx(
|
|
195
|
+
f.get('start'),
|
|
196
|
+
f.get('end'),
|
|
197
|
+
region,
|
|
198
|
+
bpPerPx,
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
ctx.beginPath()
|
|
202
|
+
const str = f.get('strand') as number
|
|
203
|
+
const xs = f.get('xs') as string
|
|
204
|
+
const pos = 'rgb(255,200,200)'
|
|
205
|
+
const neg = 'rgb(200,200,255)'
|
|
206
|
+
const neutral = 'rgb(200,200,200)'
|
|
207
|
+
|
|
208
|
+
if (xs === '+') {
|
|
209
|
+
ctx.strokeStyle = pos
|
|
210
|
+
} else if (xs === '-') {
|
|
211
|
+
ctx.strokeStyle = neg
|
|
212
|
+
} else if (str === 1) {
|
|
213
|
+
ctx.strokeStyle = pos
|
|
214
|
+
} else if (str === -1) {
|
|
215
|
+
ctx.strokeStyle = neg
|
|
216
|
+
} else {
|
|
217
|
+
ctx.strokeStyle = neutral
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
ctx.lineWidth = Math.log(f.get('score') + 1)
|
|
221
|
+
ctx.moveTo(left, height - offset * 2)
|
|
222
|
+
ctx.bezierCurveTo(left, 0, right, 0, right, height - offset * 2)
|
|
223
|
+
ctx.stroke()
|
|
224
|
+
})
|
|
178
225
|
}
|
|
179
226
|
|
|
180
227
|
if (displayCrossHatches) {
|
|
@@ -14,6 +14,11 @@ export default ConfigurationSchema(
|
|
|
14
14
|
'the proportion of reads containing a insertion/clip indicator',
|
|
15
15
|
defaultValue: 0.3,
|
|
16
16
|
},
|
|
17
|
+
drawArcs: {
|
|
18
|
+
type: 'boolean',
|
|
19
|
+
description: 'Draw sashimi-style arcs for intron features',
|
|
20
|
+
defaultValue: true,
|
|
21
|
+
},
|
|
17
22
|
drawInterbaseCounts: {
|
|
18
23
|
type: 'boolean',
|
|
19
24
|
description:
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ConfigurationSchema } from '@jbrowse/core/configuration'
|
|
2
|
+
import ConfigSchema from './configSchema'
|
|
3
|
+
import PluginManager from '@jbrowse/core/PluginManager'
|
|
4
|
+
import SNPCoverageRenderer from './SNPCoverageRenderer'
|
|
5
|
+
|
|
6
|
+
import { WiggleRendering } from '@jbrowse/plugin-wiggle'
|
|
7
|
+
|
|
8
|
+
export const configSchema = ConfigurationSchema(
|
|
9
|
+
'SNPCoverageRenderer',
|
|
10
|
+
{},
|
|
11
|
+
{ baseConfiguration: ConfigSchema, explicitlyTyped: true },
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
export default function register(pluginManager: PluginManager) {
|
|
15
|
+
pluginManager.addRendererType(
|
|
16
|
+
() =>
|
|
17
|
+
new SNPCoverageRenderer({
|
|
18
|
+
name: 'SNPCoverageRenderer',
|
|
19
|
+
ReactComponent: WiggleRendering,
|
|
20
|
+
configSchema,
|
|
21
|
+
pluginManager,
|
|
22
|
+
}),
|
|
23
|
+
)
|
|
24
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,49 +1,21 @@
|
|
|
1
|
-
import { lazy } from 'react'
|
|
2
|
-
import { ConfigurationSchema } from '@jbrowse/core/configuration'
|
|
3
|
-
import AdapterType from '@jbrowse/core/pluggableElementTypes/AdapterType'
|
|
4
|
-
import DisplayType from '@jbrowse/core/pluggableElementTypes/DisplayType'
|
|
5
|
-
import {
|
|
6
|
-
createBaseTrackConfig,
|
|
7
|
-
createBaseTrackModel,
|
|
8
|
-
} from '@jbrowse/core/pluggableElementTypes/models'
|
|
9
1
|
import { FileLocation } from '@jbrowse/core/util/types'
|
|
10
|
-
import TrackType from '@jbrowse/core/pluggableElementTypes/TrackType'
|
|
11
|
-
import WidgetType from '@jbrowse/core/pluggableElementTypes/WidgetType'
|
|
12
2
|
import Plugin from '@jbrowse/core/Plugin'
|
|
13
3
|
import PluginManager from '@jbrowse/core/PluginManager'
|
|
14
|
-
import { BaseLinearDisplayComponent } from '@jbrowse/plugin-linear-genome-view'
|
|
15
|
-
import { LinearWiggleDisplayReactComponent } from '@jbrowse/plugin-wiggle'
|
|
16
|
-
import {
|
|
17
|
-
configSchema as alignmentsFeatureDetailConfigSchema,
|
|
18
|
-
stateModelFactory as alignmentsFeatureDetailStateModelFactory,
|
|
19
|
-
} from './AlignmentsFeatureDetail'
|
|
20
|
-
import BamAdapterF from './BamAdapter'
|
|
21
4
|
import * as MismatchParser from './BamAdapter/MismatchParser'
|
|
22
|
-
import CramAdapterF from './CramAdapter'
|
|
23
|
-
import HtsgetBamAdapterF from './HtsgetBamAdapter'
|
|
24
|
-
import {
|
|
25
|
-
configSchemaFactory as linearAligmentsDisplayConfigSchemaFactory,
|
|
26
|
-
modelFactory as linearAlignmentsDisplayModelFactory,
|
|
27
|
-
ReactComponent as LinearAlignmentsDisplayReactComponent,
|
|
28
|
-
} from './LinearAlignmentsDisplay'
|
|
29
|
-
import {
|
|
30
|
-
configSchemaFactory as linearPileupDisplayConfigSchemaFactory,
|
|
31
|
-
modelFactory as linearPileupDisplayModelFactory,
|
|
32
|
-
} from './LinearPileupDisplay'
|
|
33
5
|
import { LinearPileupDisplayModel } from './LinearPileupDisplay/model'
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
import PileupRenderer, {
|
|
39
|
-
configSchema as pileupRendererConfigSchema,
|
|
40
|
-
ReactComponent as PileupRendererReactComponent,
|
|
41
|
-
} from './PileupRenderer'
|
|
6
|
+
|
|
7
|
+
import BamAdapterF from './CramAdapter'
|
|
8
|
+
import CramAdapterF from './BamAdapter'
|
|
9
|
+
import HtsgetBamAdapterF from './HtsgetBamAdapter'
|
|
42
10
|
import SNPCoverageAdapterF from './SNPCoverageAdapter'
|
|
43
|
-
import SNPCoverageRenderer
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
11
|
+
import SNPCoverageRendererF from './SNPCoverageRenderer'
|
|
12
|
+
import PileupRendererF from './PileupRenderer'
|
|
13
|
+
import LinearAlignmentsDisplayF from './LinearAlignmentsDisplay'
|
|
14
|
+
import LinearSNPCoverageDisplayF from './LinearSNPCoverageDisplay'
|
|
15
|
+
import LinearPileupDisplayF from './LinearPileupDisplay'
|
|
16
|
+
import AlignmentsTrackF from './AlignmentsTrack'
|
|
17
|
+
import AlignmentsFeatureWidgetF from './AlignmentsFeatureDetail'
|
|
18
|
+
|
|
47
19
|
import {
|
|
48
20
|
PileupGetGlobalValueForTag,
|
|
49
21
|
PileupGetVisibleModifications,
|
|
@@ -51,8 +23,8 @@ import {
|
|
|
51
23
|
import {
|
|
52
24
|
makeIndex,
|
|
53
25
|
makeIndexType,
|
|
54
|
-
AdapterGuesser,
|
|
55
26
|
getFileName,
|
|
27
|
+
AdapterGuesser,
|
|
56
28
|
TrackTypeGuesser,
|
|
57
29
|
} from '@jbrowse/core/util/tracks'
|
|
58
30
|
|
|
@@ -63,93 +35,19 @@ export default class AlignmentsPlugin extends Plugin {
|
|
|
63
35
|
name = 'AlignmentsPlugin'
|
|
64
36
|
|
|
65
37
|
install(pluginManager: PluginManager) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
),
|
|
80
|
-
})
|
|
81
|
-
const linearAlignmentsDisplay = pluginManager.getDisplayType(
|
|
82
|
-
'LinearAlignmentsDisplay',
|
|
83
|
-
)
|
|
84
|
-
// Add LinearAlignmentsDisplay here so that it has priority over the other
|
|
85
|
-
// linear displays (defaults to order the displays are added, but we have
|
|
86
|
-
// to add the Pileup and SNPCoverage displays first).
|
|
87
|
-
track.addDisplayType(linearAlignmentsDisplay)
|
|
88
|
-
return track
|
|
89
|
-
})
|
|
90
|
-
pluginManager.addDisplayType(() => {
|
|
91
|
-
const configSchema = linearPileupDisplayConfigSchemaFactory(pluginManager)
|
|
92
|
-
return new DisplayType({
|
|
93
|
-
name: 'LinearPileupDisplay',
|
|
94
|
-
configSchema,
|
|
95
|
-
stateModel: linearPileupDisplayModelFactory(
|
|
96
|
-
pluginManager,
|
|
97
|
-
configSchema,
|
|
98
|
-
),
|
|
99
|
-
trackType: 'AlignmentsTrack',
|
|
100
|
-
viewType: 'LinearGenomeView',
|
|
101
|
-
ReactComponent: BaseLinearDisplayComponent,
|
|
102
|
-
})
|
|
103
|
-
})
|
|
104
|
-
pluginManager.addDisplayType(() => {
|
|
105
|
-
const configSchema =
|
|
106
|
-
linearSNPCoverageDisplayConfigSchemaFactory(pluginManager)
|
|
107
|
-
return new DisplayType({
|
|
108
|
-
name: 'LinearSNPCoverageDisplay',
|
|
109
|
-
configSchema,
|
|
110
|
-
stateModel: linearSNPCoverageDisplayModelFactory(
|
|
111
|
-
pluginManager,
|
|
112
|
-
configSchema,
|
|
113
|
-
),
|
|
114
|
-
trackType: 'AlignmentsTrack',
|
|
115
|
-
viewType: 'LinearGenomeView',
|
|
116
|
-
ReactComponent: LinearWiggleDisplayReactComponent,
|
|
117
|
-
})
|
|
118
|
-
})
|
|
119
|
-
pluginManager.addDisplayType(() => {
|
|
120
|
-
const configSchema =
|
|
121
|
-
linearAligmentsDisplayConfigSchemaFactory(pluginManager)
|
|
122
|
-
return new DisplayType({
|
|
123
|
-
name: 'LinearAlignmentsDisplay',
|
|
124
|
-
configSchema,
|
|
125
|
-
stateModel: linearAlignmentsDisplayModelFactory(
|
|
126
|
-
pluginManager,
|
|
127
|
-
configSchema,
|
|
128
|
-
),
|
|
129
|
-
trackType: 'AlignmentsTrack',
|
|
130
|
-
viewType: 'LinearGenomeView',
|
|
131
|
-
ReactComponent: LinearAlignmentsDisplayReactComponent,
|
|
132
|
-
})
|
|
133
|
-
})
|
|
134
|
-
pluginManager.addWidgetType(
|
|
135
|
-
() =>
|
|
136
|
-
new WidgetType({
|
|
137
|
-
name: 'AlignmentsFeatureWidget',
|
|
138
|
-
heading: 'Feature details',
|
|
139
|
-
configSchema: alignmentsFeatureDetailConfigSchema,
|
|
140
|
-
stateModel: alignmentsFeatureDetailStateModelFactory(pluginManager),
|
|
141
|
-
ReactComponent: lazy(
|
|
142
|
-
() => import('./AlignmentsFeatureDetail/AlignmentsFeatureDetail'),
|
|
143
|
-
),
|
|
144
|
-
}),
|
|
145
|
-
)
|
|
146
|
-
pluginManager.addAdapterType(
|
|
147
|
-
() =>
|
|
148
|
-
new AdapterType({
|
|
149
|
-
name: 'BamAdapter',
|
|
150
|
-
...pluginManager.load(BamAdapterF),
|
|
151
|
-
}),
|
|
152
|
-
)
|
|
38
|
+
;[
|
|
39
|
+
CramAdapterF,
|
|
40
|
+
BamAdapterF,
|
|
41
|
+
LinearPileupDisplayF,
|
|
42
|
+
LinearSNPCoverageDisplayF,
|
|
43
|
+
AlignmentsTrackF,
|
|
44
|
+
SNPCoverageAdapterF,
|
|
45
|
+
HtsgetBamAdapterF,
|
|
46
|
+
PileupRendererF,
|
|
47
|
+
SNPCoverageRendererF,
|
|
48
|
+
LinearAlignmentsDisplayF,
|
|
49
|
+
AlignmentsFeatureWidgetF,
|
|
50
|
+
].map(f => f(pluginManager))
|
|
153
51
|
|
|
154
52
|
pluginManager.addToExtensionPoint(
|
|
155
53
|
'Core-guessAdapterForLocation',
|
|
@@ -159,56 +57,21 @@ export default class AlignmentsPlugin extends Plugin {
|
|
|
159
57
|
index?: FileLocation,
|
|
160
58
|
adapterHint?: string,
|
|
161
59
|
) => {
|
|
162
|
-
const regexGuess = /\.
|
|
163
|
-
const adapterName = '
|
|
60
|
+
const regexGuess = /\.cram$/i
|
|
61
|
+
const adapterName = 'CramAdapter'
|
|
164
62
|
const fileName = getFileName(file)
|
|
165
|
-
const indexName = index && getFileName(index)
|
|
166
63
|
if (regexGuess.test(fileName) || adapterHint === adapterName) {
|
|
167
64
|
return {
|
|
168
65
|
type: adapterName,
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
location: index || makeIndex(file, '.bai'),
|
|
172
|
-
indexType: makeIndexType(indexName, 'CSI', 'BAI'),
|
|
173
|
-
},
|
|
66
|
+
cramLocation: file,
|
|
67
|
+
craiLocation: index || makeIndex(file, '.crai'),
|
|
174
68
|
}
|
|
175
69
|
}
|
|
176
70
|
return adapterGuesser(file, index, adapterHint)
|
|
177
71
|
}
|
|
178
72
|
},
|
|
179
73
|
)
|
|
180
|
-
pluginManager.addToExtensionPoint(
|
|
181
|
-
'Core-guessTrackTypeForLocation',
|
|
182
|
-
(trackTypeGuesser: TrackTypeGuesser) => {
|
|
183
|
-
return (adapterName: string) => {
|
|
184
|
-
if (adapterName === 'BamAdapter') {
|
|
185
|
-
return 'AlignmentsTrack'
|
|
186
|
-
}
|
|
187
|
-
return trackTypeGuesser(adapterName)
|
|
188
|
-
}
|
|
189
|
-
},
|
|
190
|
-
)
|
|
191
74
|
|
|
192
|
-
pluginManager.addAdapterType(
|
|
193
|
-
() =>
|
|
194
|
-
new AdapterType({
|
|
195
|
-
name: 'SNPCoverageAdapter',
|
|
196
|
-
adapterMetadata: {
|
|
197
|
-
category: null,
|
|
198
|
-
displayName: null,
|
|
199
|
-
hiddenFromGUI: true,
|
|
200
|
-
description: null,
|
|
201
|
-
},
|
|
202
|
-
...pluginManager.load(SNPCoverageAdapterF),
|
|
203
|
-
}),
|
|
204
|
-
)
|
|
205
|
-
pluginManager.addAdapterType(
|
|
206
|
-
() =>
|
|
207
|
-
new AdapterType({
|
|
208
|
-
name: 'CramAdapter',
|
|
209
|
-
...pluginManager.load(CramAdapterF),
|
|
210
|
-
}),
|
|
211
|
-
)
|
|
212
75
|
pluginManager.addToExtensionPoint(
|
|
213
76
|
'Core-guessAdapterForLocation',
|
|
214
77
|
(adapterGuesser: AdapterGuesser) => {
|
|
@@ -217,14 +80,18 @@ export default class AlignmentsPlugin extends Plugin {
|
|
|
217
80
|
index?: FileLocation,
|
|
218
81
|
adapterHint?: string,
|
|
219
82
|
) => {
|
|
220
|
-
const regexGuess = /\.
|
|
221
|
-
const adapterName = '
|
|
83
|
+
const regexGuess = /\.bam$/i
|
|
84
|
+
const adapterName = 'BamAdapter'
|
|
222
85
|
const fileName = getFileName(file)
|
|
86
|
+
const indexName = index && getFileName(index)
|
|
223
87
|
if (regexGuess.test(fileName) || adapterHint === adapterName) {
|
|
224
88
|
return {
|
|
225
89
|
type: adapterName,
|
|
226
|
-
|
|
227
|
-
|
|
90
|
+
bamLocation: file,
|
|
91
|
+
index: {
|
|
92
|
+
location: index || makeIndex(file, '.bai'),
|
|
93
|
+
indexType: makeIndexType(indexName, 'CSI', 'BAI'),
|
|
94
|
+
},
|
|
228
95
|
}
|
|
229
96
|
}
|
|
230
97
|
return adapterGuesser(file, index, adapterHint)
|
|
@@ -235,7 +102,7 @@ export default class AlignmentsPlugin extends Plugin {
|
|
|
235
102
|
'Core-guessTrackTypeForLocation',
|
|
236
103
|
(trackTypeGuesser: TrackTypeGuesser) => {
|
|
237
104
|
return (adapterName: string) => {
|
|
238
|
-
if (adapterName === 'CramAdapter') {
|
|
105
|
+
if (adapterName === 'BamAdapter' || adapterName === 'CramAdapter') {
|
|
239
106
|
return 'AlignmentsTrack'
|
|
240
107
|
}
|
|
241
108
|
return trackTypeGuesser(adapterName)
|
|
@@ -243,38 +110,6 @@ export default class AlignmentsPlugin extends Plugin {
|
|
|
243
110
|
},
|
|
244
111
|
)
|
|
245
112
|
|
|
246
|
-
pluginManager.addAdapterType(
|
|
247
|
-
() =>
|
|
248
|
-
new AdapterType({
|
|
249
|
-
name: 'HtsgetBamAdapter',
|
|
250
|
-
adapterMetadata: {
|
|
251
|
-
category: null,
|
|
252
|
-
hiddenFromGUI: true,
|
|
253
|
-
displayName: null,
|
|
254
|
-
description: null,
|
|
255
|
-
},
|
|
256
|
-
...pluginManager.load(HtsgetBamAdapterF),
|
|
257
|
-
}),
|
|
258
|
-
)
|
|
259
|
-
pluginManager.addRendererType(
|
|
260
|
-
() =>
|
|
261
|
-
new PileupRenderer({
|
|
262
|
-
name: 'PileupRenderer',
|
|
263
|
-
ReactComponent: PileupRendererReactComponent,
|
|
264
|
-
configSchema: pileupRendererConfigSchema,
|
|
265
|
-
pluginManager,
|
|
266
|
-
}),
|
|
267
|
-
)
|
|
268
|
-
pluginManager.addRendererType(
|
|
269
|
-
() =>
|
|
270
|
-
new SNPCoverageRenderer({
|
|
271
|
-
name: 'SNPCoverageRenderer',
|
|
272
|
-
ReactComponent: SNPCoverageRendererReactComponent,
|
|
273
|
-
configSchema: SNPCoverageRendererConfigSchema,
|
|
274
|
-
pluginManager,
|
|
275
|
-
}),
|
|
276
|
-
)
|
|
277
|
-
|
|
278
113
|
pluginManager.addRpcMethod(
|
|
279
114
|
() => new PileupGetGlobalValueForTag(pluginManager),
|
|
280
115
|
)
|