jbrowse-plugin-protein3d 0.7.0 → 0.8.0
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.js +10 -2
- package/dist/LaunchProteinView/hooks/useAlphaFoldDBSearch.d.ts +3 -0
- package/dist/LaunchProteinView/hooks/useAlphaFoldDBSearch.js +25 -1
- package/dist/LaunchProteinView/hooks/useUniProtSearch.d.ts +2 -1
- package/dist/LaunchProteinView/hooks/useUniProtSearch.js +3 -1
- package/dist/LaunchProteinView/utils/launchViewUtils.d.ts +2 -9
- package/dist/LaunchProteinView/utils/launchViewUtils.js +3 -45
- package/dist/LaunchProteinView/utils/structureUrls.d.ts +8 -0
- package/dist/LaunchProteinView/utils/structureUrls.js +48 -0
- package/dist/LaunchProteinView/utils/util.d.ts +8 -0
- package/dist/LaunchProteinView/utils/util.js +18 -0
- package/dist/ProteinView/proteinViewSpec.d.ts +4 -0
- package/dist/ProteinView/structureModel.js +19 -1
- 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 +1 -1
- package/src/LaunchProteinView/components/AlphaFoldDBSearch.tsx +30 -7
- package/src/LaunchProteinView/hooks/useAlphaFoldDBSearch.ts +33 -1
- package/src/LaunchProteinView/hooks/useUniProtSearch.ts +6 -0
- package/src/LaunchProteinView/utils/extractTaxonId.test.ts +28 -0
- package/src/LaunchProteinView/utils/launchViewUtils.ts +22 -63
- package/src/LaunchProteinView/utils/structureUrls.ts +66 -0
- package/src/LaunchProteinView/utils/util.ts +20 -0
- package/src/ProteinView/proteinViewSpec.ts +4 -0
- package/src/ProteinView/structureModel.test.ts +48 -0
- package/src/ProteinView/structureModel.ts +24 -1
- package/src/version.ts +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ErrorMessage, LoadingEllipses } from '@jbrowse/core/ui';
|
|
3
|
-
import { DialogActions, DialogContent, Typography } from '@mui/material';
|
|
3
|
+
import { DialogActions, DialogContent, TextField, Typography, } from '@mui/material';
|
|
4
4
|
import { observer } from 'mobx-react';
|
|
5
5
|
import { makeStyles } from 'tss-react/mui';
|
|
6
6
|
import AlphaFoldDBSearchStatus from './AlphaFoldDBSearchStatus';
|
|
@@ -28,6 +28,12 @@ const useStyles = makeStyles()({
|
|
|
28
28
|
gap: 20,
|
|
29
29
|
alignItems: 'flex-start',
|
|
30
30
|
},
|
|
31
|
+
endRow: {
|
|
32
|
+
display: 'flex',
|
|
33
|
+
flexDirection: 'row',
|
|
34
|
+
gap: 12,
|
|
35
|
+
alignItems: 'flex-start',
|
|
36
|
+
},
|
|
31
37
|
});
|
|
32
38
|
const AlphaFoldDBSearch = observer(function AlphaFoldDBSearch({ feature, session, view, handleClose, alignmentAlgorithm, onAlignmentAlgorithmChange, }) {
|
|
33
39
|
const { classes } = useStyles();
|
|
@@ -35,7 +41,9 @@ const AlphaFoldDBSearch = observer(function AlphaFoldDBSearch({ feature, session
|
|
|
35
41
|
return (React.createElement(React.Fragment, null,
|
|
36
42
|
React.createElement(DialogContent, { className: classes.dialogContent },
|
|
37
43
|
state.error ? React.createElement(ErrorMessage, { error: state.error }) : null,
|
|
38
|
-
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(
|
|
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
|
+
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 => { state.setTaxonId(event.target.value); }, placeholder: String(state.effectiveTaxonId), slotProps: { inputLabel: { shrink: true } }, sx: { width: 180 } }))) : null }),
|
|
39
47
|
state.loadingStatuses.map(status => (React.createElement(LoadingEllipses, { key: status, variant: "subtitle2", message: status }))),
|
|
40
48
|
state.showUniprotResults && (React.createElement(React.Fragment, null,
|
|
41
49
|
React.createElement(Typography, { variant: "body2", color: "textSecondary" },
|
|
@@ -10,6 +10,9 @@ export default function useAlphaFoldDBSearch({ feature, view, }: {
|
|
|
10
10
|
setLookupMode: import("react").Dispatch<import("react").SetStateAction<LookupMode>>;
|
|
11
11
|
manualUniprotId: string;
|
|
12
12
|
setManualUniprotId: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
13
|
+
taxonId: string;
|
|
14
|
+
setTaxonId: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
15
|
+
effectiveTaxonId: number;
|
|
13
16
|
selectedQueryId: string;
|
|
14
17
|
setSelectedQueryId: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
15
18
|
sequenceSearchType: SequenceSearchType;
|
|
@@ -1,15 +1,34 @@
|
|
|
1
1
|
import { useState } from 'react';
|
|
2
|
+
import { getConf } from '@jbrowse/core/configuration';
|
|
3
|
+
import { getSession } from '@jbrowse/core/util';
|
|
2
4
|
import useAlphaFoldData from './useAlphaFoldData';
|
|
3
5
|
import useAlphaFoldSequenceSearch from './useAlphaFoldSequenceSearch';
|
|
4
6
|
import useDebouncedValue from './useDebouncedValue';
|
|
5
7
|
import useTranscriptIsoformSelection from './useTranscriptIsoformSelection';
|
|
6
8
|
import useUniProtSearch from './useUniProtSearch';
|
|
7
9
|
import getSearchDescription from '../utils/getSearchDescription';
|
|
8
|
-
import { extractFeatureIdentifiers, stripStopCodon } from '../utils/util';
|
|
10
|
+
import { extractFeatureIdentifiers, extractTaxonId, stripStopCodon, } from '../utils/util';
|
|
9
11
|
export default function useAlphaFoldDBSearch({ feature, view, }) {
|
|
10
12
|
const [lookupMode, setLookupMode] = useState('auto');
|
|
11
13
|
const [manualUniprotId, setManualUniprotId] = useState('');
|
|
14
|
+
const [taxonIdInput, setTaxonIdInput] = useState('');
|
|
12
15
|
const geneIds = extractFeatureIdentifiers(feature);
|
|
16
|
+
// The gene-name UniProt search is ambiguous across species, so scope it to
|
|
17
|
+
// the assembly's organism. jb2hubs assemblies carry the NCBI taxon in the
|
|
18
|
+
// reference-sequence track metadata (UCSC: metadata.taxId, GenArk:
|
|
19
|
+
// metadata.ucsc.taxId). Falls back to human via searchUniProtEntries when
|
|
20
|
+
// absent; a user override (taxonIdInput) always wins.
|
|
21
|
+
const assemblyName = view.assemblyNames[0];
|
|
22
|
+
const assembly = assemblyName
|
|
23
|
+
? getSession(view).assemblyManager.get(assemblyName)
|
|
24
|
+
: undefined;
|
|
25
|
+
const assemblyTaxonId = assembly
|
|
26
|
+
? extractTaxonId(getConf(assembly, ['sequence', 'metadata']))
|
|
27
|
+
: undefined;
|
|
28
|
+
const overrideTaxon = Number(taxonIdInput.trim());
|
|
29
|
+
const effectiveTaxonId = taxonIdInput.trim() !== '' && Number.isFinite(overrideTaxon) && overrideTaxon > 0
|
|
30
|
+
? overrideTaxon
|
|
31
|
+
: assemblyTaxonId;
|
|
13
32
|
const [selectedQueryId, setSelectedQueryId] = useState('auto');
|
|
14
33
|
const [sequenceSearchType, setSequenceSearchType] = useState('md5');
|
|
15
34
|
const [selectedUniprotId, setSelectedUniprotId] = useState();
|
|
@@ -21,6 +40,7 @@ export default function useAlphaFoldDBSearch({ feature, view, }) {
|
|
|
21
40
|
recognizedIds: geneIds.recognizedIds,
|
|
22
41
|
geneId: geneIds.geneId,
|
|
23
42
|
geneName: geneIds.geneName,
|
|
43
|
+
organismId: effectiveTaxonId,
|
|
24
44
|
selectedQueryId,
|
|
25
45
|
enabled: isAutoMode,
|
|
26
46
|
});
|
|
@@ -84,6 +104,10 @@ export default function useAlphaFoldDBSearch({ feature, view, }) {
|
|
|
84
104
|
setLookupMode,
|
|
85
105
|
manualUniprotId,
|
|
86
106
|
setManualUniprotId,
|
|
107
|
+
taxonId: taxonIdInput,
|
|
108
|
+
setTaxonId: setTaxonIdInput,
|
|
109
|
+
// shown as the field placeholder so the user sees the organism in effect
|
|
110
|
+
effectiveTaxonId: effectiveTaxonId ?? 9606,
|
|
87
111
|
selectedQueryId,
|
|
88
112
|
setSelectedQueryId,
|
|
89
113
|
sequenceSearchType,
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { UniProtEntry } from '../services/lookupMethods';
|
|
2
|
-
export default function useUniProtSearch({ recognizedIds, geneId, geneName, selectedQueryId, enabled, }: {
|
|
2
|
+
export default function useUniProtSearch({ recognizedIds, geneId, geneName, organismId, selectedQueryId, enabled, }: {
|
|
3
3
|
recognizedIds?: string[];
|
|
4
4
|
geneId?: string;
|
|
5
5
|
geneName?: string;
|
|
6
|
+
organismId?: number;
|
|
6
7
|
selectedQueryId?: string;
|
|
7
8
|
enabled?: boolean;
|
|
8
9
|
}): {
|
|
@@ -2,7 +2,7 @@ import useSWR from 'swr';
|
|
|
2
2
|
import { STATIC_SWR_OPTIONS } from './swrOptions';
|
|
3
3
|
import { searchUniProtEntries } from '../services/lookupMethods';
|
|
4
4
|
import { isRecognizedDatabaseId } from '../utils/util';
|
|
5
|
-
export default function useUniProtSearch({ recognizedIds = [], geneId, geneName, selectedQueryId = 'auto', enabled = true, }) {
|
|
5
|
+
export default function useUniProtSearch({ recognizedIds = [], geneId, geneName, organismId, selectedQueryId = 'auto', enabled = true, }) {
|
|
6
6
|
// Determine what to search based on selectedQueryId
|
|
7
7
|
let idsToSearch = [];
|
|
8
8
|
let geneNameToSearch;
|
|
@@ -25,11 +25,13 @@ export default function useUniProtSearch({ recognizedIds = [], geneId, geneName,
|
|
|
25
25
|
idsToSearch.join(','),
|
|
26
26
|
geneNameToSearch,
|
|
27
27
|
geneId,
|
|
28
|
+
organismId,
|
|
28
29
|
]
|
|
29
30
|
: null, async () => searchUniProtEntries({
|
|
30
31
|
recognizedIds: idsToSearch,
|
|
31
32
|
geneId,
|
|
32
33
|
geneName: geneNameToSearch,
|
|
34
|
+
organismId,
|
|
33
35
|
}), {
|
|
34
36
|
...STATIC_SWR_OPTIONS,
|
|
35
37
|
keepPreviousData: true,
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { ALPHAFOLD_VERSION, getAlphaFoldConfidenceUrl, getAlphaFoldMsaUrl, getAlphaFoldStructureUrl, getConfidenceUrlFromTarget, getPdbStructureUrl, getStructureUrlFromTarget, getUniprotIdFromAlphaFoldTarget } from './structureUrls';
|
|
2
|
+
export { ALPHAFOLD_VERSION, getAlphaFoldConfidenceUrl, getAlphaFoldMsaUrl, getAlphaFoldStructureUrl, getConfidenceUrlFromTarget, getPdbStructureUrl, getStructureUrlFromTarget, getUniprotIdFromAlphaFoldTarget, };
|
|
1
3
|
import type { AbstractSessionModel, Feature, SessionWithAddTracks } from '@jbrowse/core/util';
|
|
2
4
|
import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view';
|
|
3
5
|
declare global {
|
|
@@ -5,14 +7,6 @@ declare global {
|
|
|
5
7
|
JBrowsePluginMsaView?: unknown;
|
|
6
8
|
}
|
|
7
9
|
}
|
|
8
|
-
export declare const ALPHAFOLD_VERSION = "v6";
|
|
9
|
-
export declare function getAlphaFoldStructureUrl(uniprotId: string, version?: string): string;
|
|
10
|
-
export declare function getAlphaFoldConfidenceUrl(uniprotId: string, version?: string): string;
|
|
11
|
-
export declare function getAlphaFoldMsaUrl(uniprotId: string, version?: string): string;
|
|
12
|
-
export declare function getPdbStructureUrl(pdbId: string): string;
|
|
13
|
-
export declare function getUniprotIdFromAlphaFoldTarget(target: string): string | undefined;
|
|
14
|
-
export declare function getStructureUrlFromTarget(target: string, db: string): string | undefined;
|
|
15
|
-
export declare function getConfidenceUrlFromTarget(target: string): string | undefined;
|
|
16
10
|
interface LaunchViewParams {
|
|
17
11
|
session: AbstractSessionModel;
|
|
18
12
|
view: LinearGenomeViewModel;
|
|
@@ -48,4 +42,3 @@ export declare function getConditionalProteinLaunches({ session, view, feature,
|
|
|
48
42
|
launchMsa: (() => import("@jbrowse/core/util").AbstractViewModel | undefined) | undefined;
|
|
49
43
|
};
|
|
50
44
|
export declare function launch3DProteinViewWithMsa(params: LaunchViewParams & Launch3DExtraParams): import("@jbrowse/core/util").AbstractViewModel | undefined;
|
|
51
|
-
export {};
|
|
@@ -1,53 +1,11 @@
|
|
|
1
1
|
import { isSessionWithAddTracks } from '@jbrowse/core/util';
|
|
2
2
|
import { maybeLaunchSideBySide } from './sideBySide';
|
|
3
|
+
import { ALPHAFOLD_VERSION, getAlphaFoldConfidenceUrl, getAlphaFoldMsaUrl, getAlphaFoldStructureUrl, getConfidenceUrlFromTarget, getPdbStructureUrl, getStructureUrlFromTarget, getUniprotIdFromAlphaFoldTarget, } from './structureUrls';
|
|
3
4
|
import { getGeneDisplayName, getTranscriptDisplayName } from './util';
|
|
4
5
|
import { proteinViewSnapshot } from '../../ProteinView/proteinViewSpec';
|
|
5
6
|
import { launchProteinAnnotationView } from '../components/launchProteinAnnotationView';
|
|
6
|
-
|
|
7
|
-
export
|
|
8
|
-
return `https://alphafold.ebi.ac.uk/files/AF-${uniprotId}-F1-model_${version}.cif`;
|
|
9
|
-
}
|
|
10
|
-
export function getAlphaFoldConfidenceUrl(uniprotId, version = ALPHAFOLD_VERSION) {
|
|
11
|
-
return `https://alphafold.ebi.ac.uk/files/AF-${uniprotId}-F1-confidence_${version}.json`;
|
|
12
|
-
}
|
|
13
|
-
export function getAlphaFoldMsaUrl(uniprotId, version = ALPHAFOLD_VERSION) {
|
|
14
|
-
return `https://alphafold.ebi.ac.uk/files/msa/AF-${uniprotId}-F1-msa_${version}.a3m`;
|
|
15
|
-
}
|
|
16
|
-
export function getPdbStructureUrl(pdbId) {
|
|
17
|
-
return `https://files.rcsb.org/download/${pdbId}.cif`;
|
|
18
|
-
}
|
|
19
|
-
// Foldseek targets may contain a description after the ID separated by a
|
|
20
|
-
// space, e.g. "AF-P16442-F1-model_v6 Histo-blood group ABO transferase".
|
|
21
|
-
function extractTargetId(target) {
|
|
22
|
-
return target.split(' ')[0];
|
|
23
|
-
}
|
|
24
|
-
export function getUniprotIdFromAlphaFoldTarget(target) {
|
|
25
|
-
// Handles both "AF-P16442-F1-model_v6" and full URLs like
|
|
26
|
-
// "https://alphafold.ebi.ac.uk/files/AF-P16442-F1-model_v6.cif"
|
|
27
|
-
const match = /AF-([A-Z0-9]+)-F\d+/.exec(extractTargetId(target));
|
|
28
|
-
return match?.[1];
|
|
29
|
-
}
|
|
30
|
-
export function getStructureUrlFromTarget(target, db) {
|
|
31
|
-
const targetId = extractTargetId(target);
|
|
32
|
-
if (targetId.startsWith('AF-')) {
|
|
33
|
-
return `https://alphafold.ebi.ac.uk/files/${targetId}.cif`;
|
|
34
|
-
}
|
|
35
|
-
if (db === 'pdb100') {
|
|
36
|
-
const pdbId = targetId.split('_')[0];
|
|
37
|
-
if (pdbId.length === 4) {
|
|
38
|
-
return getPdbStructureUrl(pdbId);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return undefined;
|
|
42
|
-
}
|
|
43
|
-
export function getConfidenceUrlFromTarget(target) {
|
|
44
|
-
const targetId = extractTargetId(target);
|
|
45
|
-
if (targetId.startsWith('AF-')) {
|
|
46
|
-
const confidenceId = targetId.replace('-model_', '-confidence_');
|
|
47
|
-
return `https://alphafold.ebi.ac.uk/files/${confidenceId}.json`;
|
|
48
|
-
}
|
|
49
|
-
return undefined;
|
|
50
|
-
}
|
|
7
|
+
// Re-exported so existing importers keep their `launchViewUtils` import path.
|
|
8
|
+
export { ALPHAFOLD_VERSION, getAlphaFoldConfidenceUrl, getAlphaFoldMsaUrl, getAlphaFoldStructureUrl, getConfidenceUrlFromTarget, getPdbStructureUrl, getStructureUrlFromTarget, getUniprotIdFromAlphaFoldTarget, };
|
|
51
9
|
export function formatViewName(prefix, feature, selectedTranscript, uniprotId) {
|
|
52
10
|
return [
|
|
53
11
|
...new Set([
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const ALPHAFOLD_VERSION = "v6";
|
|
2
|
+
export declare function getAlphaFoldStructureUrl(uniprotId: string, version?: string): string;
|
|
3
|
+
export declare function getAlphaFoldConfidenceUrl(uniprotId: string, version?: string): string;
|
|
4
|
+
export declare function getAlphaFoldMsaUrl(uniprotId: string, version?: string): string;
|
|
5
|
+
export declare function getPdbStructureUrl(pdbId: string): string;
|
|
6
|
+
export declare function getUniprotIdFromAlphaFoldTarget(target: string): string | undefined;
|
|
7
|
+
export declare function getStructureUrlFromTarget(target: string, db: string): string | undefined;
|
|
8
|
+
export declare function getConfidenceUrlFromTarget(target: string): string | undefined;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// Pure structure-URL builders and target parsers. Kept dependency-free so both
|
|
2
|
+
// the launch flow and the ProteinView model (e.g. resolving a `uniprotId`/`pdbId`
|
|
3
|
+
// shorthand at hydration) can import them without pulling in heavy launch code.
|
|
4
|
+
export const ALPHAFOLD_VERSION = 'v6';
|
|
5
|
+
export function getAlphaFoldStructureUrl(uniprotId, version = ALPHAFOLD_VERSION) {
|
|
6
|
+
return `https://alphafold.ebi.ac.uk/files/AF-${uniprotId}-F1-model_${version}.cif`;
|
|
7
|
+
}
|
|
8
|
+
export function getAlphaFoldConfidenceUrl(uniprotId, version = ALPHAFOLD_VERSION) {
|
|
9
|
+
return `https://alphafold.ebi.ac.uk/files/AF-${uniprotId}-F1-confidence_${version}.json`;
|
|
10
|
+
}
|
|
11
|
+
export function getAlphaFoldMsaUrl(uniprotId, version = ALPHAFOLD_VERSION) {
|
|
12
|
+
return `https://alphafold.ebi.ac.uk/files/msa/AF-${uniprotId}-F1-msa_${version}.a3m`;
|
|
13
|
+
}
|
|
14
|
+
export function getPdbStructureUrl(pdbId) {
|
|
15
|
+
return `https://files.rcsb.org/download/${pdbId}.cif`;
|
|
16
|
+
}
|
|
17
|
+
// Foldseek targets may contain a description after the ID separated by a
|
|
18
|
+
// space, e.g. "AF-P16442-F1-model_v6 Histo-blood group ABO transferase".
|
|
19
|
+
function extractTargetId(target) {
|
|
20
|
+
return target.split(' ')[0];
|
|
21
|
+
}
|
|
22
|
+
export function getUniprotIdFromAlphaFoldTarget(target) {
|
|
23
|
+
// Handles both "AF-P16442-F1-model_v6" and full URLs like
|
|
24
|
+
// "https://alphafold.ebi.ac.uk/files/AF-P16442-F1-model_v6.cif"
|
|
25
|
+
const match = /AF-([A-Z0-9]+)-F\d+/.exec(extractTargetId(target));
|
|
26
|
+
return match?.[1];
|
|
27
|
+
}
|
|
28
|
+
export function getStructureUrlFromTarget(target, db) {
|
|
29
|
+
const targetId = extractTargetId(target);
|
|
30
|
+
if (targetId.startsWith('AF-')) {
|
|
31
|
+
return `https://alphafold.ebi.ac.uk/files/${targetId}.cif`;
|
|
32
|
+
}
|
|
33
|
+
if (db === 'pdb100') {
|
|
34
|
+
const pdbId = targetId.split('_')[0];
|
|
35
|
+
if (pdbId.length === 4) {
|
|
36
|
+
return getPdbStructureUrl(pdbId);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
export function getConfidenceUrlFromTarget(target) {
|
|
42
|
+
const targetId = extractTargetId(target);
|
|
43
|
+
if (targetId.startsWith('AF-')) {
|
|
44
|
+
const confidenceId = targetId.replace('-model_', '-confidence_');
|
|
45
|
+
return `https://alphafold.ebi.ac.uk/files/${confidenceId}.json`;
|
|
46
|
+
}
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import type { Feature } from '@jbrowse/core/util';
|
|
2
2
|
export declare function stripStopCodon(seq: string): string;
|
|
3
|
+
/**
|
|
4
|
+
* Pull an NCBI taxon id out of reference-sequence-track metadata. jb2hubs
|
|
5
|
+
* assemblies expose it differently by source: UCSC golden-path spreads it flat
|
|
6
|
+
* (`metadata.taxId`), GenArk nests the raw hub stanza (`metadata.ucsc.taxId`).
|
|
7
|
+
* `taxonId` is accepted too. Returns a positive integer, or undefined when
|
|
8
|
+
* absent/unparseable so callers can fall back to a default organism.
|
|
9
|
+
*/
|
|
10
|
+
export declare function extractTaxonId(metadata: unknown): number | undefined;
|
|
3
11
|
export declare function getTranscriptFeatures(feature: Feature): Feature[];
|
|
4
12
|
export declare function stripTrailingVersion(s?: string): string | undefined;
|
|
5
13
|
export declare function getId(val?: Feature): string;
|
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
export function stripStopCodon(seq) {
|
|
2
2
|
return seq.replaceAll('*', '');
|
|
3
3
|
}
|
|
4
|
+
/**
|
|
5
|
+
* Pull an NCBI taxon id out of reference-sequence-track metadata. jb2hubs
|
|
6
|
+
* assemblies expose it differently by source: UCSC golden-path spreads it flat
|
|
7
|
+
* (`metadata.taxId`), GenArk nests the raw hub stanza (`metadata.ucsc.taxId`).
|
|
8
|
+
* `taxonId` is accepted too. Returns a positive integer, or undefined when
|
|
9
|
+
* absent/unparseable so callers can fall back to a default organism.
|
|
10
|
+
*/
|
|
11
|
+
export function extractTaxonId(metadata) {
|
|
12
|
+
if (metadata === null || typeof metadata !== 'object') {
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
const m = metadata;
|
|
16
|
+
const ucsc = m.ucsc !== null && typeof m.ucsc === 'object'
|
|
17
|
+
? m.ucsc
|
|
18
|
+
: undefined;
|
|
19
|
+
const n = Number(m.taxId ?? m.taxonId ?? ucsc?.taxId);
|
|
20
|
+
return Number.isFinite(n) && n > 0 ? n : undefined;
|
|
21
|
+
}
|
|
4
22
|
export function getTranscriptFeatures(feature) {
|
|
5
23
|
// check if we are looking at a 'two-level' or 'three-level' feature by
|
|
6
24
|
// finding exon/CDS subfeatures. we want to select from transcript names
|
|
@@ -9,6 +9,8 @@ import type { SimpleFeatureSerialized } from '@jbrowse/core/util';
|
|
|
9
9
|
export interface ProteinStructureSpec {
|
|
10
10
|
url?: string;
|
|
11
11
|
data?: string;
|
|
12
|
+
uniprotId?: string;
|
|
13
|
+
pdbId?: string;
|
|
12
14
|
connectedViewId?: string;
|
|
13
15
|
feature?: SimpleFeatureSerialized;
|
|
14
16
|
userProvidedTranscriptSequence?: string;
|
|
@@ -48,6 +50,8 @@ export declare function proteinViewSnapshot(spec: ProteinViewSpec): {
|
|
|
48
50
|
userProvidedTranscriptSequence: string;
|
|
49
51
|
url?: string;
|
|
50
52
|
data?: string;
|
|
53
|
+
uniprotId?: string;
|
|
54
|
+
pdbId?: string;
|
|
51
55
|
connectedViewId?: string;
|
|
52
56
|
feature?: SimpleFeatureSerialized;
|
|
53
57
|
initialSelection?: {
|
|
@@ -12,7 +12,7 @@ import { kyteDoolittleScores, mapResidueValuesToColumns } from './residueTracks'
|
|
|
12
12
|
import subscribeMolstarInteraction from './subscribeMolstarInteraction';
|
|
13
13
|
import { coerceAlignmentAlgorithm } from './types';
|
|
14
14
|
import { checkHovered } from './util';
|
|
15
|
-
import { getUniprotIdFromAlphaFoldTarget } from '../LaunchProteinView/utils/
|
|
15
|
+
import { getAlphaFoldStructureUrl, getPdbStructureUrl, getUniprotIdFromAlphaFoldTarget, } from '../LaunchProteinView/utils/structureUrls';
|
|
16
16
|
import { stripStopCodon } from '../LaunchProteinView/utils/util';
|
|
17
17
|
import { genomeToTranscriptSeqMapping } from '../mappings';
|
|
18
18
|
const Structure = types
|
|
@@ -52,6 +52,24 @@ const Structure = types
|
|
|
52
52
|
* session spec open with a domain pre-highlighted, with no click.
|
|
53
53
|
*/
|
|
54
54
|
initialSelection: types.frozen(),
|
|
55
|
+
})
|
|
56
|
+
// Input-only shorthand: remap a `{ uniprotId }`/`{ pdbId }` snapshot to a
|
|
57
|
+
// concrete `url` at hydration and strip the shorthand keys (they are not
|
|
58
|
+
// stored — uniprotId stays derivable from the url via the getter below), so a
|
|
59
|
+
// hand-authored snapshot loads without the caller knowing the AlphaFold/RCSB
|
|
60
|
+
// URL format. An explicit url/data always wins; the shorthand resolves the
|
|
61
|
+
// canonical isoform (AF-<id>-F1) only. Idempotent: a re-snapshot has no
|
|
62
|
+
// shorthand keys and an already-set url, so it passes through unchanged.
|
|
63
|
+
.preProcessSnapshot(({ uniprotId, pdbId, ...rest }) => {
|
|
64
|
+
const hasSource = rest.url !== undefined || rest.data !== undefined;
|
|
65
|
+
const url = hasSource
|
|
66
|
+
? rest.url
|
|
67
|
+
: uniprotId !== undefined
|
|
68
|
+
? getAlphaFoldStructureUrl(uniprotId)
|
|
69
|
+
: pdbId !== undefined
|
|
70
|
+
? getPdbStructureUrl(pdbId)
|
|
71
|
+
: rest.url;
|
|
72
|
+
return { ...rest, url };
|
|
55
73
|
})
|
|
56
74
|
.volatile(() => ({
|
|
57
75
|
/**
|