jbrowse-plugin-msaview 2.3.8 → 2.4.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/AddHighlightModel/GenomeMouseoverHighlight.js +4 -15
- package/dist/AddHighlightModel/GenomeMouseoverHighlight.js.map +1 -1
- package/dist/AddHighlightModel/MsaToGenomeHighlight.js +5 -8
- package/dist/AddHighlightModel/MsaToGenomeHighlight.js.map +1 -1
- package/dist/AddHighlightModel/util.d.ts +3 -0
- package/dist/AddHighlightModel/util.js +3 -0
- package/dist/AddHighlightModel/util.js.map +1 -1
- package/dist/LaunchMsaView/components/LaunchMsaViewDialog.js +3 -8
- package/dist/LaunchMsaView/components/LaunchMsaViewDialog.js.map +1 -1
- package/dist/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.js +7 -10
- package/dist/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.js.map +1 -1
- package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.js +2 -5
- package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.js.map +1 -1
- package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.js +0 -3
- package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.js.map +1 -1
- package/dist/LaunchMsaView/components/NCBIBlastQuery/blastLaunchView.d.ts +4 -4
- package/dist/LaunchMsaView/components/NCBIBlastQuery/blastLaunchView.js +2 -2
- package/dist/LaunchMsaView/components/NCBIBlastQuery/blastLaunchView.js.map +1 -1
- package/dist/LaunchMsaView/components/NCBIBlastQuery/consts.d.ts +4 -0
- package/dist/LaunchMsaView/components/NCBIBlastQuery/consts.js +2 -0
- package/dist/LaunchMsaView/components/NCBIBlastQuery/consts.js.map +1 -1
- package/dist/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.js +10 -21
- package/dist/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.js.map +1 -1
- package/dist/LaunchMsaView/components/PreLoadedMSA/types.d.ts +1 -0
- package/dist/LaunchMsaView/components/PreLoadedMSA/types.js +4 -1
- package/dist/LaunchMsaView/components/PreLoadedMSA/types.js.map +1 -1
- package/dist/LaunchMsaView/components/types.d.ts +0 -3
- package/dist/LaunchMsaView/components/useFeatureSequence.d.ts +4 -4
- package/dist/LaunchMsaView/components/useFeatureSequence.js +2 -4
- package/dist/LaunchMsaView/components/useFeatureSequence.js.map +1 -1
- package/dist/LaunchMsaView/components/useSWRFeatureSequence.d.ts +4 -5
- package/dist/LaunchMsaView/components/useSWRFeatureSequence.js +11 -30
- package/dist/LaunchMsaView/components/useSWRFeatureSequence.js.map +1 -1
- package/dist/MsaViewPanel/afterCreateAutoruns.js +4 -13
- package/dist/MsaViewPanel/afterCreateAutoruns.js.map +1 -1
- package/dist/MsaViewPanel/components/ConnectStructureDialog.js +2 -2
- package/dist/MsaViewPanel/components/ConnectStructureDialog.js.map +1 -1
- package/dist/MsaViewPanel/components/LoadingBLAST.js +2 -3
- package/dist/MsaViewPanel/components/LoadingBLAST.js.map +1 -1
- package/dist/MsaViewPanel/model.d.ts +4 -11
- package/dist/MsaViewPanel/model.js +6 -20
- package/dist/MsaViewPanel/model.js.map +1 -1
- package/dist/MsaViewPanel/msaDataStore.d.ts +0 -1
- package/dist/MsaViewPanel/msaDataStore.js +0 -9
- package/dist/MsaViewPanel/msaDataStore.js.map +1 -1
- package/dist/MsaViewPanel/structureConnection.d.ts +6 -4
- package/dist/MsaViewPanel/structureConnection.js +6 -6
- package/dist/MsaViewPanel/structureConnection.js.map +1 -1
- package/dist/MsaViewPanel/structureConnection.test.js +1 -19
- package/dist/MsaViewPanel/structureConnection.test.js.map +1 -1
- package/dist/jbrowse-plugin-msaview.umd.production.min.js +25 -27
- package/dist/jbrowse-plugin-msaview.umd.production.min.js.map +4 -4
- package/dist/utils/blastCache.d.ts +7 -13
- package/dist/utils/blastCache.js +0 -12
- package/dist/utils/blastCache.js.map +1 -1
- package/dist/utils/msa.d.ts +2 -1
- package/dist/utils/msa.js +0 -3
- package/dist/utils/msa.js.map +1 -1
- package/dist/utils/ncbiBlast.d.ts +3 -2
- package/dist/utils/ncbiBlast.js +1 -1
- package/dist/utils/ncbiBlast.js.map +1 -1
- package/dist/utils/taxonomyNames.js +9 -4
- package/dist/utils/taxonomyNames.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +22 -20
- package/src/AddHighlightModel/GenomeMouseoverHighlight.tsx +7 -21
- package/src/AddHighlightModel/MsaToGenomeHighlight.tsx +10 -10
- package/src/AddHighlightModel/util.ts +6 -0
- package/src/LaunchMsaView/components/LaunchMsaViewDialog.tsx +3 -16
- package/src/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.tsx +8 -12
- package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.tsx +6 -15
- package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.tsx +0 -9
- package/src/LaunchMsaView/components/NCBIBlastQuery/blastLaunchView.ts +6 -6
- package/src/LaunchMsaView/components/NCBIBlastQuery/consts.ts +7 -0
- package/src/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.tsx +12 -27
- package/src/LaunchMsaView/components/PreLoadedMSA/types.ts +6 -0
- package/src/LaunchMsaView/components/types.ts +0 -3
- package/src/LaunchMsaView/components/useFeatureSequence.ts +1 -7
- package/src/LaunchMsaView/components/useSWRFeatureSequence.ts +10 -37
- package/src/MsaViewPanel/afterCreateAutoruns.ts +7 -15
- package/src/MsaViewPanel/components/ConnectStructureDialog.tsx +2 -2
- package/src/MsaViewPanel/components/LoadingBLAST.tsx +4 -3
- package/src/MsaViewPanel/model.ts +16 -29
- package/src/MsaViewPanel/msaDataStore.ts +0 -9
- package/src/MsaViewPanel/structureConnection.test.ts +0 -21
- package/src/MsaViewPanel/structureConnection.ts +7 -7
- package/src/utils/blastCache.ts +14 -37
- package/src/utils/msa.ts +5 -6
- package/src/utils/ncbiBlast.ts +9 -5
- package/src/utils/taxonomyNames.ts +13 -4
- package/src/version.ts +1 -1
- package/dist/LaunchMsaView/components/EnsemblGeneTree/EnsemblGeneTree.d.ts +0 -8
- package/dist/LaunchMsaView/components/EnsemblGeneTree/EnsemblGeneTree.js +0 -70
- package/dist/LaunchMsaView/components/EnsemblGeneTree/EnsemblGeneTree.js.map +0 -1
- package/dist/LaunchMsaView/components/EnsemblGeneTree/ensemblGeneTreeLaunchView.d.ts +0 -13
- package/dist/LaunchMsaView/components/EnsemblGeneTree/ensemblGeneTreeLaunchView.js +0 -12
- package/dist/LaunchMsaView/components/EnsemblGeneTree/ensemblGeneTreeLaunchView.js.map +0 -1
- package/dist/LaunchMsaView/components/EnsemblGeneTree/ensemblGeneTreeUtils.d.ts +0 -6
- package/dist/LaunchMsaView/components/EnsemblGeneTree/ensemblGeneTreeUtils.js +0 -25
- package/dist/LaunchMsaView/components/EnsemblGeneTree/ensemblGeneTreeUtils.js.map +0 -1
- package/dist/LaunchMsaView/components/EnsemblGeneTree/gatherSequencesFromTree.d.ts +0 -2
- package/dist/LaunchMsaView/components/EnsemblGeneTree/gatherSequencesFromTree.js +0 -20
- package/dist/LaunchMsaView/components/EnsemblGeneTree/gatherSequencesFromTree.js.map +0 -1
- package/dist/LaunchMsaView/components/EnsemblGeneTree/types.d.ts +0 -24
- package/dist/LaunchMsaView/components/EnsemblGeneTree/types.js +0 -2
- package/dist/LaunchMsaView/components/EnsemblGeneTree/types.js.map +0 -1
- package/dist/LaunchMsaView/components/EnsemblGeneTree/useGeneTree.d.ts +0 -10
- package/dist/LaunchMsaView/components/EnsemblGeneTree/useGeneTree.js +0 -11
- package/dist/LaunchMsaView/components/EnsemblGeneTree/useGeneTree.js.map +0 -1
- package/dist/LaunchMsaView/components/EnsemblGeneTree/util.d.ts +0 -1
- package/dist/LaunchMsaView/components/EnsemblGeneTree/util.js +0 -2
- package/dist/LaunchMsaView/components/EnsemblGeneTree/util.js.map +0 -1
- package/src/LaunchMsaView/components/EnsemblGeneTree/EnsemblGeneTree.tsx +0 -123
- package/src/LaunchMsaView/components/EnsemblGeneTree/ensemblGeneTreeLaunchView.ts +0 -30
- package/src/LaunchMsaView/components/EnsemblGeneTree/ensemblGeneTreeUtils.ts +0 -47
- package/src/LaunchMsaView/components/EnsemblGeneTree/gatherSequencesFromTree.ts +0 -22
- package/src/LaunchMsaView/components/EnsemblGeneTree/types.ts +0 -28
- package/src/LaunchMsaView/components/EnsemblGeneTree/useGeneTree.ts +0 -17
- package/src/LaunchMsaView/components/EnsemblGeneTree/util.ts +0 -6
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
export const BASE_BLAST_URL = 'https://blast.ncbi.nlm.nih.gov/Blast.cgi'
|
|
2
|
+
|
|
2
3
|
export const msaAlgorithms = ['clustalo', 'muscle', 'kalign', 'mafft'] as const
|
|
3
4
|
export type MsaAlgorithm = (typeof msaAlgorithms)[number]
|
|
5
|
+
|
|
6
|
+
export const blastDatabaseOptions = ['nr', 'nr_cluster_seq'] as const
|
|
7
|
+
export type BlastDatabase = (typeof blastDatabaseOptions)[number]
|
|
8
|
+
|
|
9
|
+
export const blastPrograms = ['blastp', 'quick-blastp'] as const
|
|
10
|
+
export type BlastProgram = (typeof blastPrograms)[number]
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React, { useState } from 'react'
|
|
2
2
|
|
|
3
|
-
import { readConfObject } from '@jbrowse/core/configuration'
|
|
4
3
|
import { ErrorMessage, LoadingEllipses, SanitizedHTML } from '@jbrowse/core/ui'
|
|
5
4
|
import { getContainingView, getEnv, getSession } from '@jbrowse/core/util'
|
|
6
5
|
import { Button, DialogActions, DialogContent, MenuItem } from '@mui/material'
|
|
@@ -15,8 +14,8 @@ import { useTranscriptSelection } from '../useTranscriptSelection'
|
|
|
15
14
|
import { swrFlags } from './consts'
|
|
16
15
|
import { fetchMSA, fetchMSAList } from './fetchMSAData'
|
|
17
16
|
import { preCalculatedLaunchView } from './preCalculatedLaunchView'
|
|
17
|
+
import { readMsaDatasets } from './types'
|
|
18
18
|
|
|
19
|
-
import type { Dataset } from './types'
|
|
20
19
|
import type { AbstractTrackModel, Feature } from '@jbrowse/core/util'
|
|
21
20
|
import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
|
|
22
21
|
|
|
@@ -45,10 +44,7 @@ const PreLoadedMSA = observer(function ({
|
|
|
45
44
|
const { assemblyNames } = view
|
|
46
45
|
const [viewError, setViewError] = useState<unknown>()
|
|
47
46
|
|
|
48
|
-
const
|
|
49
|
-
const datasets = readConfObject(jbrowse, ['msa', 'datasets']) as
|
|
50
|
-
| Dataset[]
|
|
51
|
-
| undefined
|
|
47
|
+
const datasets = readMsaDatasets(session.jbrowse)
|
|
52
48
|
const [selectedDatasetId, setSelectedDatasetId] = useState(
|
|
53
49
|
datasets?.[0]?.datasetId,
|
|
54
50
|
)
|
|
@@ -58,14 +54,8 @@ const PreLoadedMSA = observer(function ({
|
|
|
58
54
|
isLoading: msaListLoading,
|
|
59
55
|
error: msaListFetchError,
|
|
60
56
|
} = useSWR(
|
|
61
|
-
|
|
62
|
-
() =>
|
|
63
|
-
selectedDataset
|
|
64
|
-
? fetchMSAList({
|
|
65
|
-
config: selectedDataset.adapter,
|
|
66
|
-
pluginManager,
|
|
67
|
-
})
|
|
68
|
-
: undefined,
|
|
57
|
+
selectedDataset ? `${selectedDataset.datasetId}-msa-list` : null,
|
|
58
|
+
() => fetchMSAList({ config: selectedDataset!.adapter, pluginManager }),
|
|
69
59
|
swrFlags,
|
|
70
60
|
)
|
|
71
61
|
|
|
@@ -83,25 +73,20 @@ const PreLoadedMSA = observer(function ({
|
|
|
83
73
|
isLoading: msaDataLoading,
|
|
84
74
|
error: msaDataFetchError,
|
|
85
75
|
} = useSWR(
|
|
86
|
-
selectedId &&
|
|
87
|
-
? `${
|
|
88
|
-
:
|
|
76
|
+
selectedId && selectedDataset && msaList
|
|
77
|
+
? `${selectedDataset.datasetId}-${selectedId}-${msaList.length}-msa`
|
|
78
|
+
: null,
|
|
89
79
|
() =>
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
})
|
|
96
|
-
: undefined,
|
|
80
|
+
fetchMSA({
|
|
81
|
+
msaId: selectedId,
|
|
82
|
+
config: selectedDataset!.adapter,
|
|
83
|
+
pluginManager,
|
|
84
|
+
}),
|
|
97
85
|
swrFlags,
|
|
98
86
|
)
|
|
99
87
|
|
|
100
88
|
const e =
|
|
101
89
|
msaListFetchError ?? msaDataFetchError ?? proteinSequenceError ?? viewError
|
|
102
|
-
if (e) {
|
|
103
|
-
console.error(e)
|
|
104
|
-
}
|
|
105
90
|
return (
|
|
106
91
|
<>
|
|
107
92
|
<DialogContent className={classes.dialogContent}>
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { readConfObject } from '@jbrowse/core/configuration'
|
|
2
|
+
|
|
1
3
|
import type { AnyConfigurationModel } from '@jbrowse/core/configuration'
|
|
2
4
|
|
|
3
5
|
export interface Dataset {
|
|
@@ -6,3 +8,7 @@ export interface Dataset {
|
|
|
6
8
|
description?: string
|
|
7
9
|
adapter: AnyConfigurationModel
|
|
8
10
|
}
|
|
11
|
+
|
|
12
|
+
export function readMsaDatasets(jbrowse: AnyConfigurationModel) {
|
|
13
|
+
return readConfObject(jbrowse, ['msa', 'datasets']) as Dataset[] | undefined
|
|
14
|
+
}
|
|
@@ -6,23 +6,17 @@ import type { Feature } from '@jbrowse/core/util'
|
|
|
6
6
|
export function useFeatureSequence({
|
|
7
7
|
view,
|
|
8
8
|
feature,
|
|
9
|
-
upDownBp = 0,
|
|
10
|
-
forceLoad = true,
|
|
11
9
|
}: {
|
|
12
10
|
view: { assemblyNames?: string[] } | undefined
|
|
13
11
|
feature?: Feature
|
|
14
|
-
upDownBp?: number
|
|
15
|
-
forceLoad?: boolean
|
|
16
12
|
}) {
|
|
17
13
|
const { sequence, error } = useSWRFeatureSequence({
|
|
18
14
|
view,
|
|
19
15
|
feature,
|
|
20
|
-
upDownBp,
|
|
21
|
-
forceLoad,
|
|
22
16
|
})
|
|
23
17
|
|
|
24
18
|
const proteinSequence =
|
|
25
|
-
sequence &&
|
|
19
|
+
sequence && feature
|
|
26
20
|
? getProteinSequenceFromFeature({
|
|
27
21
|
seq: sequence.seq,
|
|
28
22
|
feature,
|
|
@@ -3,77 +3,50 @@ import useSWR from 'swr'
|
|
|
3
3
|
|
|
4
4
|
import { fetchSeq } from './fetchSeq'
|
|
5
5
|
|
|
6
|
-
import type { SeqState } from './types'
|
|
7
6
|
import type { Feature } from '@jbrowse/core/util'
|
|
8
7
|
|
|
9
8
|
async function featureSequenceFetcher({
|
|
10
9
|
feature,
|
|
11
10
|
assemblyName,
|
|
12
|
-
upDownBp,
|
|
13
11
|
view,
|
|
14
12
|
}: {
|
|
15
13
|
feature: Feature
|
|
16
14
|
assemblyName: string
|
|
17
|
-
upDownBp: number
|
|
18
15
|
view: { assemblyNames?: string[] }
|
|
19
|
-
})
|
|
16
|
+
}) {
|
|
20
17
|
const session = getSession(view)
|
|
21
18
|
const { start, end, refName } = feature.toJSON() as {
|
|
22
19
|
start: number
|
|
23
20
|
end: number
|
|
24
21
|
refName: string
|
|
25
22
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
assemblyName,
|
|
35
|
-
session,
|
|
36
|
-
}),
|
|
37
|
-
fetchSeq({
|
|
38
|
-
start: Math.max(0, b),
|
|
39
|
-
end: start,
|
|
40
|
-
refName,
|
|
41
|
-
assemblyName,
|
|
42
|
-
session,
|
|
43
|
-
}),
|
|
44
|
-
fetchSeq({
|
|
45
|
-
start: end,
|
|
46
|
-
end: e,
|
|
47
|
-
refName,
|
|
48
|
-
assemblyName,
|
|
49
|
-
session,
|
|
50
|
-
}),
|
|
51
|
-
])
|
|
52
|
-
return { seq, upstream, downstream }
|
|
23
|
+
const seq = await fetchSeq({
|
|
24
|
+
start,
|
|
25
|
+
end,
|
|
26
|
+
refName,
|
|
27
|
+
assemblyName,
|
|
28
|
+
session,
|
|
29
|
+
})
|
|
30
|
+
return { seq }
|
|
53
31
|
}
|
|
54
32
|
|
|
55
33
|
export function useSWRFeatureSequence({
|
|
56
34
|
view,
|
|
57
35
|
feature,
|
|
58
|
-
upDownBp = 0,
|
|
59
|
-
forceLoad = true,
|
|
60
36
|
}: {
|
|
61
37
|
view: { assemblyNames?: string[] } | undefined
|
|
62
38
|
feature?: Feature
|
|
63
|
-
upDownBp?: number
|
|
64
|
-
forceLoad?: boolean
|
|
65
39
|
}) {
|
|
66
40
|
const assemblyName = view?.assemblyNames?.[0]
|
|
67
41
|
const { data, error } = useSWR(
|
|
68
42
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
69
43
|
feature && assemblyName && view
|
|
70
|
-
? [feature.id(), assemblyName,
|
|
44
|
+
? [feature.id(), assemblyName, 'feature-sequence']
|
|
71
45
|
: null,
|
|
72
46
|
() =>
|
|
73
47
|
featureSequenceFetcher({
|
|
74
48
|
feature: feature!,
|
|
75
49
|
assemblyName: assemblyName!,
|
|
76
|
-
upDownBp,
|
|
77
50
|
view: view!,
|
|
78
51
|
}),
|
|
79
52
|
{
|
|
@@ -8,7 +8,10 @@ import {
|
|
|
8
8
|
retrieveMsaData,
|
|
9
9
|
storeMsaData,
|
|
10
10
|
} from './msaDataStore'
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
gappedToUngappedPosition,
|
|
13
|
+
getProteinViews,
|
|
14
|
+
} from './structureConnection'
|
|
12
15
|
import { getUniprotIdFromAlphaFoldUrl } from './util'
|
|
13
16
|
|
|
14
17
|
import type { JBrowsePluginMsaViewModel } from './model'
|
|
@@ -41,8 +44,7 @@ export function loadStoredData(self: JBrowsePluginMsaViewModel) {
|
|
|
41
44
|
export function storeDataToIndexedDB(self: JBrowsePluginMsaViewModel) {
|
|
42
45
|
const { rows, dataStoreId } = self
|
|
43
46
|
if (rows.length > 0 && !dataStoreId) {
|
|
44
|
-
|
|
45
|
-
if (hasFilehandle) {
|
|
47
|
+
if (self.msaFilehandle || self.treeFilehandle) {
|
|
46
48
|
return
|
|
47
49
|
}
|
|
48
50
|
|
|
@@ -194,18 +196,13 @@ export function highlightConnectedStructures(self: JBrowsePluginMsaViewModel) {
|
|
|
194
196
|
}
|
|
195
197
|
|
|
196
198
|
export function autoConnectStructures(self: JBrowsePluginMsaViewModel) {
|
|
197
|
-
const views = getSession(self).views as unknown[]
|
|
198
199
|
const { connectedViewId, uniprotId, rows, connectedStructures } = self
|
|
199
200
|
|
|
200
201
|
if (!uniprotId || rows.length === 0) {
|
|
201
202
|
return
|
|
202
203
|
}
|
|
203
204
|
|
|
204
|
-
for (const view of views) {
|
|
205
|
-
if (!isProteinView(view)) {
|
|
206
|
-
continue
|
|
207
|
-
}
|
|
208
|
-
|
|
205
|
+
for (const view of getProteinViews(getSession(self).views)) {
|
|
209
206
|
for (
|
|
210
207
|
let structureIdx = 0;
|
|
211
208
|
structureIdx < view.structures.length;
|
|
@@ -245,7 +242,6 @@ export function autoConnectStructures(self: JBrowsePluginMsaViewModel) {
|
|
|
245
242
|
}
|
|
246
243
|
|
|
247
244
|
export function observeProteinHighlights(self: JBrowsePluginMsaViewModel) {
|
|
248
|
-
const views = getSession(self).views as unknown[]
|
|
249
245
|
const { connectedViewId, transcriptToMsaMap, querySeqName } = self
|
|
250
246
|
|
|
251
247
|
if (!connectedViewId || !transcriptToMsaMap) {
|
|
@@ -254,11 +250,7 @@ export function observeProteinHighlights(self: JBrowsePluginMsaViewModel) {
|
|
|
254
250
|
|
|
255
251
|
const columns = new Set<number>()
|
|
256
252
|
|
|
257
|
-
for (const view of views) {
|
|
258
|
-
if (!isProteinView(view)) {
|
|
259
|
-
continue
|
|
260
|
-
}
|
|
261
|
-
|
|
253
|
+
for (const view of getProteinViews(getSession(self).views)) {
|
|
262
254
|
for (const structure of view.structures) {
|
|
263
255
|
if (structure.connectedViewId !== connectedViewId) {
|
|
264
256
|
continue
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
import { observer } from 'mobx-react'
|
|
16
16
|
import { makeStyles } from 'tss-react/mui'
|
|
17
17
|
|
|
18
|
-
import {
|
|
18
|
+
import { getProteinViews } from '../structureConnection'
|
|
19
19
|
|
|
20
20
|
import type { JBrowsePluginMsaViewModel } from '../model'
|
|
21
21
|
|
|
@@ -39,7 +39,7 @@ const ConnectStructureDialog = observer(function ConnectStructureDialog({
|
|
|
39
39
|
const [selectedMsaRow, setSelectedMsaRow] = useState(model.querySeqName)
|
|
40
40
|
const [error, setError] = useState<string>()
|
|
41
41
|
|
|
42
|
-
const proteinViews = (session.views
|
|
42
|
+
const proteinViews = getProteinViews(session.views)
|
|
43
43
|
|
|
44
44
|
const selectedView = proteinViews.find(v => v.id === selectedViewId)
|
|
45
45
|
const structures = selectedView?.structures ?? []
|
|
@@ -60,7 +60,7 @@ const LoadingBLAST = observer(function LoadingBLAST2({
|
|
|
60
60
|
model: JBrowsePluginMsaViewModel
|
|
61
61
|
baseUrl: string
|
|
62
62
|
}) {
|
|
63
|
-
const { progress, rid, error
|
|
63
|
+
const { progress, rid, error } = model
|
|
64
64
|
const { classes } = useStyles()
|
|
65
65
|
return (
|
|
66
66
|
<div className={classes.margin}>
|
|
@@ -69,8 +69,9 @@ const LoadingBLAST = observer(function LoadingBLAST2({
|
|
|
69
69
|
<RIDError baseUrl={baseUrl} rid={rid} error={error} />
|
|
70
70
|
) : rid ? (
|
|
71
71
|
<RIDProgress baseUrl={baseUrl} rid={rid} progress={progress} />
|
|
72
|
-
) :
|
|
73
|
-
|
|
72
|
+
) : (
|
|
73
|
+
<Typography>{progress || 'Initializing BLAST query'}</Typography>
|
|
74
|
+
)}
|
|
74
75
|
</div>
|
|
75
76
|
)
|
|
76
77
|
})
|
|
@@ -22,13 +22,17 @@ import { genomeToMSA } from './genomeToMSA'
|
|
|
22
22
|
import { msaCoordToGenomeCoord } from './msaCoordToGenomeCoord'
|
|
23
23
|
import { buildAlignmentMaps, runPairwiseAlignment } from './pairwiseAlignment'
|
|
24
24
|
import {
|
|
25
|
-
|
|
26
|
-
mapToRecord,
|
|
25
|
+
getProteinViews,
|
|
27
26
|
ungappedToGappedPosition,
|
|
28
27
|
} from './structureConnection'
|
|
29
28
|
|
|
30
29
|
import type { ProteinView, StructureConnection } from './structureConnection'
|
|
31
30
|
import type { MafRegion, MsaViewInitState } from './types'
|
|
31
|
+
import type {
|
|
32
|
+
BlastDatabase,
|
|
33
|
+
BlastProgram,
|
|
34
|
+
MsaAlgorithm,
|
|
35
|
+
} from '../LaunchMsaView/components/NCBIBlastQuery/consts'
|
|
32
36
|
import type { Feature } from '@jbrowse/core/util'
|
|
33
37
|
import type { Instance } from '@jbrowse/mobx-state-tree'
|
|
34
38
|
import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
|
|
@@ -49,9 +53,9 @@ export interface IRegion {
|
|
|
49
53
|
|
|
50
54
|
export interface BlastParams {
|
|
51
55
|
baseUrl: string
|
|
52
|
-
blastDatabase:
|
|
53
|
-
msaAlgorithm:
|
|
54
|
-
blastProgram:
|
|
56
|
+
blastDatabase: BlastDatabase
|
|
57
|
+
msaAlgorithm: MsaAlgorithm
|
|
58
|
+
blastProgram: BlastProgram
|
|
55
59
|
selectedTranscript?: Feature
|
|
56
60
|
proteinSequence: string
|
|
57
61
|
rid?: string
|
|
@@ -179,13 +183,6 @@ export default function stateModelFactory() {
|
|
|
179
183
|
: undefined
|
|
180
184
|
},
|
|
181
185
|
|
|
182
|
-
/**
|
|
183
|
-
* #getter
|
|
184
|
-
*/
|
|
185
|
-
get processing() {
|
|
186
|
-
return !!self.progress
|
|
187
|
-
},
|
|
188
|
-
|
|
189
186
|
/**
|
|
190
187
|
* #getter
|
|
191
188
|
*/
|
|
@@ -198,14 +195,12 @@ export default function stateModelFactory() {
|
|
|
198
195
|
* #getter
|
|
199
196
|
*/
|
|
200
197
|
get connectedProteinViews() {
|
|
201
|
-
const
|
|
202
|
-
const unknownViews = views as unknown[]
|
|
198
|
+
const proteinViews = getProteinViews(getSession(self).views)
|
|
203
199
|
const result: (StructureConnection & { proteinView: ProteinView })[] =
|
|
204
200
|
[]
|
|
205
201
|
for (const conn of self.connectedStructures) {
|
|
206
|
-
const proteinView =
|
|
207
|
-
|
|
208
|
-
isProteinView(v) && v.id === conn.proteinViewId,
|
|
202
|
+
const proteinView = proteinViews.find(
|
|
203
|
+
v => v.id === conn.proteinViewId,
|
|
209
204
|
)
|
|
210
205
|
if (proteinView) {
|
|
211
206
|
result.push({ ...conn, proteinView })
|
|
@@ -251,12 +246,6 @@ export default function stateModelFactory() {
|
|
|
251
246
|
}
|
|
252
247
|
return genomeToMSA({ model: self as JBrowsePluginMsaViewModel })
|
|
253
248
|
},
|
|
254
|
-
/**
|
|
255
|
-
* #getter
|
|
256
|
-
*/
|
|
257
|
-
get clickCol2() {
|
|
258
|
-
return undefined
|
|
259
|
-
},
|
|
260
249
|
}))
|
|
261
250
|
|
|
262
251
|
.actions(self => ({
|
|
@@ -383,10 +372,8 @@ export default function stateModelFactory() {
|
|
|
383
372
|
|
|
384
373
|
const ungappedMsaSequence = msaSequence.replaceAll('-', '')
|
|
385
374
|
|
|
386
|
-
const
|
|
387
|
-
|
|
388
|
-
const proteinView = (views as unknown[]).find(
|
|
389
|
-
(v): v is ProteinView => isProteinView(v) && v.id === proteinViewId,
|
|
375
|
+
const proteinView = getProteinViews(getSession(self).views).find(
|
|
376
|
+
v => v.id === proteinViewId,
|
|
390
377
|
)
|
|
391
378
|
if (!proteinView) {
|
|
392
379
|
throw new Error(`ProteinView "${proteinViewId}" not found`)
|
|
@@ -412,8 +399,8 @@ export default function stateModelFactory() {
|
|
|
412
399
|
proteinViewId,
|
|
413
400
|
structureIdx,
|
|
414
401
|
msaRowName: rowName,
|
|
415
|
-
msaToStructure:
|
|
416
|
-
structureToMsa:
|
|
402
|
+
msaToStructure: Object.fromEntries(seq1ToSeq2),
|
|
403
|
+
structureToMsa: Object.fromEntries(seq2ToSeq1),
|
|
417
404
|
}
|
|
418
405
|
|
|
419
406
|
self.connectedStructures.push(connection)
|
|
@@ -66,15 +66,6 @@ export async function retrieveMsaData(id: string) {
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
export async function deleteMsaData(id: string) {
|
|
70
|
-
try {
|
|
71
|
-
const db = await getDB()
|
|
72
|
-
await db.delete(STORE_NAME, id)
|
|
73
|
-
} catch (e) {
|
|
74
|
-
console.warn('Failed to delete MSA data:', e)
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
69
|
export async function cleanupOldData(maxAgeMs = 7 * 24 * 60 * 60 * 1000) {
|
|
79
70
|
try {
|
|
80
71
|
const db = await getDB()
|
|
@@ -2,7 +2,6 @@ import { describe, expect, test } from 'vitest'
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
gappedToUngappedPosition,
|
|
5
|
-
mapToRecord,
|
|
6
5
|
ungappedToGappedPosition,
|
|
7
6
|
} from './structureConnection'
|
|
8
7
|
|
|
@@ -121,23 +120,3 @@ describe('gappedToUngappedPosition and ungappedToGappedPosition are inverses', (
|
|
|
121
120
|
}
|
|
122
121
|
})
|
|
123
122
|
})
|
|
124
|
-
|
|
125
|
-
describe('mapToRecord', () => {
|
|
126
|
-
test('converts Map to Record', () => {
|
|
127
|
-
const map = new Map<number, number>([
|
|
128
|
-
[0, 5],
|
|
129
|
-
[1, 10],
|
|
130
|
-
[2, 15],
|
|
131
|
-
])
|
|
132
|
-
const record = mapToRecord(map)
|
|
133
|
-
expect(record[0]).toBe(5)
|
|
134
|
-
expect(record[1]).toBe(10)
|
|
135
|
-
expect(record[2]).toBe(15)
|
|
136
|
-
})
|
|
137
|
-
|
|
138
|
-
test('handles empty Map', () => {
|
|
139
|
-
const map = new Map<number, number>()
|
|
140
|
-
const record = mapToRecord(map)
|
|
141
|
-
expect(Object.keys(record)).toHaveLength(0)
|
|
142
|
-
})
|
|
143
|
-
})
|
|
@@ -21,6 +21,13 @@ export function isProteinView(view: unknown): view is ProteinView {
|
|
|
21
21
|
return v.type === 'ProteinView' && Array.isArray(v.structures)
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Extract all ProteinView instances from a session's views array.
|
|
26
|
+
*/
|
|
27
|
+
export function getProteinViews(views: { type: string }[]): ProteinView[] {
|
|
28
|
+
return (views as unknown[]).filter(isProteinView)
|
|
29
|
+
}
|
|
30
|
+
|
|
24
31
|
/**
|
|
25
32
|
* Represents a connection between the MSA view and a protein structure
|
|
26
33
|
*/
|
|
@@ -82,10 +89,3 @@ export function ungappedToGappedPosition(
|
|
|
82
89
|
}
|
|
83
90
|
return undefined
|
|
84
91
|
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Convert Map to plain object for MST frozen storage
|
|
88
|
-
*/
|
|
89
|
-
export function mapToRecord(map: Map<number, number>): Record<number, number> {
|
|
90
|
-
return Object.fromEntries(map)
|
|
91
|
-
}
|
package/src/utils/blastCache.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { openDB } from 'idb'
|
|
2
2
|
|
|
3
|
+
import type {
|
|
4
|
+
BlastDatabase,
|
|
5
|
+
BlastProgram,
|
|
6
|
+
MsaAlgorithm,
|
|
7
|
+
} from '../LaunchMsaView/components/NCBIBlastQuery/consts'
|
|
8
|
+
|
|
3
9
|
const DB_NAME = 'jbrowse-msaview-blast-cache'
|
|
4
10
|
const STORE_NAME = 'blast-results'
|
|
5
11
|
const DB_VERSION = 2
|
|
@@ -7,9 +13,9 @@ const DB_VERSION = 2
|
|
|
7
13
|
export interface CachedBlastResult {
|
|
8
14
|
id: string
|
|
9
15
|
proteinSequence: string
|
|
10
|
-
blastDatabase:
|
|
11
|
-
blastProgram:
|
|
12
|
-
msaAlgorithm:
|
|
16
|
+
blastDatabase: BlastDatabase
|
|
17
|
+
blastProgram: BlastProgram
|
|
18
|
+
msaAlgorithm: MsaAlgorithm
|
|
13
19
|
msa: string
|
|
14
20
|
tree: string
|
|
15
21
|
treeMetadata: string
|
|
@@ -36,8 +42,8 @@ async function getDB() {
|
|
|
36
42
|
|
|
37
43
|
function createCacheKey(
|
|
38
44
|
proteinSequence: string,
|
|
39
|
-
blastDatabase:
|
|
40
|
-
blastProgram:
|
|
45
|
+
blastDatabase: BlastDatabase,
|
|
46
|
+
blastProgram: BlastProgram,
|
|
41
47
|
transcriptId?: string,
|
|
42
48
|
) {
|
|
43
49
|
if (transcriptId) {
|
|
@@ -46,27 +52,6 @@ function createCacheKey(
|
|
|
46
52
|
return `${blastDatabase}:${blastProgram}:${proteinSequence}`
|
|
47
53
|
}
|
|
48
54
|
|
|
49
|
-
export async function getCachedBlastResult({
|
|
50
|
-
proteinSequence,
|
|
51
|
-
blastDatabase,
|
|
52
|
-
blastProgram,
|
|
53
|
-
transcriptId,
|
|
54
|
-
}: {
|
|
55
|
-
proteinSequence: string
|
|
56
|
-
blastDatabase: string
|
|
57
|
-
blastProgram: string
|
|
58
|
-
transcriptId?: string
|
|
59
|
-
}) {
|
|
60
|
-
const db = await getDB()
|
|
61
|
-
const id = createCacheKey(
|
|
62
|
-
proteinSequence,
|
|
63
|
-
blastDatabase,
|
|
64
|
-
blastProgram,
|
|
65
|
-
transcriptId,
|
|
66
|
-
)
|
|
67
|
-
return db.get(STORE_NAME, id)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
55
|
export async function saveBlastResult({
|
|
71
56
|
proteinSequence,
|
|
72
57
|
blastDatabase,
|
|
@@ -82,9 +67,9 @@ export async function saveBlastResult({
|
|
|
82
67
|
geneName,
|
|
83
68
|
}: {
|
|
84
69
|
proteinSequence: string
|
|
85
|
-
blastDatabase:
|
|
86
|
-
blastProgram:
|
|
87
|
-
msaAlgorithm:
|
|
70
|
+
blastDatabase: BlastDatabase
|
|
71
|
+
blastProgram: BlastProgram
|
|
72
|
+
msaAlgorithm: MsaAlgorithm
|
|
88
73
|
msa: string
|
|
89
74
|
tree: string
|
|
90
75
|
treeMetadata: string
|
|
@@ -127,14 +112,6 @@ export async function getAllCachedResults() {
|
|
|
127
112
|
return results.toSorted((a, b) => b.timestamp - a.timestamp)
|
|
128
113
|
}
|
|
129
114
|
|
|
130
|
-
export async function getCachedResultsByGeneId(geneId: string) {
|
|
131
|
-
const db = await getDB()
|
|
132
|
-
const results = await db.getAll(STORE_NAME)
|
|
133
|
-
return results
|
|
134
|
-
.filter(r => r.geneId === geneId)
|
|
135
|
-
.toSorted((a, b) => b.timestamp - a.timestamp)
|
|
136
|
-
}
|
|
137
|
-
|
|
138
115
|
export async function deleteCachedResult(id: string) {
|
|
139
116
|
const db = await getDB()
|
|
140
117
|
await db.delete(STORE_NAME, id)
|
package/src/utils/msa.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { textfetch, timeout } from './fetch'
|
|
2
2
|
|
|
3
|
+
import type { MsaAlgorithm } from '../LaunchMsaView/components/NCBIBlastQuery/consts'
|
|
4
|
+
|
|
3
5
|
const base = `https://www.ebi.ac.uk/Tools/services/rest`
|
|
4
6
|
|
|
5
7
|
const algorithms: Record<
|
|
6
|
-
|
|
8
|
+
MsaAlgorithm,
|
|
7
9
|
{
|
|
8
10
|
params: Record<string, string>
|
|
9
11
|
msaResult: string
|
|
@@ -38,7 +40,7 @@ async function wait({
|
|
|
38
40
|
algorithm,
|
|
39
41
|
}: {
|
|
40
42
|
jobId: string
|
|
41
|
-
algorithm:
|
|
43
|
+
algorithm: MsaAlgorithm
|
|
42
44
|
onProgress: (arg: string) => void
|
|
43
45
|
}) {
|
|
44
46
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
@@ -62,14 +64,11 @@ export async function launchMSA({
|
|
|
62
64
|
sequence,
|
|
63
65
|
onProgress,
|
|
64
66
|
}: {
|
|
65
|
-
algorithm:
|
|
67
|
+
algorithm: MsaAlgorithm
|
|
66
68
|
sequence: string
|
|
67
69
|
onProgress: (arg: string) => void
|
|
68
70
|
}) {
|
|
69
71
|
const config = algorithms[algorithm]
|
|
70
|
-
if (!config) {
|
|
71
|
-
throw new Error(`unknown algorithm: ${algorithm}`)
|
|
72
|
-
}
|
|
73
72
|
|
|
74
73
|
onProgress(`Launching ${algorithm} MSA...`)
|
|
75
74
|
|
package/src/utils/ncbiBlast.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { jsonfetch, textfetch, timeout } from './fetch'
|
|
2
2
|
|
|
3
3
|
import type { BlastResults } from './types'
|
|
4
|
+
import type {
|
|
5
|
+
BlastDatabase,
|
|
6
|
+
BlastProgram,
|
|
7
|
+
} from '../LaunchMsaView/components/NCBIBlastQuery/consts'
|
|
4
8
|
|
|
5
9
|
export async function queryBlastFromRid({
|
|
6
10
|
rid,
|
|
@@ -35,8 +39,8 @@ export async function queryBlast({
|
|
|
35
39
|
onRid,
|
|
36
40
|
}: {
|
|
37
41
|
query: string
|
|
38
|
-
blastDatabase:
|
|
39
|
-
blastProgram:
|
|
42
|
+
blastDatabase: BlastDatabase
|
|
43
|
+
blastProgram: BlastProgram
|
|
40
44
|
baseUrl: string
|
|
41
45
|
onProgress: (arg: string) => void
|
|
42
46
|
onRid: (arg: string) => void
|
|
@@ -59,8 +63,8 @@ async function initialQuery({
|
|
|
59
63
|
baseUrl,
|
|
60
64
|
}: {
|
|
61
65
|
query: string
|
|
62
|
-
blastProgram:
|
|
63
|
-
blastDatabase:
|
|
66
|
+
blastProgram: BlastProgram
|
|
67
|
+
blastDatabase: BlastDatabase
|
|
64
68
|
baseUrl: string
|
|
65
69
|
}) {
|
|
66
70
|
const res = await textfetch(baseUrl, {
|
|
@@ -70,7 +74,7 @@ async function initialQuery({
|
|
|
70
74
|
PROGRAM: blastProgram === 'quick-blastp' ? 'blastp' : blastProgram,
|
|
71
75
|
DATABASE: blastDatabase,
|
|
72
76
|
QUERY: query,
|
|
73
|
-
...(blastDatabase === '
|
|
77
|
+
...(blastDatabase === 'nr_cluster_seq'
|
|
74
78
|
? {
|
|
75
79
|
CLUSTERED_DB: 'on',
|
|
76
80
|
DB_TYPE: 'Experimental Databases',
|