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
@@ -1,22 +1,21 @@
1
1
  import { getSession } from '@jbrowse/core/util'
2
- import { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
3
2
 
4
3
  // locals
5
- import { JBrowsePluginProteinViewModel } from './model'
4
+ import { JBrowsePluginProteinStructureModel } from './model'
6
5
 
7
6
  export function proteinToGenomeMapping({
8
7
  model,
9
8
  structureSeqPos,
10
9
  }: {
11
10
  structureSeqPos: number
12
- model: JBrowsePluginProteinViewModel
11
+ model: JBrowsePluginProteinStructureModel
13
12
  }) {
14
13
  const {
15
14
  genomeToTranscriptSeqMapping,
16
- alignment,
15
+ pairwiseAlignment,
17
16
  structureSeqToTranscriptSeqPosition,
18
17
  } = model
19
- if (!genomeToTranscriptSeqMapping || !alignment) {
18
+ if (!genomeToTranscriptSeqMapping || !pairwiseAlignment) {
20
19
  return undefined
21
20
  }
22
21
  const { p2g, strand } = genomeToTranscriptSeqMapping
@@ -28,9 +27,10 @@ export function proteinToGenomeMapping({
28
27
  if (s0 === undefined) {
29
28
  return undefined
30
29
  }
30
+
31
31
  const start = s0
32
32
  const end = start + 3 * strand
33
- return [Math.min(start, end), Math.max(start, end)]
33
+ return [Math.min(start, end), Math.max(start, end)] as const
34
34
  }
35
35
 
36
36
  export async function clickProteinToGenome({
@@ -38,17 +38,16 @@ export async function clickProteinToGenome({
38
38
  structureSeqPos,
39
39
  }: {
40
40
  structureSeqPos: number
41
- model: JBrowsePluginProteinViewModel
41
+ model: JBrowsePluginProteinStructureModel
42
42
  }) {
43
43
  const session = getSession(model)
44
44
  const result = proteinToGenomeMapping({ structureSeqPos, model })
45
- const { genomeToTranscriptSeqMapping, zoomToBaseLevel } = model
45
+ const { connectedView, genomeToTranscriptSeqMapping, zoomToBaseLevel } = model
46
46
  const { assemblyManager } = session
47
47
  if (!genomeToTranscriptSeqMapping || result === undefined) {
48
48
  return undefined
49
49
  }
50
50
  const [s1, s2] = result
51
- const lgv = session.views[0] as LinearGenomeViewModel
52
51
  const { strand, refName } = genomeToTranscriptSeqMapping
53
52
  model.setClickGenomeHighlights([
54
53
  {
@@ -58,15 +57,18 @@ export async function clickProteinToGenome({
58
57
  end: s2,
59
58
  },
60
59
  ])
61
-
62
- if (!zoomToBaseLevel) {
63
- const assembly = assemblyManager.get(lgv.assemblyNames[0])
64
- const r = assembly?.getCanonicalRefName(refName) ?? refName
65
- lgv.centerAt(s1, r)
66
- } else {
67
- await lgv.navToLocString(
68
- `${refName}:${s1}-${s2}${strand === -1 ? '[rev]' : ''}`,
69
- )
60
+ if (connectedView) {
61
+ if (zoomToBaseLevel) {
62
+ await connectedView.navToLocString(
63
+ `${refName}:${s1}-${s2}${strand === -1 ? '[rev]' : ''}`,
64
+ )
65
+ } else {
66
+ const assembly = assemblyManager.get(connectedView.assemblyNames[0]!)
67
+ connectedView.centerAt(
68
+ s1,
69
+ assembly?.getCanonicalRefName(refName) ?? refName,
70
+ )
71
+ }
70
72
  }
71
73
  }
72
74
 
@@ -74,26 +76,26 @@ export function hoverProteinToGenome({
74
76
  model,
75
77
  structureSeqPos,
76
78
  }: {
77
- structureSeqPos: number
78
- model: JBrowsePluginProteinViewModel
79
+ structureSeqPos?: number
80
+ model: JBrowsePluginProteinStructureModel
79
81
  }) {
80
- const session = getSession(model)
81
- const result = proteinToGenomeMapping({ structureSeqPos, model })
82
- const { genomeToTranscriptSeqMapping } = model
83
- if (!genomeToTranscriptSeqMapping || !result) {
84
- return
85
- }
86
- if (!result) {
87
- session.notify('Genome position not found')
82
+ if (structureSeqPos === undefined) {
83
+ model.setHoverGenomeHighlights([])
84
+ } else {
85
+ const mappedGenomeCoordinate = proteinToGenomeMapping({
86
+ structureSeqPos,
87
+ model,
88
+ })
89
+ const { genomeToTranscriptSeqMapping } = model
90
+ if (genomeToTranscriptSeqMapping && mappedGenomeCoordinate) {
91
+ model.setHoverGenomeHighlights([
92
+ {
93
+ assemblyName: 'hg38',
94
+ refName: genomeToTranscriptSeqMapping.refName,
95
+ start: mappedGenomeCoordinate[0],
96
+ end: mappedGenomeCoordinate[1],
97
+ },
98
+ ])
99
+ }
88
100
  }
89
- const [s1, s2] = result
90
- const { refName } = genomeToTranscriptSeqMapping
91
- model.setHoverGenomeHighlights([
92
- {
93
- assemblyName: 'hg38',
94
- refName,
95
- start: s1,
96
- end: s2,
97
- },
98
- ])
99
101
  }
@@ -13,7 +13,7 @@ export default function selectResidue({
13
13
  }) {
14
14
  const sel = getMolstarStructureSelection({ structure, selectedResidue })
15
15
  const loci = StructureSelection.toLociWithSourceUnits(sel)
16
- plugin?.managers.interactivity.lociSelects.select({
16
+ plugin.managers.interactivity.lociSelects.select({
17
17
  loci,
18
18
  })
19
19
  }
@@ -0,0 +1,512 @@
1
+ import { autorun } from 'mobx'
2
+ import { Region as IRegion } from '@jbrowse/core/util/types'
3
+ import { Instance, addDisposer, getParent, types } from 'mobx-state-tree'
4
+ import {
5
+ SimpleFeature,
6
+ SimpleFeatureSerialized,
7
+ getSession,
8
+ } from '@jbrowse/core/util'
9
+ import { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
10
+
11
+ // locals
12
+ import { checkHovered, invertMap, toStr } from './util'
13
+ import { launchPairwiseAlignment } from './launchRemotePairwiseAlignment'
14
+ import {
15
+ genomeToTranscriptSeqMapping,
16
+ structureSeqVsTranscriptSeqMap,
17
+ structurePositionToAlignmentMap,
18
+ transcriptPositionToAlignmentMap,
19
+ PairwiseAlignment,
20
+ } from '../mappings'
21
+ import { PluginContext } from 'molstar/lib/mol-plugin/context'
22
+ import {
23
+ StructureElement,
24
+ StructureProperties,
25
+ } from 'molstar/lib/mol-model/structure'
26
+ import {
27
+ clickProteinToGenome,
28
+ hoverProteinToGenome,
29
+ } from './proteinToGenomeMapping'
30
+ import selectResidue from './selectResidue'
31
+ import clearSelection from './clearSelection'
32
+ import highlightResidue from './highlightResidue'
33
+
34
+ type LGV = LinearGenomeViewModel
35
+ type MaybeLGV = LGV | undefined
36
+ type MaybePairwiseAlignment = PairwiseAlignment | undefined
37
+ type StructureModel = Awaited<
38
+ ReturnType<PluginContext['builders']['structure']['createModel']>
39
+ >
40
+
41
+ const Structure = types
42
+ .model({
43
+ /**
44
+ * #property
45
+ */
46
+ url: types.maybe(types.string),
47
+ /**
48
+ * #property
49
+ */
50
+ data: types.maybe(types.string),
51
+ /**
52
+ * #property
53
+ */
54
+ connectedViewId: types.maybe(types.string),
55
+ /**
56
+ * #property
57
+ */
58
+ pairwiseAlignment: types.frozen<MaybePairwiseAlignment>(),
59
+ /**
60
+ * #property
61
+ */
62
+ feature: types.frozen<SimpleFeatureSerialized | undefined>(),
63
+ /**
64
+ * #property
65
+ */
66
+ userProvidedTranscriptSequence: types.string,
67
+ })
68
+ .volatile(() => ({
69
+ /**
70
+ * #volatile
71
+ */
72
+ model: undefined as StructureModel | undefined,
73
+ /**
74
+ * #volatile
75
+ */
76
+ clickGenomeHighlights: [] as IRegion[],
77
+ /**
78
+ * #volatile
79
+ */
80
+ hoverGenomeHighlights: [] as IRegion[],
81
+
82
+ /**
83
+ * #volatile
84
+ */
85
+ clickPosition: undefined as
86
+ | {
87
+ structureSeqPos: number
88
+ code: string
89
+ chain: string
90
+ }
91
+ | undefined,
92
+ /**
93
+ * #volatile
94
+ */
95
+ hoverPosition: undefined as
96
+ | {
97
+ structureSeqPos?: number
98
+ code?: string
99
+ chain?: string
100
+ }
101
+ | undefined,
102
+ /**
103
+ * #volatile
104
+ */
105
+ pairwiseAlignmentStatus: '',
106
+ /**
107
+ * #volatile
108
+ */
109
+ structureSequences: undefined as string[] | undefined,
110
+ }))
111
+ .actions(self => ({
112
+ /**
113
+ * #action
114
+ */
115
+ setModel(model: StructureModel) {
116
+ self.model = model
117
+ },
118
+
119
+ setSequences(str?: string[]) {
120
+ self.structureSequences = str
121
+ },
122
+ }))
123
+ .views(self => ({
124
+ /**
125
+ * #getter
126
+ */
127
+ get connectedView() {
128
+ const { views } = getSession(self)
129
+ return views.find(f => f.id === self.connectedViewId) as MaybeLGV
130
+ },
131
+ }))
132
+ .actions(self => ({
133
+ /**
134
+ * #action
135
+ */
136
+ setClickedPosition(arg?: {
137
+ structureSeqPos: number
138
+ code: string
139
+ chain: string
140
+ }) {
141
+ self.clickPosition = arg
142
+ },
143
+ /**
144
+ * #action
145
+ */
146
+ setClickGenomeHighlights(r: IRegion[]) {
147
+ self.clickGenomeHighlights = r
148
+ },
149
+ /**
150
+ * #action
151
+ */
152
+ clearClickGenomeHighlights() {
153
+ self.clickGenomeHighlights = []
154
+ },
155
+ /**
156
+ * #action
157
+ */
158
+ setHoverGenomeHighlights(r: IRegion[]) {
159
+ self.hoverGenomeHighlights = r
160
+ },
161
+ /**
162
+ * #action
163
+ */
164
+ clearHoverGenomeHighlights() {
165
+ self.hoverGenomeHighlights = []
166
+ },
167
+ /**
168
+ * #action
169
+ */
170
+ setHoveredPosition(arg?: {
171
+ structureSeqPos?: number
172
+ chain?: string
173
+ code?: string
174
+ }) {
175
+ self.hoverPosition = arg
176
+ },
177
+ /**
178
+ * #action
179
+ */
180
+ setAlignment(r?: PairwiseAlignment) {
181
+ self.pairwiseAlignment = r
182
+ },
183
+ /**
184
+ * #action
185
+ */
186
+ setAlignmentStatus(str: string) {
187
+ self.pairwiseAlignmentStatus = str
188
+ },
189
+ }))
190
+ .views(self => ({
191
+ /**
192
+ * #getter
193
+ */
194
+ get structureSeqToTranscriptSeqPosition() {
195
+ return self.pairwiseAlignment
196
+ ? structureSeqVsTranscriptSeqMap(self.pairwiseAlignment)
197
+ .structureSeqToTranscriptSeqPosition
198
+ : undefined
199
+ },
200
+ /**
201
+ * #getter
202
+ */
203
+ get transcriptSeqToStructureSeqPosition() {
204
+ return self.pairwiseAlignment
205
+ ? structureSeqVsTranscriptSeqMap(self.pairwiseAlignment)
206
+ .transcriptSeqToStructureSeqPosition
207
+ : undefined
208
+ },
209
+ /**
210
+ * #getter
211
+ */
212
+ get structurePositionToAlignmentMap() {
213
+ return self.pairwiseAlignment
214
+ ? structurePositionToAlignmentMap(self.pairwiseAlignment)
215
+ : undefined
216
+ },
217
+ /**
218
+ * #getter
219
+ */
220
+ get transcriptPositionToAlignmentMap() {
221
+ return self.pairwiseAlignment
222
+ ? transcriptPositionToAlignmentMap(self.pairwiseAlignment)
223
+ : undefined
224
+ },
225
+ /**
226
+ * #getter
227
+ */
228
+ get pairwiseAlignmentToTranscriptPosition() {
229
+ return this.transcriptPositionToAlignmentMap
230
+ ? invertMap(this.transcriptPositionToAlignmentMap)
231
+ : undefined
232
+ },
233
+ /**
234
+ * #getter
235
+ */
236
+ get pairwiseAlignmentToStructurePosition() {
237
+ return this.structurePositionToAlignmentMap
238
+ ? invertMap(this.structurePositionToAlignmentMap)
239
+ : undefined
240
+ },
241
+ /**
242
+ * #getter
243
+ */
244
+ get clickString() {
245
+ const r = self.clickPosition
246
+ return r === undefined ? '' : toStr(r)
247
+ },
248
+ /**
249
+ * #getter
250
+ */
251
+ get hoverString() {
252
+ const r = self.hoverPosition
253
+ return r === undefined ? '' : toStr(r)
254
+ },
255
+ /**
256
+ * #getter
257
+ */
258
+ get genomeToTranscriptSeqMapping() {
259
+ return self.feature
260
+ ? genomeToTranscriptSeqMapping(new SimpleFeature(self.feature))
261
+ : undefined
262
+ },
263
+ /**
264
+ * #getter
265
+ */
266
+ get structureSeqHoverPos() {
267
+ return self.hoverPosition?.structureSeqPos
268
+ },
269
+
270
+ /**
271
+ * #getter
272
+ */
273
+ get exactMatch() {
274
+ const r1 = self.userProvidedTranscriptSequence.replaceAll('*', '')
275
+ const r2 = self.structureSequences?.[0]?.replaceAll('*', '')
276
+ return r1 === r2
277
+ },
278
+
279
+ get zoomToBaseLevel(): boolean {
280
+ // @ts-expect-error
281
+ return getParent(self, 2).zoomToBaseLevel
282
+ },
283
+ get showHighlight(): boolean {
284
+ // @ts-expect-error
285
+ return getParent(self, 2).showHighlight
286
+ },
287
+ get molstarPluginContext(): PluginContext | undefined {
288
+ // @ts-expect-error
289
+ return getParent(self, 2).molstarPluginContext
290
+ },
291
+ }))
292
+ .actions(self => ({
293
+ afterAttach() {
294
+ // pairwise align transcript sequence to structure residues
295
+ addDisposer(
296
+ self,
297
+ autorun(async () => {
298
+ try {
299
+ const {
300
+ userProvidedTranscriptSequence,
301
+ structureSequences,
302
+ exactMatch,
303
+ } = self
304
+ const seq1 = userProvidedTranscriptSequence
305
+ const seq2 = structureSequences?.[0]
306
+
307
+ if (!!self.pairwiseAlignment || !seq1 || !seq2) {
308
+ return
309
+ }
310
+ const r1 = seq1.replaceAll('*', '')
311
+ const r2 = seq2.replaceAll('*', '')
312
+ if (exactMatch) {
313
+ let consensus = ''
314
+ // eslint-disable-next-line @typescript-eslint/prefer-for-of
315
+ for (let i = 0; i < r1.length; i++) {
316
+ consensus += '|'
317
+ }
318
+ self.setAlignment({
319
+ consensus,
320
+ alns: [
321
+ { id: 'seq1', seq: r1 },
322
+ { id: 'seq2', seq: r2 },
323
+ ],
324
+ })
325
+ } else {
326
+ const pairwiseAlignment = await launchPairwiseAlignment({
327
+ seq1: r1,
328
+ seq2: r2,
329
+ algorithm: 'emboss_needle',
330
+ onProgress: arg => {
331
+ self.setAlignmentStatus(arg)
332
+ },
333
+ })
334
+ self.setAlignment(pairwiseAlignment.pairwiseAlignment)
335
+
336
+ // showHighlight when we are
337
+ // @ts-expect-error
338
+ getParent(self, 2).setShowHighlight(true)
339
+ // @ts-expect-error
340
+ getParent(self, 2).setShowAlignment(true)
341
+ }
342
+ } catch (e) {
343
+ console.error(e)
344
+ // @ts-expect-error
345
+ getParent(self, 2).setError(e)
346
+ }
347
+ }),
348
+ )
349
+
350
+ // convert hover over the genome to structure position
351
+ addDisposer(
352
+ self,
353
+ autorun(() => {
354
+ const { hovered } = getSession(self)
355
+ const {
356
+ transcriptSeqToStructureSeqPosition,
357
+ genomeToTranscriptSeqMapping,
358
+ connectedView,
359
+ } = self
360
+ if (
361
+ connectedView?.initialized &&
362
+ genomeToTranscriptSeqMapping &&
363
+ checkHovered(hovered)
364
+ ) {
365
+ const { hoverPosition } = hovered
366
+ const pos = genomeToTranscriptSeqMapping.g2p[hoverPosition.coord]
367
+ const c0 =
368
+ pos === undefined
369
+ ? undefined
370
+ : transcriptSeqToStructureSeqPosition?.[pos]
371
+
372
+ if (c0 !== undefined) {
373
+ self.setHoveredPosition({
374
+ structureSeqPos: c0,
375
+ })
376
+ }
377
+ }
378
+ }),
379
+ )
380
+
381
+ addDisposer(
382
+ self,
383
+ autorun(() => {
384
+ const { molstarPluginContext } = self
385
+ if (molstarPluginContext) {
386
+ const ret =
387
+ molstarPluginContext.behaviors.interaction.click.subscribe(e => {
388
+ if (StructureElement.Loci.is(e.current.loci)) {
389
+ const loc = StructureElement.Loci.getFirstLocation(
390
+ e.current.loci,
391
+ )
392
+ if (loc) {
393
+ const pos = StructureProperties.residue.auth_seq_id(loc)
394
+ const code = StructureProperties.atom.label_comp_id(loc)
395
+ const chain = StructureProperties.chain.auth_asym_id(loc)
396
+ self.setHoveredPosition({
397
+ structureSeqPos: pos - 1,
398
+ code,
399
+ chain,
400
+ })
401
+
402
+ clickProteinToGenome({
403
+ model: self as JBrowsePluginProteinStructureModel,
404
+ structureSeqPos: pos - 1,
405
+ }).catch((e: unknown) => {
406
+ console.error(e)
407
+ // @ts-expect-error
408
+ getParent(self, 2).setError(e)
409
+ })
410
+ }
411
+ }
412
+ })
413
+ return () => {
414
+ ret.unsubscribe()
415
+ }
416
+ }
417
+ return () => {}
418
+ }),
419
+ )
420
+
421
+ addDisposer(
422
+ self,
423
+ autorun(() => {
424
+ const { molstarPluginContext } = self
425
+ if (molstarPluginContext) {
426
+ const ret =
427
+ molstarPluginContext.behaviors.interaction.hover.subscribe(e => {
428
+ if (StructureElement.Loci.is(e.current.loci)) {
429
+ const loc = StructureElement.Loci.getFirstLocation(
430
+ e.current.loci,
431
+ )
432
+ if (loc) {
433
+ // example code for this label
434
+ // https://github.com/molstar/molstar/blob/60550cfea1f62a50a764d5714307d6d1049be71d/src/mol-theme/label.ts#L255-L264
435
+ const pos = StructureProperties.residue.auth_seq_id(loc)
436
+ const code = StructureProperties.atom.label_comp_id(loc)
437
+ const chain = StructureProperties.chain.auth_asym_id(loc)
438
+ self.setHoveredPosition({
439
+ structureSeqPos: pos - 1,
440
+ code,
441
+ chain,
442
+ })
443
+ hoverProteinToGenome({
444
+ model: self as JBrowsePluginProteinStructureModel,
445
+ structureSeqPos: pos - 1,
446
+ })
447
+ }
448
+ }
449
+ })
450
+ return () => {
451
+ ret.unsubscribe()
452
+ }
453
+ }
454
+ return () => {}
455
+ }),
456
+ )
457
+
458
+ addDisposer(
459
+ self,
460
+ autorun(() => {
461
+ const {
462
+ showHighlight,
463
+ structureSeqToTranscriptSeqPosition,
464
+ molstarPluginContext,
465
+ } = self
466
+ const structure =
467
+ molstarPluginContext?.managers.structure.hierarchy.current
468
+ .structures[0]?.cell.obj?.data
469
+ if (structure && structureSeqToTranscriptSeqPosition) {
470
+ if (showHighlight) {
471
+ for (const coord of Object.keys(
472
+ structureSeqToTranscriptSeqPosition,
473
+ )) {
474
+ selectResidue({
475
+ structure,
476
+ plugin: molstarPluginContext,
477
+ selectedResidue: +coord + 1,
478
+ })
479
+ }
480
+ } else {
481
+ clearSelection({
482
+ plugin: molstarPluginContext,
483
+ })
484
+ }
485
+ }
486
+ }),
487
+ )
488
+
489
+ addDisposer(
490
+ self,
491
+ autorun(() => {
492
+ const { structureSeqHoverPos, molstarPluginContext } = self
493
+ const structure =
494
+ molstarPluginContext?.managers.structure.hierarchy.current
495
+ .structures[0]?.cell.obj?.data
496
+ if (structure && structureSeqHoverPos !== undefined) {
497
+ highlightResidue({
498
+ structure,
499
+ plugin: molstarPluginContext,
500
+ selectedResidue: structureSeqHoverPos,
501
+ })
502
+ }
503
+ }),
504
+ )
505
+ },
506
+ }))
507
+
508
+ export default Structure
509
+
510
+ export type JBrowsePluginProteinStructureStateModel = typeof Structure
511
+ export type JBrowsePluginProteinStructureModel =
512
+ Instance<JBrowsePluginProteinStructureStateModel>
@@ -5,23 +5,14 @@ import { createPluginUI } from 'molstar/lib/mol-plugin-ui'
5
5
  import { renderReact18 } from 'molstar/lib/mol-plugin-ui/react18'
6
6
  import { DefaultPluginUISpec } from 'molstar/lib/mol-plugin-ui/spec'
7
7
 
8
- // locals
9
- import { loadStructureFromURL } from './loadStructureFromURL'
10
- import { loadStructureFromData } from './loadStructureFromData'
11
-
12
8
  export default function useProteinView({
13
- url,
14
- data,
15
9
  showControls,
16
10
  }: {
17
- url?: string
18
- data?: string
19
11
  showControls: boolean
20
12
  }) {
21
13
  const parentRef = useRef<HTMLDivElement>(null)
22
14
  const [plugin, setPlugin] = useState<PluginContext>()
23
15
  const [error, setError] = useState<unknown>()
24
- const [seq, setSeq] = useState('')
25
16
 
26
17
  useEffect(() => {
27
18
  let p: PluginContext | undefined
@@ -48,14 +39,6 @@ export default function useProteinView({
48
39
  })
49
40
  await p.initialized
50
41
  setPlugin(p)
51
-
52
- if (url) {
53
- const { seq } = await loadStructureFromURL({ url, plugin: p })
54
- setSeq(seq)
55
- } else if (data) {
56
- const { seq } = await loadStructureFromData({ data, plugin: p })
57
- setSeq(seq)
58
- }
59
42
  } catch (e) {
60
43
  console.error(e)
61
44
  setError(e)
@@ -64,7 +47,7 @@ export default function useProteinView({
64
47
  return () => {
65
48
  p?.unmount()
66
49
  }
67
- }, [url, data, showControls])
50
+ }, [showControls])
68
51
 
69
- return { parentRef, error, plugin, seq }
52
+ return { parentRef, error, plugin }
70
53
  }