jbrowse-plugin-protein3d 0.0.3 → 0.0.4

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 (189) hide show
  1. package/dist/AddHighlightModel/GenomeMouseoverHighlight.js +3 -9
  2. package/dist/AddHighlightModel/GenomeMouseoverHighlight.js.map +1 -1
  3. package/dist/AddHighlightModel/ProteinToGenomeClickHighlight.js +4 -3
  4. package/dist/AddHighlightModel/ProteinToGenomeClickHighlight.js.map +1 -1
  5. package/dist/AddHighlightModel/ProteinToGenomeHoverHighlight.d.ts +1 -2
  6. package/dist/AddHighlightModel/ProteinToGenomeHoverHighlight.js +4 -3
  7. package/dist/AddHighlightModel/ProteinToGenomeHoverHighlight.js.map +1 -1
  8. package/dist/AddHighlightModel/util.js +1 -1
  9. package/dist/AddHighlightModel/util.js.map +1 -1
  10. package/dist/AlphaFoldConfidenceAdapter/AlphaFoldConfidenceAdapter.d.ts +16 -0
  11. package/dist/AlphaFoldConfidenceAdapter/AlphaFoldConfidenceAdapter.js +43 -0
  12. package/dist/AlphaFoldConfidenceAdapter/AlphaFoldConfidenceAdapter.js.map +1 -0
  13. package/dist/AlphaFoldConfidenceAdapter/configSchema.d.ts +13 -0
  14. package/dist/AlphaFoldConfidenceAdapter/configSchema.js +16 -0
  15. package/dist/AlphaFoldConfidenceAdapter/configSchema.js.map +1 -0
  16. package/dist/AlphaFoldConfidenceAdapter/index.d.ts +2 -0
  17. package/dist/AlphaFoldConfidenceAdapter/index.js +11 -0
  18. package/dist/AlphaFoldConfidenceAdapter/index.js.map +1 -0
  19. package/dist/AlphaMissensePathogenicityAdapter/AlphaMissensePathogenicityAdapter.d.ts +30 -0
  20. package/dist/AlphaMissensePathogenicityAdapter/AlphaMissensePathogenicityAdapter.js +78 -0
  21. package/dist/AlphaMissensePathogenicityAdapter/AlphaMissensePathogenicityAdapter.js.map +1 -0
  22. package/dist/AlphaMissensePathogenicityAdapter/configSchema.d.ts +13 -0
  23. package/dist/AlphaMissensePathogenicityAdapter/configSchema.js +16 -0
  24. package/dist/AlphaMissensePathogenicityAdapter/configSchema.js.map +1 -0
  25. package/dist/AlphaMissensePathogenicityAdapter/index.d.ts +2 -0
  26. package/dist/AlphaMissensePathogenicityAdapter/index.js +11 -0
  27. package/dist/AlphaMissensePathogenicityAdapter/index.js.map +1 -0
  28. package/dist/LaunchProteinView/components/AlphaFoldDBSearch.js +161 -11
  29. package/dist/LaunchProteinView/components/AlphaFoldDBSearch.js.map +1 -1
  30. package/dist/LaunchProteinView/components/AlphaFoldDBSearchStatus.js +8 -6
  31. package/dist/LaunchProteinView/components/AlphaFoldDBSearchStatus.js.map +1 -1
  32. package/dist/LaunchProteinView/components/HelpButton.js +6 -2
  33. package/dist/LaunchProteinView/components/HelpButton.js.map +1 -1
  34. package/dist/LaunchProteinView/components/HelpDialog.js +3 -1
  35. package/dist/LaunchProteinView/components/HelpDialog.js.map +1 -1
  36. package/dist/LaunchProteinView/components/LaunchProteinViewDialog.js +6 -2
  37. package/dist/LaunchProteinView/components/LaunchProteinViewDialog.js.map +1 -1
  38. package/dist/LaunchProteinView/components/MSATable.js +3 -1
  39. package/dist/LaunchProteinView/components/MSATable.js.map +1 -1
  40. package/dist/LaunchProteinView/components/TranscriptSelector.js +3 -1
  41. package/dist/LaunchProteinView/components/TranscriptSelector.js.map +1 -1
  42. package/dist/LaunchProteinView/components/UserProvidedStructure.js +18 -11
  43. package/dist/LaunchProteinView/components/UserProvidedStructure.js.map +1 -1
  44. package/dist/LaunchProteinView/components/calculateProteinSequence.js +5 -3
  45. package/dist/LaunchProteinView/components/calculateProteinSequence.js.map +1 -1
  46. package/dist/LaunchProteinView/components/useLocalStructureFileSequence.d.ts +1 -1
  47. package/dist/LaunchProteinView/components/useLocalStructureFileSequence.js +29 -9
  48. package/dist/LaunchProteinView/components/useLocalStructureFileSequence.js.map +1 -1
  49. package/dist/LaunchProteinView/components/useRemoteStructureFileSequence.d.ts +1 -1
  50. package/dist/LaunchProteinView/components/useRemoteStructureFileSequence.js +25 -8
  51. package/dist/LaunchProteinView/components/useRemoteStructureFileSequence.js.map +1 -1
  52. package/dist/LaunchProteinView/components/util.js +1 -1
  53. package/dist/LaunchProteinView/index.js +7 -3
  54. package/dist/LaunchProteinView/index.js.map +1 -1
  55. package/dist/ProteinView/{loadStructureFromData.d.ts → addStructureFromData.d.ts} +2 -2
  56. package/dist/ProteinView/{loadStructureFromData.js → addStructureFromData.js} +3 -8
  57. package/dist/ProteinView/addStructureFromData.js.map +1 -0
  58. package/dist/ProteinView/{loadStructureFromURL.d.ts → addStructureFromURL.d.ts} +2 -2
  59. package/dist/ProteinView/{loadStructureFromURL.js → addStructureFromURL.js} +11 -9
  60. package/dist/ProteinView/addStructureFromURL.js.map +1 -0
  61. package/dist/ProteinView/clearSelection.js +1 -1
  62. package/dist/ProteinView/clearSelection.js.map +1 -1
  63. package/dist/ProteinView/components/ProteinAlignment.d.ts +2 -2
  64. package/dist/ProteinView/components/ProteinAlignment.js +37 -26
  65. package/dist/ProteinView/components/ProteinAlignment.js.map +1 -1
  66. package/dist/ProteinView/components/ProteinAlignmentHelpButton.d.ts +2 -2
  67. package/dist/ProteinView/components/ProteinAlignmentHelpButton.js +6 -4
  68. package/dist/ProteinView/components/ProteinAlignmentHelpButton.js.map +1 -1
  69. package/dist/ProteinView/components/ProteinAlignmentHelpDialog.js +6 -5
  70. package/dist/ProteinView/components/ProteinAlignmentHelpDialog.js.map +1 -1
  71. package/dist/ProteinView/components/ProteinView.js +18 -60
  72. package/dist/ProteinView/components/ProteinView.js.map +1 -1
  73. package/dist/ProteinView/components/{Header.js → ProteinViewHeader.js} +29 -12
  74. package/dist/ProteinView/components/ProteinViewHeader.js.map +1 -0
  75. package/dist/ProteinView/components/SplitString.d.ts +4 -4
  76. package/dist/ProteinView/components/SplitString.js +3 -3
  77. package/dist/ProteinView/components/SplitString.js.map +1 -1
  78. package/dist/ProteinView/genomeToProtein.d.ts +2 -2
  79. package/dist/ProteinView/genomeToProtein.js +4 -5
  80. package/dist/ProteinView/genomeToProtein.js.map +1 -1
  81. package/dist/ProteinView/highlightResidue.js +2 -2
  82. package/dist/ProteinView/highlightResidue.js.map +1 -1
  83. package/dist/ProteinView/launchRemotePairwiseAlignment.d.ts +2 -5
  84. package/dist/ProteinView/launchRemotePairwiseAlignment.js +7 -3
  85. package/dist/ProteinView/launchRemotePairwiseAlignment.js.map +1 -1
  86. package/dist/ProteinView/model.d.ts +496 -160
  87. package/dist/ProteinView/model.js +61 -246
  88. package/dist/ProteinView/model.js.map +1 -1
  89. package/dist/ProteinView/proteinToGenomeMapping.d.ts +6 -6
  90. package/dist/ProteinView/proteinToGenomeMapping.js +29 -28
  91. package/dist/ProteinView/proteinToGenomeMapping.js.map +1 -1
  92. package/dist/ProteinView/selectResidue.js +1 -1
  93. package/dist/ProteinView/selectResidue.js.map +1 -1
  94. package/dist/ProteinView/structureModel.d.ts +183 -0
  95. package/dist/ProteinView/structureModel.js +407 -0
  96. package/dist/ProteinView/structureModel.js.map +1 -0
  97. package/dist/ProteinView/useProteinView.d.ts +1 -4
  98. package/dist/ProteinView/useProteinView.js +3 -15
  99. package/dist/ProteinView/useProteinView.js.map +1 -1
  100. package/dist/ProteinView/util.d.ts +3 -3
  101. package/dist/ProteinView/util.js +8 -6
  102. package/dist/ProteinView/util.js.map +1 -1
  103. package/dist/UniProtVariationAdapter/UniProtVariationAdapter.d.ts +15 -0
  104. package/dist/UniProtVariationAdapter/UniProtVariationAdapter.js +55 -0
  105. package/dist/UniProtVariationAdapter/UniProtVariationAdapter.js.map +1 -0
  106. package/dist/UniProtVariationAdapter/configSchema.d.ts +17 -0
  107. package/dist/UniProtVariationAdapter/configSchema.js +20 -0
  108. package/dist/UniProtVariationAdapter/configSchema.js.map +1 -0
  109. package/dist/UniProtVariationAdapter/index.d.ts +2 -0
  110. package/dist/UniProtVariationAdapter/index.js +11 -0
  111. package/dist/UniProtVariationAdapter/index.js.map +1 -0
  112. package/dist/genomeToTranscriptMapping.d.ts +2 -2
  113. package/dist/genomeToTranscriptMapping.js +3 -3
  114. package/dist/genomeToTranscriptMapping.js.map +1 -1
  115. package/dist/index.js +6 -0
  116. package/dist/index.js.map +1 -1
  117. package/dist/jbrowse-plugin-protein3d.umd.production.min.js +1467 -1482
  118. package/dist/jbrowse-plugin-protein3d.umd.production.min.js.map +4 -4
  119. package/dist/mappings.d.ts +12 -10
  120. package/dist/mappings.js +7 -7
  121. package/dist/mappings.js.map +1 -1
  122. package/dist/mappings.test.js +7 -5
  123. package/dist/mappings.test.js.map +1 -1
  124. package/dist/test_data/gene.d.ts +577 -64
  125. package/dist/test_data/gene.js +1 -1
  126. package/dist/test_data/gene.js.map +1 -1
  127. package/package.json +16 -15
  128. package/src/AddHighlightModel/GenomeMouseoverHighlight.tsx +4 -17
  129. package/src/AddHighlightModel/ProteinToGenomeClickHighlight.tsx +17 -14
  130. package/src/AddHighlightModel/ProteinToGenomeHoverHighlight.tsx +18 -17
  131. package/src/AddHighlightModel/util.ts +1 -1
  132. package/src/AlphaFoldConfidenceAdapter/AlphaFoldConfidenceAdapter.ts +63 -0
  133. package/src/AlphaFoldConfidenceAdapter/configSchema.ts +21 -0
  134. package/src/AlphaFoldConfidenceAdapter/index.ts +19 -0
  135. package/src/AlphaMissensePathogenicityAdapter/AlphaMissensePathogenicityAdapter.ts +109 -0
  136. package/src/AlphaMissensePathogenicityAdapter/configSchema.ts +21 -0
  137. package/src/AlphaMissensePathogenicityAdapter/index.ts +19 -0
  138. package/src/LaunchProteinView/components/AlphaFoldDBSearch.tsx +172 -10
  139. package/src/LaunchProteinView/components/AlphaFoldDBSearchStatus.tsx +8 -6
  140. package/src/LaunchProteinView/components/HelpButton.tsx +10 -2
  141. package/src/LaunchProteinView/components/HelpDialog.tsx +6 -1
  142. package/src/LaunchProteinView/components/LaunchProteinViewDialog.tsx +9 -2
  143. package/src/LaunchProteinView/components/MSATable.tsx +3 -1
  144. package/src/LaunchProteinView/components/TranscriptSelector.tsx +9 -7
  145. package/src/LaunchProteinView/components/UserProvidedStructure.tsx +17 -12
  146. package/src/LaunchProteinView/components/calculateProteinSequence.ts +6 -4
  147. package/src/LaunchProteinView/components/useLocalStructureFileSequence.ts +28 -9
  148. package/src/LaunchProteinView/components/useRemoteStructureFileSequence.ts +23 -8
  149. package/src/LaunchProteinView/components/util.ts +1 -1
  150. package/src/LaunchProteinView/index.ts +36 -26
  151. package/src/ProteinView/{loadStructureFromData.ts → addStructureFromData.ts} +2 -8
  152. package/src/ProteinView/{loadStructureFromURL.ts → addStructureFromURL.ts} +11 -11
  153. package/src/ProteinView/clearSelection.ts +1 -1
  154. package/src/ProteinView/components/ProteinAlignment.tsx +51 -35
  155. package/src/ProteinView/components/ProteinAlignmentHelpButton.tsx +4 -4
  156. package/src/ProteinView/components/ProteinAlignmentHelpDialog.tsx +15 -11
  157. package/src/ProteinView/components/ProteinView.tsx +22 -82
  158. package/src/ProteinView/components/{Header.tsx → ProteinViewHeader.tsx} +44 -23
  159. package/src/ProteinView/components/SplitString.tsx +8 -8
  160. package/src/ProteinView/genomeToProtein.ts +5 -9
  161. package/src/ProteinView/highlightResidue.ts +2 -2
  162. package/src/ProteinView/launchRemotePairwiseAlignment.ts +6 -3
  163. package/src/ProteinView/model.ts +74 -287
  164. package/src/ProteinView/proteinToGenomeMapping.ts +40 -38
  165. package/src/ProteinView/selectResidue.ts +1 -1
  166. package/src/ProteinView/structureModel.ts +512 -0
  167. package/src/ProteinView/useProteinView.ts +2 -19
  168. package/src/ProteinView/util.ts +20 -9
  169. package/src/UniProtVariationAdapter/UniProtVariationAdapter.ts +99 -0
  170. package/src/UniProtVariationAdapter/configSchema.ts +25 -0
  171. package/src/UniProtVariationAdapter/index.ts +17 -0
  172. package/src/__snapshots__/mappings.test.ts.snap +224 -224
  173. package/src/genomeToTranscriptMapping.ts +9 -9
  174. package/src/index.ts +6 -0
  175. package/src/mappings.test.ts +7 -5
  176. package/src/mappings.ts +25 -23
  177. package/src/test_data/gene.ts +3 -3
  178. package/dist/ProteinView/components/Header.js.map +0 -1
  179. package/dist/ProteinView/loadStructureFromData.js.map +0 -1
  180. package/dist/ProteinView/loadStructureFromURL.js.map +0 -1
  181. package/dist/ProteinView/useProteinViewClickBehavior.d.ts +0 -8
  182. package/dist/ProteinView/useProteinViewClickBehavior.js +0 -34
  183. package/dist/ProteinView/useProteinViewClickBehavior.js.map +0 -1
  184. package/dist/ProteinView/useProteinViewHoverBehavior.d.ts +0 -6
  185. package/dist/ProteinView/useProteinViewHoverBehavior.js +0 -31
  186. package/dist/ProteinView/useProteinViewHoverBehavior.js.map +0 -1
  187. package/src/ProteinView/useProteinViewClickBehavior.ts +0 -48
  188. package/src/ProteinView/useProteinViewHoverBehavior.ts +0 -44
  189. /package/dist/ProteinView/components/{Header.d.ts → ProteinViewHeader.d.ts} +0 -0
