jbrowse-plugin-protein3d 0.8.0 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AddHighlightModel/GenomeTo1DProteinHoverHighlight.js +2 -11
- package/dist/AddHighlightModel/ProteinToGenomeHighlightInner.js +8 -4
- package/dist/AddHighlightModel/ProteinToMsaHoverSync.js +6 -2
- package/dist/AddHighlightModel/proteinViewLookup.d.ts +37 -0
- package/dist/AddHighlightModel/proteinViewLookup.js +23 -0
- package/dist/AddHighlightModel/util.d.ts +0 -3
- package/dist/AddHighlightModel/util.js +0 -4
- package/dist/LaunchProteinView/components/AlphaFoldDBSearch.js +3 -1
- package/dist/LaunchProteinView/components/AlphaFoldDBSearchStatus.js +2 -1
- package/dist/LaunchProteinView/components/FoldseekActionMenu.js +4 -3
- package/dist/LaunchProteinView/components/FoldseekResultsTable.js +1 -1
- package/dist/LaunchProteinView/components/FoldseekSearch.js +2 -2
- package/dist/LaunchProteinView/components/LaunchProteinViewDialog.js +1 -1
- package/dist/LaunchProteinView/components/ProteinViewActions.js +3 -3
- package/dist/LaunchProteinView/components/SequenceMismatchNotice.js +2 -3
- package/dist/LaunchProteinView/components/StructureSourcePicker.js +1 -1
- package/dist/LaunchProteinView/components/UniProtResultsTable.js +2 -1
- package/dist/LaunchProteinView/components/UserProvidedStructure.js +4 -2
- package/dist/LaunchProteinView/components/proteinAssemblySetup.js +2 -1
- package/dist/LaunchProteinView/components/proteinTrackSetup.d.ts +0 -41
- package/dist/LaunchProteinView/components/proteinTrackSetup.js +14 -16
- package/dist/LaunchProteinView/hooks/useAlphaFoldDBSearch.js +6 -4
- package/dist/LaunchProteinView/hooks/useAlphaFoldData.d.ts +1 -1
- package/dist/LaunchProteinView/hooks/useAlphaFoldData.js +2 -2
- package/dist/LaunchProteinView/hooks/useAlphaFoldSequenceSearch.js +2 -2
- package/dist/LaunchProteinView/hooks/useStructureFileSequence.js +4 -13
- package/dist/LaunchProteinView/hooks/useTranscriptIsoformSelection.d.ts +3 -2
- package/dist/LaunchProteinView/hooks/useTranscriptIsoformSelection.js +7 -4
- package/dist/LaunchProteinView/index.js +58 -10
- package/dist/LaunchProteinView/services/foldseekApi.d.ts +0 -21
- package/dist/LaunchProteinView/services/foldseekApi.js +13 -10
- package/dist/LaunchProteinView/utils/caCoordsToPdb.d.ts +10 -2
- package/dist/LaunchProteinView/utils/caCoordsToPdb.js +7 -8
- package/dist/LaunchProteinView/utils/calculateProteinSequence.d.ts +3 -13
- package/dist/LaunchProteinView/utils/calculateProteinSequence.js +25 -16
- package/dist/LaunchProteinView/utils/geneticCodes.d.ts +14 -0
- package/dist/LaunchProteinView/utils/geneticCodes.js +227 -0
- package/dist/LaunchProteinView/utils/launchViewUtils.d.ts +4 -13
- package/dist/LaunchProteinView/utils/launchViewUtils.js +4 -6
- package/dist/LaunchProteinView/utils/sideBySide.js +25 -4
- package/dist/LaunchProteinView/utils/structureUrls.d.ts +30 -1
- package/dist/LaunchProteinView/utils/structureUrls.js +63 -1
- package/dist/LaunchProteinView/utils/util.d.ts +24 -1
- package/dist/LaunchProteinView/utils/util.js +30 -6
- package/dist/LaunchProteinViewExtensionPoint/index.js +38 -17
- package/dist/LaunchProteinViewExtensionPoint/resolveShortLaunch.d.ts +3 -2
- package/dist/LaunchProteinViewExtensionPoint/resolveShortLaunch.js +20 -6
- package/dist/ProteinView/addStructureFromData.d.ts +4 -0
- package/dist/ProteinView/addStructureFromData.js +5 -1
- package/dist/ProteinView/addStructureFromURL.d.ts +3 -0
- package/dist/ProteinView/addStructureFromURL.js +4 -1
- package/dist/ProteinView/applyLociInteractivity.d.ts +9 -20
- package/dist/ProteinView/applyLociInteractivity.js +15 -15
- package/dist/ProteinView/chooseMappedEntity.js +20 -10
- package/dist/ProteinView/components/AddStructureDialog.js +17 -18
- package/dist/ProteinView/components/FeatureBar.js +2 -4
- package/dist/ProteinView/components/ManualAlignmentDialog.js +29 -15
- package/dist/ProteinView/components/ProteinAlignment.js +58 -18
- package/dist/ProteinView/components/ProteinFeatureTrack.js +2 -5
- package/dist/ProteinView/components/ProteinView.js +1 -1
- package/dist/ProteinView/components/SplitString.d.ts +9 -0
- package/dist/ProteinView/components/SplitString.js +22 -3
- package/dist/ProteinView/extractStructureSequences.d.ts +38 -4
- package/dist/ProteinView/extractStructureSequences.js +39 -0
- package/dist/ProteinView/hooks/useProteinFeatureTrackData.d.ts +15 -11
- package/dist/ProteinView/hooks/useProteinFeatureTrackData.js +25 -18
- package/dist/ProteinView/hooks/useStructureUniProt.d.ts +26 -0
- package/dist/ProteinView/hooks/useStructureUniProt.js +47 -0
- package/dist/ProteinView/hooks/useUniProtFeatures.js +8 -6
- package/dist/ProteinView/loadStructureData.d.ts +16 -1
- package/dist/ProteinView/loadStructureData.js +10 -5
- package/dist/ProteinView/model.d.ts +29 -26
- package/dist/ProteinView/model.js +2 -2
- package/dist/ProteinView/pairwiseAlignment.d.ts +10 -0
- package/dist/ProteinView/pairwiseAlignment.js +209 -177
- package/dist/ProteinView/pdbUniProtMapping.d.ts +43 -0
- package/dist/ProteinView/pdbUniProtMapping.js +130 -0
- package/dist/ProteinView/proteinViewSpec.d.ts +3 -2
- package/dist/ProteinView/residueTracks.d.ts +0 -2
- package/dist/ProteinView/residueTracks.js +2 -2
- package/dist/ProteinView/structureFormat.d.ts +27 -0
- package/dist/ProteinView/structureFormat.js +65 -0
- package/dist/ProteinView/structureModel.d.ts +41 -25
- package/dist/ProteinView/structureModel.js +114 -100
- package/dist/ProteinView/structurePipeline.d.ts +2 -0
- package/dist/ProteinView/structurePipeline.js +6 -2
- package/dist/ProteinView/subscribeMolstarInteraction.d.ts +9 -7
- package/dist/ProteinView/subscribeMolstarInteraction.js +1 -1
- package/dist/ProteinView/types.d.ts +7 -1
- package/dist/ProteinView/types.js +6 -1
- package/dist/ProteinView/useProteinView.js +1 -1
- package/dist/ProteinView/util.d.ts +14 -0
- package/dist/ProteinView/util.js +17 -0
- package/dist/fetchUtils.d.ts +7 -0
- package/dist/fetchUtils.js +7 -1
- package/dist/jbrowse-plugin-protein3d.umd.production.min.js +17 -16
- package/dist/jbrowse-plugin-protein3d.umd.production.min.js.map +4 -4
- package/dist/mappings.d.ts +22 -0
- package/dist/mappings.js +31 -10
- package/dist/{molstar-chunk-Z2FKPQGY.js → molstar-chunk-UJIWPKE3.js} +1 -1
- package/dist/{molstar-chunk-Z2FKPQGY.js.map → molstar-chunk-UJIWPKE3.js.map} +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +17 -14
- package/src/AddHighlightModel/GenomeTo1DProteinHoverHighlight.tsx +5 -14
- package/src/AddHighlightModel/ProteinToGenomeHighlightInner.tsx +23 -18
- package/src/AddHighlightModel/ProteinToMsaHoverSync.tsx +6 -2
- package/src/AddHighlightModel/msaHoverSyncGuard.test.ts +4 -8
- package/src/AddHighlightModel/proteinViewLookup.test.ts +31 -0
- package/src/AddHighlightModel/proteinViewLookup.ts +56 -0
- package/src/AddHighlightModel/util.ts +0 -9
- package/src/BaseProteinAnnotationAdapter.ts +4 -1
- package/src/LaunchProteinView/components/AlphaFoldDBSearch.tsx +3 -1
- package/src/LaunchProteinView/components/AlphaFoldDBSearchStatus.tsx +2 -3
- package/src/LaunchProteinView/components/FoldseekActionMenu.tsx +7 -5
- package/src/LaunchProteinView/components/FoldseekResultsTable.tsx +1 -1
- package/src/LaunchProteinView/components/FoldseekSearch.tsx +2 -2
- package/src/LaunchProteinView/components/LaunchProteinViewDialog.tsx +1 -0
- package/src/LaunchProteinView/components/ProteinViewActions.tsx +19 -3
- package/src/LaunchProteinView/components/SequenceMismatchNotice.tsx +1 -2
- package/src/LaunchProteinView/components/StructureSourcePicker.tsx +1 -1
- package/src/LaunchProteinView/components/UniProtResultsTable.tsx +2 -3
- package/src/LaunchProteinView/components/UserProvidedStructure.tsx +4 -2
- package/src/LaunchProteinView/components/proteinAssemblySetup.ts +3 -1
- package/src/LaunchProteinView/components/proteinTrackSetup.ts +15 -18
- package/src/LaunchProteinView/hooks/useAlphaFoldDBSearch.ts +6 -3
- package/src/LaunchProteinView/hooks/useAlphaFoldData.ts +2 -2
- package/src/LaunchProteinView/hooks/useAlphaFoldSequenceSearch.ts +2 -2
- package/src/LaunchProteinView/hooks/useSafeLaunch.ts +4 -1
- package/src/LaunchProteinView/hooks/useStructureFileSequence.ts +4 -16
- package/src/LaunchProteinView/hooks/useTranscriptIsoformSelection.ts +17 -5
- package/src/LaunchProteinView/index.ts +113 -34
- package/src/LaunchProteinView/services/foldseekApi.ts +16 -11
- package/src/LaunchProteinView/utils/caCoordsToPdb.ts +9 -8
- package/src/LaunchProteinView/utils/calculateProteinSequence.ts +42 -22
- package/src/LaunchProteinView/utils/geneticCodes.ts +298 -0
- package/src/LaunchProteinView/utils/launchViewUtils.ts +6 -26
- package/src/LaunchProteinView/utils/pickStructureSequence.test.ts +39 -0
- package/src/LaunchProteinView/utils/sideBySide.test.ts +47 -0
- package/src/LaunchProteinView/utils/sideBySide.ts +31 -6
- package/src/LaunchProteinView/utils/stripStopCodon.test.ts +23 -0
- package/src/LaunchProteinView/utils/structureUrls.test.ts +78 -0
- package/src/LaunchProteinView/utils/structureUrls.ts +81 -1
- package/src/LaunchProteinView/utils/util.ts +37 -7
- package/src/LaunchProteinViewExtensionPoint/index.ts +62 -34
- package/src/LaunchProteinViewExtensionPoint/resolveShortLaunch.ts +35 -8
- package/src/Protein1DViewRegistry/index.test.ts +8 -1
- package/src/ProteinView/addStructureFromData.ts +5 -1
- package/src/ProteinView/addStructureFromURL.ts +8 -2
- package/src/ProteinView/applyLociInteractivity.ts +16 -41
- package/src/ProteinView/autoScroll.test.ts +15 -5
- package/src/ProteinView/chooseMappedEntity.test.ts +75 -5
- package/src/ProteinView/chooseMappedEntity.ts +23 -10
- package/src/ProteinView/components/AddStructureDialog.tsx +24 -21
- package/src/ProteinView/components/FeatureBar.tsx +2 -4
- package/src/ProteinView/components/ManualAlignmentDialog.tsx +31 -14
- package/src/ProteinView/components/ProteinAlignment.tsx +105 -44
- package/src/ProteinView/components/ProteinFeatureTrack.tsx +2 -4
- package/src/ProteinView/components/ProteinView.tsx +4 -0
- package/src/ProteinView/components/SplitString.tsx +23 -4
- package/src/ProteinView/components/matchRuns.test.ts +26 -0
- package/src/ProteinView/extractStructureSequences.test.ts +105 -0
- package/src/ProteinView/extractStructureSequences.ts +73 -4
- package/src/ProteinView/geneExplorerLinkage.test.ts +8 -2
- package/src/ProteinView/hooks/layoutFeature.test.ts +87 -0
- package/src/ProteinView/hooks/useProteinFeatureTrackData.ts +38 -22
- package/src/ProteinView/hooks/useStructureUniProt.ts +95 -0
- package/src/ProteinView/hooks/useUniProtFeatures.ts +9 -6
- package/src/ProteinView/labelSeqIdIntegration.test.ts +163 -0
- package/src/ProteinView/loadStructureData.ts +28 -6
- package/src/ProteinView/model.ts +9 -2
- package/src/ProteinView/molstarSelectionQuery.test.ts +147 -0
- package/src/ProteinView/pairwiseAlignment.test.ts +28 -0
- package/src/ProteinView/pairwiseAlignment.ts +269 -210
- package/src/ProteinView/pdbUniProtMapping.test.ts +184 -0
- package/src/ProteinView/pdbUniProtMapping.ts +181 -0
- package/src/ProteinView/proteinViewSpec.ts +2 -1
- package/src/ProteinView/residueTracks.ts +2 -2
- package/src/ProteinView/structureFormat.test.ts +81 -0
- package/src/ProteinView/structureFormat.ts +83 -0
- package/src/ProteinView/structureLoader.test.ts +58 -4
- package/src/ProteinView/structureModel.ts +149 -133
- package/src/ProteinView/structurePipeline.ts +23 -2
- package/src/ProteinView/structureSuperposer.test.ts +3 -1
- package/src/ProteinView/subscribeMolstarInteraction.ts +10 -9
- package/src/ProteinView/types.ts +7 -2
- package/src/ProteinView/useProteinView.ts +1 -1
- package/src/ProteinView/util.test.ts +33 -1
- package/src/ProteinView/util.ts +21 -0
- package/src/UniProtVariationAdapter/parseUniProtVariants.test.ts +1 -4
- package/src/fetchUtils.ts +7 -1
- package/src/mappings.test.characterization.test.ts +16 -1
- package/src/mappings.ts +45 -10
- package/src/version.ts +1 -1
|
@@ -3,7 +3,7 @@ import { SimpleFeature, getSession } from '@jbrowse/core/util';
|
|
|
3
3
|
import { observer } from 'mobx-react';
|
|
4
4
|
import Highlight from './Highlight';
|
|
5
5
|
import { protein1DViewRegistry } from '../Protein1DViewRegistry';
|
|
6
|
-
import {
|
|
6
|
+
import { genomeHoverToTranscriptPos } from '../ProteinView/util';
|
|
7
7
|
import { genomeToTranscriptSeqMapping } from '../mappings';
|
|
8
8
|
const GenomeTo1DProteinHoverHighlight = observer(function GenomeTo1DProteinHoverHighlight({ model, }) {
|
|
9
9
|
const session = getSession(model);
|
|
@@ -17,17 +17,8 @@ const GenomeTo1DProteinHoverHighlight = observer(function GenomeTo1DProteinHover
|
|
|
17
17
|
if (!protein1DInfo) {
|
|
18
18
|
return null;
|
|
19
19
|
}
|
|
20
|
-
if (!checkHovered(hovered)) {
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
23
|
-
const { coord, refName } = hovered.hoverPosition;
|
|
24
20
|
const feature = new SimpleFeature(protein1DInfo.feature);
|
|
25
|
-
const
|
|
26
|
-
const { g2p } = mapping;
|
|
27
|
-
// g2p is keyed by genomic position on the transcript's own refName; without
|
|
28
|
-
// this gate the same numeric coord on an unrelated chromosome would match a
|
|
29
|
-
// key and light a protein residue for a different locus.
|
|
30
|
-
const proteinPos = refName === mapping.refName ? g2p[coord - 1] : undefined;
|
|
21
|
+
const proteinPos = genomeHoverToTranscriptPos(hovered, genomeToTranscriptSeqMapping(feature));
|
|
31
22
|
if (proteinPos === undefined) {
|
|
32
23
|
return null;
|
|
33
24
|
}
|
|
@@ -2,17 +2,21 @@ import React from 'react';
|
|
|
2
2
|
import { getSession } from '@jbrowse/core/util';
|
|
3
3
|
import { observer } from 'mobx-react';
|
|
4
4
|
import Highlight from './Highlight';
|
|
5
|
-
import {
|
|
5
|
+
import { getProteinViews, getStructuresConnectedTo } from './proteinViewLookup';
|
|
6
6
|
const ProteinToGenomeHighlightInner = observer(function ProteinToGenomeHighlightInner({ model, field, }) {
|
|
7
7
|
const session = getSession(model);
|
|
8
8
|
const { assemblyManager } = session;
|
|
9
|
-
const { assemblyNames } = model;
|
|
10
|
-
const proteinView = getProteinView(session);
|
|
9
|
+
const { assemblyNames, id: viewId } = model;
|
|
11
10
|
const assemblyName = assemblyNames[0];
|
|
12
11
|
const assembly = assemblyName
|
|
13
12
|
? assemblyManager.get(assemblyName)
|
|
14
13
|
: undefined;
|
|
15
|
-
|
|
14
|
+
// Only structures that declare this genome view as their connection: the
|
|
15
|
+
// regions are transcript coordinates on that view's assembly, so painting
|
|
16
|
+
// them into any other genome view would place a highlight at coordinates
|
|
17
|
+
// that mean nothing there.
|
|
18
|
+
const structures = getStructuresConnectedTo(getProteinViews(session), viewId);
|
|
19
|
+
return assembly && assemblyName ? (React.createElement(React.Fragment, null, structures.flatMap((structure, idx) => structure[field].map((r, idx2) => (React.createElement(Highlight, { key: `${r.refName}-${r.start}-${r.end}-${idx}-${idx2}`, model: model, region: {
|
|
16
20
|
start: r.start,
|
|
17
21
|
end: r.end,
|
|
18
22
|
refName: r.refName,
|
|
@@ -4,7 +4,7 @@ import { autorun, untracked } from 'mobx';
|
|
|
4
4
|
import { observer } from 'mobx-react';
|
|
5
5
|
import { findConnectedMsaView } from './findConnectedMsaView';
|
|
6
6
|
import { findStructureRowName } from './msaRowMatch';
|
|
7
|
-
import { getProteinView } from './
|
|
7
|
+
import { getProteinView } from './proteinViewLookup';
|
|
8
8
|
import { stripStopCodon } from '../LaunchProteinView/utils/util';
|
|
9
9
|
const ProteinToMsaHoverSync = observer(function ProteinToMsaHoverSync({ model, }) {
|
|
10
10
|
const session = getSession(model);
|
|
@@ -27,7 +27,11 @@ const ProteinToMsaHoverSync = observer(function ProteinToMsaHoverSync({ model, }
|
|
|
27
27
|
// on every hover, so the per-hover conversions below stay cheap.
|
|
28
28
|
let structureRowName;
|
|
29
29
|
disposers.push(autorun(() => {
|
|
30
|
-
|
|
30
|
+
// The *mapped* entity, not entity [0]: hover positions below are in the
|
|
31
|
+
// mapped entity's coordinates (molstar interactions are gated to it), so
|
|
32
|
+
// matching chain A's sequence for a heteromer whose gene is chain C
|
|
33
|
+
// finds no row and silently falls back to a wrong 1:1 mapping.
|
|
34
|
+
const seq = proteinView.primaryStructure?.mappedStructureSeq;
|
|
31
35
|
structureRowName = findStructureRowName(msaView.rowMap, seq === undefined ? undefined : stripStopCodon(seq));
|
|
32
36
|
}));
|
|
33
37
|
if (msaView.setMousePos) {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { JBrowsePluginProteinStructureModel } from '../ProteinView/model';
|
|
2
|
+
import type { AbstractSessionModel } from '@jbrowse/core/util';
|
|
3
|
+
/**
|
|
4
|
+
* What the highlight/hover bridges need from a ProteinView. Declared
|
|
5
|
+
* structurally (like ParentProteinView in structureModel.ts) because the MST
|
|
6
|
+
* Instance type of `structures` widens to a snapshot union at the array
|
|
7
|
+
* boundary, which would force a cast at every call site.
|
|
8
|
+
*/
|
|
9
|
+
export interface HighlightSourceProteinView {
|
|
10
|
+
id: string;
|
|
11
|
+
connectedMsaViewId?: string;
|
|
12
|
+
structures: JBrowsePluginProteinStructureModel[];
|
|
13
|
+
primaryStructure?: JBrowsePluginProteinStructureModel;
|
|
14
|
+
}
|
|
15
|
+
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
|
+
interface ConnectableStructure {
|
|
25
|
+
connectedViewId?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Every structure across all ProteinViews that declares this genome view as its
|
|
29
|
+
* connection. Structures are paired to a genome view explicitly, so a second
|
|
30
|
+
* LinearGenomeView doesn't mirror another view's highlights (the coordinates
|
|
31
|
+
* would be meaningless there, possibly on a different assembly), and a second
|
|
32
|
+
* ProteinView isn't ignored.
|
|
33
|
+
*/
|
|
34
|
+
export declare function getStructuresConnectedTo<T extends ConnectableStructure>(proteinViews: {
|
|
35
|
+
structures: T[];
|
|
36
|
+
}[], viewId: string): T[];
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export function getProteinViews(session) {
|
|
2
|
+
return session.views.filter(v => v.type === 'ProteinView');
|
|
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
|
+
/**
|
|
15
|
+
* Every structure across all ProteinViews that declares this genome view as its
|
|
16
|
+
* connection. Structures are paired to a genome view explicitly, so a second
|
|
17
|
+
* LinearGenomeView doesn't mirror another view's highlights (the coordinates
|
|
18
|
+
* would be meaningless there, possibly on a different assembly), and a second
|
|
19
|
+
* ProteinView isn't ignored.
|
|
20
|
+
*/
|
|
21
|
+
export function getStructuresConnectedTo(proteinViews, viewId) {
|
|
22
|
+
return proteinViews.flatMap(view => view.structures.filter(s => s.connectedViewId === viewId));
|
|
23
|
+
}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import type { JBrowsePluginProteinViewModel } from '../ProteinView/model';
|
|
2
|
-
import type { AbstractSessionModel } from '@jbrowse/core/util';
|
|
3
1
|
import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view';
|
|
4
2
|
export interface HighlightRegion {
|
|
5
3
|
refName: string;
|
|
@@ -20,4 +18,3 @@ export declare const useStyles: (params: void, muiStyleOverridesParams?: {
|
|
|
20
18
|
css: import("tss-react").Css;
|
|
21
19
|
cx: import("tss-react").Cx;
|
|
22
20
|
};
|
|
23
|
-
export declare function getProteinView(session: AbstractSessionModel): JBrowsePluginProteinViewModel | undefined;
|
|
@@ -43,7 +43,9 @@ const AlphaFoldDBSearch = observer(function AlphaFoldDBSearch({ feature, session
|
|
|
43
43
|
state.error ? React.createElement(ErrorMessage, { error: state.error }) : null,
|
|
44
44
|
React.createElement(UniProtIdInput, { lookupMode: state.lookupMode, onLookupModeChange: state.setLookupMode, manualUniprotId: state.manualUniprotId, onManualUniprotIdChange: state.setManualUniprotId, featureUniprotId: state.featureUniprotId, hasProteinSequence: !!state.userSelectedProteinSequence?.seq, sequenceSearchType: state.sequenceSearchType, onSequenceSearchTypeChange: state.setSequenceSearchType, endContent: state.showIdentifierSelector ? (React.createElement("div", { className: classes.endRow },
|
|
45
45
|
React.createElement(IdentifierSelector, { recognizedIds: state.recognizedIds, geneName: state.geneName, selectedId: state.selectedQueryId, onSelectedIdChange: state.setSelectedQueryId }),
|
|
46
|
-
React.createElement(TextField, { size: "small", label: "Organism (NCBI taxon)", helperText: "Scopes the gene-name search", value: state.taxonId, onChange: event => {
|
|
46
|
+
React.createElement(TextField, { size: "small", label: "Organism (NCBI taxon)", helperText: "Scopes the gene-name search", value: state.taxonId, onChange: event => {
|
|
47
|
+
state.setTaxonId(event.target.value);
|
|
48
|
+
}, placeholder: String(state.effectiveTaxonId), slotProps: { inputLabel: { shrink: true } }, sx: { width: 180 } }))) : null }),
|
|
47
49
|
state.loadingStatuses.map(status => (React.createElement(LoadingEllipses, { key: status, variant: "subtitle2", message: status }))),
|
|
48
50
|
state.showUniprotResults && (React.createElement(React.Fragment, null,
|
|
49
51
|
React.createElement(Typography, { variant: "body2", color: "textSecondary" },
|
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { Typography } from '@mui/material';
|
|
3
3
|
import IsoformSequencesToggle from './IsoformSequencesToggle';
|
|
4
4
|
import ExternalLink from '../../components/ExternalLink';
|
|
5
|
+
import { uniprotEntryUrl } from '../utils/structureUrls';
|
|
5
6
|
import { getTranscriptDisplayName } from '../utils/util';
|
|
6
7
|
function NotFound({ uniprotId }) {
|
|
7
8
|
return (React.createElement(Typography, null,
|
|
@@ -15,7 +16,7 @@ export default function AlphaFoldDBSearchStatus({ uniprotId, selectedTranscript,
|
|
|
15
16
|
React.createElement(Typography, null,
|
|
16
17
|
"UniProt link:",
|
|
17
18
|
' ',
|
|
18
|
-
React.createElement(ExternalLink, { href:
|
|
19
|
+
React.createElement(ExternalLink, { href: uniprotEntryUrl(uniprotId) }, uniprotId)),
|
|
19
20
|
React.createElement(Typography, null,
|
|
20
21
|
"AlphaFoldDB link: ",
|
|
21
22
|
React.createElement(ExternalLink, { href: url }, url))),
|
|
@@ -3,7 +3,8 @@ import { ErrorMessage } from '@jbrowse/core/ui';
|
|
|
3
3
|
import { Button, Menu, MenuItem } from '@mui/material';
|
|
4
4
|
import { useSafeLaunch } from '../hooks/useSafeLaunch';
|
|
5
5
|
import { caCoordsToPdb, hasValidCaCoords } from '../utils/caCoordsToPdb';
|
|
6
|
-
import { getConditionalProteinLaunches,
|
|
6
|
+
import { getConditionalProteinLaunches, launch3DProteinView, } from '../utils/launchViewUtils';
|
|
7
|
+
import { getConfidenceUrlFromTarget, getUniprotIdFromAlphaFoldTarget, } from '../utils/structureUrls';
|
|
7
8
|
export default function FoldseekActionMenu({ hit, session, view, feature, selectedTranscript, userProvidedTranscriptSequence, onClose, }) {
|
|
8
9
|
const [anchorEl, setAnchorEl] = useState(null);
|
|
9
10
|
const open = Boolean(anchorEl);
|
|
@@ -18,7 +19,7 @@ export default function FoldseekActionMenu({ hit, session, view, feature, select
|
|
|
18
19
|
const baseParams = { session, view, feature, selectedTranscript, uniprotId };
|
|
19
20
|
const handleLaunch3D = runLaunch(() => {
|
|
20
21
|
// Use tCa coordinates to generate PDB data if no URL is available
|
|
21
|
-
const pdbData = !hit.structureUrl && hasValidCaCoords(hit
|
|
22
|
+
const pdbData = !hit.structureUrl && hasValidCaCoords(hit)
|
|
22
23
|
? caCoordsToPdb(hit.tCa, hit.tSeq, 'A', hit.target)
|
|
23
24
|
: undefined;
|
|
24
25
|
launch3DProteinView({
|
|
@@ -32,7 +33,7 @@ export default function FoldseekActionMenu({ hit, session, view, feature, select
|
|
|
32
33
|
...baseParams,
|
|
33
34
|
confidenceUrl: getConfidenceUrlFromTarget(hit.target),
|
|
34
35
|
});
|
|
35
|
-
const canLoad = !!hit.structureUrl || hasValidCaCoords(hit
|
|
36
|
+
const canLoad = !!hit.structureUrl || hasValidCaCoords(hit);
|
|
36
37
|
if (!canLoad) {
|
|
37
38
|
return React.createElement("span", null, "-");
|
|
38
39
|
}
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Typography, } from '@mui/material';
|
|
3
3
|
import { makeStyles } from 'tss-react/mui';
|
|
4
4
|
import FoldseekActionMenu from './FoldseekActionMenu';
|
|
5
|
-
import { getStructureUrlFromTarget } from '../utils/
|
|
5
|
+
import { getStructureUrlFromTarget } from '../utils/structureUrls';
|
|
6
6
|
const useStyles = makeStyles()(theme => ({
|
|
7
7
|
root: {
|
|
8
8
|
display: 'flex',
|
|
@@ -9,7 +9,7 @@ import TranscriptSelector from './TranscriptSelector';
|
|
|
9
9
|
import useFoldseekSearch from '../hooks/useFoldseekSearch';
|
|
10
10
|
import useTranscriptIsoformSelection from '../hooks/useTranscriptIsoformSelection';
|
|
11
11
|
import { DEFAULT_DATABASES } from '../services/foldseekApi';
|
|
12
|
-
import {
|
|
12
|
+
import { stripAllStopCodons } from '../utils/util';
|
|
13
13
|
const useStyles = makeStyles()({
|
|
14
14
|
dialogContent: {
|
|
15
15
|
width: '80em',
|
|
@@ -33,7 +33,7 @@ const FoldseekSearch = observer(function FoldseekSearch({ feature, session, view
|
|
|
33
33
|
const { results, cleanedAaSequence, di3Sequence, isLoading, isPredicting, error, statusMessage, predictStructure, search, reset, } = useFoldseekSearch();
|
|
34
34
|
const { transcripts, isoformSequences, isLoading: isLoadingIsoforms, error: isoformError, selectedTranscriptId: effectiveSelectedTranscriptId, setSelectedTranscriptId: setUserSelection, selectedTranscript, selectedIsoform: selectedIsoformData, } = useTranscriptIsoformSelection({ feature, view });
|
|
35
35
|
const cleanedSequence = selectedIsoformData
|
|
36
|
-
?
|
|
36
|
+
? stripAllStopCodons(selectedIsoformData.seq)
|
|
37
37
|
: '';
|
|
38
38
|
const sequence = userEditedSequence ?? cleanedSequence;
|
|
39
39
|
// Any change to the input sequence makes an existing 3Di prediction (and any
|
|
@@ -14,7 +14,7 @@ export default function LaunchProteinViewDialog({ handleClose, feature, model, }
|
|
|
14
14
|
const [alignmentAlgorithm, setAlignmentAlgorithm] = useLocalStorage('jbrowse-protein3d-alignment-algorithm', DEFAULT_ALIGNMENT_ALGORITHM);
|
|
15
15
|
const session = getSession(model);
|
|
16
16
|
const view = getContainingView(model);
|
|
17
|
-
return (React.createElement(Dialog, { maxWidth: "xl", title: "Launch protein view", titleNode: React.createElement(React.Fragment, null,
|
|
17
|
+
return (React.createElement(Dialog, { "data-testid": "launch-protein-view-dialog", maxWidth: "xl", title: "Launch protein view", titleNode: React.createElement(React.Fragment, null,
|
|
18
18
|
"Launch protein view ",
|
|
19
19
|
React.createElement(HelpButton, null)), open: true, onClose: handleClose },
|
|
20
20
|
React.createElement(Tabs, { value: choice, onChange: (_, val) => {
|
|
@@ -2,7 +2,7 @@ import React, { useState } from 'react';
|
|
|
2
2
|
import { ErrorMessage } from '@jbrowse/core/ui';
|
|
3
3
|
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
|
|
4
4
|
import SettingsIcon from '@mui/icons-material/Settings';
|
|
5
|
-
import { Button, ButtonGroup, IconButton, Tooltip, Typography } from '@mui/material';
|
|
5
|
+
import { Button, ButtonGroup, IconButton, Tooltip, Typography, } from '@mui/material';
|
|
6
6
|
import LaunchOptionsDialog from './LaunchOptionsDialog';
|
|
7
7
|
import LaunchSettingsDialog from './LaunchSettingsDialog';
|
|
8
8
|
import SequenceMismatchNotice from './SequenceMismatchNotice';
|
|
@@ -95,8 +95,8 @@ export default function ProteinViewActions({ handleClose, uniprotId, userSelecte
|
|
|
95
95
|
} }, "Cancel"),
|
|
96
96
|
showMissingReasons ? (React.createElement(Typography, { variant: "body2", color: "error", sx: { mr: 2 } }, missingReasons.join('. '))) : null,
|
|
97
97
|
React.createElement(ButtonGroup, { variant: "contained", color: "primary", size: "small" },
|
|
98
|
-
React.createElement(Button, { disabled: !canLaunch, onClick: handleLaunch3DView }, "Launch"),
|
|
99
|
-
React.createElement(Button, { disabled: !canLaunch, onClick: () => {
|
|
98
|
+
React.createElement(Button, { "data-testid": "protein-launch-button", disabled: !canLaunch, onClick: handleLaunch3DView }, "Launch"),
|
|
99
|
+
React.createElement(Button, { "data-testid": "protein-launch-options-button", disabled: !canLaunch, onClick: () => {
|
|
100
100
|
setDialogOpen(true);
|
|
101
101
|
}, "aria-label": "More launch options" },
|
|
102
102
|
React.createElement(ArrowDropDownIcon, null))),
|
|
@@ -6,8 +6,7 @@ export default function SequenceMismatchNotice({ alignmentAlgorithm, onAlignment
|
|
|
6
6
|
return (React.createElement(Typography, { variant: "body2", sx: { mr: 2, display: 'flex', alignItems: 'center' } },
|
|
7
7
|
"Transcript and structure sequences differ, will run",
|
|
8
8
|
' ',
|
|
9
|
-
ALIGNMENT_ALGORITHM_LABELS[alignmentAlgorithm]
|
|
10
|
-
|
|
11
|
-
"alignment",
|
|
9
|
+
ALIGNMENT_ALGORITHM_LABELS[alignmentAlgorithm],
|
|
10
|
+
" alignment",
|
|
12
11
|
React.createElement(AlignmentSettingsButton, { value: alignmentAlgorithm, onChange: onAlignmentAlgorithmChange })));
|
|
13
12
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Button, FormControl, FormControlLabel, Radio, RadioGroup, TextField, Typography, } from '@mui/material';
|
|
3
3
|
import HelpButton from './HelpButton';
|
|
4
|
-
import { getPdbStructureUrl } from '../utils/
|
|
4
|
+
import { getPdbStructureUrl } from '../utils/structureUrls';
|
|
5
5
|
export default function StructureSourcePicker({ choice, setChoice, structureURL, setStructureURL, setFile, pdbId, setPdbId, }) {
|
|
6
6
|
return (React.createElement("div", { style: { display: 'flex', margin: 30 } },
|
|
7
7
|
React.createElement(Typography, null,
|
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { Chip, Paper, Radio, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Typography, } from '@mui/material';
|
|
3
3
|
import { makeStyles } from 'tss-react/mui';
|
|
4
4
|
import ExternalLink from '../../components/ExternalLink';
|
|
5
|
+
import { uniprotEntryUrl } from '../utils/structureUrls';
|
|
5
6
|
const useStyles = makeStyles()(theme => ({
|
|
6
7
|
tableContainer: {
|
|
7
8
|
maxHeight: 200,
|
|
@@ -57,7 +58,7 @@ export default function UniProtResultsTable({ entries, selectedAccession, onSele
|
|
|
57
58
|
React.createElement(TableCell, { padding: "checkbox" },
|
|
58
59
|
React.createElement(Radio, { checked: selectedAccession === entry.accession, size: "small" })),
|
|
59
60
|
React.createElement(TableCell, null,
|
|
60
|
-
React.createElement(ExternalLink, { href:
|
|
61
|
+
React.createElement(ExternalLink, { href: uniprotEntryUrl(entry.accession) }, entry.accession)),
|
|
61
62
|
React.createElement(TableCell, null, entry.geneName ?? '-'),
|
|
62
63
|
React.createElement(TableCell, null, entry.organismName ?? '-'),
|
|
63
64
|
React.createElement(TableCell, null, entry.proteinName
|
|
@@ -40,8 +40,10 @@ const UserProvidedStructure = observer(function UserProvidedStructure({ feature,
|
|
|
40
40
|
const activeURL = choice === 'file' ? '' : structureURL;
|
|
41
41
|
const { sequences: structureSequences, error: fileError } = useStructureFileSequence({ file: activeFile, url: activeURL });
|
|
42
42
|
const structureName = activeFile?.name ?? activeURL.slice(activeURL.lastIndexOf('/') + 1);
|
|
43
|
-
const
|
|
44
|
-
|
|
43
|
+
const { transcripts: options, isoformSequences,
|
|
44
|
+
// the chain the isoforms are compared against — not blindly chain 0, which
|
|
45
|
+
// mismatched every heteromer the view itself went on to map correctly
|
|
46
|
+
structureSequence, selectedTranscriptId: userSelection, setSelectedTranscriptId: setUserSelection, selectedTranscript, selectedIsoform: protein, error: isoformError, } = useTranscriptIsoformSelection({ feature, view, structureSequences });
|
|
45
47
|
const error = isoformError ?? launchError ?? fileError;
|
|
46
48
|
const canLaunch = !!(activeURL || activeFile) && !!protein && !!selectedTranscript;
|
|
47
49
|
const sequencesDiffer = !!protein?.seq &&
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { uniprotFastaUrl } from '../utils/structureUrls';
|
|
1
2
|
/**
|
|
2
3
|
* Sets up a temporary assembly for a protein sequence from UniProt
|
|
3
4
|
*/
|
|
@@ -12,7 +13,7 @@ export function setupProteinAssembly(session, uniprotId) {
|
|
|
12
13
|
type: 'UnindexedFastaAdapter',
|
|
13
14
|
rewriteRefNames: "jexl:split(refName,'|')[1]",
|
|
14
15
|
fastaLocation: {
|
|
15
|
-
uri:
|
|
16
|
+
uri: uniprotFastaUrl(uniprotId),
|
|
16
17
|
},
|
|
17
18
|
},
|
|
18
19
|
},
|
|
@@ -1,45 +1,4 @@
|
|
|
1
1
|
import type { SessionWithAddTracks } from '@jbrowse/core/util';
|
|
2
|
-
/**
|
|
3
|
-
* Fetches UniProt GFF data and extracts unique feature types
|
|
4
|
-
*/
|
|
5
|
-
export declare function fetchUniProtFeatureTypes(uniprotId: string): Promise<string[]>;
|
|
6
|
-
/**
|
|
7
|
-
* Adds UniProt feature tracks for each feature type
|
|
8
|
-
*/
|
|
9
|
-
export declare function addUniProtFeatureTracks({ session, uniprotId, featureTypes, }: {
|
|
10
|
-
session: SessionWithAddTracks;
|
|
11
|
-
uniprotId: string;
|
|
12
|
-
featureTypes: string[];
|
|
13
|
-
}): void;
|
|
14
|
-
/**
|
|
15
|
-
* Adds antigen annotation track from EBI
|
|
16
|
-
*/
|
|
17
|
-
export declare function addAntigenTrack({ session, uniprotId, }: {
|
|
18
|
-
session: SessionWithAddTracks;
|
|
19
|
-
uniprotId: string;
|
|
20
|
-
}): void;
|
|
21
|
-
/**
|
|
22
|
-
* Adds variation track from EBI
|
|
23
|
-
*/
|
|
24
|
-
export declare function addVariationTrack({ session, uniprotId, }: {
|
|
25
|
-
session: SessionWithAddTracks;
|
|
26
|
-
uniprotId: string;
|
|
27
|
-
}): void;
|
|
28
|
-
/**
|
|
29
|
-
* Adds AlphaFold confidence track
|
|
30
|
-
*/
|
|
31
|
-
export declare function addAlphaFoldConfidenceTrack({ session, uniprotId, confidenceUrl, }: {
|
|
32
|
-
session: SessionWithAddTracks;
|
|
33
|
-
uniprotId: string;
|
|
34
|
-
confidenceUrl: string | undefined;
|
|
35
|
-
}): void;
|
|
36
|
-
/**
|
|
37
|
-
* Adds AlphaMissense pathogenicity scores track
|
|
38
|
-
*/
|
|
39
|
-
export declare function addAlphaMissenseTrack({ session, uniprotId, }: {
|
|
40
|
-
session: SessionWithAddTracks;
|
|
41
|
-
uniprotId: string;
|
|
42
|
-
}): void;
|
|
43
2
|
/**
|
|
44
3
|
* Adds all protein annotation tracks for a given UniProt ID
|
|
45
4
|
*/
|
|
@@ -1,26 +1,24 @@
|
|
|
1
|
+
import { myfetch } from '../../fetchUtils';
|
|
2
|
+
import { uniprotGffUrl } from '../utils/structureUrls';
|
|
1
3
|
/**
|
|
2
4
|
* Fetches UniProt GFF data and extracts unique feature types
|
|
3
5
|
*/
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
const res = await fetch(url);
|
|
7
|
-
if (!res.ok) {
|
|
8
|
-
throw new Error(`HTTP ${res.status} fetching ${url}`);
|
|
9
|
-
}
|
|
10
|
-
const data = await res.text();
|
|
6
|
+
async function fetchUniProtFeatureTypes(uniprotId) {
|
|
7
|
+
const data = await (await myfetch(uniprotGffUrl(uniprotId))).text();
|
|
11
8
|
return [
|
|
12
9
|
...new Set(data
|
|
13
10
|
.split('\n')
|
|
14
11
|
.filter(f => !f.startsWith('#'))
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
.map(f => f.split('\t')[2]))
|
|
12
|
+
// column 3 is the GFF type; a line without one would otherwise become an
|
|
13
|
+
// `undefined`-named track
|
|
14
|
+
.map(f => f.split('\t')[2]?.trim())
|
|
15
|
+
.filter((f) => !!f)),
|
|
18
16
|
];
|
|
19
17
|
}
|
|
20
18
|
/**
|
|
21
19
|
* Adds UniProt feature tracks for each feature type
|
|
22
20
|
*/
|
|
23
|
-
|
|
21
|
+
function addUniProtFeatureTracks({ session, uniprotId, featureTypes, }) {
|
|
24
22
|
featureTypes.forEach(type => {
|
|
25
23
|
const trackId = `${uniprotId}-${type}`;
|
|
26
24
|
session.addTrackConf({
|
|
@@ -30,7 +28,7 @@ export function addUniProtFeatureTracks({ session, uniprotId, featureTypes, }) {
|
|
|
30
28
|
adapter: {
|
|
31
29
|
type: 'Gff3Adapter',
|
|
32
30
|
gffLocation: {
|
|
33
|
-
uri:
|
|
31
|
+
uri: uniprotGffUrl(uniprotId),
|
|
34
32
|
},
|
|
35
33
|
},
|
|
36
34
|
assemblyNames: [uniprotId],
|
|
@@ -47,7 +45,7 @@ export function addUniProtFeatureTracks({ session, uniprotId, featureTypes, }) {
|
|
|
47
45
|
/**
|
|
48
46
|
* Adds antigen annotation track from EBI
|
|
49
47
|
*/
|
|
50
|
-
|
|
48
|
+
function addAntigenTrack({ session, uniprotId, }) {
|
|
51
49
|
session.addTrackConf({
|
|
52
50
|
type: 'FeatureTrack',
|
|
53
51
|
trackId: `${uniprotId}-Antigen`,
|
|
@@ -64,7 +62,7 @@ export function addAntigenTrack({ session, uniprotId, }) {
|
|
|
64
62
|
/**
|
|
65
63
|
* Adds variation track from EBI
|
|
66
64
|
*/
|
|
67
|
-
|
|
65
|
+
function addVariationTrack({ session, uniprotId, }) {
|
|
68
66
|
session.addTrackConf({
|
|
69
67
|
type: 'FeatureTrack',
|
|
70
68
|
trackId: `${uniprotId}-Variation`,
|
|
@@ -81,7 +79,7 @@ export function addVariationTrack({ session, uniprotId, }) {
|
|
|
81
79
|
/**
|
|
82
80
|
* Adds AlphaFold confidence track
|
|
83
81
|
*/
|
|
84
|
-
|
|
82
|
+
function addAlphaFoldConfidenceTrack({ session, uniprotId, confidenceUrl, }) {
|
|
85
83
|
if (confidenceUrl) {
|
|
86
84
|
session.addTrackConf({
|
|
87
85
|
type: 'QuantitativeTrack',
|
|
@@ -100,7 +98,7 @@ export function addAlphaFoldConfidenceTrack({ session, uniprotId, confidenceUrl,
|
|
|
100
98
|
/**
|
|
101
99
|
* Adds AlphaMissense pathogenicity scores track
|
|
102
100
|
*/
|
|
103
|
-
|
|
101
|
+
function addAlphaMissenseTrack({ session, uniprotId, }) {
|
|
104
102
|
session.addTrackConf({
|
|
105
103
|
type: 'MultiQuantitativeTrack',
|
|
106
104
|
trackId: `${uniprotId}-AlphaMissense-scores`,
|
|
@@ -26,7 +26,9 @@ export default function useAlphaFoldDBSearch({ feature, view, }) {
|
|
|
26
26
|
? extractTaxonId(getConf(assembly, ['sequence', 'metadata']))
|
|
27
27
|
: undefined;
|
|
28
28
|
const overrideTaxon = Number(taxonIdInput.trim());
|
|
29
|
-
const effectiveTaxonId = taxonIdInput.trim() !== '' &&
|
|
29
|
+
const effectiveTaxonId = taxonIdInput.trim() !== '' &&
|
|
30
|
+
Number.isFinite(overrideTaxon) &&
|
|
31
|
+
overrideTaxon > 0
|
|
30
32
|
? overrideTaxon
|
|
31
33
|
: assemblyTaxonId;
|
|
32
34
|
const [selectedQueryId, setSelectedQueryId] = useState('auto');
|
|
@@ -55,13 +57,13 @@ export default function useAlphaFoldDBSearch({ feature, view, }) {
|
|
|
55
57
|
: effectiveLookupMode === 'manual'
|
|
56
58
|
? debouncedManualUniprotId
|
|
57
59
|
: undefined;
|
|
58
|
-
const { isLoading: isAlphaFoldLoading, isValidating: isAlphaFoldValidating, error: alphaFoldError, url: alphaFoldUrl, confidenceUrl: alphaFoldConfidenceUrl,
|
|
60
|
+
const { isLoading: isAlphaFoldLoading, isValidating: isAlphaFoldValidating, error: alphaFoldError, url: alphaFoldUrl, confidenceUrl: alphaFoldConfidenceUrl, structureSequences: alphaFoldStructureSequences, } = useAlphaFoldData({
|
|
59
61
|
uniprotId: isSequenceMode ? undefined : uniprotId,
|
|
60
62
|
});
|
|
61
|
-
const { transcripts: transcriptOptions, isoformSequences, isLoading: isIsoformLoading, error: isoformError, selectedTranscriptId: effectiveTranscriptId, setSelectedTranscriptId: setUserSelection, selectedTranscript, selectedIsoform: userSelectedProteinSequence, } = useTranscriptIsoformSelection({
|
|
63
|
+
const { transcripts: transcriptOptions, isoformSequences, structureSequence: alphaFoldStructureSequence, isLoading: isIsoformLoading, error: isoformError, selectedTranscriptId: effectiveTranscriptId, setSelectedTranscriptId: setUserSelection, selectedTranscript, selectedIsoform: userSelectedProteinSequence, } = useTranscriptIsoformSelection({
|
|
62
64
|
feature,
|
|
63
65
|
view,
|
|
64
|
-
|
|
66
|
+
structureSequences: alphaFoldStructureSequences,
|
|
65
67
|
resetKey: uniprotId,
|
|
66
68
|
});
|
|
67
69
|
const { uniprotId: seqSearchUniprotId, cifUrl: seqSearchUrl, plddtDocUrl: seqSearchConfidenceUrl, structureSequence: seqSearchStructureSequence, isLoading: isSequenceSearchLoading, isValidating: isSequenceSearchValidating, error: sequenceSearchError, } = useAlphaFoldSequenceSearch({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import useStructureFileSequence from './useStructureFileSequence';
|
|
2
|
-
import { getAlphaFoldConfidenceUrl, getAlphaFoldStructureUrl, } from '../utils/
|
|
2
|
+
import { getAlphaFoldConfidenceUrl, getAlphaFoldStructureUrl, } from '../utils/structureUrls';
|
|
3
3
|
export default function useAlphaFoldData({ uniprotId, }) {
|
|
4
4
|
const url = uniprotId ? getAlphaFoldStructureUrl(uniprotId) : undefined;
|
|
5
5
|
const confidenceUrl = uniprotId
|
|
@@ -12,6 +12,6 @@ export default function useAlphaFoldData({ uniprotId, }) {
|
|
|
12
12
|
error,
|
|
13
13
|
url,
|
|
14
14
|
confidenceUrl,
|
|
15
|
-
|
|
15
|
+
structureSequences: sequences,
|
|
16
16
|
};
|
|
17
17
|
}
|
|
@@ -3,13 +3,13 @@ import useSWR from 'swr';
|
|
|
3
3
|
import { STATIC_SWR_OPTIONS } from './swrOptions';
|
|
4
4
|
import { jsonfetch } from '../../fetchUtils';
|
|
5
5
|
import { md5 } from '../utils/md5';
|
|
6
|
-
import {
|
|
6
|
+
import { stripAllStopCodons } from '../utils/util';
|
|
7
7
|
export default function useAlphaFoldSequenceSearch({ sequence, searchType, enabled = true, }) {
|
|
8
8
|
const searchValue = useMemo(() => {
|
|
9
9
|
if (!sequence) {
|
|
10
10
|
return undefined;
|
|
11
11
|
}
|
|
12
|
-
const cleanSeq =
|
|
12
|
+
const cleanSeq = stripAllStopCodons(sequence.toUpperCase());
|
|
13
13
|
return searchType === 'md5' ? md5(cleanSeq) : cleanSeq;
|
|
14
14
|
}, [sequence, searchType]);
|
|
15
15
|
const { data, error, isLoading, isValidating } = useSWR(enabled && searchValue
|
|
@@ -4,22 +4,13 @@ import { addStructureFromData } from '../../ProteinView/addStructureFromData';
|
|
|
4
4
|
import { addStructureFromURL } from '../../ProteinView/addStructureFromURL';
|
|
5
5
|
import { extractStructureSequences } from '../../ProteinView/extractStructureSequences';
|
|
6
6
|
import { withTemporaryMolstarPlugin } from '../../ProteinView/withTemporaryMolstarPlugin';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if (ext === 'cif' || ext === 'mmcif' || ext === 'bcif') {
|
|
11
|
-
return 'mmcif';
|
|
12
|
-
}
|
|
13
|
-
return 'pdb';
|
|
14
|
-
}
|
|
7
|
+
// Format is detected by addStructureFromData/addStructureFromURL themselves.
|
|
8
|
+
// This hook used to detect it here, for the file branch only, which meant the
|
|
9
|
+
// dialog preview and the view that followed could disagree about the same file.
|
|
15
10
|
async function fetchSequences({ file, url }) {
|
|
16
11
|
return withTemporaryMolstarPlugin(async (plugin) => {
|
|
17
12
|
const { model } = file
|
|
18
|
-
? await addStructureFromData({
|
|
19
|
-
data: await file.text(),
|
|
20
|
-
plugin,
|
|
21
|
-
format: detectStructureFormat(file.name),
|
|
22
|
-
})
|
|
13
|
+
? await addStructureFromData({ data: await file.text(), plugin })
|
|
23
14
|
: await addStructureFromURL({ url: url, plugin });
|
|
24
15
|
return extractStructureSequences(model);
|
|
25
16
|
});
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import type { Feature } from '@jbrowse/core/util';
|
|
2
|
-
export default function useTranscriptIsoformSelection({ feature, view,
|
|
2
|
+
export default function useTranscriptIsoformSelection({ feature, view, structureSequences, resetKey, }: {
|
|
3
3
|
feature: Feature;
|
|
4
4
|
view?: {
|
|
5
5
|
assemblyNames?: string[];
|
|
6
6
|
};
|
|
7
|
-
|
|
7
|
+
structureSequences?: string[];
|
|
8
8
|
resetKey?: string;
|
|
9
9
|
}): {
|
|
10
10
|
transcripts: Feature[];
|
|
11
11
|
isoformSequences: import("../utils/util").IsoformSequences | undefined;
|
|
12
|
+
structureSequence: string | undefined;
|
|
12
13
|
isLoading: boolean;
|
|
13
14
|
error: any;
|
|
14
15
|
selectedTranscriptId: string | undefined;
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import useIsoformProteinSequences from './useIsoformProteinSequences';
|
|
2
2
|
import useTranscriptSelection from './useTranscriptSelection';
|
|
3
|
-
import { getId, getTranscriptFeatures } from '../utils/util';
|
|
3
|
+
import { getId, getTranscriptFeatures, pickStructureSequence, } from '../utils/util';
|
|
4
4
|
// Bundles the transcript-isoform wiring shared by all three launch tabs:
|
|
5
|
-
// list transcripts, fetch their protein sequences,
|
|
6
|
-
//
|
|
7
|
-
|
|
5
|
+
// list transcripts, fetch their protein sequences, pick which chain of the
|
|
6
|
+
// structure to compare against, auto/manually select a transcript, and resolve
|
|
7
|
+
// the selection back to its feature + sequence.
|
|
8
|
+
export default function useTranscriptIsoformSelection({ feature, view, structureSequences, resetKey, }) {
|
|
8
9
|
const transcripts = getTranscriptFeatures(feature);
|
|
9
10
|
const { isoformSequences, isLoading, error } = useIsoformProteinSequences({
|
|
10
11
|
feature,
|
|
11
12
|
view,
|
|
12
13
|
});
|
|
14
|
+
const structureSequence = pickStructureSequence(structureSequences, isoformSequences);
|
|
13
15
|
const { userSelection, setUserSelection } = useTranscriptSelection({
|
|
14
16
|
options: transcripts,
|
|
15
17
|
isoformSequences,
|
|
@@ -23,6 +25,7 @@ export default function useTranscriptIsoformSelection({ feature, view, structure
|
|
|
23
25
|
return {
|
|
24
26
|
transcripts,
|
|
25
27
|
isoformSequences,
|
|
28
|
+
structureSequence,
|
|
26
29
|
isLoading,
|
|
27
30
|
error,
|
|
28
31
|
selectedTranscriptId: userSelection,
|