jbrowse-plugin-protein3d 0.4.10 → 0.4.11
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/LaunchProteinView/components/AlphaFoldDBSearch.d.ts +5 -3
- package/dist/LaunchProteinView/components/AlphaFoldDBSearch.js +1 -4
- package/dist/LaunchProteinView/components/AlphaFoldDBSearchStatus.js +8 -13
- package/dist/LaunchProteinView/components/FoldseekSearch.d.ts +5 -3
- package/dist/LaunchProteinView/components/FoldseekSearch.js +7 -15
- package/dist/LaunchProteinView/components/IsoformSequencesToggle.d.ts +10 -0
- package/dist/LaunchProteinView/components/IsoformSequencesToggle.js +13 -0
- package/dist/LaunchProteinView/components/LaunchProteinViewDialog.js +6 -3
- package/dist/LaunchProteinView/components/StructureSourcePicker.d.ts +1 -2
- package/dist/LaunchProteinView/components/StructureSourcePicker.js +1 -1
- package/dist/LaunchProteinView/components/UserProvidedStructure.d.ts +6 -3
- package/dist/LaunchProteinView/components/UserProvidedStructure.js +10 -35
- package/dist/LaunchProteinView/hooks/swrOptions.d.ts +5 -0
- package/dist/LaunchProteinView/hooks/swrOptions.js +8 -0
- package/dist/LaunchProteinView/hooks/useAlphaFoldDBSearch.js +5 -12
- package/dist/LaunchProteinView/hooks/useAlphaFoldData.js +2 -4
- package/dist/LaunchProteinView/hooks/useAlphaFoldSequenceSearch.js +2 -3
- package/dist/LaunchProteinView/hooks/useIsoformProteinSequences.js +8 -4
- package/dist/LaunchProteinView/hooks/{useRemoteStructureFileSequence.d.ts → useStructureFileSequence.d.ts} +2 -1
- package/dist/LaunchProteinView/hooks/useStructureFileSequence.js +47 -0
- package/dist/LaunchProteinView/hooks/useTranscriptIsoformSelection.d.ts +24 -0
- package/dist/LaunchProteinView/hooks/useTranscriptIsoformSelection.js +33 -0
- package/dist/LaunchProteinView/hooks/useUniProtSearch.js +2 -3
- package/dist/LaunchProteinView/utils/calculateProteinSequence.d.ts +4 -5
- package/dist/LaunchProteinView/utils/calculateProteinSequence.js +2 -4
- package/dist/LaunchProteinView/utils/util.d.ts +0 -1
- package/dist/LaunchProteinView/utils/util.js +0 -3
- package/dist/LaunchProteinViewExtensionPoint/index.js +44 -7
- package/dist/LaunchProteinViewExtensionPoint/resolveShortLaunch.d.ts +26 -0
- package/dist/LaunchProteinViewExtensionPoint/resolveShortLaunch.js +91 -0
- package/dist/ProteinView/components/FeatureBar.js +2 -2
- package/dist/ProteinView/components/FeatureTypeLabel.js +2 -2
- package/dist/ProteinView/components/HeaderStructureInfo.d.ts +1 -1
- package/dist/ProteinView/components/HeaderStructureInfo.js +12 -6
- package/dist/ProteinView/components/ProteinAlignment.js +5 -5
- package/dist/ProteinView/components/ProteinFeatureTrack.js +3 -3
- package/dist/ProteinView/components/ProteinView.js +7 -2
- package/dist/ProteinView/components/ProteinViewHeader.js +69 -18
- package/dist/ProteinView/components/ResidueValueTrack.js +4 -4
- package/dist/ProteinView/constants.d.ts +4 -2
- package/dist/ProteinView/constants.js +4 -2
- package/dist/ProteinView/model.d.ts +24 -10
- package/dist/ProteinView/model.js +12 -0
- package/dist/ProteinView/structureModel.d.ts +26 -1
- package/dist/ProteinView/structureModel.js +53 -8
- package/dist/ProteinView/useProteinView.js +43 -8
- package/dist/jbrowse-plugin-protein3d.umd.production.min.js +15 -15
- package/dist/jbrowse-plugin-protein3d.umd.production.min.js.map +4 -4
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -1
- package/src/LaunchProteinView/components/AlphaFoldDBSearch.tsx +5 -6
- package/src/LaunchProteinView/components/AlphaFoldDBSearchStatus.tsx +12 -27
- package/src/LaunchProteinView/components/FoldseekSearch.tsx +17 -24
- package/src/LaunchProteinView/components/IsoformSequencesToggle.tsx +41 -0
- package/src/LaunchProteinView/components/LaunchProteinViewDialog.tsx +10 -3
- package/src/LaunchProteinView/components/StructureSourcePicker.tsx +0 -2
- package/src/LaunchProteinView/components/UserProvidedStructure.tsx +24 -53
- package/src/LaunchProteinView/hooks/swrOptions.ts +8 -0
- package/src/LaunchProteinView/hooks/useAlphaFoldDBSearch.ts +17 -28
- package/src/LaunchProteinView/hooks/useAlphaFoldData.ts +2 -4
- package/src/LaunchProteinView/hooks/useAlphaFoldSequenceSearch.ts +2 -3
- package/src/LaunchProteinView/hooks/useIsoformProteinSequences.ts +8 -4
- package/src/LaunchProteinView/hooks/useStructureFileSequence.ts +64 -0
- package/src/LaunchProteinView/hooks/useTranscriptIsoformSelection.ts +47 -0
- package/src/LaunchProteinView/hooks/useUniProtSearch.ts +2 -3
- package/src/LaunchProteinView/utils/calculateProteinSequence.ts +5 -6
- package/src/LaunchProteinView/utils/util.ts +0 -4
- package/src/LaunchProteinViewExtensionPoint/index.ts +54 -6
- package/src/LaunchProteinViewExtensionPoint/resolveShortLaunch.ts +143 -0
- package/src/ProteinView/components/FeatureBar.tsx +2 -7
- package/src/ProteinView/components/FeatureTypeLabel.tsx +2 -2
- package/src/ProteinView/components/HeaderStructureInfo.tsx +21 -10
- package/src/ProteinView/components/ProteinAlignment.tsx +13 -9
- package/src/ProteinView/components/ProteinFeatureTrack.tsx +3 -3
- package/src/ProteinView/components/ProteinView.tsx +11 -2
- package/src/ProteinView/components/ProteinViewHeader.tsx +104 -43
- package/src/ProteinView/components/ResidueValueTrack.tsx +4 -4
- package/src/ProteinView/constants.ts +4 -2
- package/src/ProteinView/model.ts +12 -0
- package/src/ProteinView/structureModel.ts +63 -8
- package/src/ProteinView/useProteinView.ts +49 -8
- package/src/version.ts +1 -1
- package/dist/LaunchProteinView/hooks/useLocalStructureFileSequence.d.ts +0 -7
- package/dist/LaunchProteinView/hooks/useLocalStructureFileSequence.js +0 -39
- package/dist/LaunchProteinView/hooks/useRemoteStructureFileSequence.js +0 -28
- package/src/LaunchProteinView/hooks/useLocalStructureFileSequence.ts +0 -60
- package/src/LaunchProteinView/hooks/useRemoteStructureFileSequence.ts +0 -41
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { AlignmentAlgorithm } from '../../ProteinView/types';
|
|
3
|
-
import type {
|
|
4
|
-
|
|
3
|
+
import type { AbstractSessionModel, Feature } from '@jbrowse/core/util';
|
|
4
|
+
import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view';
|
|
5
|
+
declare const AlphaFoldDBSearch: ({ feature, session, view, handleClose, alignmentAlgorithm, onAlignmentAlgorithmChange, }: {
|
|
5
6
|
feature: Feature;
|
|
6
|
-
|
|
7
|
+
session: AbstractSessionModel;
|
|
8
|
+
view: LinearGenomeViewModel;
|
|
7
9
|
handleClose: () => void;
|
|
8
10
|
alignmentAlgorithm: AlignmentAlgorithm;
|
|
9
11
|
onAlignmentAlgorithmChange: (algorithm: AlignmentAlgorithm) => void;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ErrorMessage, LoadingEllipses } from '@jbrowse/core/ui';
|
|
3
|
-
import { getContainingView, getSession } from '@jbrowse/core/util';
|
|
4
3
|
import { DialogActions, DialogContent, Typography } from '@mui/material';
|
|
5
4
|
import { observer } from 'mobx-react';
|
|
6
5
|
import { makeStyles } from 'tss-react/mui';
|
|
@@ -30,10 +29,8 @@ const useStyles = makeStyles()({
|
|
|
30
29
|
alignItems: 'flex-start',
|
|
31
30
|
},
|
|
32
31
|
});
|
|
33
|
-
const AlphaFoldDBSearch = observer(function AlphaFoldDBSearch({ feature,
|
|
32
|
+
const AlphaFoldDBSearch = observer(function AlphaFoldDBSearch({ feature, session, view, handleClose, alignmentAlgorithm, onAlignmentAlgorithmChange, }) {
|
|
34
33
|
const { classes } = useStyles();
|
|
35
|
-
const session = getSession(model);
|
|
36
|
-
const view = getContainingView(model);
|
|
37
34
|
const state = useAlphaFoldDBSearch({ feature, view });
|
|
38
35
|
return (React.createElement(React.Fragment, null,
|
|
39
36
|
React.createElement(DialogContent, { className: classes.dialogContent },
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import React
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Typography } from '@mui/material';
|
|
3
|
+
import IsoformSequencesToggle from './IsoformSequencesToggle';
|
|
4
4
|
import ExternalLink from '../../components/ExternalLink';
|
|
5
|
-
import {
|
|
5
|
+
import { getTranscriptDisplayName } from '../utils/util';
|
|
6
6
|
function NotFound({ uniprotId }) {
|
|
7
7
|
return (React.createElement(Typography, null,
|
|
8
8
|
"No structure found for this UniProtID in AlphaFoldDB",
|
|
@@ -10,7 +10,6 @@ function NotFound({ uniprotId }) {
|
|
|
10
10
|
React.createElement(ExternalLink, { href: `https://alphafold.ebi.ac.uk/search/text/${uniprotId}` }, "(search for results)")));
|
|
11
11
|
}
|
|
12
12
|
export default function AlphaFoldDBSearchStatus({ uniprotId, selectedTranscript, structureSequence, isoformSequences, url, }) {
|
|
13
|
-
const [showAllProteinSequences, setShowAllProteinSequences] = useState(false);
|
|
14
13
|
return uniprotId ? (React.createElement(React.Fragment, null,
|
|
15
14
|
React.createElement("div", null,
|
|
16
15
|
React.createElement(Typography, null,
|
|
@@ -20,16 +19,12 @@ export default function AlphaFoldDBSearchStatus({ uniprotId, selectedTranscript,
|
|
|
20
19
|
React.createElement(Typography, null,
|
|
21
20
|
"AlphaFoldDB link: ",
|
|
22
21
|
React.createElement(ExternalLink, { href: url }, url))),
|
|
23
|
-
structureSequence ? (React.createElement(
|
|
24
|
-
React.createElement(Button, { variant: "contained", color: "primary", onClick: () => {
|
|
25
|
-
setShowAllProteinSequences(!showAllProteinSequences);
|
|
26
|
-
} }, showAllProteinSequences
|
|
27
|
-
? 'Hide all isoform protein sequences'
|
|
28
|
-
: 'Show all isoform protein sequences'),
|
|
29
|
-
showAllProteinSequences ? (React.createElement(MSATable, { structureSequence: structureSequence, structureName: uniprotId, isoformSequences: isoformSequences })) : null)) : (React.createElement(NotFound, { uniprotId: uniprotId })))) : (React.createElement(Typography, null,
|
|
22
|
+
structureSequence ? (React.createElement(IsoformSequencesToggle, { structureSequence: structureSequence, structureName: uniprotId, isoformSequences: isoformSequences })) : (React.createElement(NotFound, { uniprotId: uniprotId })))) : (React.createElement(Typography, null,
|
|
30
23
|
"Searching",
|
|
31
24
|
' ',
|
|
32
|
-
selectedTranscript
|
|
25
|
+
selectedTranscript
|
|
26
|
+
? getTranscriptDisplayName(selectedTranscript)
|
|
27
|
+
: 'transcript',
|
|
33
28
|
' ',
|
|
34
29
|
"for UniProt ID"));
|
|
35
30
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type {
|
|
3
|
-
|
|
2
|
+
import type { AbstractSessionModel, Feature } from '@jbrowse/core/util';
|
|
3
|
+
import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view';
|
|
4
|
+
declare const FoldseekSearch: ({ feature, session, view, handleClose, }: {
|
|
4
5
|
feature: Feature;
|
|
5
|
-
|
|
6
|
+
session: AbstractSessionModel;
|
|
7
|
+
view: LinearGenomeViewModel;
|
|
6
8
|
handleClose: () => void;
|
|
7
9
|
}) => React.JSX.Element;
|
|
8
10
|
export default FoldseekSearch;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
2
|
import { ErrorMessage, LoadingEllipses } from '@jbrowse/core/ui';
|
|
3
|
-
import { getContainingView, getSession } from '@jbrowse/core/util';
|
|
4
3
|
import { Button, DialogActions, DialogContent, TextField, Typography, } from '@mui/material';
|
|
5
4
|
import { observer } from 'mobx-react';
|
|
6
5
|
import { makeStyles } from 'tss-react/mui';
|
|
@@ -8,10 +7,9 @@ import FoldseekDatabaseSelector from './FoldseekDatabaseSelector';
|
|
|
8
7
|
import FoldseekResultsTable from './FoldseekResultsTable';
|
|
9
8
|
import TranscriptSelector from './TranscriptSelector';
|
|
10
9
|
import useFoldseekSearch from '../hooks/useFoldseekSearch';
|
|
11
|
-
import
|
|
12
|
-
import useTranscriptSelection from '../hooks/useTranscriptSelection';
|
|
10
|
+
import useTranscriptIsoformSelection from '../hooks/useTranscriptIsoformSelection';
|
|
13
11
|
import { DEFAULT_DATABASES } from '../services/foldseekApi';
|
|
14
|
-
import {
|
|
12
|
+
import { stripStopCodon } from '../utils/util';
|
|
15
13
|
const useStyles = makeStyles()({
|
|
16
14
|
dialogContent: {
|
|
17
15
|
width: '80em',
|
|
@@ -28,21 +26,15 @@ const useStyles = makeStyles()({
|
|
|
28
26
|
gap: 8,
|
|
29
27
|
},
|
|
30
28
|
});
|
|
31
|
-
const FoldseekSearch = observer(function FoldseekSearch({ feature,
|
|
29
|
+
const FoldseekSearch = observer(function FoldseekSearch({ feature, session, view, handleClose, }) {
|
|
32
30
|
const { classes } = useStyles();
|
|
33
|
-
const session = getSession(model);
|
|
34
|
-
const view = getContainingView(model);
|
|
35
31
|
const [userEditedSequence, setUserEditedSequence] = useState();
|
|
36
32
|
const [selectedDatabases, setSelectedDatabases] = useState(DEFAULT_DATABASES);
|
|
37
33
|
const { results, cleanedAaSequence, di3Sequence, isLoading, isPredicting, error, statusMessage, predictStructure, search, reset, } = useFoldseekSearch();
|
|
38
|
-
const transcripts =
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const selectedIsoformData = effectiveSelectedTranscriptId
|
|
43
|
-
? isoformSequences?.[effectiveSelectedTranscriptId]
|
|
44
|
-
: undefined;
|
|
45
|
-
const cleanedSequence = selectedIsoformData?.seq.replace(/\*/g, '') ?? '';
|
|
34
|
+
const { transcripts, isoformSequences, isLoading: isLoadingIsoforms, error: isoformError, selectedTranscriptId: effectiveSelectedTranscriptId, setSelectedTranscriptId: setUserSelection, selectedTranscript, selectedIsoform: selectedIsoformData, } = useTranscriptIsoformSelection({ feature, view });
|
|
35
|
+
const cleanedSequence = selectedIsoformData
|
|
36
|
+
? stripStopCodon(selectedIsoformData.seq)
|
|
37
|
+
: '';
|
|
46
38
|
const sequence = userEditedSequence ?? cleanedSequence;
|
|
47
39
|
const setUserSelectionWithReset = (id) => {
|
|
48
40
|
setUserSelection(id);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Feature } from '@jbrowse/core/util';
|
|
3
|
+
export default function IsoformSequencesToggle({ structureSequence, structureName, isoformSequences, }: {
|
|
4
|
+
structureSequence: string;
|
|
5
|
+
structureName: string;
|
|
6
|
+
isoformSequences: Record<string, {
|
|
7
|
+
feature: Feature;
|
|
8
|
+
seq: string;
|
|
9
|
+
}>;
|
|
10
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { Button } from '@mui/material';
|
|
3
|
+
import MSATable from './MSATable';
|
|
4
|
+
export default function IsoformSequencesToggle({ structureSequence, structureName, isoformSequences, }) {
|
|
5
|
+
const [show, setShow] = useState(false);
|
|
6
|
+
return (React.createElement("div", { style: { margin: 10 } },
|
|
7
|
+
React.createElement(Button, { variant: "contained", color: "primary", onClick: () => {
|
|
8
|
+
setShow(!show);
|
|
9
|
+
} }, show
|
|
10
|
+
? 'Hide all isoform protein sequences'
|
|
11
|
+
: 'Show all isoform protein sequences'),
|
|
12
|
+
show ? (React.createElement(MSATable, { structureSequence: structureSequence, structureName: structureName, isoformSequences: isoformSequences })) : null));
|
|
13
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
2
|
import { Dialog } from '@jbrowse/core/ui';
|
|
3
|
+
import { getContainingView, getSession } from '@jbrowse/core/util';
|
|
3
4
|
import { Tab, Tabs } from '@mui/material';
|
|
4
5
|
import AlphaFoldDBSearch from './AlphaFoldDBSearch';
|
|
5
6
|
import FoldseekSearch from './FoldseekSearch';
|
|
@@ -11,6 +12,8 @@ import { useLocalStorage } from '../hooks/useLocalStorage';
|
|
|
11
12
|
export default function LaunchProteinViewDialog({ handleClose, feature, model, }) {
|
|
12
13
|
const [choice, setChoice] = useState(0);
|
|
13
14
|
const [alignmentAlgorithm, setAlignmentAlgorithm] = useLocalStorage('jbrowse-protein3d-alignment-algorithm', DEFAULT_ALIGNMENT_ALGORITHM);
|
|
15
|
+
const session = getSession(model);
|
|
16
|
+
const view = getContainingView(model);
|
|
14
17
|
return (React.createElement(Dialog, { maxWidth: "xl", title: "Launch protein view", titleNode: React.createElement(React.Fragment, null,
|
|
15
18
|
"Launch protein view ",
|
|
16
19
|
React.createElement(HelpButton, null)), open: true, onClose: handleClose },
|
|
@@ -21,9 +24,9 @@ export default function LaunchProteinViewDialog({ handleClose, feature, model, }
|
|
|
21
24
|
React.createElement(Tab, { value: 1, label: "Foldseek search" }),
|
|
22
25
|
React.createElement(Tab, { value: 2, label: "Open file manually" })),
|
|
23
26
|
React.createElement(TabPanel, { value: choice, index: 0 },
|
|
24
|
-
React.createElement(AlphaFoldDBSearch, {
|
|
27
|
+
React.createElement(AlphaFoldDBSearch, { session: session, view: view, feature: feature, handleClose: handleClose, alignmentAlgorithm: alignmentAlgorithm, onAlignmentAlgorithmChange: setAlignmentAlgorithm })),
|
|
25
28
|
React.createElement(TabPanel, { value: choice, index: 1 },
|
|
26
|
-
React.createElement(FoldseekSearch, {
|
|
29
|
+
React.createElement(FoldseekSearch, { session: session, view: view, feature: feature, handleClose: handleClose })),
|
|
27
30
|
React.createElement(TabPanel, { value: choice, index: 2 },
|
|
28
|
-
React.createElement(UserProvidedStructure, {
|
|
31
|
+
React.createElement(UserProvidedStructure, { session: session, view: view, feature: feature, handleClose: handleClose, alignmentAlgorithm: alignmentAlgorithm, onAlignmentAlgorithmChange: setAlignmentAlgorithm }))));
|
|
29
32
|
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
export default function StructureSourcePicker({ choice, setChoice, structureURL, setStructureURL,
|
|
2
|
+
export default function StructureSourcePicker({ choice, setChoice, structureURL, setStructureURL, setFile, pdbId, setPdbId, }: {
|
|
3
3
|
choice: string;
|
|
4
4
|
setChoice: (c: string) => void;
|
|
5
5
|
structureURL: string;
|
|
6
6
|
setStructureURL: (url: string) => void;
|
|
7
|
-
file: File | undefined;
|
|
8
7
|
setFile: (f: File) => void;
|
|
9
8
|
pdbId: string;
|
|
10
9
|
setPdbId: (id: string) => void;
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { Button, FormControl, FormControlLabel, Radio, RadioGroup, TextField, Typography, } from '@mui/material';
|
|
3
3
|
import HelpButton from './HelpButton';
|
|
4
4
|
import { getPdbStructureUrl } from '../utils/launchViewUtils';
|
|
5
|
-
export default function StructureSourcePicker({ choice, setChoice, structureURL, setStructureURL,
|
|
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,
|
|
8
8
|
"Open your structure file ",
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { AlignmentAlgorithm } from '../../ProteinView/types';
|
|
3
|
-
import type {
|
|
4
|
-
|
|
3
|
+
import type { AbstractSessionModel, Feature } from '@jbrowse/core/util';
|
|
4
|
+
import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view';
|
|
5
|
+
type LGV = LinearGenomeViewModel;
|
|
6
|
+
declare const UserProvidedStructure: ({ feature, session, view, handleClose, alignmentAlgorithm, onAlignmentAlgorithmChange, }: {
|
|
5
7
|
feature: Feature;
|
|
6
|
-
|
|
8
|
+
session: AbstractSessionModel;
|
|
9
|
+
view: LGV;
|
|
7
10
|
handleClose: () => void;
|
|
8
11
|
alignmentAlgorithm: AlignmentAlgorithm;
|
|
9
12
|
onAlignmentAlgorithmChange: (algorithm: AlignmentAlgorithm) => void;
|
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
2
|
import { ErrorMessage, LoadingEllipses } from '@jbrowse/core/ui';
|
|
3
|
-
import { getContainingView, getSession } from '@jbrowse/core/util';
|
|
4
3
|
import { Button, DialogActions, DialogContent } from '@mui/material';
|
|
5
4
|
import { observer } from 'mobx-react';
|
|
6
5
|
import { makeStyles } from 'tss-react/mui';
|
|
7
|
-
import
|
|
6
|
+
import IsoformSequencesToggle from './IsoformSequencesToggle';
|
|
8
7
|
import SequenceMismatchNotice from './SequenceMismatchNotice';
|
|
9
8
|
import StructureSourcePicker from './StructureSourcePicker';
|
|
10
9
|
import TranscriptSelector from './TranscriptSelector';
|
|
11
10
|
import ExternalLink from '../../components/ExternalLink';
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import useRemoteStructureFileSequence from '../hooks/useRemoteStructureFileSequence';
|
|
15
|
-
import useTranscriptSelection from '../hooks/useTranscriptSelection';
|
|
11
|
+
import useStructureFileSequence from '../hooks/useStructureFileSequence';
|
|
12
|
+
import useTranscriptIsoformSelection from '../hooks/useTranscriptIsoformSelection';
|
|
16
13
|
import { launch3DProteinView } from '../utils/launchViewUtils';
|
|
17
|
-
import { getGeneDisplayName,
|
|
14
|
+
import { getGeneDisplayName, getTranscriptDisplayName, stripStopCodon, } from '../utils/util';
|
|
18
15
|
const useStyles = makeStyles()(theme => ({
|
|
19
16
|
dialogContent: {
|
|
20
17
|
marginTop: theme.spacing(6),
|
|
@@ -31,36 +28,20 @@ function HelpText() {
|
|
|
31
28
|
React.createElement(ExternalLink, { href: "https://github.com/sokrypton/ColabFold" }, "ColabFold"),
|
|
32
29
|
". This plugin will align the protein sequence calculated from the genome to the protein sequence embedded in the structure file which allows for slight differences in these two representations."));
|
|
33
30
|
}
|
|
34
|
-
const UserProvidedStructure = observer(function UserProvidedStructure({ feature,
|
|
31
|
+
const UserProvidedStructure = observer(function UserProvidedStructure({ feature, session, view, handleClose, alignmentAlgorithm, onAlignmentAlgorithmChange, }) {
|
|
35
32
|
const { classes } = useStyles();
|
|
36
|
-
const session = getSession(model);
|
|
37
33
|
const [file, setFile] = useState();
|
|
38
34
|
const [pdbId, setPdbId] = useState('');
|
|
39
35
|
const [choice, setChoice] = useState('file');
|
|
40
36
|
const [submitError, setSubmitError] = useState();
|
|
41
37
|
const [structureURL, setStructureURL] = useState('');
|
|
42
|
-
const [showAllProteinSequences, setShowAllProteinSequences] = useState(false);
|
|
43
38
|
const activeFile = choice === 'file' ? file : undefined;
|
|
44
39
|
const activeURL = choice === 'file' ? '' : structureURL;
|
|
45
|
-
const
|
|
46
|
-
const view = getContainingView(model);
|
|
47
|
-
const { isoformSequences, error: isoformError } = useIsoformProteinSequences({
|
|
48
|
-
feature,
|
|
49
|
-
view,
|
|
50
|
-
});
|
|
51
|
-
const { sequences: localSequences, error: localFileError } = useLocalStructureFileSequence({ file: activeFile });
|
|
52
|
-
const { sequences: remoteSequences, error: remoteFileError } = useRemoteStructureFileSequence({ url: activeURL });
|
|
40
|
+
const { sequences: structureSequences, error: fileError } = useStructureFileSequence({ file: activeFile, url: activeURL });
|
|
53
41
|
const structureName = activeFile?.name ?? activeURL.slice(activeURL.lastIndexOf('/') + 1);
|
|
54
|
-
const structureSequences = activeFile ? localSequences : remoteSequences;
|
|
55
42
|
const structureSequence = structureSequences?.[0];
|
|
56
|
-
const { userSelection, setUserSelection } =
|
|
57
|
-
|
|
58
|
-
isoformSequences,
|
|
59
|
-
structureSequence,
|
|
60
|
-
});
|
|
61
|
-
const selectedTranscript = options.find(val => getId(val) === userSelection);
|
|
62
|
-
const protein = userSelection ? isoformSequences?.[userSelection] : undefined;
|
|
63
|
-
const error = isoformError ?? submitError ?? localFileError ?? remoteFileError;
|
|
43
|
+
const { transcripts: options, isoformSequences, selectedTranscriptId: userSelection, setSelectedTranscriptId: setUserSelection, selectedTranscript, selectedIsoform: protein, error: isoformError, } = useTranscriptIsoformSelection({ feature, view, structureSequence });
|
|
44
|
+
const error = isoformError ?? submitError ?? fileError;
|
|
64
45
|
const canLaunch = !!(activeURL || activeFile) && !!protein && !!selectedTranscript;
|
|
65
46
|
const sequencesDiffer = !!protein?.seq &&
|
|
66
47
|
!!structureSequence &&
|
|
@@ -94,16 +75,10 @@ const UserProvidedStructure = observer(function UserProvidedStructure({ feature,
|
|
|
94
75
|
React.createElement(DialogContent, { className: classes.dialogContent },
|
|
95
76
|
error ? React.createElement(ErrorMessage, { error: error }) : null,
|
|
96
77
|
React.createElement(HelpText, null),
|
|
97
|
-
React.createElement(StructureSourcePicker, { choice: choice, setChoice: setChoice, structureURL: structureURL, setStructureURL: setStructureURL,
|
|
78
|
+
React.createElement(StructureSourcePicker, { choice: choice, setChoice: setChoice, structureURL: structureURL, setStructureURL: setStructureURL, setFile: setFile, pdbId: pdbId, setPdbId: setPdbId }),
|
|
98
79
|
React.createElement("div", { style: { margin: 20 } }, isoformSequences ? (structureSequence ? (React.createElement(React.Fragment, null,
|
|
99
80
|
React.createElement(TranscriptSelector, { val: userSelection, setVal: setUserSelection, structureSequence: structureSequence, isoforms: options, feature: feature, isoformSequences: isoformSequences }),
|
|
100
|
-
React.createElement(
|
|
101
|
-
React.createElement(Button, { variant: "contained", color: "primary", onClick: () => {
|
|
102
|
-
setShowAllProteinSequences(!showAllProteinSequences);
|
|
103
|
-
} }, showAllProteinSequences
|
|
104
|
-
? 'Hide all isoform protein sequences'
|
|
105
|
-
: 'Show all isoform protein sequences'),
|
|
106
|
-
showAllProteinSequences ? (React.createElement(MSATable, { structureSequence: structureSequence, structureName: structureName, isoformSequences: isoformSequences })) : null))) : null) : (React.createElement(LoadingEllipses, { title: "Loading protein sequences", variant: "h6" })))),
|
|
81
|
+
React.createElement(IsoformSequencesToggle, { structureSequence: structureSequence, structureName: structureName, isoformSequences: isoformSequences }))) : null) : (React.createElement(LoadingEllipses, { title: "Loading protein sequences", variant: "h6" })))),
|
|
107
82
|
React.createElement(DialogActions, null,
|
|
108
83
|
sequencesDiffer ? (React.createElement(SequenceMismatchNotice, { alignmentAlgorithm: alignmentAlgorithm, onAlignmentAlgorithmChange: onAlignmentAlgorithmChange })) : null,
|
|
109
84
|
React.createElement(Button, { variant: "contained", color: "secondary", onClick: () => {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Shared SWR config for one-shot fetches that should never auto-revalidate
|
|
2
|
+
// (structure files, computed protein sequences). keepPreviousData is opt-in
|
|
3
|
+
// per-hook since it avoids result flicker when the key changes.
|
|
4
|
+
export const STATIC_SWR_OPTIONS = {
|
|
5
|
+
revalidateOnFocus: false,
|
|
6
|
+
revalidateOnReconnect: false,
|
|
7
|
+
revalidateIfStale: false,
|
|
8
|
+
};
|
|
@@ -2,11 +2,10 @@ import { useState } from 'react';
|
|
|
2
2
|
import useAlphaFoldData from './useAlphaFoldData';
|
|
3
3
|
import useAlphaFoldSequenceSearch from './useAlphaFoldSequenceSearch';
|
|
4
4
|
import useDebouncedValue from './useDebouncedValue';
|
|
5
|
-
import
|
|
6
|
-
import useTranscriptSelection from './useTranscriptSelection';
|
|
5
|
+
import useTranscriptIsoformSelection from './useTranscriptIsoformSelection';
|
|
7
6
|
import useUniProtSearch from './useUniProtSearch';
|
|
8
7
|
import getSearchDescription from '../utils/getSearchDescription';
|
|
9
|
-
import { extractFeatureIdentifiers,
|
|
8
|
+
import { extractFeatureIdentifiers, stripStopCodon } from '../utils/util';
|
|
10
9
|
export default function useAlphaFoldDBSearch({ feature, view, }) {
|
|
11
10
|
const [lookupMode, setLookupMode] = useState('auto');
|
|
12
11
|
const [manualUniprotId, setManualUniprotId] = useState('');
|
|
@@ -14,12 +13,10 @@ export default function useAlphaFoldDBSearch({ feature, view, }) {
|
|
|
14
13
|
const [selectedQueryId, setSelectedQueryId] = useState('auto');
|
|
15
14
|
const [sequenceSearchType, setSequenceSearchType] = useState('md5');
|
|
16
15
|
const [selectedUniprotId, setSelectedUniprotId] = useState();
|
|
17
|
-
const transcriptOptions = getTranscriptFeatures(feature);
|
|
18
16
|
const featureUniprotId = geneIds.uniprotId;
|
|
19
17
|
const effectiveLookupMode = lookupMode === 'auto' && featureUniprotId ? 'feature' : lookupMode;
|
|
20
18
|
const isSequenceMode = effectiveLookupMode === 'sequence';
|
|
21
19
|
const isAutoMode = effectiveLookupMode === 'auto';
|
|
22
|
-
const { isoformSequences, isLoading: isIsoformLoading, error: isoformError, } = useIsoformProteinSequences({ feature, view });
|
|
23
20
|
const { entries: uniprotEntries, isLoading: isLookupLoading, error: lookupError, } = useUniProtSearch({
|
|
24
21
|
recognizedIds: geneIds.recognizedIds,
|
|
25
22
|
geneId: geneIds.geneId,
|
|
@@ -41,16 +38,12 @@ export default function useAlphaFoldDBSearch({ feature, view, }) {
|
|
|
41
38
|
const { isLoading: isAlphaFoldLoading, error: alphaFoldError, url: alphaFoldUrl, confidenceUrl: alphaFoldConfidenceUrl, structureSequence: alphaFoldStructureSequence, } = useAlphaFoldData({
|
|
42
39
|
uniprotId: isSequenceMode ? undefined : uniprotId,
|
|
43
40
|
});
|
|
44
|
-
const {
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
const { transcripts: transcriptOptions, isoformSequences, isLoading: isIsoformLoading, error: isoformError, selectedTranscriptId: effectiveTranscriptId, setSelectedTranscriptId: setUserSelection, selectedTranscript, selectedIsoform: userSelectedProteinSequence, } = useTranscriptIsoformSelection({
|
|
42
|
+
feature,
|
|
43
|
+
view,
|
|
47
44
|
structureSequence: alphaFoldStructureSequence,
|
|
48
45
|
resetKey: uniprotId,
|
|
49
46
|
});
|
|
50
|
-
const selectedTranscript = transcriptOptions.find(f => getId(f) === effectiveTranscriptId);
|
|
51
|
-
const userSelectedProteinSequence = effectiveTranscriptId
|
|
52
|
-
? isoformSequences?.[effectiveTranscriptId]
|
|
53
|
-
: undefined;
|
|
54
47
|
const { uniprotId: seqSearchUniprotId, cifUrl: seqSearchUrl, plddtDocUrl: seqSearchConfidenceUrl, structureSequence: seqSearchStructureSequence, isLoading: isSequenceSearchLoading, error: sequenceSearchError, } = useAlphaFoldSequenceSearch({
|
|
55
48
|
sequence: userSelectedProteinSequence?.seq,
|
|
56
49
|
searchType: sequenceSearchType,
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import useStructureFileSequence from './useStructureFileSequence';
|
|
2
2
|
import { getAlphaFoldConfidenceUrl, getAlphaFoldStructureUrl, } from '../utils/launchViewUtils';
|
|
3
3
|
export default function useAlphaFoldData({ uniprotId, }) {
|
|
4
4
|
const url = uniprotId ? getAlphaFoldStructureUrl(uniprotId) : undefined;
|
|
5
5
|
const confidenceUrl = uniprotId
|
|
6
6
|
? getAlphaFoldConfidenceUrl(uniprotId)
|
|
7
7
|
: undefined;
|
|
8
|
-
const { sequences, isLoading, error } =
|
|
9
|
-
url,
|
|
10
|
-
});
|
|
8
|
+
const { sequences, isLoading, error } = useStructureFileSequence({ url });
|
|
11
9
|
return {
|
|
12
10
|
isLoading,
|
|
13
11
|
error,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
2
|
import useSWR from 'swr';
|
|
3
|
+
import { STATIC_SWR_OPTIONS } from './swrOptions';
|
|
3
4
|
import { jsonfetch } from '../../fetchUtils';
|
|
4
5
|
import { md5 } from '../utils/md5';
|
|
5
6
|
import { stripStopCodon } from '../utils/util';
|
|
@@ -14,9 +15,7 @@ export default function useAlphaFoldSequenceSearch({ sequence, searchType, enabl
|
|
|
14
15
|
const { data, error, isLoading } = useSWR(enabled && searchValue
|
|
15
16
|
? `https://alphafold.ebi.ac.uk/api/sequence/summary?id=${encodeURIComponent(searchValue)}&type=${searchType}`
|
|
16
17
|
: null, jsonfetch, {
|
|
17
|
-
|
|
18
|
-
revalidateOnReconnect: false,
|
|
19
|
-
revalidateIfStale: false,
|
|
18
|
+
...STATIC_SWR_OPTIONS,
|
|
20
19
|
keepPreviousData: true,
|
|
21
20
|
});
|
|
22
21
|
return {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { getSession } from '@jbrowse/core/util';
|
|
1
2
|
import useSWR from 'swr';
|
|
3
|
+
import { STATIC_SWR_OPTIONS } from './swrOptions';
|
|
2
4
|
import { fetchProteinSeq } from '../utils/calculateProteinSequence';
|
|
3
5
|
import { getTranscriptFeatures } from '../utils/util';
|
|
4
6
|
export default function useIsoformProteinSequences({ feature, view, }) {
|
|
@@ -7,7 +9,11 @@ export default function useIsoformProteinSequences({ feature, view, }) {
|
|
|
7
9
|
const errors = [];
|
|
8
10
|
const results = await Promise.all(transcripts.map(async (f) => {
|
|
9
11
|
try {
|
|
10
|
-
const seq = await fetchProteinSeq({
|
|
12
|
+
const seq = await fetchProteinSeq({
|
|
13
|
+
session: getSession(view),
|
|
14
|
+
assemblyName: view?.assemblyNames?.[0],
|
|
15
|
+
feature: f,
|
|
16
|
+
});
|
|
11
17
|
return seq ? [f.id(), { feature: f, seq }] : undefined;
|
|
12
18
|
}
|
|
13
19
|
catch (e) {
|
|
@@ -27,9 +33,7 @@ export default function useIsoformProteinSequences({ feature, view, }) {
|
|
|
27
33
|
}
|
|
28
34
|
return Object.fromEntries(entries);
|
|
29
35
|
}, {
|
|
30
|
-
|
|
31
|
-
revalidateOnReconnect: false,
|
|
32
|
-
revalidateIfStale: false,
|
|
36
|
+
...STATIC_SWR_OPTIONS,
|
|
33
37
|
keepPreviousData: true,
|
|
34
38
|
});
|
|
35
39
|
return { isLoading, isoformSequences: data, error };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import useSWR from 'swr';
|
|
2
|
+
import { STATIC_SWR_OPTIONS } from './swrOptions';
|
|
3
|
+
import { addStructureFromData } from '../../ProteinView/addStructureFromData';
|
|
4
|
+
import { addStructureFromURL } from '../../ProteinView/addStructureFromURL';
|
|
5
|
+
import { extractStructureSequences } from '../../ProteinView/extractStructureSequences';
|
|
6
|
+
import { withTemporaryMolstarPlugin } from '../../ProteinView/withTemporaryMolstarPlugin';
|
|
7
|
+
function detectStructureFormat(fileName) {
|
|
8
|
+
const dot = fileName.lastIndexOf('.');
|
|
9
|
+
const ext = dot >= 0 ? fileName.slice(dot + 1).toLowerCase() : '';
|
|
10
|
+
if (ext === 'cif' || ext === 'mmcif' || ext === 'bcif') {
|
|
11
|
+
return 'mmcif';
|
|
12
|
+
}
|
|
13
|
+
return 'pdb';
|
|
14
|
+
}
|
|
15
|
+
async function fetchSequences({ file, url }) {
|
|
16
|
+
return withTemporaryMolstarPlugin(async (plugin) => {
|
|
17
|
+
const { model } = file
|
|
18
|
+
? await addStructureFromData({
|
|
19
|
+
data: await file.text(),
|
|
20
|
+
plugin,
|
|
21
|
+
format: detectStructureFormat(file.name),
|
|
22
|
+
})
|
|
23
|
+
: await addStructureFromURL({ url: url, plugin });
|
|
24
|
+
return extractStructureSequences(model);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
// Extract protein sequences from a structure given either a local File or a
|
|
28
|
+
// remote URL (exactly one is expected). Used directly for user-provided
|
|
29
|
+
// structures and wrapped by useAlphaFoldData for AlphaFoldDB URLs.
|
|
30
|
+
export default function useStructureFileSequence({ file, url, }) {
|
|
31
|
+
const key = file
|
|
32
|
+
? ['structure-file', file.name, file.size, file.lastModified]
|
|
33
|
+
: url
|
|
34
|
+
? ['structure-url', url]
|
|
35
|
+
: null;
|
|
36
|
+
const { data, error, isLoading } = useSWR(key, async () => {
|
|
37
|
+
const seq = await fetchSequences({ file, url });
|
|
38
|
+
if (!seq) {
|
|
39
|
+
throw new Error('no sequences detected in file');
|
|
40
|
+
}
|
|
41
|
+
return seq;
|
|
42
|
+
}, {
|
|
43
|
+
...STATIC_SWR_OPTIONS,
|
|
44
|
+
keepPreviousData: true,
|
|
45
|
+
});
|
|
46
|
+
return { error, isLoading, sequences: data };
|
|
47
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Feature } from '@jbrowse/core/util';
|
|
2
|
+
export default function useTranscriptIsoformSelection({ feature, view, structureSequence, resetKey, }: {
|
|
3
|
+
feature: Feature;
|
|
4
|
+
view?: {
|
|
5
|
+
assemblyNames?: string[];
|
|
6
|
+
};
|
|
7
|
+
structureSequence?: string;
|
|
8
|
+
resetKey?: string;
|
|
9
|
+
}): {
|
|
10
|
+
transcripts: Feature[];
|
|
11
|
+
isoformSequences: Record<string, {
|
|
12
|
+
feature: Feature;
|
|
13
|
+
seq: string;
|
|
14
|
+
}> | undefined;
|
|
15
|
+
isLoading: boolean;
|
|
16
|
+
error: any;
|
|
17
|
+
selectedTranscriptId: string | undefined;
|
|
18
|
+
setSelectedTranscriptId: import("react").Dispatch<import("react").SetStateAction<string | undefined>>;
|
|
19
|
+
selectedTranscript: Feature | undefined;
|
|
20
|
+
selectedIsoform: {
|
|
21
|
+
feature: Feature;
|
|
22
|
+
seq: string;
|
|
23
|
+
} | undefined;
|
|
24
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import useIsoformProteinSequences from './useIsoformProteinSequences';
|
|
2
|
+
import useTranscriptSelection from './useTranscriptSelection';
|
|
3
|
+
import { getId, getTranscriptFeatures } from '../utils/util';
|
|
4
|
+
// Bundles the transcript-isoform wiring shared by all three launch tabs:
|
|
5
|
+
// list transcripts, fetch their protein sequences, auto/manually select one,
|
|
6
|
+
// and resolve the selection back to its feature + sequence.
|
|
7
|
+
export default function useTranscriptIsoformSelection({ feature, view, structureSequence, resetKey, }) {
|
|
8
|
+
const transcripts = getTranscriptFeatures(feature);
|
|
9
|
+
const { isoformSequences, isLoading, error } = useIsoformProteinSequences({
|
|
10
|
+
feature,
|
|
11
|
+
view,
|
|
12
|
+
});
|
|
13
|
+
const { userSelection, setUserSelection } = useTranscriptSelection({
|
|
14
|
+
options: transcripts,
|
|
15
|
+
isoformSequences,
|
|
16
|
+
structureSequence,
|
|
17
|
+
resetKey,
|
|
18
|
+
});
|
|
19
|
+
const selectedTranscript = transcripts.find(f => getId(f) === userSelection);
|
|
20
|
+
const selectedIsoform = userSelection
|
|
21
|
+
? isoformSequences?.[userSelection]
|
|
22
|
+
: undefined;
|
|
23
|
+
return {
|
|
24
|
+
transcripts,
|
|
25
|
+
isoformSequences,
|
|
26
|
+
isLoading,
|
|
27
|
+
error,
|
|
28
|
+
selectedTranscriptId: userSelection,
|
|
29
|
+
setSelectedTranscriptId: setUserSelection,
|
|
30
|
+
selectedTranscript,
|
|
31
|
+
selectedIsoform,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import useSWR from 'swr';
|
|
2
|
+
import { STATIC_SWR_OPTIONS } from './swrOptions';
|
|
2
3
|
import { searchUniProtEntries } from '../services/lookupMethods';
|
|
3
4
|
import { isRecognizedDatabaseId } from '../utils/util';
|
|
4
5
|
export default function useUniProtSearch({ recognizedIds = [], geneId, geneName, selectedQueryId = 'auto', enabled = true, }) {
|
|
@@ -29,9 +30,7 @@ export default function useUniProtSearch({ recognizedIds = [], geneId, geneName,
|
|
|
29
30
|
geneId,
|
|
30
31
|
geneName: geneNameToSearch,
|
|
31
32
|
}), {
|
|
32
|
-
|
|
33
|
-
revalidateOnReconnect: false,
|
|
34
|
-
revalidateIfStale: false,
|
|
33
|
+
...STATIC_SWR_OPTIONS,
|
|
35
34
|
keepPreviousData: true,
|
|
36
35
|
});
|
|
37
36
|
return {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Feature } from '@jbrowse/core/util';
|
|
1
|
+
import type { AbstractSessionModel, Feature } from '@jbrowse/core/util';
|
|
2
2
|
export interface Feat {
|
|
3
3
|
start: number;
|
|
4
4
|
end: number;
|
|
@@ -20,9 +20,8 @@ export declare function getProteinSequence({ feature, seq, }: {
|
|
|
20
20
|
seq: string;
|
|
21
21
|
feature: Feature;
|
|
22
22
|
}): string;
|
|
23
|
-
export declare function fetchProteinSeq({ feature,
|
|
23
|
+
export declare function fetchProteinSeq({ feature, session, assemblyName, }: {
|
|
24
24
|
feature: Feature;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
} | undefined;
|
|
25
|
+
session: AbstractSessionModel;
|
|
26
|
+
assemblyName: string | undefined;
|
|
28
27
|
}): Promise<string | undefined>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getConf } from '@jbrowse/core/configuration';
|
|
2
|
-
import { defaultCodonTable, generateCodonTable,
|
|
2
|
+
import { defaultCodonTable, generateCodonTable, revcom, } from '@jbrowse/core/util';
|
|
3
3
|
export function stitch(subfeats, sequence) {
|
|
4
4
|
return subfeats.map(sub => sequence.slice(sub.start, sub.end)).join('');
|
|
5
5
|
}
|
|
@@ -45,13 +45,11 @@ export function getProteinSequence({ feature, seq, }) {
|
|
|
45
45
|
codonTable: generateCodonTable(defaultCodonTable),
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
|
-
export async function fetchProteinSeq({ feature,
|
|
48
|
+
export async function fetchProteinSeq({ feature, session, assemblyName, }) {
|
|
49
49
|
const start = feature.get('start');
|
|
50
50
|
const end = feature.get('end');
|
|
51
51
|
const refName = feature.get('refName');
|
|
52
|
-
const session = getSession(view);
|
|
53
52
|
const { assemblyManager, rpcManager } = session;
|
|
54
|
-
const assemblyName = view?.assemblyNames?.[0];
|
|
55
53
|
const assembly = assemblyName
|
|
56
54
|
? await assemblyManager.waitForAssembly(assemblyName)
|
|
57
55
|
: undefined;
|