@jbrowse/plugin-alignments 1.4.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.
Files changed (67) hide show
  1. package/dist/AlignmentsFeatureDetail/index.d.ts +7 -4
  2. package/dist/AlignmentsTrack/index.d.ts +2 -0
  3. package/dist/BamAdapter/index.d.ts +2 -4
  4. package/dist/CramAdapter/index.d.ts +1 -4
  5. package/dist/HtsgetBamAdapter/HtsgetBamAdapter.d.ts +2 -1
  6. package/dist/HtsgetBamAdapter/index.d.ts +2 -4
  7. package/dist/LinearAlignmentsDisplay/index.d.ts +2 -3
  8. package/dist/LinearAlignmentsDisplay/models/model.d.ts +6 -6
  9. package/dist/LinearPileupDisplay/index.d.ts +2 -2
  10. package/dist/LinearPileupDisplay/model.d.ts +9 -10
  11. package/dist/LinearSNPCoverageDisplay/components/Tooltip.d.ts +1 -1
  12. package/dist/LinearSNPCoverageDisplay/index.d.ts +2 -2
  13. package/dist/LinearSNPCoverageDisplay/models/model.d.ts +3 -2
  14. package/dist/PileupRPC/rpcMethods.d.ts +2 -16
  15. package/dist/PileupRenderer/PileupRenderer.d.ts +20 -7
  16. package/dist/PileupRenderer/index.d.ts +2 -3
  17. package/dist/SNPCoverageAdapter/SNPCoverageAdapter.d.ts +38 -26
  18. package/dist/SNPCoverageAdapter/index.d.ts +1 -5
  19. package/dist/SNPCoverageRenderer/index.d.ts +3 -3
  20. package/dist/plugin-alignments.cjs.development.js +4488 -4254
  21. package/dist/plugin-alignments.cjs.development.js.map +1 -1
  22. package/dist/plugin-alignments.cjs.production.min.js +1 -1
  23. package/dist/plugin-alignments.cjs.production.min.js.map +1 -1
  24. package/dist/plugin-alignments.esm.js +4485 -4251
  25. package/dist/plugin-alignments.esm.js.map +1 -1
  26. package/package.json +4 -4
  27. package/src/AlignmentsFeatureDetail/index.test.js +2 -4
  28. package/src/AlignmentsFeatureDetail/{index.js → index.ts} +19 -3
  29. package/src/AlignmentsTrack/index.ts +36 -0
  30. package/src/BamAdapter/BamAdapter.test.ts +8 -0
  31. package/src/BamAdapter/BamAdapter.ts +11 -5
  32. package/src/BamAdapter/BamSlightlyLazyFeature.ts +9 -19
  33. package/src/BamAdapter/MismatchParser.test.ts +24 -2
  34. package/src/BamAdapter/MismatchParser.ts +6 -5
  35. package/src/BamAdapter/configSchema.ts +5 -2
  36. package/src/BamAdapter/index.ts +11 -5
  37. package/src/CramAdapter/CramAdapter.test.ts +6 -0
  38. package/src/CramAdapter/CramAdapter.ts +4 -2
  39. package/src/CramAdapter/CramTestAdapters.ts +2 -1
  40. package/src/CramAdapter/configSchema.ts +8 -2
  41. package/src/CramAdapter/index.ts +11 -4
  42. package/src/HtsgetBamAdapter/HtsgetBamAdapter.ts +2 -2
  43. package/src/HtsgetBamAdapter/index.ts +18 -5
  44. package/src/LinearAlignmentsDisplay/index.ts +20 -3
  45. package/src/LinearAlignmentsDisplay/models/configSchema.test.js +8 -69
  46. package/src/LinearPileupDisplay/configSchema.test.js +2 -13
  47. package/src/LinearPileupDisplay/configSchema.ts +4 -6
  48. package/src/LinearPileupDisplay/index.ts +19 -2
  49. package/src/LinearPileupDisplay/model.ts +53 -51
  50. package/src/LinearSNPCoverageDisplay/components/Tooltip.tsx +17 -12
  51. package/src/LinearSNPCoverageDisplay/index.ts +19 -2
  52. package/src/LinearSNPCoverageDisplay/models/configSchema.test.js +2 -13
  53. package/src/LinearSNPCoverageDisplay/models/model.ts +23 -6
  54. package/src/PileupRPC/rpcMethods.ts +8 -2
  55. package/src/PileupRenderer/PileupRenderer.tsx +154 -128
  56. package/src/PileupRenderer/components/PileupRendering.tsx +4 -8
  57. package/src/PileupRenderer/configSchema.ts +2 -2
  58. package/src/PileupRenderer/index.ts +16 -3
  59. package/src/SNPCoverageAdapter/SNPCoverageAdapter.ts +95 -25
  60. package/src/SNPCoverageAdapter/index.ts +17 -5
  61. package/src/SNPCoverageRenderer/SNPCoverageRenderer.ts +62 -15
  62. package/src/SNPCoverageRenderer/configSchema.js +5 -0
  63. package/src/SNPCoverageRenderer/index.ts +24 -0
  64. package/src/index.ts +91 -165
  65. package/src/SNPCoverageAdapter/SNPCoverageAdapter.test.ts +0 -269
  66. package/src/SNPCoverageAdapter/__snapshots__/SNPCoverageAdapter.test.ts.snap +0 -579
  67. package/src/SNPCoverageRenderer/index.js +0 -11
