jbrowse-plugin-protein3d 0.11.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 +11 -0
- 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/ProteinViewActions.js +3 -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 +3 -10
- package/dist/LaunchProteinView/hooks/useAlphaFoldDBSearch.js +24 -55
- 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/useTranscriptIsoformSelection.js +5 -2
- package/dist/LaunchProteinView/hooks/useTranscriptSelection.js +1 -1
- package/dist/LaunchProteinView/hooks/useUniProtIdLookup.d.ts +1 -4
- package/dist/LaunchProteinView/hooks/useUniProtIdLookup.js +9 -10
- package/dist/LaunchProteinView/services/alphaFoldModels.d.ts +24 -0
- package/dist/LaunchProteinView/services/alphaFoldModels.js +49 -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/launchViewUtils.d.ts +1 -2
- package/dist/LaunchProteinView/utils/launchViewUtils.js +1 -2
- package/dist/LaunchProteinView/utils/structureUrls.d.ts +2 -1
- package/dist/LaunchProteinView/utils/structureUrls.js +9 -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 +3 -0
- package/dist/ProteinView/__fixtures__/structureFixtures.js +6 -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 +8 -5
- package/dist/ProteinView/chooseMappedEntity.js +34 -18
- package/dist/ProteinView/components/HeaderStructureInfo.js +9 -5
- package/dist/ProteinView/components/ManualAlignmentDialog.js +10 -3
- package/dist/ProteinView/components/ProteinAlignment.js +14 -4
- package/dist/ProteinView/components/ProteinAlignmentHelpDialog.js +1 -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 +15 -3
- package/dist/ProteinView/extractStructureSequences.js +32 -4
- 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 +96 -37
- package/dist/ProteinView/model.js +50 -83
- 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 +16 -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 +109 -15
- package/dist/ProteinView/structureModel.js +199 -82
- 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 +2 -1
- 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/ProteinViewActions.tsx +3 -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 +30 -75
- package/src/LaunchProteinView/hooks/useAlphaFoldData.ts +30 -15
- package/src/LaunchProteinView/hooks/useFoldseekSearch.ts +3 -0
- package/src/LaunchProteinView/hooks/useTranscriptIsoformSelection.ts +9 -9
- package/src/LaunchProteinView/hooks/useTranscriptSelection.ts +1 -1
- package/src/LaunchProteinView/hooks/useUniProtIdLookup.ts +11 -10
- package/src/LaunchProteinView/services/alphaFoldModels.test.ts +76 -0
- package/src/LaunchProteinView/services/alphaFoldModels.ts +87 -0
- package/src/LaunchProteinView/utils/calculateProteinSequence.ts +26 -6
- package/src/LaunchProteinView/utils/isoformRanking.ts +138 -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 +27 -0
- package/src/LaunchProteinView/utils/structureUrls.ts +10 -17
- package/src/LaunchProteinView/utils/util.ts +0 -81
- package/src/LaunchProteinViewExtensionPoint/index.ts +44 -20
- package/src/ProteinView/__fixtures__/structureFixtures.ts +12 -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 +26 -0
- package/src/ProteinView/chooseMappedEntity.ts +48 -20
- package/src/ProteinView/components/HeaderStructureInfo.tsx +10 -6
- package/src/ProteinView/components/ManualAlignmentDialog.tsx +18 -3
- package/src/ProteinView/components/ProteinAlignment.tsx +41 -7
- package/src/ProteinView/components/ProteinAlignmentHelpDialog.tsx +6 -1
- package/src/ProteinView/components/ProteinView.tsx +3 -6
- package/src/ProteinView/components/ProteinViewHeader.tsx +9 -1
- 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 +48 -2
- package/src/ProteinView/extractStructureSequences.ts +58 -5
- 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 +66 -94
- 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 +30 -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 +210 -1
- package/src/ProteinView/structureModel.ts +254 -105
- 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
|
@@ -29,6 +29,13 @@ Source and details in [harness/](harness/).
|
|
|
29
29
|
Example at
|
|
30
30
|
https://jbrowse.org/code/jb2/latest/?config=%2Fucsc%2Fhg38%2Fconfig.json&session=share-aZOIjR_qs4&password=NT4sa
|
|
31
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
|
+
|
|
32
39
|
## Publication
|
|
33
40
|
|
|
34
41
|
If you find this tool useful please cite our work
|
|
@@ -54,6 +61,10 @@ See [DEVELOPERS.md](DEVELOPERS.md)
|
|
|
54
61
|
Notes on the parts that are easy to get subtly wrong, written for someone
|
|
55
62
|
extending the plugin or checking what a number on screen means:
|
|
56
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.
|
|
57
68
|
- [Residue numbering](docs/residue-numbering.md): how a paper's R248 becomes
|
|
58
69
|
position 154 in the file, `label_seq_id` 155 for Mol\*, and the codon on
|
|
59
70
|
chr17, and how a session spec names a residue the literature's way.
|
|
@@ -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();
|
|
@@ -18,9 +18,9 @@ export default function ProteinViewActions({ handleClose, uniprotId, userSelecte
|
|
|
18
18
|
selectedTranscript,
|
|
19
19
|
url,
|
|
20
20
|
});
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
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;
|
|
24
24
|
// Suppress the derived reasons while loading or while a real upstream error
|
|
25
25
|
// is displayed above via <ErrorMessage> — a duplicate hint would mislead.
|
|
26
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,31 +1,25 @@
|
|
|
1
|
-
import type { SequenceSearchType } from './useAlphaFoldSequenceSearch';
|
|
2
1
|
import type { Feature } from '@jbrowse/core/util';
|
|
3
2
|
import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view';
|
|
4
3
|
export default function useAlphaFoldDBSearch({ feature, view, }: {
|
|
5
4
|
feature: Feature;
|
|
6
5
|
view: LinearGenomeViewModel;
|
|
7
6
|
}): {
|
|
8
|
-
sequenceSearchType: SequenceSearchType;
|
|
9
|
-
setSequenceSearchType: import("react").Dispatch<import("react").SetStateAction<SequenceSearchType>>;
|
|
10
7
|
userSelection: string | undefined;
|
|
11
8
|
setUserSelection: import("react").Dispatch<import("react").SetStateAction<string | undefined>>;
|
|
12
9
|
transcriptOptions: Feature[];
|
|
13
10
|
selectedTranscript: Feature | undefined;
|
|
14
11
|
isoformSequences: import("../utils/util").IsoformSequences | undefined;
|
|
15
12
|
userSelectedProteinSequence: import("../utils/util").IsoformSequence | undefined;
|
|
16
|
-
uniprotId: string | undefined;
|
|
17
13
|
url: string | undefined;
|
|
18
14
|
confidenceUrl: string | undefined;
|
|
15
|
+
modelAccession: string | undefined;
|
|
19
16
|
structureSequence: string | undefined;
|
|
17
|
+
noModel: boolean;
|
|
20
18
|
error: any;
|
|
21
19
|
loadingStatuses: string[];
|
|
22
|
-
isSequenceSearchLoading: boolean;
|
|
23
|
-
showStructureSelectors: boolean;
|
|
24
20
|
sequencesMatch: boolean | undefined;
|
|
25
21
|
showUniprotResults: boolean;
|
|
26
22
|
showNoResults: boolean;
|
|
27
|
-
showSequenceSearchStatus: boolean;
|
|
28
|
-
showAlphaFoldDBSearchStatus: boolean;
|
|
29
23
|
isLoading: boolean;
|
|
30
24
|
lookupMode: import("../components/UniProtIdInput").LookupMode;
|
|
31
25
|
setLookupMode: import("react").Dispatch<import("react").SetStateAction<import("../components/UniProtIdInput").LookupMode>>;
|
|
@@ -36,17 +30,16 @@ export default function useAlphaFoldDBSearch({ feature, view, }: {
|
|
|
36
30
|
effectiveTaxonId: number;
|
|
37
31
|
selectedQueryId: string;
|
|
38
32
|
setSelectedQueryId: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
39
|
-
selectedUniprotId: string | undefined;
|
|
40
33
|
setSelectedUniprotId: import("react").Dispatch<import("react").SetStateAction<string | undefined>>;
|
|
41
34
|
selectedTableAccession: string | undefined;
|
|
42
35
|
uniprotEntries: import("../services/lookupMethods").UniProtEntry[];
|
|
43
36
|
isLookupLoading: boolean;
|
|
44
37
|
lookupError: any;
|
|
38
|
+
uniprotId: string | undefined;
|
|
45
39
|
featureUniprotId: string | undefined;
|
|
46
40
|
recognizedIds: string[];
|
|
47
41
|
geneName: string | undefined;
|
|
48
42
|
isAutoMode: boolean;
|
|
49
|
-
isSequenceMode: boolean;
|
|
50
43
|
showIdentifierSelector: boolean;
|
|
51
44
|
searchDescription: string;
|
|
52
45
|
searchDescriptionOr: string;
|
|
@@ -1,80 +1,51 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
2
|
import useAlphaFoldData from './useAlphaFoldData';
|
|
3
|
-
import useAlphaFoldSequenceSearch from './useAlphaFoldSequenceSearch';
|
|
4
3
|
import useTranscriptIsoformSelection from './useTranscriptIsoformSelection';
|
|
5
4
|
import useUniProtIdLookup from './useUniProtIdLookup';
|
|
6
5
|
import { stripStopCodon } from '../utils/util';
|
|
7
6
|
export default function useAlphaFoldDBSearch({ feature, view, }) {
|
|
8
7
|
const lookup = useUniProtIdLookup({ feature, view });
|
|
9
|
-
const { uniprotId,
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
const
|
|
8
|
+
const { uniprotId, isAutoMode, isLookupLoading } = lookup;
|
|
9
|
+
const { isLoading: isAlphaFoldLoading, isValidating: isAlphaFoldValidating, error: alphaFoldError, model, noModel, } = useAlphaFoldData({ uniprotId, feature, view });
|
|
10
|
+
// a stable array, or the isoform picker realigns on every render
|
|
11
|
+
const modelSequence = model?.sequence;
|
|
12
|
+
const structureSequences = useMemo(() => (modelSequence ? [modelSequence] : undefined), [modelSequence]);
|
|
13
|
+
const { transcripts: transcriptOptions, isoformSequences, structureSequence, isLoading: isIsoformLoading, error: isoformError, selectedTranscriptId: userSelection, setSelectedTranscriptId: setUserSelection, selectedTranscript, selectedIsoform: userSelectedProteinSequence, } = useTranscriptIsoformSelection({
|
|
13
14
|
feature,
|
|
14
15
|
view,
|
|
15
|
-
structureSequences
|
|
16
|
-
resetKey:
|
|
16
|
+
structureSequences,
|
|
17
|
+
resetKey: model?.url,
|
|
17
18
|
});
|
|
18
|
-
const { uniprotId: seqSearchUniprotId, cifUrl: seqSearchUrl, plddtDocUrl: seqSearchConfidenceUrl, structureSequence: seqSearchStructureSequence, isLoading: isSequenceSearchLoading, isValidating: isSequenceSearchValidating, error: sequenceSearchError, } = useAlphaFoldSequenceSearch({
|
|
19
|
-
sequence: userSelectedProteinSequence?.seq,
|
|
20
|
-
searchType: sequenceSearchType,
|
|
21
|
-
enabled: isSequenceMode,
|
|
22
|
-
});
|
|
23
|
-
// Merge alphafold / sequence-search results
|
|
24
|
-
const finalUrl = isSequenceMode ? seqSearchUrl : alphaFoldUrl;
|
|
25
|
-
const finalConfidenceUrl = isSequenceMode
|
|
26
|
-
? seqSearchConfidenceUrl
|
|
27
|
-
: alphaFoldConfidenceUrl;
|
|
28
|
-
const finalStructureSequence = isSequenceMode
|
|
29
|
-
? seqSearchStructureSequence
|
|
30
|
-
: alphaFoldStructureSequence;
|
|
31
|
-
const finalUniprotId = isSequenceMode ? seqSearchUniprotId : uniprotId;
|
|
32
|
-
// While a structure fetch is in flight, finalStructureSequence may still be
|
|
33
|
-
// the previous selection's sequence (keepPreviousData). Comparing that stale
|
|
34
|
-
// sequence to the freshly-selected transcript would give a wrong match, so
|
|
35
|
-
// the match is treated as unknown until the fetch settles.
|
|
36
|
-
const isStructureValidating = isSequenceMode
|
|
37
|
-
? isSequenceSearchValidating
|
|
38
|
-
: isAlphaFoldValidating;
|
|
39
19
|
const loadingStatuses = [
|
|
40
20
|
isLookupLoading && 'Looking up UniProt ID',
|
|
41
21
|
isIsoformLoading && 'Loading protein sequences from transcript isoforms',
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
isSequenceSearchLoading &&
|
|
45
|
-
'Searching AlphaFoldDB by sequence',
|
|
46
|
-
].filter((s) => !!s);
|
|
22
|
+
isAlphaFoldLoading && 'Asking AlphaFold DB for models',
|
|
23
|
+
].filter(s => typeof s === 'string');
|
|
47
24
|
const isLoading = loadingStatuses.length > 0;
|
|
48
|
-
//
|
|
49
|
-
|
|
50
|
-
// one-frame gaps that previously caused brief error flashes
|
|
51
|
-
const rawError = isoformError ?? lookup.lookupError ?? alphaFoldError ?? sequenceSearchError;
|
|
25
|
+
// errors wait for loading to finish, so a lookup in flight doesn't flash one
|
|
26
|
+
const rawError = isoformError ?? lookup.lookupError ?? alphaFoldError;
|
|
52
27
|
const error = isLoading ? undefined : rawError;
|
|
53
28
|
return {
|
|
54
29
|
...lookup,
|
|
55
|
-
|
|
56
|
-
setSequenceSearchType,
|
|
57
|
-
userSelection: effectiveTranscriptId,
|
|
30
|
+
userSelection,
|
|
58
31
|
setUserSelection,
|
|
59
32
|
transcriptOptions,
|
|
60
33
|
selectedTranscript,
|
|
61
34
|
isoformSequences,
|
|
62
35
|
userSelectedProteinSequence,
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
structureSequence
|
|
36
|
+
url: model?.url,
|
|
37
|
+
confidenceUrl: model?.confidenceUrl,
|
|
38
|
+
modelAccession: model?.accession,
|
|
39
|
+
structureSequence,
|
|
40
|
+
noModel,
|
|
67
41
|
error,
|
|
68
42
|
loadingStatuses,
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
(isSequenceMode || !!(finalStructureSequence && finalUniprotId)),
|
|
73
|
-
sequencesMatch: !isStructureValidating &&
|
|
43
|
+
// While the structure is refetched, structureSequence is still the previous
|
|
44
|
+
// selection's (keepPreviousData), so a match is unknown until it settles.
|
|
45
|
+
sequencesMatch: !isAlphaFoldValidating &&
|
|
74
46
|
userSelectedProteinSequence?.seq &&
|
|
75
|
-
|
|
76
|
-
? stripStopCodon(userSelectedProteinSequence.seq) ===
|
|
77
|
-
finalStructureSequence
|
|
47
|
+
structureSequence
|
|
48
|
+
? stripStopCodon(userSelectedProteinSequence.seq) === structureSequence
|
|
78
49
|
: undefined,
|
|
79
50
|
showUniprotResults: !!isoformSequences &&
|
|
80
51
|
isAutoMode &&
|
|
@@ -83,8 +54,6 @@ export default function useAlphaFoldDBSearch({ feature, view, }) {
|
|
|
83
54
|
isAutoMode &&
|
|
84
55
|
!isLookupLoading &&
|
|
85
56
|
lookup.uniprotEntries.length === 0,
|
|
86
|
-
showSequenceSearchStatus: isSequenceMode,
|
|
87
|
-
showAlphaFoldDBSearchStatus: !!finalStructureSequence && !!finalUniprotId && !isSequenceMode,
|
|
88
57
|
isLoading,
|
|
89
58
|
};
|
|
90
59
|
}
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
import type { Feature } from '@jbrowse/core/util';
|
|
2
|
+
/** The AlphaFold DB model a launch opens for this gene's accession. */
|
|
3
|
+
export default function useAlphaFoldData({ uniprotId, feature, view, }: {
|
|
2
4
|
uniprotId?: string;
|
|
5
|
+
feature: Feature;
|
|
6
|
+
view?: {
|
|
7
|
+
assemblyNames?: string[];
|
|
8
|
+
};
|
|
3
9
|
}): {
|
|
4
10
|
isLoading: boolean;
|
|
5
11
|
isValidating: boolean;
|
|
6
12
|
error: any;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
structureSequences: string[] | undefined;
|
|
13
|
+
model: import("../services/alphaFoldModels").AlphaFoldModel | undefined;
|
|
14
|
+
noModel: boolean;
|
|
10
15
|
};
|
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const {
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import useSWR from 'swr';
|
|
3
|
+
import { STATIC_SWR_OPTIONS } from './swrOptions';
|
|
4
|
+
import useIsoformProteinSequences from './useIsoformProteinSequences';
|
|
5
|
+
import { fetchAlphaFoldModels, pickAlphaFoldModel, } from '../services/alphaFoldModels';
|
|
6
|
+
/** The AlphaFold DB model a launch opens for this gene's accession. */
|
|
7
|
+
export default function useAlphaFoldData({ uniprotId, feature, view, }) {
|
|
8
|
+
const { data, isLoading, isValidating, error } = useSWR(uniprotId ? ['alphafold-models', uniprotId] : null, ([, id]) => fetchAlphaFoldModels(id), { ...STATIC_SWR_OPTIONS, keepPreviousData: true });
|
|
9
|
+
const { isoformSequences } = useIsoformProteinSequences({ feature, view });
|
|
10
|
+
// with an error, data is the previous accession's (keepPreviousData)
|
|
11
|
+
const model = useMemo(() => data && !error ? pickAlphaFoldModel(data, isoformSequences) : undefined, [data, error, isoformSequences]);
|
|
9
12
|
return {
|
|
10
13
|
isLoading,
|
|
11
14
|
isValidating,
|
|
12
15
|
error,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
structureSequences: sequences,
|
|
16
|
+
model,
|
|
17
|
+
noModel: !!uniprotId && !isLoading && !error && data?.length === 0,
|
|
16
18
|
};
|
|
17
19
|
}
|
|
@@ -80,12 +80,15 @@ export default function useFoldseekSearch() {
|
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
};
|
|
83
|
+
// the aborted operation's own finally skips these, so reset clears them
|
|
83
84
|
const reset = () => {
|
|
84
85
|
abortRef.current?.abort();
|
|
85
86
|
setResults(undefined);
|
|
86
87
|
setPredictData(undefined);
|
|
87
88
|
setError(undefined);
|
|
88
89
|
setStatusMessage('');
|
|
90
|
+
setIsLoading(false);
|
|
91
|
+
setIsPredicting(false);
|
|
89
92
|
};
|
|
90
93
|
return {
|
|
91
94
|
results,
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
1
2
|
import useIsoformProteinSequences from './useIsoformProteinSequences';
|
|
2
3
|
import useTranscriptSelection from './useTranscriptSelection';
|
|
3
|
-
import {
|
|
4
|
+
import { pickStructureSequence } from '../utils/isoformRanking';
|
|
5
|
+
import { getId, getTranscriptFeatures } from '../utils/util';
|
|
4
6
|
// Bundles the transcript-isoform wiring shared by all three launch tabs:
|
|
5
7
|
// list transcripts, fetch their protein sequences, pick which chain of the
|
|
6
8
|
// structure to compare against, auto/manually select a transcript, and resolve
|
|
@@ -11,7 +13,8 @@ export default function useTranscriptIsoformSelection({ feature, view, structure
|
|
|
11
13
|
feature,
|
|
12
14
|
view,
|
|
13
15
|
});
|
|
14
|
-
|
|
16
|
+
// one alignment per chain, so not once per render
|
|
17
|
+
const structureSequence = useMemo(() => pickStructureSequence(structureSequences, isoformSequences), [structureSequences, isoformSequences]);
|
|
15
18
|
const { userSelection, setUserSelection } = useTranscriptSelection({
|
|
16
19
|
options: transcripts,
|
|
17
20
|
isoformSequences,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useState } from 'react';
|
|
2
|
-
import { selectBestTranscript } from '../utils/
|
|
2
|
+
import { selectBestTranscript } from '../utils/isoformRanking';
|
|
3
3
|
export default function useTranscriptSelection({ options, isoformSequences, structureSequence, resetKey, }) {
|
|
4
4
|
const [userSelection, setUserSelection] = useState();
|
|
5
5
|
const [prevResetKey, setPrevResetKey] = useState(resetKey);
|
|
@@ -4,8 +4,7 @@ import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view';
|
|
|
4
4
|
/**
|
|
5
5
|
* Which UniProt entry a feature is, by the dialog's lookup modes: the
|
|
6
6
|
* feature's own attribute, the ID-mapping search over its recognised ids and
|
|
7
|
-
* gene name, a typed accession
|
|
8
|
-
* search itself names the entry). Shared by every tab that starts from an
|
|
7
|
+
* gene name, or a typed accession. Shared by every tab that starts from an
|
|
9
8
|
* accession so they agree on what the gene is.
|
|
10
9
|
*/
|
|
11
10
|
export default function useUniProtIdLookup({ feature, view, }: {
|
|
@@ -21,7 +20,6 @@ export default function useUniProtIdLookup({ feature, view, }: {
|
|
|
21
20
|
effectiveTaxonId: number;
|
|
22
21
|
selectedQueryId: string;
|
|
23
22
|
setSelectedQueryId: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
24
|
-
selectedUniprotId: string | undefined;
|
|
25
23
|
setSelectedUniprotId: import("react").Dispatch<import("react").SetStateAction<string | undefined>>;
|
|
26
24
|
selectedTableAccession: string | undefined;
|
|
27
25
|
uniprotEntries: import("../services/lookupMethods").UniProtEntry[];
|
|
@@ -32,7 +30,6 @@ export default function useUniProtIdLookup({ feature, view, }: {
|
|
|
32
30
|
recognizedIds: string[];
|
|
33
31
|
geneName: string | undefined;
|
|
34
32
|
isAutoMode: boolean;
|
|
35
|
-
isSequenceMode: boolean;
|
|
36
33
|
showIdentifierSelector: boolean;
|
|
37
34
|
searchDescription: string;
|
|
38
35
|
searchDescriptionOr: string;
|