@@ -2,45 +2,55 @@ import PluginManager from '@jbrowse/core/PluginManager'
2
2
  import DisplayType from '@jbrowse/core/pluggableElementTypes/DisplayType'
3
3
  import { PluggableElementType } from '@jbrowse/core/pluggableElementTypes'
4
4
  import { IAnyModelType } from 'mobx-state-tree'
5
- import { getSession, getContainingTrack } from '@jbrowse/core/util'
5
+ import { getSession, getContainingTrack, Feature } from '@jbrowse/core/util'
6
6
 
7
7
  // icons
8
8
  import AddIcon from '@mui/icons-material/Add'
9
9
 
10
10
  // locals
11
11
  import LaunchProteinViewDialog from './components/LaunchProteinViewDialog'
12
+ import { MenuItem } from '@jbrowse/core/ui'
12
13
 
13
14
  function isDisplay(elt: { name: string }): elt is DisplayType {
14
15
  return elt.name === 'LinearBasicDisplay'
15
16
  }
16
17
 
17
18
  function extendStateModel(stateModel: IAnyModelType) {
18
- return stateModel.views(self => {
19
- const superContextMenuItems = self.contextMenuItems
20
- return {
21
- contextMenuItems() {
22
- const feature = self.contextMenuFeature
23
- const track = getContainingTrack(self)
24
- return [
25
- ...superContextMenuItems(),
26
- ...(feature
27
- ? [
28
- {
29
- label: 'Launch 3-D protein view',
30
- icon: AddIcon,
31
- onClick: () => {
32
- getSession(track).queueDialog(handleClose => [
33
- LaunchProteinViewDialog,
34
- { model: track, handleClose, feature },
35
- ])
19
+ return stateModel.views(
20
+ (self: {
21
+ contextMenuItems: () => MenuItem[]
22
+ contextMenuFeature?: Feature
23
+ }) => {
24
+ const superContextMenuItems = self.contextMenuItems
25
+ return {
26
+ contextMenuItems() {
27
+ const feature = self.contextMenuFeature
28
+ const track = getContainingTrack(self)
29
+ return [
30
+ ...superContextMenuItems(),
31
+ ...(feature
32
+ ? [
33
+ {
34
+ label: 'Launch protein view',
35
+ icon: AddIcon,
36
+ onClick: () => {
37
+ getSession(track).queueDialog(handleClose => [
38
+ LaunchProteinViewDialog,
39
+ {
40
+ model: track,
41
+ handleClose,
42
+ feature,
43
+ },
44
+ ])
45
+ },
36
46
  },
37
- },
38
- ]
39
- : []),
40
- ]
41
- },
42
- }
43
- })
47
+ ]
48
+ : []),
49
+ ]
50
+ },
51
+ }
52
+ },
53
+ )
44
54
  }
45
55
 
46
56
  export default function LaunchProteinViewF(pluginManager: PluginManager) {
@@ -7,7 +7,7 @@ export interface LoadStructureOptions {
7
7
  }
8
8
 
9
9
  // adapted from https://github.com/molstar/molstar/blob/ab4130d42d0ab2591f62460292ade0203207d4d2/src/apps/viewer/app.ts#L255C1-L259C6
10
- export async function loadStructureFromData({
10
+ export async function addStructureFromData({
11
11
  data,
12
12
  format = 'pdb',
13
13
  options,
@@ -18,8 +18,6 @@ export async function loadStructureFromData({
18
18
  options?: LoadStructureOptions & { label?: string; dataLabel?: string }
19
19
  plugin: PluginContext
20
20
  }) {
21
- await plugin.clear()
22
-
23
21
  const _data = await plugin.builders.data.rawData({
24
22
  data,
25
23
  label: options?.dataLabel,
@@ -30,10 +28,6 @@ export async function loadStructureFromData({
30
28
  format,
31
29
  )
32
30
  const model = await plugin.builders.structure.createModel(trajectory)
33
- const seq = model.obj?.data.sequence.sequences[0].sequence.label
34
- .toArray()
35
- // @ts-expect-error
36
- .join('')
37
31
 
38
32
  await plugin.builders.structure.hierarchy.applyPreset(
39
33
  trajectory,
@@ -44,5 +38,5 @@ export async function loadStructureFromData({
44
38
  },
45
39
  )
46
40
 
47
- return { seq: seq as string }
41
+ return { model }
48
42
  }
@@ -7,7 +7,7 @@ export interface LoadStructureOptions {
7
7
  }
8
8
 
9
9
  // adapted from https://github.com/molstar/molstar/blob/ab4130d42d0ab2591f62460292ade0203207d4d2/src/apps/viewer/app.ts#L230
10
- export async function loadStructureFromURL({
10
+ export async function addStructureFromURL({
11
11
  url,
12
12
  format = 'mmcif',
13
13
  isBinary,
@@ -20,11 +20,16 @@ export async function loadStructureFromURL({
20
20
  options?: LoadStructureOptions & { label?: string }
21
21
  plugin: PluginContext
22
22
  }) {
23
- await plugin.clear()
24
-
25
23
  const data = await plugin.builders.data.download(
26
- { url, isBinary },
27
- { state: { isGhost: true } },
24
+ {
25
+ url,
26
+ isBinary,
27
+ },
28
+ {
29
+ state: {
30
+ isGhost: true,
31
+ },
32
+ },
28
33
  )
29
34
 
30
35
  const trajectory = await plugin.builders.structure.parseTrajectory(
@@ -32,10 +37,6 @@ export async function loadStructureFromURL({
32
37
  format,
33
38
  )
34
39
  const model = await plugin.builders.structure.createModel(trajectory)
35
- const seq = model.obj?.data.sequence.sequences[0].sequence.label
36
- .toArray()
37
- // @ts-expect-error
38
- .join('')
39
40
 
40
41
  await plugin.builders.structure.hierarchy.applyPreset(
41
42
  trajectory,
@@ -45,6 +46,5 @@ export async function loadStructureFromURL({
45
46
  representationPresetParams: options?.representationParams,
46
47
  },
47
48
  )
48
-
49
- return { seq: seq as string }
49
+ return { model }
50
50
  }
@@ -1,5 +1,5 @@
1
1
  import { PluginContext } from 'molstar/lib/mol-plugin/context'
2
2
 
3
3
  export default function clearSelection({ plugin }: { plugin: PluginContext }) {
4
- plugin?.managers.interactivity.lociSelects.deselectAll()
4
+ plugin.managers.interactivity.lociSelects.deselectAll()
5
5
  }
@@ -1,9 +1,9 @@
1
- import React from 'react'
1
+ import React, { useEffect, useState } from 'react'
2
2
  import { observer } from 'mobx-react'
3
3
  import { Tooltip, Typography } from '@mui/material'
4
4
 
5
5
  // locals
6
- import { JBrowsePluginProteinViewModel } from '../model'
6
+ import { JBrowsePluginProteinStructureModel } from '../model'
7
7
  import ProteinAlignmentHelpButton from './ProteinAlignmentHelpButton'
8
8
  import {
9
9
  clickProteinToGenome,
@@ -14,42 +14,58 @@ import SplitString from './SplitString'
14
14
  const ProteinAlignment = observer(function ({
15
15
  model,
16
16
  }: {
17
- model: JBrowsePluginProteinViewModel
17
+ model: JBrowsePluginProteinStructureModel
18
18
  }) {
19
19
  const {
20
- structureSeqHoverPos,
21
- alignment,
20
+ pairwiseAlignment,
21
+ pairwiseAlignmentToStructurePosition,
22
22
  structurePositionToAlignmentMap,
23
- alignmentToStructurePosition,
23
+ structureSeqHoverPos,
24
24
  showHighlight,
25
25
  } = model
26
- const a0 = alignment!.alns[0].seq as string
27
- const a1 = alignment!.alns[1].seq as string
28
- const con = alignment!.consensus
29
- const set = new Set<number>()
26
+
27
+ const [pairwiseAlignmentHoverPos, setPairwiseAlignmentHoverPos] =
28
+ useState<number>()
29
+
30
+ useEffect(() => {
31
+ setPairwiseAlignmentHoverPos(
32
+ structureSeqHoverPos === undefined
33
+ ? undefined
34
+ : structurePositionToAlignmentMap?.[structureSeqHoverPos],
35
+ )
36
+ }, [structurePositionToAlignmentMap, structureSeqHoverPos])
37
+
38
+ if (!pairwiseAlignment) {
39
+ return <div>No pairwiseAlignment</div>
40
+ }
41
+ const a0 = pairwiseAlignment.alns[0].seq
42
+ const a1 = pairwiseAlignment.alns[1].seq
43
+ const con = pairwiseAlignment.consensus
44
+ const gapSet = new Set<number>()
30
45
  // eslint-disable-next-line unicorn/no-for-loop
31
46
  for (let i = 0; i < con.length; i++) {
32
47
  const letter = con[i]
33
48
  if (letter === '|') {
34
- set.add(i)
49
+ gapSet.add(i)
35
50
  }
36
51
  }
37
52
 
38
- const alignmentHoverPos =
39
- structureSeqHoverPos !== undefined
40
- ? structurePositionToAlignmentMap?.[structureSeqHoverPos]
41
- : undefined
42
-
43
- function onMouseOver(alignmentPos: number) {
44
- const structureSeqPos = alignmentToStructurePosition[alignmentPos]
45
- model.setHoveredPosition({ structureSeqPos })
46
- hoverProteinToGenome({ model, structureSeqPos })
53
+ function onMouseOver(p: number) {
54
+ setPairwiseAlignmentHoverPos(p)
55
+ if (pairwiseAlignmentToStructurePosition) {
56
+ const structureSeqPos = pairwiseAlignmentToStructurePosition[p]
57
+ model.setHoveredPosition({ structureSeqPos })
58
+ hoverProteinToGenome({ model, structureSeqPos })
59
+ }
47
60
  }
48
- function onClick(alignmentPos: number) {
49
- const structureSeqPos = alignmentToStructurePosition[alignmentPos]
50
- clickProteinToGenome({ model, structureSeqPos }).catch(e => {
51
- console.error(e)
52
- })
61
+ function onClick(pairwiseAlignmentPos: number) {
62
+ if (pairwiseAlignmentToStructurePosition) {
63
+ const structureSeqPos =
64
+ pairwiseAlignmentToStructurePosition[pairwiseAlignmentPos]!
65
+ clickProteinToGenome({ model, structureSeqPos }).catch((e: unknown) => {
66
+ console.error(e)
67
+ })
68
+ }
53
69
  }
54
70
  return (
55
71
  <div>
@@ -75,14 +91,14 @@ const ProteinAlignment = observer(function ({
75
91
  }}
76
92
  >
77
93
  <div>
78
- <Tooltip title="This is the sequence of the protein from the structure file">
79
- <span>STRUCT&nbsp;</span>
94
+ <Tooltip title="This is the sequence of the protein from the reference genome transcript">
95
+ <span>GENOME&nbsp;</span>
80
96
  </Tooltip>
81
97
  <SplitString
82
98
  str={a0}
83
99
  showHighlight={showHighlight}
84
- col={alignmentHoverPos}
85
- set={set}
100
+ hoveredPosition={pairwiseAlignmentHoverPos}
101
+ gapSet={gapSet}
86
102
  onMouseOver={onMouseOver}
87
103
  onClick={onClick}
88
104
  />
@@ -92,21 +108,21 @@ const ProteinAlignment = observer(function ({
92
108
  <SplitString
93
109
  showHighlight={showHighlight}
94
110
  str={con}
95
- col={alignmentHoverPos}
96
- set={set}
111
+ hoveredPosition={pairwiseAlignmentHoverPos}
112
+ gapSet={gapSet}
97
113
  onMouseOver={onMouseOver}
98
114
  onClick={onClick}
99
115
  />
100
116
  </div>
101
117
  <div>
102
- <Tooltip title="This is the sequence of the protein from the reference genome transcript">
103
- <span>GENOME&nbsp;</span>
118
+ <Tooltip title="This is the sequence of the protein from the structure file">
119
+ <span>STRUCT&nbsp;</span>
104
120
  </Tooltip>
105
121
  <SplitString
106
122
  str={a1}
107
- col={alignmentHoverPos}
123
+ hoveredPosition={pairwiseAlignmentHoverPos}
108
124
  showHighlight={showHighlight}
109
- set={set}
125
+ gapSet={gapSet}
110
126
  onMouseOver={onMouseOver}
111
127
  onClick={onClick}
112
128
  />
@@ -3,7 +3,7 @@ import { IconButton } from '@mui/material'
3
3
  import { getSession } from '@jbrowse/core/util'
4
4
 
5
5
  // locals
6
- import { JBrowsePluginProteinViewModel } from '../model'
6
+ import { JBrowsePluginProteinStructureModel } from '../model'
7
7
 
8
8
  // icons
9
9
  import Help from '@mui/icons-material/Help'
@@ -15,17 +15,17 @@ const ProteinAlignmentHelpDialog = lazy(
15
15
  export default function ProteinAlignmentHelpButton({
16
16
  model,
17
17
  }: {
18
- model: JBrowsePluginProteinViewModel
18
+ model: JBrowsePluginProteinStructureModel
19
19
  }) {
20
20
  return (
21
21
  <IconButton
22
22
  style={{ float: 'right' }}
23
- onClick={() =>
23
+ onClick={() => {
24
24
  getSession(model).queueDialog(handleClose => [
25
25
  ProteinAlignmentHelpDialog,
26
26
  { handleClose },
27
27
  ])
28
- }
28
+ }}
29
29
  >
30
30
  <Help />
31
31
  </IconButton>
@@ -3,7 +3,6 @@ import {
3
3
  Button,
4
4
  DialogActions,
5
5
  DialogContent,
6
- Divider,
7
6
  Typography,
8
7
  TypographyProps,
9
8
  } from '@mui/material'
@@ -30,17 +29,17 @@ export default function ProteinAlignmentHelpDialog({
30
29
  <Dialog open maxWidth="lg" onClose={handleClose} title="Protein alignment">
31
30
  <DialogContent>
32
31
  <Typography2>
33
- This panel shows the computed alignment of the reference genome
34
- sequence to the structure sequence. The structure file (PDB file,
35
- mmCIF file, etc) has a stored representation of the e.g. amino acid
36
- sequence but the sequence in the structure file can differ from the
37
- sequence from the gene on the genome browser
32
+ This panel shows the computed pairwise alignment of the reference
33
+ genome sequence to the structure sequence. The structure file (PDB
34
+ file, mmCIF file, etc) has a stored representation of the e.g. amino
35
+ acid sequence but the sequence in the structure file can differ from
36
+ the sequence from the gene on the genome browser
38
37
  </Typography2>
39
38
  <Typography2>
40
39
  In order to resolve this, we align the two sequences together (using
41
- EMBOSS needle) to get alignment of the genome&apos;s representation of
42
- the protein and the structure file&apos;s representation of the
43
- protein.
40
+ EMBOSS needle) to get pairwise alignment of the genome&apos;s
41
+ representation of the protein and the structure file&apos;s
42
+ representation of the protein.
44
43
  </Typography2>
45
44
  <Typography2>
46
45
  If you need a 100% fidelity protein, you can do a folding with e.g.
@@ -48,9 +47,14 @@ export default function ProteinAlignmentHelpDialog({
48
47
  sequence of the transcript
49
48
  </Typography2>
50
49
  </DialogContent>
51
- <Divider />
52
50
  <DialogActions>
53
- <Button onClick={() => handleClose()} color="primary">
51
+ <Button
52
+ onClick={() => {
53
+ handleClose()
54
+ }}
55
+ variant="contained"
56
+ color="primary"
57
+ >
54
58
  Close
55
59
  </Button>
56
60
  </DialogActions>
@@ -1,121 +1,55 @@
1
1
  import React, { useEffect } from 'react'
2
2
  import { observer } from 'mobx-react'
3
- import { ErrorMessage } from '@jbrowse/core/ui'
4
- import { PluginContext } from 'molstar/lib/mol-plugin/context'
3
+ import { ErrorMessage, ResizeHandle } from '@jbrowse/core/ui'
5
4
 
6
5
  // locals
7
6
  import { JBrowsePluginProteinViewModel } from '../model'
8
- import Header from './Header'
7
+ import ProteinViewHeader from './ProteinViewHeader'
9
8
 
10
9
  // hooks
11
10
  import useProteinView from '../useProteinView'
12
- import useProteinViewClickBehavior from '../useProteinViewClickBehavior'
13
- import useProteinViewHoverBehavior from '../useProteinViewHoverBehavior'
14
-
15
- // utils
16
- import selectResidue from '../selectResidue'
17
- import highlightResidue from '../highlightResidue'
18
- import clearSelection from '../clearSelection'
19
11
 
20
12
  // css
21
13
  import css from '../css/molstar'
22
14
 
23
- if (document?.head) {
24
- const style = document.createElement('style')
25
- style.append(css)
26
- document.head?.append(style)
27
- }
15
+ const style = document.createElement('style')
16
+ style.append(css)
17
+ document.head.append(style)
28
18
 
29
19
  const ProteinView = observer(function ({
30
20
  model,
31
21
  }: {
32
22
  model: JBrowsePluginProteinViewModel
33
23
  }) {
34
- const { url, data, showControls } = model
35
- const { plugin, seq, parentRef, error } = useProteinView({
36
- url,
37
- data,
24
+ const { showControls } = model
25
+ const { plugin, parentRef, error } = useProteinView({
38
26
  showControls,
39
27
  })
28
+
29
+ useEffect(() => {
30
+ model.setMolstarPluginContext(plugin)
31
+ }, [plugin, model])
32
+
40
33
  return error ? (
41
34
  <ErrorMessage error={error} />
42
35
  ) : (
43
- <ProteinViewContainer
44
- model={model}
45
- plugin={plugin}
46
- seq={seq}
47
- parentRef={parentRef}
48
- />
36
+ <ProteinViewContainer model={model} parentRef={parentRef} />
49
37
  )
50
38
  })
51
39
 
52
40
  const ProteinViewContainer = observer(function ({
53
41
  model,
54
- plugin,
55
- seq,
56
42
  parentRef,
57
43
  }: {
58
44
  model: JBrowsePluginProteinViewModel
59
- plugin?: PluginContext
60
- seq?: string
61
45
  parentRef?: React.RefObject<HTMLDivElement>
62
46
  }) {
63
- const {
64
- width,
65
- height,
66
- structureSeqToTranscriptSeqPosition,
67
- seq2,
68
- structureSeqHoverPos,
69
- showHighlight,
70
- alignment,
71
- } = model
72
-
73
- const { error } = useProteinViewClickBehavior({ plugin, model })
74
- useProteinViewHoverBehavior({ plugin, model })
75
-
76
- const structure =
77
- plugin?.managers.structure.hierarchy.current.structures[0]?.cell.obj?.data
78
-
79
- useEffect(() => {
80
- model.setSeqs(seq, seq2)
81
- }, [seq, model, seq2])
82
-
83
- useEffect(() => {
84
- if (!plugin || !structureSeqToTranscriptSeqPosition || !structure) {
85
- return
86
- }
87
- if (showHighlight) {
88
- for (const coord of Object.keys(structureSeqToTranscriptSeqPosition)) {
89
- selectResidue({
90
- structure,
91
- plugin,
92
- selectedResidue: +coord + 1,
93
- })
94
- }
95
- } else {
96
- clearSelection({ plugin })
97
- }
98
- }, [plugin, structure, showHighlight, structureSeqToTranscriptSeqPosition])
99
-
100
- useEffect(() => {
101
- if (!plugin || !structure || structureSeqHoverPos === undefined) {
102
- return
103
- }
104
- if (structureSeqHoverPos !== undefined) {
105
- highlightResidue({
106
- structure,
107
- plugin,
108
- selectedResidue: structureSeqHoverPos,
109
- })
110
- } else {
111
- console.warn('not found')
112
- }
113
- }, [plugin, structure, structureSeqHoverPos])
47
+ const { width, height, error } = model
114
48
 
115
49
  return (
116
- <div style={{ background: !alignment ? '#ccc' : undefined }}>
50
+ <div style={{ background: '#ccc' }}>
117
51
  {error ? <ErrorMessage error={error} /> : null}
118
- <Header model={model} />
52
+ <ProteinViewHeader model={model} />
119
53
  <div
120
54
  ref={parentRef}
121
55
  style={{
@@ -124,6 +58,12 @@ const ProteinViewContainer = observer(function ({
124
58
  height,
125
59
  }}
126
60
  />
61
+ <ResizeHandle
62
+ style={{ height: 4, background: 'grey' }}
63
+ onDrag={delta => {
64
+ model.setHeight(model.height + delta)
65
+ }}
66
+ />
127
67
  </div>
128
68
  )
129
69
  })
@@ -1,5 +1,6 @@
1
1
  import React from 'react'
2
2
  import { observer } from 'mobx-react'
3
+ import { LoadingEllipses } from '@jbrowse/core/ui'
3
4
  import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton'
4
5
 
5
6
  // icons
@@ -9,48 +10,62 @@ import Visibility from '@mui/icons-material/Visibility'
9
10
  // locals
10
11
  import { JBrowsePluginProteinViewModel } from '../model'
11
12
  import ProteinAlignment from './ProteinAlignment'
12
- import { LoadingEllipses } from '@jbrowse/core/ui'
13
13
 
14
14
  const ProteinViewHeader = observer(function ({
15
15
  model,
16
16
  }: {
17
17
  model: JBrowsePluginProteinViewModel
18
18
  }) {
19
- const { alignment, showAlignment } = model
19
+ const { structures, showAlignment } = model
20
20
  return (
21
21
  <div>
22
22
  <InformativeHeaderArea model={model} />
23
- {showAlignment ? (
24
- alignment ? (
25
- <ProteinAlignment model={model} />
26
- ) : (
27
- <LoadingEllipses message="Loading pairwise alignment" />
28
- )
29
- ) : null}
23
+ {showAlignment
24
+ ? structures.map((structure, idx) => {
25
+ const { pairwiseAlignment } = structure
26
+ return (
27
+ <div key={idx}>
28
+ {pairwiseAlignment ? (
29
+ <ProteinAlignment key={idx} model={structure} />
30
+ ) : (
31
+ <LoadingEllipses message="Loading pairwise alignment" />
32
+ )}
33
+ </div>
34
+ )
35
+ })
36
+ : null}
30
37
  </div>
31
38
  )
32
39
  })
33
40
 
34
- const InformativeHeaderArea = observer(function ({
41
+ const StructureInfoHeaderArea = observer(function ({
35
42
  model,
36
43
  }: {
37
44
  model: JBrowsePluginProteinViewModel
38
45
  }) {
39
- const {
40
- showAlignment,
41
- clickString,
42
- hoverString,
43
- showHighlight,
44
- zoomToBaseLevel,
45
- } = model
46
- return (
47
- <div style={{ display: 'flex' }}>
48
- <span>
46
+ return model.structures.map((s, id) => {
47
+ const { clickString, hoverString } = s
48
+
49
+ return (
50
+ <span key={id}>
49
51
  {[
50
52
  clickString ? `Click: ${clickString}` : '',
51
53
  hoverString ? `Hover: ${hoverString}` : '',
52
54
  ].join(' ')}
53
55
  </span>
56
+ )
57
+ })
58
+ })
59
+
60
+ const InformativeHeaderArea = observer(function ({
61
+ model,
62
+ }: {
63
+ model: JBrowsePluginProteinViewModel
64
+ }) {
65
+ const { showAlignment, showHighlight, zoomToBaseLevel } = model
66
+ return (
67
+ <div style={{ display: 'flex' }}>
68
+ <StructureInfoHeaderArea model={model} />
54
69
  <span style={{ flexGrow: 1 }} />
55
70
  <CascadingMenuButton
56
71
  menuItems={[
@@ -59,21 +74,27 @@ const InformativeHeaderArea = observer(function ({
59
74
  type: 'checkbox',
60
75
  checked: showAlignment,
61
76
  icon: Visibility,
62
- onClick: () => model.setShowAlignment(!showAlignment),
77
+ onClick: () => {
78
+ model.setShowAlignment(!showAlignment)
79
+ },
63
80
  },
64
81
  {
65
82
  label: 'Show pairwise alignment as highlight',
66
83
  type: 'checkbox',
67
84
  checked: showHighlight,
68
85
  icon: Visibility,
69
- onClick: () => model.setShowHighlight(!showHighlight),
86
+ onClick: () => {
87
+ model.setShowHighlight(!showHighlight)
88
+ },
70
89
  },
71
90
  {
72
91
  label: 'Zoom to base level on click',
73
92
  type: 'checkbox',
74
93
  checked: zoomToBaseLevel,
75
94
  icon: Visibility,
76
- onClick: () => model.setZoomToBaseLevel(!zoomToBaseLevel),
95
+ onClick: () => {
96
+ model.setZoomToBaseLevel(!zoomToBaseLevel)
97
+ },
77
98
  },
78
99
  ]}
79
100
  >