@@ -5,10 +5,7 @@ import {
5
5
  svgFeatureRendererConfigSchema,
6
6
  SvgFeatureRendererReactComponent,
7
7
  } from '@jbrowse/plugin-svg'
8
- import PileupRenderer, {
9
- configSchema as pileupRendererConfigSchema,
10
- ReactComponent as PileupRendererReactComponent,
11
- } from '../PileupRenderer'
8
+ import PileupRenderer from '../PileupRenderer'
12
9
  import configSchemaFactory from './configSchema'
13
10
 
14
11
  // mock warnings to avoid unnecessary outputs
@@ -22,15 +19,7 @@ afterEach(() => {
22
19
 
23
20
  class PileupRendererPlugin extends Plugin {
24
21
  install(pluginManager) {
25
- pluginManager.addRendererType(
26
- () =>
27
- new PileupRenderer({
28
- name: 'PileupRenderer',
29
- ReactComponent: PileupRendererReactComponent,
30
- configSchema: pileupRendererConfigSchema,
31
- pluginManager,
32
- }),
33
- )
22
+ PileupRenderer(pluginManager)
34
23
  }
35
24
  }
36
25
 
@@ -4,12 +4,10 @@ import { types, Instance } from 'mobx-state-tree'
4
4
  import PluginManager from '@jbrowse/core/PluginManager'
5
5
 
6
6
  function PileupConfigFactory(pluginManager: PluginManager) {
7
- const PileupRendererConfigSchema = pluginManager.getRendererType(
8
- 'PileupRenderer',
9
- ).configSchema
10
- const SvgFeatureRendererConfigSchema = pluginManager.getRendererType(
11
- 'SvgFeatureRenderer',
12
- ).configSchema
7
+ const PileupRendererConfigSchema =
8
+ pluginManager.getRendererType('PileupRenderer').configSchema
9
+ const SvgFeatureRendererConfigSchema =
10
+ pluginManager.getRendererType('SvgFeatureRenderer').configSchema
13
11
 
14
12
  // modify config schema to take in a sub coverage display
15
13
  return ConfigurationSchema(
@@ -1,2 +1,19 @@
1
- export { default as configSchemaFactory } from './configSchema'
2
- export { default as modelFactory } from './model'
1
+ import configSchemaFactory from './configSchema'
2
+ import modelFactory from './model'
3
+ import DisplayType from '@jbrowse/core/pluggableElementTypes/DisplayType'
4
+ import PluginManager from '@jbrowse/core/PluginManager'
5
+ import { BaseLinearDisplayComponent } from '@jbrowse/plugin-linear-genome-view'
6
+
7
+ export default function register(pluginManager: PluginManager) {
8
+ pluginManager.addDisplayType(() => {
9
+ const configSchema = configSchemaFactory(pluginManager)
10
+ return new DisplayType({
11
+ name: 'LinearPileupDisplay',
12
+ configSchema,
13
+ stateModel: modelFactory(configSchema),
14
+ trackType: 'AlignmentsTrack',
15
+ viewType: 'LinearGenomeView',
16
+ ReactComponent: BaseLinearDisplayComponent,
17
+ })
18
+ })
19
+ }
@@ -19,7 +19,6 @@ import {
19
19
  } from '@jbrowse/plugin-linear-genome-view'
20
20
  import { cast, types, addDisposer, getEnv, Instance } from 'mobx-state-tree'
21
21
  import copy from 'copy-to-clipboard'
22
- import PluginManager from '@jbrowse/core/PluginManager'
23
22
  import { Feature } from '@jbrowse/core/util/simpleFeature'
24
23
  import MenuOpenIcon from '@material-ui/icons/MenuOpen'
25
24
  import SortIcon from '@material-ui/icons/Sort'
@@ -49,10 +48,7 @@ const rendererTypes = new Map([
49
48
 
50
49
  type LGV = LinearGenomeViewModel
51
50
 
52
- const stateModelFactory = (
53
- pluginManager: PluginManager,
54
- configSchema: LinearPileupDisplayConfigModel,
55
- ) =>
51
+ const stateModelFactory = (configSchema: LinearPileupDisplayConfigModel) =>
56
52
  types
57
53
  .compose(
58
54
  'LinearPileupDisplay',
@@ -182,12 +178,13 @@ const stateModelFactory = (
182
178
  }
183
179
 
184
180
  if (colorBy?.type === 'modifications') {
185
- const uniqueModificationsSet = await getUniqueModificationValues(
186
- self,
187
- getConf(self.parentTrack, ['adapter']),
188
- colorBy,
189
- view.staticBlocks,
190
- )
181
+ const uniqueModificationsSet =
182
+ await getUniqueModificationValues(
183
+ self,
184
+ getConf(self.parentTrack, ['adapter']),
185
+ colorBy,
186
+ view.staticBlocks,
187
+ )
191
188
  self.updateModificationColorMap(uniqueModificationsSet)
192
189
  }
193
190
 
@@ -216,9 +213,9 @@ const stateModelFactory = (
216
213
  } else {
217
214
  self.setReady(true)
218
215
  }
219
- } catch (error) {
220
- console.error(error)
221
- self.setError(error)
216
+ } catch (e) {
217
+ console.error(e)
218
+ self.setError(e)
222
219
  }
223
220
  },
224
221
  { delay: 1000 },
@@ -244,10 +241,9 @@ const stateModelFactory = (
244
241
 
245
242
  // uses copy-to-clipboard and generates notification
246
243
  copyFeatureToClipboard(feature: Feature) {
247
- const copiedFeature = feature.toJSON()
248
- delete copiedFeature.uniqueId
244
+ const { uniqueId, ...rest } = feature.toJSON()
249
245
  const session = getSession(self)
250
- copy(JSON.stringify(copiedFeature, null, 4))
246
+ copy(JSON.stringify(rest, null, 4))
251
247
  session.notify('Copied to clipboard', 'success')
252
248
  },
253
249
 
@@ -387,21 +383,20 @@ const stateModelFactory = (
387
383
 
388
384
  get filters() {
389
385
  let filters: string[] = []
390
- if (self.filterBy) {
391
- const { flagInclude, flagExclude } = self.filterBy
392
- filters = [
393
- `jexl:((get(feature,'flags')&${flagInclude})==${flagInclude}) && !(get(feature,'flags')&${flagExclude})`,
394
- ]
395
- if (self.filterBy.tagFilter) {
396
- const { tag, value } = self.filterBy.tagFilter
397
- filters.push(
398
- `jexl:"${value}" =='*' ? getTag(feature,"${tag}") != undefined : getTag(feature,"${tag}") == "${value}"`,
399
- )
400
- }
401
- if (self.filterBy.readName) {
402
- const { readName } = self.filterBy
403
- filters.push(`jexl:get(feature,'name') == "${readName}"`)
404
- }
386
+ const { flagInclude, flagExclude, tagFilter, readName } =
387
+ self.filterBy
388
+
389
+ filters = [
390
+ `jexl:((get(feature,'flags')&${flagInclude})==${flagInclude}) && !(get(feature,'flags')&${flagExclude})`,
391
+ ]
392
+ if (tagFilter) {
393
+ const { tag, value } = tagFilter
394
+ filters.push(
395
+ `jexl:"${value}" =='*' ? getTag(feature,"${tag}") != undefined : getTag(feature,"${tag}") == "${value}"`,
396
+ )
397
+ }
398
+ if (readName) {
399
+ filters.push(`jexl:get(feature,'name') == "${readName}"`)
405
400
  }
406
401
  return new SerializableFilterChain({ filters })
407
402
  },
@@ -463,10 +458,12 @@ const stateModelFactory = (
463
458
  ),
464
459
  {
465
460
  label: 'Sort by tag...',
466
- onClick: () =>
467
- getSession(self).setDialogComponent(SortByTagDlg, {
468
- model: self,
469
- }),
461
+ onClick: () => {
462
+ getSession(self).queueDialog((doneCallback: Function) => [
463
+ SortByTagDlg,
464
+ { model: self, handleClose: doneCallback },
465
+ ])
466
+ },
470
467
  },
471
468
  {
472
469
  label: 'Clear sort',
@@ -511,9 +508,10 @@ const stateModelFactory = (
511
508
  {
512
509
  label: 'Modifications or methylation',
513
510
  onClick: () => {
514
- getSession(self).setDialogComponent(ModificationsDlg, {
515
- model: self,
516
- })
511
+ getSession(self).queueDialog((doneCallback: Function) => [
512
+ ModificationsDlg,
513
+ { model: self, handleClose: doneCallback },
514
+ ])
517
515
  },
518
516
  },
519
517
  {
@@ -531,9 +529,10 @@ const stateModelFactory = (
531
529
  {
532
530
  label: 'Color by tag...',
533
531
  onClick: () => {
534
- getSession(self).setDialogComponent(ColorByTagDlg, {
535
- model: self,
536
- })
532
+ getSession(self).queueDialog((doneCallback: Function) => [
533
+ ColorByTagDlg,
534
+ { model: self, handleClose: doneCallback },
535
+ ])
537
536
  },
538
537
  },
539
538
  ],
@@ -542,25 +541,28 @@ const stateModelFactory = (
542
541
  label: 'Filter by',
543
542
  icon: FilterListIcon,
544
543
  onClick: () => {
545
- getSession(self).setDialogComponent(FilterByTagDlg, {
546
- model: self,
547
- })
544
+ getSession(self).queueDialog((doneCallback: Function) => [
545
+ FilterByTagDlg,
546
+ { model: self, handleClose: doneCallback },
547
+ ])
548
548
  },
549
549
  },
550
550
  {
551
551
  label: 'Set feature height',
552
552
  onClick: () => {
553
- getSession(self).setDialogComponent(SetFeatureHeightDlg, {
554
- model: self,
555
- })
553
+ getSession(self).queueDialog((doneCallback: Function) => [
554
+ SetFeatureHeightDlg,
555
+ { model: self, handleClose: doneCallback },
556
+ ])
556
557
  },
557
558
  },
558
559
  {
559
560
  label: 'Set max height',
560
561
  onClick: () => {
561
- getSession(self).setDialogComponent(SetMaxHeightDlg, {
562
- model: self,
563
- })
562
+ getSession(self).queueDialog((doneCallback: Function) => [
563
+ SetMaxHeightDlg,
564
+ { model: self, handleClose: doneCallback },
565
+ ])
564
566
  },
565
567
  },
566
568
  {
@@ -11,6 +11,15 @@ type Count = {
11
11
  }
12
12
  }
13
13
 
14
+ type SNPInfo = {
15
+ ref: Count
16
+ cov: Count
17
+ lowqual: Count
18
+ noncov: Count
19
+ delskips: Count
20
+ total: number
21
+ }
22
+
14
23
  const en = (n: number) => n.toLocaleString('en-US')
15
24
 
16
25
  const TooltipContents = React.forwardRef(
@@ -22,16 +31,8 @@ const TooltipContents = React.forwardRef(
22
31
  .filter(f => !!f)
23
32
  .join(':')
24
33
 
25
- const info = feature.get('snpinfo') as {
26
- ref: Count
27
- cov: Count
28
- lowqual: Count
29
- noncov: Count
30
- delskips: Count
31
- total: number
32
- }
33
-
34
- const total = info.total
34
+ const info = feature.get('snpinfo') as SNPInfo
35
+ const total = info?.total
35
36
 
36
37
  return (
37
38
  <div ref={ref}>
@@ -61,7 +62,7 @@ const TooltipContents = React.forwardRef(
61
62
  <td>{base.toUpperCase()}</td>
62
63
  <td>{score.total}</td>
63
64
  <td>
64
- {base === 'total'
65
+ {base === 'total' || base === 'skip'
65
66
  ? '---'
66
67
  : `${Math.floor((score.total / total) * 100)}%`}
67
68
  </td>
@@ -91,7 +92,11 @@ const SNPCoverageTooltip = observer(
91
92
  clientMouseCoord: Coord
92
93
  clientRect?: ClientRect
93
94
  }) => {
94
- return <Tooltip TooltipContents={TooltipContents} {...props} />
95
+ const { model } = props
96
+ const { featureUnderMouse: feat } = model
97
+ return feat && feat.get('type') === 'skip' ? null : (
98
+ <Tooltip TooltipContents={TooltipContents} {...props} />
99
+ )
95
100
  },
96
101
  )
97
102
 
@@ -1,2 +1,19 @@
1
- export { default as configSchemaFactory } from './models/configSchema'
2
- export { default as modelFactory } from './models/model'
1
+ import PluginManager from '@jbrowse/core/PluginManager'
2
+ import configSchemaFactory from './models/configSchema'
3
+ import modelFactory from './models/model'
4
+ import { LinearWiggleDisplayReactComponent } from '@jbrowse/plugin-wiggle'
5
+ import DisplayType from '@jbrowse/core/pluggableElementTypes/DisplayType'
6
+
7
+ export default function register(pluginManager: PluginManager) {
8
+ pluginManager.addDisplayType(() => {
9
+ const configSchema = configSchemaFactory(pluginManager)
10
+ return new DisplayType({
11
+ name: 'LinearSNPCoverageDisplay',
12
+ configSchema,
13
+ stateModel: modelFactory(pluginManager, configSchema),
14
+ trackType: 'AlignmentsTrack',
15
+ viewType: 'LinearGenomeView',
16
+ ReactComponent: LinearWiggleDisplayReactComponent,
17
+ })
18
+ })
19
+ }
@@ -1,9 +1,6 @@
1
1
  import Plugin from '@jbrowse/core/Plugin'
2
2
  import PluginManager from '@jbrowse/core/PluginManager'
3
- import SNPCoverageRenderer, {
4
- configSchema as snpCoverageRendererConfigSchema,
5
- ReactComponent as SNPCoverageRendererReactComponent,
6
- } from '../../SNPCoverageRenderer' // change renderer
3
+ import SNPCoverageRenderer from '../../SNPCoverageRenderer' // change renderer
7
4
  import configSchemaFactory from './configSchema'
8
5
 
9
6
  // mock warnings to avoid unnecessary outputs
@@ -17,15 +14,7 @@ afterEach(() => {
17
14
  // change renderer
18
15
  class SNPCoverageRendererPlugin extends Plugin {
19
16
  install(pluginManager) {
20
- pluginManager.addRendererType(
21
- () =>
22
- new SNPCoverageRenderer({
23
- name: 'SNPCoverageRenderer',
24
- ReactComponent: SNPCoverageRendererReactComponent,
25
- configSchema: snpCoverageRendererConfigSchema,
26
- pluginManager,
27
- }),
28
- )
17
+ SNPCoverageRenderer(pluginManager)
29
18
  }
30
19
  }
31
20
 
@@ -30,6 +30,7 @@ const stateModelFactory = (
30
30
  type: types.literal('LinearSNPCoverageDisplay'),
31
31
  drawInterbaseCounts: types.maybe(types.boolean),
32
32
  drawIndicators: types.maybe(types.boolean),
33
+ drawArcs: types.maybe(types.boolean),
33
34
  filterBy: types.optional(
34
35
  types.model({
35
36
  flagInclude: types.optional(types.number, 0),
@@ -98,10 +99,19 @@ const stateModelFactory = (
98
99
  self.drawIndicators === undefined
99
100
  ? configBlob.drawIndicators
100
101
  : self.drawIndicators,
102
+ drawArcs:
103
+ self.drawArcs === undefined
104
+ ? configBlob.drawArcs
105
+ : self.drawArcs,
101
106
  },
102
107
  getEnv(self),
103
108
  )
104
109
  },
110
+ get drawArcsSetting() {
111
+ return self.drawArcs !== undefined
112
+ ? self.drawArcs
113
+ : readConfObject(this.rendererConfig, 'drawArcs')
114
+ },
105
115
  get drawInterbaseCountsSetting() {
106
116
  return self.drawInterbaseCounts !== undefined
107
117
  ? self.drawInterbaseCounts
@@ -143,6 +153,9 @@ const stateModelFactory = (
143
153
  toggleDrawInterbaseCounts() {
144
154
  self.drawInterbaseCounts = !self.drawInterbaseCountsSetting
145
155
  },
156
+ toggleDrawArcs() {
157
+ self.drawArcs = !self.drawArcsSetting
158
+ },
146
159
  afterAttach() {
147
160
  addDisposer(
148
161
  self,
@@ -217,6 +230,14 @@ const stateModelFactory = (
217
230
  self.toggleDrawInterbaseCounts()
218
231
  },
219
232
  },
233
+ {
234
+ label: 'Draw arcs',
235
+ type: 'checkbox',
236
+ checked: self.drawArcsSetting,
237
+ onClick: () => {
238
+ self.toggleDrawArcs()
239
+ },
240
+ },
220
241
  ]
221
242
  },
222
243
  // The SNPCoverage filters are called twice because the BAM/CRAM
@@ -225,12 +246,8 @@ const stateModelFactory = (
225
246
  get filters() {
226
247
  let filters: string[] = []
227
248
  if (self.filterBy) {
228
- const {
229
- flagInclude,
230
- flagExclude,
231
- tagFilter,
232
- readName,
233
- } = self.filterBy
249
+ const { flagInclude, flagExclude, tagFilter, readName } =
250
+ self.filterBy
234
251
  filters = [
235
252
  `jexl:get(feature,'snpinfo') != undefined ? true : ` +
236
253
  `((get(feature,'flags')&${flagInclude})==${flagInclude}) && ` +
@@ -14,6 +14,7 @@ export class PileupGetGlobalValueForTag extends RpcMethodType {
14
14
 
15
15
  async serializeArguments(
16
16
  args: RenderArgs & { signal?: AbortSignal; statusCallback?: Function },
17
+ rpcDriverClassName: string,
17
18
  ) {
18
19
  const { rootModel } = this.pluginManager
19
20
  const assemblyManager = rootModel?.session?.assemblyManager
@@ -21,7 +22,9 @@ export class PileupGetGlobalValueForTag extends RpcMethodType {
21
22
  throw new Error('no assembly manager available')
22
23
  }
23
24
 
24
- return renameRegionsIfNeeded(assemblyManager, args)
25
+ const renamedArgs = await renameRegionsIfNeeded(assemblyManager, args)
26
+
27
+ return super.serializeArguments(renamedArgs, rpcDriverClassName)
25
28
  }
26
29
 
27
30
  async execute(
@@ -63,6 +66,7 @@ export class PileupGetVisibleModifications extends RpcMethodType {
63
66
 
64
67
  async serializeArguments(
65
68
  args: RenderArgs & { signal?: AbortSignal; statusCallback?: Function },
69
+ rpcDriverClassName: string,
66
70
  ) {
67
71
  const { rootModel } = this.pluginManager
68
72
  const assemblyManager = rootModel?.session?.assemblyManager
@@ -70,7 +74,9 @@ export class PileupGetVisibleModifications extends RpcMethodType {
70
74
  throw new Error('no assembly manager available')
71
75
  }
72
76
 
73
- return renameRegionsIfNeeded(assemblyManager, args)
77
+ const renamedArgs = await renameRegionsIfNeeded(assemblyManager, args)
78
+
79
+ return super.serializeArguments(renamedArgs, rpcDriverClassName)
74
80
  }
75
81
 
76
82
  async execute(