jbrowse-plugin-protein3d 0.10.0 → 0.11.1
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/README.md +23 -2
- package/dist/AddHighlightModel/HighlightComponents.js +1 -3
- package/dist/AddHighlightModel/proteinViewLookup.d.ts +0 -10
- package/dist/AddHighlightModel/proteinViewLookup.js +0 -10
- package/dist/LaunchProteinView/components/AlphaFoldDBSearch.js +12 -7
- package/dist/LaunchProteinView/components/AlphaFoldDBSearchStatus.d.ts +3 -5
- package/dist/LaunchProteinView/components/AlphaFoldDBSearchStatus.js +3 -17
- package/dist/LaunchProteinView/components/FoldseekSearch.js +1 -1
- package/dist/LaunchProteinView/components/LaunchProteinViewDialog.js +7 -3
- package/dist/LaunchProteinView/components/PdbResultsTable.d.ts +7 -0
- package/dist/LaunchProteinView/components/PdbResultsTable.js +70 -0
- package/dist/LaunchProteinView/components/PdbSearch.d.ts +13 -0
- package/dist/LaunchProteinView/components/PdbSearch.js +92 -0
- package/dist/LaunchProteinView/components/ProteinViewActions.js +4 -3
- package/dist/LaunchProteinView/components/TranscriptSelector.js +8 -2
- package/dist/LaunchProteinView/components/UniProtIdInput.d.ts +2 -6
- package/dist/LaunchProteinView/components/UniProtIdInput.js +9 -14
- package/dist/LaunchProteinView/components/proteinTrackSetup.js +7 -4
- package/dist/LaunchProteinView/hooks/useAlphaFoldDBSearch.d.ts +24 -28
- package/dist/LaunchProteinView/hooks/useAlphaFoldDBSearch.js +30 -140
- package/dist/LaunchProteinView/hooks/useAlphaFoldData.d.ts +9 -4
- package/dist/LaunchProteinView/hooks/useAlphaFoldData.js +13 -11
- package/dist/LaunchProteinView/hooks/useFoldseekSearch.js +3 -0
- package/dist/LaunchProteinView/hooks/usePdbBestStructures.d.ts +6 -0
- package/dist/LaunchProteinView/hooks/usePdbBestStructures.js +19 -0
- package/dist/LaunchProteinView/hooks/useTranscriptIsoformSelection.js +5 -2
- package/dist/LaunchProteinView/hooks/useTranscriptSelection.js +1 -1
- package/dist/LaunchProteinView/hooks/useUniProtIdLookup.d.ts +36 -0
- package/dist/LaunchProteinView/hooks/useUniProtIdLookup.js +98 -0
- package/dist/LaunchProteinView/services/alphaFoldModels.d.ts +24 -0
- package/dist/LaunchProteinView/services/alphaFoldModels.js +49 -0
- package/dist/LaunchProteinView/services/pdbeBestStructures.d.ts +22 -0
- package/dist/LaunchProteinView/services/pdbeBestStructures.js +66 -0
- package/dist/LaunchProteinView/utils/calculateProteinSequence.d.ts +7 -0
- package/dist/LaunchProteinView/utils/calculateProteinSequence.js +19 -6
- package/dist/LaunchProteinView/utils/isoformRanking.d.ts +44 -0
- package/dist/LaunchProteinView/utils/isoformRanking.js +85 -0
- package/dist/LaunchProteinView/utils/launchHelpers.d.ts +2 -1
- package/dist/LaunchProteinView/utils/launchHelpers.js +2 -1
- package/dist/LaunchProteinView/utils/launchViewUtils.d.ts +1 -2
- package/dist/LaunchProteinView/utils/launchViewUtils.js +1 -2
- package/dist/LaunchProteinView/utils/structureUrls.d.ts +11 -1
- package/dist/LaunchProteinView/utils/structureUrls.js +28 -13
- package/dist/LaunchProteinView/utils/util.d.ts +0 -29
- package/dist/LaunchProteinView/utils/util.js +0 -46
- package/dist/LaunchProteinViewExtensionPoint/index.js +27 -17
- package/dist/ProteinView/__fixtures__/structureFixtures.d.ts +10 -0
- package/dist/ProteinView/__fixtures__/structureFixtures.js +18 -0
- package/dist/ProteinView/addStructureFromData.d.ts +1 -0
- package/dist/ProteinView/addStructureFromURL.d.ts +1 -0
- package/dist/ProteinView/alignmentQuality.d.ts +44 -0
- package/dist/ProteinView/alignmentQuality.js +75 -0
- package/dist/ProteinView/applyColorTheme.d.ts +2 -0
- package/dist/ProteinView/applyColorTheme.js +4 -0
- package/dist/ProteinView/applyLociInteractivity.d.ts +42 -16
- package/dist/ProteinView/applyLociInteractivity.js +40 -34
- package/dist/ProteinView/chooseMappedEntity.d.ts +22 -10
- package/dist/ProteinView/chooseMappedEntity.js +56 -16
- package/dist/ProteinView/components/AlignmentRuler.d.ts +5 -4
- package/dist/ProteinView/components/AlignmentRuler.js +7 -6
- package/dist/ProteinView/components/ChainSelect.js +4 -3
- package/dist/ProteinView/components/FeatureBar.js +14 -3
- package/dist/ProteinView/components/HeaderStructureInfo.js +14 -2
- package/dist/ProteinView/components/ManualAlignmentDialog.js +10 -3
- package/dist/ProteinView/components/ProteinAlignment.js +26 -12
- package/dist/ProteinView/components/ProteinAlignmentHelpButton.js +1 -2
- package/dist/ProteinView/components/ProteinAlignmentHelpDialog.js +2 -1
- package/dist/ProteinView/components/ProteinView.js +3 -6
- package/dist/ProteinView/components/ProteinViewHeader.js +3 -2
- package/dist/ProteinView/connectedHover.d.ts +36 -0
- package/dist/ProteinView/connectedHover.js +28 -0
- package/dist/ProteinView/coordinates.d.ts +14 -0
- package/dist/ProteinView/coordinates.js +21 -0
- package/dist/ProteinView/extractStructureSequences.d.ts +66 -3
- package/dist/ProteinView/extractStructureSequences.js +139 -10
- package/dist/ProteinView/frameSelection.d.ts +32 -0
- package/dist/ProteinView/frameSelection.js +46 -0
- package/dist/ProteinView/hooks/useProteinFeatureTrackData.js +1 -1
- package/dist/ProteinView/hooks/useStructureUniProt.d.ts +9 -5
- package/dist/ProteinView/hooks/useStructureUniProt.js +9 -17
- package/dist/ProteinView/loadStructureData.d.ts +3 -0
- package/dist/ProteinView/loadStructureData.js +13 -3
- package/dist/ProteinView/lociChannel.d.ts +27 -0
- package/dist/ProteinView/lociChannel.js +31 -0
- package/dist/ProteinView/model.d.ts +132 -37
- package/dist/ProteinView/model.js +51 -84
- package/dist/ProteinView/molstarExports.d.ts +1 -0
- package/dist/ProteinView/molstarExports.js +1 -0
- package/dist/ProteinView/pairwiseAlignment.d.ts +6 -0
- package/dist/ProteinView/pairwiseAlignment.js +21 -7
- package/dist/ProteinView/pdbUniProtMapping.d.ts +28 -1
- package/dist/ProteinView/pdbUniProtMapping.js +90 -3
- package/dist/ProteinView/proteinViewSpec.d.ts +24 -2
- package/dist/ProteinView/proteinViewSpec.js +16 -0
- package/dist/ProteinView/showLoading.d.ts +1 -1
- package/dist/ProteinView/showLoading.js +6 -6
- package/dist/ProteinView/storedSettings.d.ts +4 -2
- package/dist/ProteinView/storedSettings.js +3 -2
- package/dist/ProteinView/structureLoader.js +10 -1
- package/dist/ProteinView/structureModel.d.ts +145 -15
- package/dist/ProteinView/structureModel.js +252 -87
- package/dist/ProteinView/structurePipeline.d.ts +1 -0
- package/dist/ProteinView/structurePipeline.js +12 -4
- package/dist/ProteinView/structureSuperposer.d.ts +4 -0
- package/dist/ProteinView/structureSuperposer.js +10 -6
- package/dist/ProteinView/subscribeMolstarInteraction.d.ts +4 -0
- package/dist/ProteinView/subscribeMolstarInteraction.js +1 -0
- package/dist/ProteinView/superposeStructures.js +15 -12
- package/dist/jbrowse-plugin-protein3d.umd.production.min.js +16 -15
- package/dist/jbrowse-plugin-protein3d.umd.production.min.js.map +4 -4
- package/dist/mappings.d.ts +21 -0
- package/dist/mappings.js +106 -10
- package/dist/{molstar-chunk-3W2VYRSS.js → molstar-chunk-2XBGYTCA.js} +11 -11
- package/dist/test_data/molstarStructure.d.ts +12 -0
- package/dist/test_data/molstarStructure.js +37 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -2
- package/src/AddHighlightModel/HighlightComponents.tsx +0 -2
- package/src/AddHighlightModel/proteinViewLookup.ts +0 -15
- package/src/LaunchProteinView/components/AlphaFoldDBSearch.tsx +18 -26
- package/src/LaunchProteinView/components/AlphaFoldDBSearchStatus.tsx +8 -37
- package/src/LaunchProteinView/components/FoldseekSearch.tsx +1 -1
- package/src/LaunchProteinView/components/LaunchProteinViewDialog.tsx +15 -3
- package/src/LaunchProteinView/components/PdbResultsTable.tsx +117 -0
- package/src/LaunchProteinView/components/PdbSearch.tsx +216 -0
- package/src/LaunchProteinView/components/ProteinViewActions.tsx +4 -3
- package/src/LaunchProteinView/components/TranscriptSelector.tsx +13 -3
- package/src/LaunchProteinView/components/UniProtIdInput.tsx +9 -48
- package/src/LaunchProteinView/components/proteinTrackSetup.ts +7 -4
- package/src/LaunchProteinView/hooks/useAlphaFoldDBSearch.ts +36 -184
- package/src/LaunchProteinView/hooks/useAlphaFoldData.ts +30 -15
- package/src/LaunchProteinView/hooks/useFoldseekSearch.ts +3 -0
- package/src/LaunchProteinView/hooks/usePdbBestStructures.ts +32 -0
- package/src/LaunchProteinView/hooks/useTranscriptIsoformSelection.ts +9 -9
- package/src/LaunchProteinView/hooks/useTranscriptSelection.ts +1 -1
- package/src/LaunchProteinView/hooks/useUniProtIdLookup.ts +129 -0
- package/src/LaunchProteinView/services/alphaFoldModels.test.ts +76 -0
- package/src/LaunchProteinView/services/alphaFoldModels.ts +87 -0
- package/src/LaunchProteinView/services/pdbeBestStructures.test.ts +72 -0
- package/src/LaunchProteinView/services/pdbeBestStructures.ts +87 -0
- package/src/LaunchProteinView/utils/calculateProteinSequence.ts +26 -6
- package/src/LaunchProteinView/utils/isoformRanking.ts +138 -0
- package/src/LaunchProteinView/utils/launchHelpers.ts +3 -0
- package/src/LaunchProteinView/utils/launchViewUtils.ts +0 -3
- package/src/LaunchProteinView/utils/pickStructureSequence.test.ts +36 -7
- package/src/LaunchProteinView/utils/selectBestTranscript.test.ts +48 -1
- package/src/LaunchProteinView/utils/structureUrls.test.ts +42 -0
- package/src/LaunchProteinView/utils/structureUrls.ts +36 -17
- package/src/LaunchProteinView/utils/util.ts +0 -81
- package/src/LaunchProteinViewExtensionPoint/index.ts +48 -18
- package/src/ProteinView/__fixtures__/structureFixtures.ts +35 -0
- package/src/ProteinView/alignmentQuality.test.ts +101 -0
- package/src/ProteinView/alignmentQuality.ts +101 -0
- package/src/ProteinView/applyColorTheme.ts +5 -0
- package/src/ProteinView/applyLociInteractivity.ts +81 -49
- package/src/ProteinView/chooseMappedEntity.test.ts +89 -0
- package/src/ProteinView/chooseMappedEntity.ts +93 -23
- package/src/ProteinView/components/AlignmentRuler.tsx +11 -5
- package/src/ProteinView/components/ChainSelect.tsx +4 -3
- package/src/ProteinView/components/FeatureBar.tsx +31 -3
- package/src/ProteinView/components/HeaderStructureInfo.tsx +21 -3
- package/src/ProteinView/components/ManualAlignmentDialog.tsx +18 -3
- package/src/ProteinView/components/ProteinAlignment.tsx +66 -15
- package/src/ProteinView/components/ProteinAlignmentHelpButton.tsx +0 -3
- package/src/ProteinView/components/ProteinAlignmentHelpDialog.tsx +15 -1
- package/src/ProteinView/components/ProteinView.tsx +3 -6
- package/src/ProteinView/components/ProteinViewHeader.tsx +9 -1
- package/src/ProteinView/components/rulerTicks.test.ts +16 -2
- package/src/ProteinView/connectedHover.test.ts +96 -0
- package/src/ProteinView/connectedHover.ts +59 -0
- package/src/ProteinView/coordinates.test.ts +20 -0
- package/src/ProteinView/coordinates.ts +25 -0
- package/src/ProteinView/extractStructureSequences.test.ts +191 -3
- package/src/ProteinView/extractStructureSequences.ts +201 -11
- package/src/ProteinView/frameSelection.test.ts +147 -0
- package/src/ProteinView/frameSelection.ts +71 -0
- package/src/ProteinView/hooks/useProteinFeatureTrackData.ts +1 -1
- package/src/ProteinView/hooks/useStructureUniProt.ts +19 -34
- package/src/ProteinView/loadStructureData.ts +22 -3
- package/src/ProteinView/lociChannel.test.ts +102 -0
- package/src/ProteinView/lociChannel.ts +54 -0
- package/src/ProteinView/model.ts +67 -95
- package/src/ProteinView/molstarExports.ts +1 -0
- package/src/ProteinView/molstarSelectionQuery.test.ts +20 -75
- package/src/ProteinView/pairwiseAlignment.ts +28 -8
- package/src/ProteinView/pdbUniProtMapping.test.ts +148 -5
- package/src/ProteinView/pdbUniProtMapping.ts +120 -5
- package/src/ProteinView/proteinViewSpec.test.ts +23 -3
- package/src/ProteinView/proteinViewSpec.ts +34 -1
- package/src/ProteinView/showLoading.test.ts +5 -5
- package/src/ProteinView/showLoading.ts +7 -9
- package/src/ProteinView/storedSettings.ts +9 -5
- package/src/ProteinView/structureLoader.test.ts +20 -0
- package/src/ProteinView/structureLoader.ts +9 -1
- package/src/ProteinView/structureModel.test.ts +314 -1
- package/src/ProteinView/structureModel.ts +318 -108
- package/src/ProteinView/structurePipeline.ts +14 -6
- package/src/ProteinView/structureSuperposer.test.ts +4 -0
- package/src/ProteinView/structureSuperposer.ts +14 -6
- package/src/ProteinView/subscribeMolstarInteraction.ts +5 -0
- package/src/ProteinView/superposeStructures.ts +17 -22
- package/src/ProteinView/withStoredSettings.test.ts +21 -2
- package/src/mappings.test.ts +77 -0
- package/src/mappings.ts +118 -9
- package/src/test_data/molstarStructure.ts +51 -0
- package/src/version.ts +1 -1
- package/dist/AddHighlightModel/ProteinToMsaHoverSync.d.ts +0 -5
- package/dist/AddHighlightModel/ProteinToMsaHoverSync.js +0 -84
- package/dist/AddHighlightModel/findConnectedMsaView.d.ts +0 -23
- package/dist/AddHighlightModel/findConnectedMsaView.js +0 -23
- package/dist/AddHighlightModel/msaRowMatch.d.ts +0 -10
- package/dist/AddHighlightModel/msaRowMatch.js +0 -16
- package/dist/LaunchProteinView/components/SequenceSearchStatus.d.ts +0 -11
- package/dist/LaunchProteinView/components/SequenceSearchStatus.js +0 -16
- package/dist/LaunchProteinView/hooks/useAlphaFoldSequenceSearch.d.ts +0 -30
- package/dist/LaunchProteinView/hooks/useAlphaFoldSequenceSearch.js +0 -31
- package/dist/LaunchProteinView/utils/md5.d.ts +0 -1
- package/dist/LaunchProteinView/utils/md5.js +0 -130
- package/src/AddHighlightModel/ProteinToMsaHoverSync.tsx +0 -150
- package/src/AddHighlightModel/findConnectedMsaView.test.ts +0 -53
- package/src/AddHighlightModel/findConnectedMsaView.ts +0 -35
- package/src/AddHighlightModel/msaHoverSyncGuard.test.ts +0 -153
- package/src/AddHighlightModel/msaRowMatch.test.ts +0 -27
- package/src/AddHighlightModel/msaRowMatch.ts +0 -20
- package/src/LaunchProteinView/components/SequenceSearchStatus.tsx +0 -41
- package/src/LaunchProteinView/hooks/useAlphaFoldSequenceSearch.ts +0 -66
- package/src/LaunchProteinView/utils/md5.ts +0 -187
- /package/dist/{molstar-chunk-3W2VYRSS.js.map → molstar-chunk-2XBGYTCA.js.map} +0 -0
package/README.md
CHANGED
|
@@ -8,8 +8,9 @@ The major workflow enabled by this is
|
|
|
8
8
|
mouseover between genome and structure
|
|
9
9
|
|
|
10
10
|
It has features to automatically look up a protein structure of interest using
|
|
11
|
-
the UniProt ID mapping API to connect to AlphaFoldDB,
|
|
12
|
-
to
|
|
11
|
+
the UniProt ID mapping API to connect to AlphaFoldDB, lists the experimental PDB
|
|
12
|
+
entries SIFTS maps to that UniProt entry, and can also use Foldseek to look up
|
|
13
|
+
related structures
|
|
13
14
|
|
|
14
15
|
## Coordinate-mapping harness
|
|
15
16
|
|
|
@@ -28,6 +29,13 @@ Source and details in [harness/](harness/).
|
|
|
28
29
|
Example at
|
|
29
30
|
https://jbrowse.org/code/jb2/latest/?config=%2Fucsc%2Fhg38%2Fconfig.json&session=share-aZOIjR_qs4&password=NT4sa
|
|
30
31
|
|
|
32
|
+
## Demos
|
|
33
|
+
|
|
34
|
+
[Structures that are easy to map wrong](docs/demos.md), each one link away: a
|
|
35
|
+
peptide bound to a larger partner, a protein bound to DNA, a receptor with
|
|
36
|
+
another protein fused into it, a phosphorylated residue, and a mitochondrial
|
|
37
|
+
protein.
|
|
38
|
+
|
|
31
39
|
## Publication
|
|
32
40
|
|
|
33
41
|
If you find this tool useful please cite our work
|
|
@@ -48,6 +56,19 @@ use it on any species there
|
|
|
48
56
|
|
|
49
57
|
See [DEVELOPERS.md](DEVELOPERS.md)
|
|
50
58
|
|
|
59
|
+
## How it works
|
|
60
|
+
|
|
61
|
+
Notes on the parts that are easy to get subtly wrong, written for someone
|
|
62
|
+
extending the plugin or checking what a number on screen means:
|
|
63
|
+
|
|
64
|
+
- [Genome to structure alignment](docs/genome-to-structure-alignment.md): why
|
|
65
|
+
the plugin aligns the transcript's translation to the structure on the fly,
|
|
66
|
+
the precedent for that in SIFTS and G2S, how it picks the chain and isoform,
|
|
67
|
+
and what sequence alignment cannot decide.
|
|
68
|
+
- [Residue numbering](docs/residue-numbering.md): how a paper's R248 becomes
|
|
69
|
+
position 154 in the file, `label_seq_id` 155 for Mol\*, and the codon on
|
|
70
|
+
chr17, and how a session spec names a residue the literature's way.
|
|
71
|
+
|
|
51
72
|
## Publishing
|
|
52
73
|
|
|
53
74
|
just push a new tag using e.g.
|
|
@@ -4,14 +4,12 @@ import GenomeMouseoverHighlight from './GenomeMouseoverHighlight';
|
|
|
4
4
|
import GenomeTo1DProteinHoverHighlight from './GenomeTo1DProteinHoverHighlight';
|
|
5
5
|
import Protein1DToGenomeHoverHighlight from './Protein1DToGenomeHoverHighlight';
|
|
6
6
|
import { ProteinToGenomeClickHighlight, ProteinToGenomeHoverHighlight, } from './ProteinToGenomeHighlight';
|
|
7
|
-
import ProteinToMsaHoverSync from './ProteinToMsaHoverSync';
|
|
8
7
|
const HighlightComponents = observer(function Highlight({ model, }) {
|
|
9
8
|
return (React.createElement(React.Fragment, null,
|
|
10
9
|
React.createElement(ProteinToGenomeClickHighlight, { model: model }),
|
|
11
10
|
React.createElement(ProteinToGenomeHoverHighlight, { model: model }),
|
|
12
11
|
React.createElement(Protein1DToGenomeHoverHighlight, { model: model }),
|
|
13
12
|
React.createElement(GenomeTo1DProteinHoverHighlight, { model: model }),
|
|
14
|
-
React.createElement(GenomeMouseoverHighlight, { model: model })
|
|
15
|
-
React.createElement(ProteinToMsaHoverSync, { model: model })));
|
|
13
|
+
React.createElement(GenomeMouseoverHighlight, { model: model })));
|
|
16
14
|
});
|
|
17
15
|
export default HighlightComponents;
|
|
@@ -8,19 +8,9 @@ import type { AbstractSessionModel } from '@jbrowse/core/util';
|
|
|
8
8
|
*/
|
|
9
9
|
export interface HighlightSourceProteinView {
|
|
10
10
|
id: string;
|
|
11
|
-
connectedMsaViewId?: string;
|
|
12
11
|
structures: JBrowsePluginProteinStructureModel[];
|
|
13
|
-
primaryStructure?: JBrowsePluginProteinStructureModel;
|
|
14
12
|
}
|
|
15
13
|
export declare function getProteinViews(session: AbstractSessionModel): HighlightSourceProteinView[];
|
|
16
|
-
/**
|
|
17
|
-
* NOTE: assumes a single ProteinView. Unlike the genome-highlight bridge (which
|
|
18
|
-
* pairs by the declared `connectedViewId`, see getStructuresConnectedTo), a
|
|
19
|
-
* second ProteinView's MSA hover sync is skipped — pairing an MSA to one of
|
|
20
|
-
* several protein views has no reliable rule when the protein view declares
|
|
21
|
-
* neither a connectedMsaViewId nor a connectedViewId.
|
|
22
|
-
*/
|
|
23
|
-
export declare function getProteinView(session: AbstractSessionModel): HighlightSourceProteinView | undefined;
|
|
24
14
|
interface ConnectableStructure {
|
|
25
15
|
connectedViewId?: string;
|
|
26
16
|
}
|
|
@@ -1,16 +1,6 @@
|
|
|
1
1
|
export function getProteinViews(session) {
|
|
2
2
|
return session.views.filter(v => v.type === 'ProteinView');
|
|
3
3
|
}
|
|
4
|
-
/**
|
|
5
|
-
* NOTE: assumes a single ProteinView. Unlike the genome-highlight bridge (which
|
|
6
|
-
* pairs by the declared `connectedViewId`, see getStructuresConnectedTo), a
|
|
7
|
-
* second ProteinView's MSA hover sync is skipped — pairing an MSA to one of
|
|
8
|
-
* several protein views has no reliable rule when the protein view declares
|
|
9
|
-
* neither a connectedMsaViewId nor a connectedViewId.
|
|
10
|
-
*/
|
|
11
|
-
export function getProteinView(session) {
|
|
12
|
-
return getProteinViews(session)[0];
|
|
13
|
-
}
|
|
14
4
|
/**
|
|
15
5
|
* Every structure across all ProteinViews that declares this genome view as its
|
|
16
6
|
* connection. Structures are paired to a genome view explicitly, so a second
|
|
@@ -6,7 +6,6 @@ import { makeStyles } from 'tss-react/mui';
|
|
|
6
6
|
import AlphaFoldDBSearchStatus from './AlphaFoldDBSearchStatus';
|
|
7
7
|
import IdentifierSelector from './IdentifierSelector';
|
|
8
8
|
import ProteinViewActions from './ProteinViewActions';
|
|
9
|
-
import SequenceSearchStatus from './SequenceSearchStatus';
|
|
10
9
|
import TranscriptSelector from './TranscriptSelector';
|
|
11
10
|
import UniProtIdInput from './UniProtIdInput';
|
|
12
11
|
import UniProtResultsTable from './UniProtResultsTable';
|
|
@@ -41,7 +40,11 @@ const AlphaFoldDBSearch = observer(function AlphaFoldDBSearch({ feature, session
|
|
|
41
40
|
return (React.createElement(React.Fragment, null,
|
|
42
41
|
React.createElement(DialogContent, { className: classes.dialogContent },
|
|
43
42
|
state.error ? React.createElement(ErrorMessage, { error: state.error }) : null,
|
|
44
|
-
|
|
43
|
+
state.noModel ? (React.createElement(Typography, null,
|
|
44
|
+
"AlphaFold DB has no model for ",
|
|
45
|
+
state.uniprotId,
|
|
46
|
+
". The PDB and Foldseek tabs may have a structure.")) : null,
|
|
47
|
+
React.createElement(UniProtIdInput, { lookupMode: state.lookupMode, onLookupModeChange: state.setLookupMode, manualUniprotId: state.manualUniprotId, onManualUniprotIdChange: state.setManualUniprotId, featureUniprotId: state.featureUniprotId, endContent: state.showIdentifierSelector ? (React.createElement("div", { className: classes.endRow },
|
|
45
48
|
React.createElement(IdentifierSelector, { recognizedIds: state.recognizedIds, geneName: state.geneName, selectedId: state.selectedQueryId, onSelectedIdChange: state.setSelectedQueryId }),
|
|
46
49
|
React.createElement(TextField, { size: "small", label: "Organism (NCBI taxon)", helperText: "Scopes the gene-name search", value: state.taxonId, onChange: event => {
|
|
47
50
|
state.setTaxonId(event.target.value);
|
|
@@ -65,13 +68,15 @@ const AlphaFoldDBSearch = observer(function AlphaFoldDBSearch({ feature, session
|
|
|
65
68
|
' ',
|
|
66
69
|
React.createElement(ExternalLink, { href: "https://www.uniprot.org/" }, "UniProt"),
|
|
67
70
|
' ',
|
|
68
|
-
"directly and use \"Enter manually\" above
|
|
69
|
-
state.
|
|
71
|
+
"directly and use \"Enter manually\" above.")),
|
|
72
|
+
state.isoformSequences &&
|
|
73
|
+
state.selectedTranscript &&
|
|
74
|
+
state.structureSequence &&
|
|
75
|
+
state.uniprotId ? (React.createElement(React.Fragment, null,
|
|
70
76
|
React.createElement("div", { className: classes.selectorsRow },
|
|
71
77
|
React.createElement(TranscriptSelector, { val: state.userSelection, setVal: state.setUserSelection, structureSequence: state.structureSequence, feature: feature, isoforms: state.transcriptOptions, isoformSequences: state.isoformSequences })),
|
|
72
|
-
|
|
73
|
-
state.showAlphaFoldDBSearchStatus && (React.createElement(AlphaFoldDBSearchStatus, { uniprotId: state.uniprotId, selectedTranscript: state.selectedTranscript, structureSequence: state.structureSequence, isoformSequences: state.isoformSequences, url: state.url })))) : null),
|
|
78
|
+
React.createElement(AlphaFoldDBSearchStatus, { uniprotId: state.modelAccession ?? state.uniprotId, structureSequence: state.structureSequence, isoformSequences: state.isoformSequences, url: state.url }))) : null),
|
|
74
79
|
React.createElement(DialogActions, null,
|
|
75
|
-
React.createElement(ProteinViewActions, { handleClose: handleClose, uniprotId: state.uniprotId, userSelectedProteinSequence: state.userSelectedProteinSequence, selectedTranscript: state.selectedTranscript, url: state.url, confidenceUrl: state.confidenceUrl, feature: feature, view: view, session: session, alignmentAlgorithm: alignmentAlgorithm, onAlignmentAlgorithmChange: onAlignmentAlgorithmChange, sequencesMatch: state.sequencesMatch, isLoading: state.isLoading, error: state.error }))));
|
|
80
|
+
React.createElement(ProteinViewActions, { handleClose: handleClose, uniprotId: state.modelAccession ?? state.uniprotId, userSelectedProteinSequence: state.userSelectedProteinSequence, selectedTranscript: state.selectedTranscript, url: state.url, confidenceUrl: state.confidenceUrl, feature: feature, view: view, session: session, alignmentAlgorithm: alignmentAlgorithm, onAlignmentAlgorithmChange: onAlignmentAlgorithmChange, sequencesMatch: state.sequencesMatch, isLoading: state.isLoading, error: state.error }))));
|
|
76
81
|
});
|
|
77
82
|
export default AlphaFoldDBSearch;
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { IsoformSequences } from '../utils/util';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
selectedTranscript?: Feature;
|
|
7
|
-
structureSequence?: string;
|
|
3
|
+
export default function AlphaFoldDBSearchStatus({ uniprotId, structureSequence, isoformSequences, url, }: {
|
|
4
|
+
uniprotId: string;
|
|
5
|
+
structureSequence: string;
|
|
8
6
|
isoformSequences: IsoformSequences;
|
|
9
7
|
url?: string;
|
|
10
8
|
}): React.JSX.Element;
|
|
@@ -3,15 +3,8 @@ import { Typography } from '@mui/material';
|
|
|
3
3
|
import IsoformSequencesToggle from './IsoformSequencesToggle';
|
|
4
4
|
import ExternalLink from '../../components/ExternalLink';
|
|
5
5
|
import { uniprotEntryUrl } from '../utils/structureUrls';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
return (React.createElement(Typography, null,
|
|
9
|
-
"No structure found for this UniProtID in AlphaFoldDB",
|
|
10
|
-
' ',
|
|
11
|
-
React.createElement(ExternalLink, { href: `https://alphafold.ebi.ac.uk/search/text/${uniprotId}` }, "(search for results)")));
|
|
12
|
-
}
|
|
13
|
-
export default function AlphaFoldDBSearchStatus({ uniprotId, selectedTranscript, structureSequence, isoformSequences, url, }) {
|
|
14
|
-
return uniprotId ? (React.createElement(React.Fragment, null,
|
|
6
|
+
export default function AlphaFoldDBSearchStatus({ uniprotId, structureSequence, isoformSequences, url, }) {
|
|
7
|
+
return (React.createElement(React.Fragment, null,
|
|
15
8
|
React.createElement("div", null,
|
|
16
9
|
React.createElement(Typography, null,
|
|
17
10
|
"UniProt link:",
|
|
@@ -20,12 +13,5 @@ export default function AlphaFoldDBSearchStatus({ uniprotId, selectedTranscript,
|
|
|
20
13
|
React.createElement(Typography, null,
|
|
21
14
|
"AlphaFoldDB link: ",
|
|
22
15
|
React.createElement(ExternalLink, { href: url }, url))),
|
|
23
|
-
|
|
24
|
-
"Searching",
|
|
25
|
-
' ',
|
|
26
|
-
selectedTranscript
|
|
27
|
-
? getTranscriptDisplayName(selectedTranscript)
|
|
28
|
-
: 'transcript',
|
|
29
|
-
' ',
|
|
30
|
-
"for UniProt ID"));
|
|
16
|
+
React.createElement(IsoformSequencesToggle, { structureSequence: structureSequence, structureName: uniprotId, isoformSequences: isoformSequences })));
|
|
31
17
|
}
|
|
@@ -77,7 +77,7 @@ const FoldseekSearch = observer(function FoldseekSearch({ feature, session, view
|
|
|
77
77
|
} }))) : null,
|
|
78
78
|
React.createElement(FoldseekDatabaseSelector, { selected: selectedDatabases, onChange: setSelectedDatabases, disabled: isBusy }),
|
|
79
79
|
statusMessage ? (React.createElement(LoadingEllipses, { variant: "subtitle2", message: statusMessage })) : null,
|
|
80
|
-
results ? (React.createElement(FoldseekResultsTable, { results: results, session: session, view: view, feature: feature, selectedTranscript: selectedTranscript, userProvidedTranscriptSequence:
|
|
80
|
+
results ? (React.createElement(FoldseekResultsTable, { results: results, session: session, view: view, feature: feature, selectedTranscript: selectedTranscript, userProvidedTranscriptSequence: selectedIsoformData?.seq, onClose: handleClose })) : null),
|
|
81
81
|
React.createElement(DialogActions, null,
|
|
82
82
|
React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => {
|
|
83
83
|
handleClose();
|
|
@@ -5,6 +5,7 @@ import { Tab, Tabs } from '@mui/material';
|
|
|
5
5
|
import AlphaFoldDBSearch from './AlphaFoldDBSearch';
|
|
6
6
|
import FoldseekSearch from './FoldseekSearch';
|
|
7
7
|
import HelpButton from './HelpButton';
|
|
8
|
+
import PdbSearch from './PdbSearch';
|
|
8
9
|
import TabPanel from './TabPanel';
|
|
9
10
|
import UserProvidedStructure from './UserProvidedStructure';
|
|
10
11
|
import { DEFAULT_ALIGNMENT_ALGORITHM } from '../../ProteinView/types';
|
|
@@ -21,12 +22,15 @@ export default function LaunchProteinViewDialog({ handleClose, feature, model, }
|
|
|
21
22
|
setChoice(val);
|
|
22
23
|
} },
|
|
23
24
|
React.createElement(Tab, { value: 0, label: "AlphaFoldDB search" }),
|
|
24
|
-
React.createElement(Tab, { value: 1, label: "
|
|
25
|
-
React.createElement(Tab, { value: 2, label: "
|
|
25
|
+
React.createElement(Tab, { value: 1, label: "PDB search" }),
|
|
26
|
+
React.createElement(Tab, { value: 2, label: "Foldseek search" }),
|
|
27
|
+
React.createElement(Tab, { value: 3, label: "Open file manually" })),
|
|
26
28
|
React.createElement(TabPanel, { value: choice, index: 0 },
|
|
27
29
|
React.createElement(AlphaFoldDBSearch, { session: session, view: view, feature: feature, handleClose: handleClose, alignmentAlgorithm: alignmentAlgorithm, onAlignmentAlgorithmChange: setAlignmentAlgorithm })),
|
|
28
30
|
React.createElement(TabPanel, { value: choice, index: 1 },
|
|
29
|
-
React.createElement(
|
|
31
|
+
React.createElement(PdbSearch, { session: session, view: view, feature: feature, handleClose: handleClose, alignmentAlgorithm: alignmentAlgorithm, onAlignmentAlgorithmChange: setAlignmentAlgorithm })),
|
|
30
32
|
React.createElement(TabPanel, { value: choice, index: 2 },
|
|
33
|
+
React.createElement(FoldseekSearch, { session: session, view: view, feature: feature, handleClose: handleClose })),
|
|
34
|
+
React.createElement(TabPanel, { value: choice, index: 3 },
|
|
31
35
|
React.createElement(UserProvidedStructure, { session: session, view: view, feature: feature, handleClose: handleClose, alignmentAlgorithm: alignmentAlgorithm, onAlignmentAlgorithmChange: setAlignmentAlgorithm }))));
|
|
32
36
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { PdbStructureEntry } from '../services/pdbeBestStructures';
|
|
3
|
+
export default function PdbResultsTable({ entries, selectedPdbId, onSelect, }: {
|
|
4
|
+
entries: PdbStructureEntry[];
|
|
5
|
+
selectedPdbId?: string;
|
|
6
|
+
onSelect: (pdbId: string) => void;
|
|
7
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Paper, Radio, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Typography, } from '@mui/material';
|
|
3
|
+
import { makeStyles } from 'tss-react/mui';
|
|
4
|
+
import ExternalLink from '../../components/ExternalLink';
|
|
5
|
+
import { rcsbEntryUrl } from '../services/pdbeBestStructures';
|
|
6
|
+
const useStyles = makeStyles()(theme => ({
|
|
7
|
+
tableContainer: {
|
|
8
|
+
maxHeight: 300,
|
|
9
|
+
},
|
|
10
|
+
headerCell: {
|
|
11
|
+
fontWeight: 'bold',
|
|
12
|
+
backgroundColor: theme.palette.mode === 'dark'
|
|
13
|
+
? theme.palette.grey[900]
|
|
14
|
+
: theme.palette.grey[100],
|
|
15
|
+
},
|
|
16
|
+
selectedRow: {
|
|
17
|
+
backgroundColor: theme.palette.action.selected,
|
|
18
|
+
},
|
|
19
|
+
clickableRow: {
|
|
20
|
+
cursor: 'pointer',
|
|
21
|
+
'&:hover': {
|
|
22
|
+
backgroundColor: theme.palette.action.hover,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
}));
|
|
26
|
+
const MAX_ROWS = 100;
|
|
27
|
+
export default function PdbResultsTable({ entries, selectedPdbId, onSelect, }) {
|
|
28
|
+
const { classes } = useStyles();
|
|
29
|
+
const shown = entries.slice(0, MAX_ROWS);
|
|
30
|
+
return (React.createElement(React.Fragment, null,
|
|
31
|
+
React.createElement(Typography, { variant: "body2", color: "textSecondary" },
|
|
32
|
+
entries.length,
|
|
33
|
+
" PDB entries, ranked by PDBe on coverage and resolution",
|
|
34
|
+
entries.length > shown.length
|
|
35
|
+
? ` (showing the first ${MAX_ROWS})`
|
|
36
|
+
: ''),
|
|
37
|
+
React.createElement(TableContainer, { component: Paper, className: classes.tableContainer },
|
|
38
|
+
React.createElement(Table, { size: "small", stickyHeader: true, "data-testid": "pdb-results-table" },
|
|
39
|
+
React.createElement(TableHead, null,
|
|
40
|
+
React.createElement(TableRow, null,
|
|
41
|
+
React.createElement(TableCell, { className: classes.headerCell, padding: "checkbox" }),
|
|
42
|
+
React.createElement(TableCell, { className: classes.headerCell }, "PDB ID"),
|
|
43
|
+
React.createElement(TableCell, { className: classes.headerCell }, "Method"),
|
|
44
|
+
React.createElement(TableCell, { className: classes.headerCell }, "Resolution"),
|
|
45
|
+
React.createElement(TableCell, { className: classes.headerCell }, "UniProt residues"),
|
|
46
|
+
React.createElement(TableCell, { className: classes.headerCell }, "Coverage"),
|
|
47
|
+
React.createElement(TableCell, { className: classes.headerCell }, "Chains"))),
|
|
48
|
+
React.createElement(TableBody, null, shown.map(entry => {
|
|
49
|
+
const selected = entry.pdbId === selectedPdbId;
|
|
50
|
+
return (React.createElement(TableRow, { key: entry.pdbId, className: `${classes.clickableRow} ${selected ? classes.selectedRow : ''}`, onClick: () => {
|
|
51
|
+
onSelect(entry.pdbId);
|
|
52
|
+
} },
|
|
53
|
+
React.createElement(TableCell, { padding: "checkbox" },
|
|
54
|
+
React.createElement(Radio, { checked: selected, size: "small" })),
|
|
55
|
+
React.createElement(TableCell, null,
|
|
56
|
+
React.createElement(ExternalLink, { href: rcsbEntryUrl(entry.pdbId) }, entry.pdbId.toUpperCase())),
|
|
57
|
+
React.createElement(TableCell, null, entry.experimentalMethod),
|
|
58
|
+
React.createElement(TableCell, null, entry.resolution === undefined
|
|
59
|
+
? '-'
|
|
60
|
+
: `${entry.resolution.toFixed(2)} Å`),
|
|
61
|
+
React.createElement(TableCell, null,
|
|
62
|
+
entry.unpStart,
|
|
63
|
+
"-",
|
|
64
|
+
entry.unpEnd),
|
|
65
|
+
React.createElement(TableCell, null,
|
|
66
|
+
(entry.coverage * 100).toFixed(0),
|
|
67
|
+
"%"),
|
|
68
|
+
React.createElement(TableCell, null, entry.chains.join(', '))));
|
|
69
|
+
}))))));
|
|
70
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { AlignmentAlgorithm } from '../../ProteinView/types';
|
|
3
|
+
import type { AbstractSessionModel, Feature } from '@jbrowse/core/util';
|
|
4
|
+
import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view';
|
|
5
|
+
declare const PdbSearch: ({ feature, session, view, handleClose, alignmentAlgorithm, onAlignmentAlgorithmChange, }: {
|
|
6
|
+
feature: Feature;
|
|
7
|
+
session: AbstractSessionModel;
|
|
8
|
+
view: LinearGenomeViewModel;
|
|
9
|
+
handleClose: () => void;
|
|
10
|
+
alignmentAlgorithm: AlignmentAlgorithm;
|
|
11
|
+
onAlignmentAlgorithmChange: (algorithm: AlignmentAlgorithm) => void;
|
|
12
|
+
}) => React.JSX.Element;
|
|
13
|
+
export default PdbSearch;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { ErrorMessage, LoadingEllipses } from '@jbrowse/core/ui';
|
|
3
|
+
import { DialogActions, DialogContent, TextField, Typography, } from '@mui/material';
|
|
4
|
+
import { observer } from 'mobx-react';
|
|
5
|
+
import { makeStyles } from 'tss-react/mui';
|
|
6
|
+
import IdentifierSelector from './IdentifierSelector';
|
|
7
|
+
import PdbResultsTable from './PdbResultsTable';
|
|
8
|
+
import ProteinViewActions from './ProteinViewActions';
|
|
9
|
+
import TranscriptSelector from './TranscriptSelector';
|
|
10
|
+
import UniProtIdInput from './UniProtIdInput';
|
|
11
|
+
import UniProtResultsTable from './UniProtResultsTable';
|
|
12
|
+
import ExternalLink from '../../components/ExternalLink';
|
|
13
|
+
import usePdbBestStructures from '../hooks/usePdbBestStructures';
|
|
14
|
+
import useTranscriptIsoformSelection from '../hooks/useTranscriptIsoformSelection';
|
|
15
|
+
import useUniProtIdLookup from '../hooks/useUniProtIdLookup';
|
|
16
|
+
import { getPdbStructureUrl, uniprotEntryUrl } from '../utils/structureUrls';
|
|
17
|
+
const useStyles = makeStyles()({
|
|
18
|
+
dialogContent: {
|
|
19
|
+
width: '80em',
|
|
20
|
+
'& > *': {
|
|
21
|
+
marginBottom: 20,
|
|
22
|
+
},
|
|
23
|
+
'& > *:last-child': {
|
|
24
|
+
marginBottom: 0,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
endRow: {
|
|
28
|
+
display: 'flex',
|
|
29
|
+
flexDirection: 'row',
|
|
30
|
+
gap: 12,
|
|
31
|
+
alignItems: 'flex-start',
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
// Experimental structures of the gene's protein, found through SIFTS: PDBe
|
|
35
|
+
// lists every entry mapped to the UniProt accession, ranked on coverage and
|
|
36
|
+
// resolution, so a reader who does not know a PDB id can still reach one.
|
|
37
|
+
// A crystal is usually a fragment, often with partners, so the view aligns
|
|
38
|
+
// the transcript to it after launch rather than expecting a sequence match
|
|
39
|
+
// here.
|
|
40
|
+
const PdbSearch = observer(function PdbSearch({ feature, session, view, handleClose, alignmentAlgorithm, onAlignmentAlgorithmChange, }) {
|
|
41
|
+
const { classes } = useStyles();
|
|
42
|
+
const lookup = useUniProtIdLookup({ feature, view });
|
|
43
|
+
const { uniprotId, isAutoMode, isLookupLoading } = lookup;
|
|
44
|
+
const { entries, error: pdbError, isLoading: isPdbLoading, } = usePdbBestStructures(uniprotId);
|
|
45
|
+
const [userPdbId, setUserPdbId] = useState();
|
|
46
|
+
const { transcripts, isoformSequences, isLoading: isIsoformLoading, error: isoformError, selectedTranscriptId, setSelectedTranscriptId, selectedTranscript, selectedIsoform, } = useTranscriptIsoformSelection({ feature, view, resetKey: uniprotId });
|
|
47
|
+
const selectedPdbId = userPdbId && entries?.some(e => e.pdbId === userPdbId)
|
|
48
|
+
? userPdbId
|
|
49
|
+
: entries?.[0]?.pdbId;
|
|
50
|
+
const loadingStatuses = [
|
|
51
|
+
isLookupLoading && 'Looking up UniProt ID',
|
|
52
|
+
isIsoformLoading && 'Loading protein sequences from transcript isoforms',
|
|
53
|
+
isPdbLoading && 'Listing PDB entries from PDBe',
|
|
54
|
+
].filter((s) => !!s);
|
|
55
|
+
const isLoading = loadingStatuses.length > 0;
|
|
56
|
+
const error = isLoading
|
|
57
|
+
? undefined
|
|
58
|
+
: (isoformError ?? lookup.lookupError ?? pdbError);
|
|
59
|
+
return (React.createElement(React.Fragment, null,
|
|
60
|
+
React.createElement(DialogContent, { className: classes.dialogContent },
|
|
61
|
+
error ? React.createElement(ErrorMessage, { error: error }) : null,
|
|
62
|
+
React.createElement(UniProtIdInput, { lookupMode: lookup.lookupMode, onLookupModeChange: lookup.setLookupMode, manualUniprotId: lookup.manualUniprotId, onManualUniprotIdChange: lookup.setManualUniprotId, featureUniprotId: lookup.featureUniprotId, endContent: lookup.showIdentifierSelector ? (React.createElement("div", { className: classes.endRow },
|
|
63
|
+
React.createElement(IdentifierSelector, { recognizedIds: lookup.recognizedIds, geneName: lookup.geneName, selectedId: lookup.selectedQueryId, onSelectedIdChange: lookup.setSelectedQueryId }),
|
|
64
|
+
React.createElement(TextField, { size: "small", label: "Organism (NCBI taxon)", helperText: "Scopes the gene-name search", value: lookup.taxonId, onChange: event => {
|
|
65
|
+
lookup.setTaxonId(event.target.value);
|
|
66
|
+
}, placeholder: String(lookup.effectiveTaxonId), slotProps: { inputLabel: { shrink: true } }, sx: { width: 180 } }))) : null }),
|
|
67
|
+
loadingStatuses.map(status => (React.createElement(LoadingEllipses, { key: status, variant: "subtitle2", message: status }))),
|
|
68
|
+
isAutoMode && lookup.uniprotEntries.length > 0 ? (React.createElement(React.Fragment, null,
|
|
69
|
+
React.createElement(Typography, { variant: "body2", color: "textSecondary" },
|
|
70
|
+
"Searched UniProt by ",
|
|
71
|
+
lookup.searchDescription),
|
|
72
|
+
React.createElement(UniProtResultsTable, { entries: lookup.uniprotEntries, selectedAccession: lookup.selectedTableAccession, onSelect: lookup.setSelectedUniprotId }))) : null,
|
|
73
|
+
isAutoMode &&
|
|
74
|
+
!isLookupLoading &&
|
|
75
|
+
lookup.uniprotEntries.length === 0 ? (React.createElement(Typography, { variant: "body2", color: "textSecondary" },
|
|
76
|
+
"No UniProt entries found for ",
|
|
77
|
+
lookup.searchDescriptionOr,
|
|
78
|
+
". Try a different identifier above, or search",
|
|
79
|
+
' ',
|
|
80
|
+
React.createElement(ExternalLink, { href: "https://www.uniprot.org/" }, "UniProt"),
|
|
81
|
+
' ',
|
|
82
|
+
"directly and use \"Enter manually\".")) : null,
|
|
83
|
+
uniprotId && entries && !isPdbLoading ? (entries.length > 0 ? (React.createElement(PdbResultsTable, { entries: entries, selectedPdbId: selectedPdbId, onSelect: setUserPdbId })) : (React.createElement(Typography, null,
|
|
84
|
+
"PDBe lists no experimental structure for",
|
|
85
|
+
' ',
|
|
86
|
+
React.createElement(ExternalLink, { href: uniprotEntryUrl(uniprotId) }, uniprotId),
|
|
87
|
+
". The AlphaFoldDB tab has a predicted one."))) : null,
|
|
88
|
+
isoformSequences && selectedTranscript ? (React.createElement(TranscriptSelector, { val: selectedTranscriptId, setVal: setSelectedTranscriptId, feature: feature, isoforms: transcripts, isoformSequences: isoformSequences })) : null),
|
|
89
|
+
React.createElement(DialogActions, null,
|
|
90
|
+
React.createElement(ProteinViewActions, { handleClose: handleClose, uniprotId: uniprotId, userSelectedProteinSequence: selectedIsoform, selectedTranscript: selectedTranscript, url: selectedPdbId ? getPdbStructureUrl(selectedPdbId) : undefined, feature: feature, view: view, session: session, alignmentAlgorithm: alignmentAlgorithm, onAlignmentAlgorithmChange: onAlignmentAlgorithmChange, isLoading: isLoading, error: error }))));
|
|
91
|
+
});
|
|
92
|
+
export default PdbSearch;
|
|
@@ -16,10 +16,11 @@ export default function ProteinViewActions({ handleClose, uniprotId, userSelecte
|
|
|
16
16
|
uniprotId,
|
|
17
17
|
userSelectedProteinSequence,
|
|
18
18
|
selectedTranscript,
|
|
19
|
+
url,
|
|
19
20
|
});
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
const canLaunch = !isLoading && missingReasons.length === 0;
|
|
21
|
+
// Loading or errored, SWR's keepPreviousData can still hold the previous
|
|
22
|
+
// accession's structure, which Launch would open under the new name.
|
|
23
|
+
const canLaunch = !isLoading && !error && missingReasons.length === 0;
|
|
23
24
|
// Suppress the derived reasons while loading or while a real upstream error
|
|
24
25
|
// is displayed above via <ErrorMessage> — a duplicate hint would mislead.
|
|
25
26
|
const showMissingReasons = !isLoading && !error && missingReasons.length > 0;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { MenuItem, TextField } from '@mui/material';
|
|
3
|
-
import { classifyIsoforms
|
|
3
|
+
import { classifyIsoforms } from '../utils/isoformRanking';
|
|
4
|
+
import { getGeneDisplayName, getTranscriptDisplayName, stripStopCodon, } from '../utils/util';
|
|
4
5
|
export default function TranscriptSelector({ val, setVal, isoforms, isoformSequences, structureSequence, feature, disabled, }) {
|
|
5
6
|
const geneName = getGeneDisplayName(feature);
|
|
6
7
|
const { matches, nonMatches, noData } = classifyIsoforms({
|
|
@@ -8,7 +9,12 @@ export default function TranscriptSelector({ val, setVal, isoforms, isoformSeque
|
|
|
8
9
|
isoformSequences,
|
|
9
10
|
structureSequence,
|
|
10
11
|
});
|
|
11
|
-
const
|
|
12
|
+
const structureLength = structureSequence
|
|
13
|
+
? stripStopCodon(structureSequence).length
|
|
14
|
+
: undefined;
|
|
15
|
+
const renderOption = ({ feature: f, length, identical }, note = identical === undefined
|
|
16
|
+
? ''
|
|
17
|
+
: ` (${identical}/${structureLength} structure residues identical)`) => (React.createElement(MenuItem, { value: f.id(), key: f.id() },
|
|
12
18
|
geneName,
|
|
13
19
|
" - ",
|
|
14
20
|
getTranscriptDisplayName(f),
|
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
|
|
3
|
-
export type LookupMode = 'auto' | 'manual' | 'feature' | 'sequence';
|
|
2
|
+
export type LookupMode = 'auto' | 'manual' | 'feature';
|
|
4
3
|
interface UniProtIdInputProps {
|
|
5
4
|
lookupMode: LookupMode;
|
|
6
5
|
onLookupModeChange: (mode: LookupMode) => void;
|
|
7
6
|
manualUniprotId: string;
|
|
8
7
|
onManualUniprotIdChange: (id: string) => void;
|
|
9
8
|
featureUniprotId?: string;
|
|
10
|
-
hasProteinSequence?: boolean;
|
|
11
|
-
sequenceSearchType?: SequenceSearchType;
|
|
12
|
-
onSequenceSearchTypeChange?: (type: SequenceSearchType) => void;
|
|
13
9
|
endContent?: React.ReactNode;
|
|
14
10
|
}
|
|
15
|
-
export default function UniProtIdInput({ lookupMode, onLookupModeChange, manualUniprotId, onManualUniprotIdChange, featureUniprotId,
|
|
11
|
+
export default function UniProtIdInput({ lookupMode, onLookupModeChange, manualUniprotId, onManualUniprotIdChange, featureUniprotId, endContent, }: UniProtIdInputProps): React.JSX.Element;
|
|
16
12
|
export {};
|
|
@@ -1,32 +1,27 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { FormControl, FormControlLabel, Radio, RadioGroup, TextField, Typography, } from '@mui/material';
|
|
3
3
|
import ExternalLink from '../../components/ExternalLink';
|
|
4
|
-
|
|
4
|
+
const LOOKUP_MODES = ['auto', 'manual', 'feature'];
|
|
5
|
+
function isLookupMode(value) {
|
|
6
|
+
return LOOKUP_MODES.some(mode => mode === value);
|
|
7
|
+
}
|
|
8
|
+
export default function UniProtIdInput({ lookupMode, onLookupModeChange, manualUniprotId, onManualUniprotIdChange, featureUniprotId, endContent, }) {
|
|
5
9
|
return (React.createElement(React.Fragment, null,
|
|
6
10
|
React.createElement("div", { style: { display: 'flex', alignItems: 'center', flexWrap: 'wrap' } },
|
|
7
11
|
React.createElement(FormControl, { component: "fieldset" },
|
|
8
12
|
React.createElement(RadioGroup, { row: true, value: lookupMode, onChange: event => {
|
|
9
|
-
|
|
13
|
+
if (isLookupMode(event.target.value)) {
|
|
14
|
+
onLookupModeChange(event.target.value);
|
|
15
|
+
}
|
|
10
16
|
} },
|
|
11
17
|
featureUniprotId && (React.createElement(FormControlLabel, { value: "feature", control: React.createElement(Radio, null), label: `From feature (${featureUniprotId})` })),
|
|
12
18
|
React.createElement(FormControlLabel, { value: "auto", control: React.createElement(Radio, null), label: "Auto-detect using UniProt ID mapping API" }),
|
|
13
|
-
React.createElement(FormControlLabel, { value: "manual", control: React.createElement(Radio, null), label: "Enter manually" }),
|
|
14
|
-
hasProteinSequence && (React.createElement(FormControlLabel, { value: "sequence", control: React.createElement(Radio, null), label: "Search sequence against AlphaFoldDB API" })))),
|
|
19
|
+
React.createElement(FormControlLabel, { value: "manual", control: React.createElement(Radio, null), label: "Enter manually" }))),
|
|
15
20
|
endContent),
|
|
16
21
|
lookupMode === 'manual' && (React.createElement("div", null,
|
|
17
22
|
React.createElement(TextField, { label: "UniProt ID", variant: "outlined", placeholder: "e.g. P68871", size: "small", value: manualUniprotId, onChange: e => {
|
|
18
23
|
onManualUniprotIdChange(e.target.value);
|
|
19
24
|
} }))),
|
|
20
|
-
lookupMode === 'sequence' &&
|
|
21
|
-
sequenceSearchType &&
|
|
22
|
-
onSequenceSearchTypeChange && (React.createElement("div", null,
|
|
23
|
-
React.createElement(FormControl, { component: "fieldset" },
|
|
24
|
-
React.createElement(RadioGroup, { row: true, value: sequenceSearchType, onChange: event => {
|
|
25
|
-
onSequenceSearchTypeChange(event.target.value);
|
|
26
|
-
} },
|
|
27
|
-
React.createElement(FormControlLabel, { value: "md5", control: React.createElement(Radio, null), label: "Exact match" }),
|
|
28
|
-
React.createElement(FormControlLabel, { value: "sequence", control: React.createElement(Radio, null), label: "Fuzzy match" }))),
|
|
29
|
-
React.createElement(Typography, { variant: "body2", color: "text.secondary" }, "May not find the canonical UniProt entry."))),
|
|
30
25
|
lookupMode === 'manual' && !manualUniprotId && (React.createElement(Typography, { variant: "body2", color: "text.secondary" },
|
|
31
26
|
"Search",
|
|
32
27
|
' ',
|
|
@@ -150,8 +150,11 @@ export async function addAllProteinTracks({ session, uniprotId, confidenceUrl, }
|
|
|
150
150
|
uniprotId,
|
|
151
151
|
confidenceUrl,
|
|
152
152
|
});
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
153
|
+
// AlphaFold DB publishes substitution scores for canonical entries only
|
|
154
|
+
if (!uniprotId.includes('-')) {
|
|
155
|
+
addAlphaMissenseTrack({
|
|
156
|
+
session,
|
|
157
|
+
uniprotId,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
157
160
|
}
|
|
@@ -1,50 +1,46 @@
|
|
|
1
|
-
import type { SequenceSearchType } from './useAlphaFoldSequenceSearch';
|
|
2
|
-
import type { LookupMode } from '../components/UniProtIdInput';
|
|
3
1
|
import type { Feature } from '@jbrowse/core/util';
|
|
4
2
|
import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view';
|
|
5
3
|
export default function useAlphaFoldDBSearch({ feature, view, }: {
|
|
6
4
|
feature: Feature;
|
|
7
5
|
view: LinearGenomeViewModel;
|
|
8
6
|
}): {
|
|
9
|
-
lookupMode: LookupMode;
|
|
10
|
-
setLookupMode: import("react").Dispatch<import("react").SetStateAction<LookupMode>>;
|
|
11
|
-
manualUniprotId: string;
|
|
12
|
-
setManualUniprotId: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
13
|
-
taxonId: string;
|
|
14
|
-
setTaxonId: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
15
|
-
effectiveTaxonId: number;
|
|
16
|
-
selectedQueryId: string;
|
|
17
|
-
setSelectedQueryId: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
18
|
-
sequenceSearchType: SequenceSearchType;
|
|
19
|
-
setSequenceSearchType: import("react").Dispatch<import("react").SetStateAction<SequenceSearchType>>;
|
|
20
|
-
selectedUniprotId: string | undefined;
|
|
21
|
-
setSelectedUniprotId: import("react").Dispatch<import("react").SetStateAction<string | undefined>>;
|
|
22
7
|
userSelection: string | undefined;
|
|
23
8
|
setUserSelection: import("react").Dispatch<import("react").SetStateAction<string | undefined>>;
|
|
24
9
|
transcriptOptions: Feature[];
|
|
25
10
|
selectedTranscript: Feature | undefined;
|
|
26
11
|
isoformSequences: import("../utils/util").IsoformSequences | undefined;
|
|
27
12
|
userSelectedProteinSequence: import("../utils/util").IsoformSequence | undefined;
|
|
28
|
-
uniprotEntries: import("../services/lookupMethods").UniProtEntry[];
|
|
29
|
-
recognizedIds: string[];
|
|
30
|
-
geneName: string | undefined;
|
|
31
|
-
featureUniprotId: string | undefined;
|
|
32
|
-
uniprotId: string | undefined;
|
|
33
13
|
url: string | undefined;
|
|
34
14
|
confidenceUrl: string | undefined;
|
|
15
|
+
modelAccession: string | undefined;
|
|
35
16
|
structureSequence: string | undefined;
|
|
17
|
+
noModel: boolean;
|
|
36
18
|
error: any;
|
|
37
19
|
loadingStatuses: string[];
|
|
38
|
-
isSequenceSearchLoading: boolean;
|
|
39
|
-
showIdentifierSelector: boolean;
|
|
40
|
-
showStructureSelectors: boolean;
|
|
41
20
|
sequencesMatch: boolean | undefined;
|
|
42
|
-
searchDescription: string;
|
|
43
|
-
searchDescriptionOr: string;
|
|
44
|
-
selectedTableAccession: string | undefined;
|
|
45
21
|
showUniprotResults: boolean;
|
|
46
22
|
showNoResults: boolean;
|
|
47
|
-
showSequenceSearchStatus: boolean;
|
|
48
|
-
showAlphaFoldDBSearchStatus: boolean;
|
|
49
23
|
isLoading: boolean;
|
|
24
|
+
lookupMode: import("../components/UniProtIdInput").LookupMode;
|
|
25
|
+
setLookupMode: import("react").Dispatch<import("react").SetStateAction<import("../components/UniProtIdInput").LookupMode>>;
|
|
26
|
+
manualUniprotId: string;
|
|
27
|
+
setManualUniprotId: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
28
|
+
taxonId: string;
|
|
29
|
+
setTaxonId: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
30
|
+
effectiveTaxonId: number;
|
|
31
|
+
selectedQueryId: string;
|
|
32
|
+
setSelectedQueryId: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
33
|
+
setSelectedUniprotId: import("react").Dispatch<import("react").SetStateAction<string | undefined>>;
|
|
34
|
+
selectedTableAccession: string | undefined;
|
|
35
|
+
uniprotEntries: import("../services/lookupMethods").UniProtEntry[];
|
|
36
|
+
isLookupLoading: boolean;
|
|
37
|
+
lookupError: any;
|
|
38
|
+
uniprotId: string | undefined;
|
|
39
|
+
featureUniprotId: string | undefined;
|
|
40
|
+
recognizedIds: string[];
|
|
41
|
+
geneName: string | undefined;
|
|
42
|
+
isAutoMode: boolean;
|
|
43
|
+
showIdentifierSelector: boolean;
|
|
44
|
+
searchDescription: string;
|
|
45
|
+
searchDescriptionOr: string;
|
|
50
46
|
};
|