jbrowse-plugin-msaview 2.2.3 → 2.2.5
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/CHANGELOG.md +1 -1
- package/README.md +229 -0
- package/dist/AddHighlightModel/GenomeMouseoverHighlight.js +23 -18
- package/dist/AddHighlightModel/GenomeMouseoverHighlight.js.map +1 -1
- package/dist/AddHighlightModel/MsaToGenomeHighlight.js +23 -13
- package/dist/AddHighlightModel/MsaToGenomeHighlight.js.map +1 -1
- package/dist/AddHighlightModel/index.js +8 -1
- package/dist/AddHighlightModel/index.js.map +1 -1
- package/dist/AddHighlightModel/util.d.ts +2 -2
- package/dist/BgzipFastaMsaAdapter/configSchema.d.ts +2 -2
- package/dist/LaunchMsaView/components/EnsemblGeneTree/EnsemblGeneTree.js +5 -11
- package/dist/LaunchMsaView/components/EnsemblGeneTree/EnsemblGeneTree.js.map +1 -1
- package/dist/LaunchMsaView/components/EnsemblGeneTree/useGeneTree.js +5 -1
- package/dist/LaunchMsaView/components/EnsemblGeneTree/useGeneTree.js.map +1 -1
- package/dist/LaunchMsaView/components/LaunchMsaViewDialog.js +16 -16
- package/dist/LaunchMsaView/components/LaunchMsaViewDialog.js.map +1 -1
- package/dist/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.js +38 -46
- package/dist/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.js.map +1 -1
- package/dist/LaunchMsaView/components/ManualMSALoader/launchView.d.ts +4 -3
- package/dist/LaunchMsaView/components/ManualMSALoader/launchView.js +4 -3
- package/dist/LaunchMsaView/components/ManualMSALoader/launchView.js.map +1 -1
- package/dist/LaunchMsaView/components/NCBIBlastQuery/CachedBlastResults.d.ts +9 -0
- package/dist/LaunchMsaView/components/NCBIBlastQuery/CachedBlastResults.js +76 -0
- package/dist/LaunchMsaView/components/NCBIBlastQuery/CachedBlastResults.js.map +1 -0
- package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.js +35 -13
- package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.js.map +1 -1
- package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.js +6 -12
- package/dist/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.js.map +1 -1
- package/dist/LaunchMsaView/components/NCBIBlastQuery/blastLaunchView.d.ts +6 -0
- package/dist/LaunchMsaView/components/NCBIBlastQuery/blastLaunchView.js +15 -0
- package/dist/LaunchMsaView/components/NCBIBlastQuery/blastLaunchView.js.map +1 -1
- package/dist/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.js +12 -34
- package/dist/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.js.map +1 -1
- package/dist/LaunchMsaView/components/PreLoadedMSA/consts.d.ts +1 -0
- package/dist/LaunchMsaView/components/PreLoadedMSA/consts.js +1 -0
- package/dist/LaunchMsaView/components/PreLoadedMSA/consts.js.map +1 -1
- package/dist/LaunchMsaView/components/TabPanel.d.ts +2 -2
- package/dist/LaunchMsaView/components/TranscriptSelector.d.ts +2 -2
- package/dist/LaunchMsaView/components/TranscriptSelector.js +3 -6
- package/dist/LaunchMsaView/components/TranscriptSelector.js.map +1 -1
- package/dist/LaunchMsaView/components/useSWRFeatureSequence.js +6 -4
- package/dist/LaunchMsaView/components/useSWRFeatureSequence.js.map +1 -1
- package/dist/LaunchMsaView/components/useTranscriptSelection.d.ts +16 -0
- package/dist/LaunchMsaView/components/useTranscriptSelection.js +31 -0
- package/dist/LaunchMsaView/components/useTranscriptSelection.js.map +1 -0
- package/dist/LaunchMsaView/components/util.d.ts +3 -1
- package/dist/LaunchMsaView/components/util.js +12 -2
- package/dist/LaunchMsaView/components/util.js.map +1 -1
- package/dist/LaunchMsaView/util.d.ts +2 -0
- package/dist/LaunchMsaView/util.js +16 -4
- package/dist/LaunchMsaView/util.js.map +1 -1
- package/dist/LaunchMsaViewExtensionPoint/index.d.ts +2 -0
- package/dist/LaunchMsaViewExtensionPoint/index.js +31 -0
- package/dist/LaunchMsaViewExtensionPoint/index.js.map +1 -0
- package/dist/MsaViewPanel/components/ConnectStructureDialog.d.ts +7 -0
- package/dist/MsaViewPanel/components/ConnectStructureDialog.js +56 -0
- package/dist/MsaViewPanel/components/ConnectStructureDialog.js.map +1 -0
- package/dist/MsaViewPanel/components/MsaViewPanel.js +4 -2
- package/dist/MsaViewPanel/components/MsaViewPanel.js.map +1 -1
- package/dist/MsaViewPanel/doLaunchBlast.d.ts +1 -0
- package/dist/MsaViewPanel/doLaunchBlast.js +65 -19
- package/dist/MsaViewPanel/doLaunchBlast.js.map +1 -1
- package/dist/MsaViewPanel/genomeToMSA.d.ts +6 -0
- package/dist/MsaViewPanel/genomeToMSA.js +38 -8
- package/dist/MsaViewPanel/genomeToMSA.js.map +1 -1
- package/dist/MsaViewPanel/genomeToMSA.test.d.ts +1 -0
- package/dist/MsaViewPanel/genomeToMSA.test.js +244 -0
- package/dist/MsaViewPanel/genomeToMSA.test.js.map +1 -0
- package/dist/MsaViewPanel/model.d.ts +719 -226
- package/dist/MsaViewPanel/model.js +467 -39
- package/dist/MsaViewPanel/model.js.map +1 -1
- package/dist/MsaViewPanel/msaCoordToGenomeCoord.d.ts +7 -2
- package/dist/MsaViewPanel/msaCoordToGenomeCoord.js +26 -27
- package/dist/MsaViewPanel/msaCoordToGenomeCoord.js.map +1 -1
- package/dist/MsaViewPanel/msaCoordToGenomeCoord.test.d.ts +1 -0
- package/dist/MsaViewPanel/msaCoordToGenomeCoord.test.js +240 -0
- package/dist/MsaViewPanel/msaCoordToGenomeCoord.test.js.map +1 -0
- package/dist/MsaViewPanel/msaDataStore.d.ts +14 -0
- package/dist/MsaViewPanel/msaDataStore.js +197 -0
- package/dist/MsaViewPanel/msaDataStore.js.map +1 -0
- package/dist/MsaViewPanel/pairwiseAlignment.d.ts +27 -0
- package/dist/MsaViewPanel/pairwiseAlignment.js +776 -0
- package/dist/MsaViewPanel/pairwiseAlignment.js.map +1 -0
- package/dist/MsaViewPanel/pairwiseAlignment.test.d.ts +1 -0
- package/dist/MsaViewPanel/pairwiseAlignment.test.js +112 -0
- package/dist/MsaViewPanel/pairwiseAlignment.test.js.map +1 -0
- package/dist/MsaViewPanel/structureConnection.d.ts +27 -0
- package/dist/MsaViewPanel/structureConnection.js +46 -0
- package/dist/MsaViewPanel/structureConnection.js.map +1 -0
- package/dist/MsaViewPanel/structureConnection.test.d.ts +1 -0
- package/dist/MsaViewPanel/structureConnection.test.js +122 -0
- package/dist/MsaViewPanel/structureConnection.test.js.map +1 -0
- package/dist/MsaViewPanel/types.d.ts +13 -0
- package/dist/MsaViewPanel/types.js +2 -0
- package/dist/MsaViewPanel/types.js.map +1 -0
- package/dist/MsaViewPanel/util.d.ts +7 -0
- package/dist/MsaViewPanel/util.js +10 -0
- package/dist/MsaViewPanel/util.js.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/jbrowse-plugin-msaview.umd.production.min.js +39 -90
- package/dist/jbrowse-plugin-msaview.umd.production.min.js.map +4 -4
- package/dist/utils/blastCache.d.ts +34 -0
- package/dist/utils/blastCache.js +58 -0
- package/dist/utils/blastCache.js.map +1 -0
- package/dist/utils/fetch.d.ts +1 -1
- package/dist/utils/fetch.js +1 -1
- package/dist/utils/fetch.js.map +1 -1
- package/dist/utils/ncbiBlast.d.ts +1 -5
- package/dist/utils/taxonomyNames.d.ts +5 -0
- package/dist/utils/taxonomyNames.js +79 -0
- package/dist/utils/taxonomyNames.js.map +1 -0
- package/dist/utils/types.d.ts +8 -5
- package/package.json +50 -54
- package/src/AddHighlightModel/GenomeMouseoverHighlight.tsx +37 -21
- package/src/AddHighlightModel/MsaToGenomeHighlight.tsx +38 -17
- package/src/AddHighlightModel/index.tsx +9 -4
- package/src/LaunchMsaView/components/EnsemblGeneTree/EnsemblGeneTree.tsx +13 -13
- package/src/LaunchMsaView/components/EnsemblGeneTree/useGeneTree.ts +6 -0
- package/src/LaunchMsaView/components/LaunchMsaViewDialog.tsx +30 -23
- package/src/LaunchMsaView/components/ManualMSALoader/ManualMSALoader.tsx +64 -51
- package/src/LaunchMsaView/components/ManualMSALoader/launchView.ts +9 -6
- package/src/LaunchMsaView/components/NCBIBlastQuery/CachedBlastResults.tsx +146 -0
- package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastAutomaticPanel.tsx +53 -22
- package/src/LaunchMsaView/components/NCBIBlastQuery/NCBIBlastManualPanel.tsx +8 -13
- package/src/LaunchMsaView/components/NCBIBlastQuery/blastLaunchView.ts +25 -0
- package/src/LaunchMsaView/components/PreLoadedMSA/PreLoadedMSADataPanel.tsx +27 -47
- package/src/LaunchMsaView/components/PreLoadedMSA/consts.ts +1 -0
- package/src/LaunchMsaView/components/TabPanel.tsx +2 -2
- package/src/LaunchMsaView/components/TranscriptSelector.tsx +13 -20
- package/src/LaunchMsaView/components/useSWRFeatureSequence.ts +5 -5
- package/src/LaunchMsaView/components/useTranscriptSelection.ts +48 -0
- package/src/LaunchMsaView/components/util.ts +17 -2
- package/src/LaunchMsaView/index.ts +1 -1
- package/src/LaunchMsaView/util.ts +25 -6
- package/src/LaunchMsaViewExtensionPoint/index.ts +74 -0
- package/src/MsaViewPanel/components/ConnectStructureDialog.tsx +156 -0
- package/src/MsaViewPanel/components/MsaViewPanel.tsx +6 -1
- package/src/MsaViewPanel/doLaunchBlast.ts +83 -23
- package/src/MsaViewPanel/genomeToMSA.test.ts +281 -0
- package/src/MsaViewPanel/genomeToMSA.ts +43 -10
- package/src/MsaViewPanel/model.ts +590 -43
- package/src/MsaViewPanel/msaCoordToGenomeCoord.test.ts +256 -0
- package/src/MsaViewPanel/msaCoordToGenomeCoord.ts +43 -29
- package/src/MsaViewPanel/msaDataStore.ts +236 -0
- package/src/MsaViewPanel/pairwiseAlignment.test.ts +140 -0
- package/src/MsaViewPanel/pairwiseAlignment.ts +818 -0
- package/src/MsaViewPanel/structureConnection.test.ts +143 -0
- package/src/MsaViewPanel/structureConnection.ts +72 -0
- package/src/MsaViewPanel/types.ts +14 -0
- package/src/MsaViewPanel/util.ts +11 -0
- package/src/index.ts +3 -1
- package/src/utils/blastCache.ts +114 -0
- package/src/utils/fetch.ts +1 -1
- package/src/utils/taxonomyNames.ts +111 -0
- package/src/utils/types.ts +9 -1
- package/dist/LaunchMsaView/components/PreLoadedMSA/findValidTranscriptId.d.ts +0 -5
- package/dist/LaunchMsaView/components/PreLoadedMSA/findValidTranscriptId.js +0 -16
- package/dist/LaunchMsaView/components/PreLoadedMSA/findValidTranscriptId.js.map +0 -1
- package/dist/out.js +0 -55381
- package/src/LaunchMsaView/components/PreLoadedMSA/findValidTranscriptId.ts +0 -25
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import React, { useState } from 'react'
|
|
2
2
|
|
|
3
|
+
import { readConfObject } from '@jbrowse/core/configuration'
|
|
3
4
|
import { Dialog } from '@jbrowse/core/ui'
|
|
4
|
-
import { AbstractTrackModel, Feature } from '@jbrowse/core/util'
|
|
5
|
+
import { AbstractTrackModel, Feature, getSession } from '@jbrowse/core/util'
|
|
5
6
|
import { Tab, Tabs } from '@mui/material'
|
|
6
7
|
|
|
7
8
|
import EnsemblGeneTree from './EnsemblGeneTree/EnsemblGeneTree'
|
|
@@ -10,12 +11,7 @@ import NCBIBlastPanel from './NCBIBlastQuery/NCBIBlastPanel'
|
|
|
10
11
|
import PreLoadedMSA from './PreLoadedMSA/PreLoadedMSADataPanel'
|
|
11
12
|
import TabPanel from './TabPanel'
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
NCBI_BLAST: 0,
|
|
15
|
-
PRELOADED_MSA: 1,
|
|
16
|
-
ENSEMBL_GENETREE: 2,
|
|
17
|
-
MANUAL_MSA: 3,
|
|
18
|
-
}
|
|
14
|
+
import type { Dataset } from './PreLoadedMSA/types'
|
|
19
15
|
|
|
20
16
|
export default function LaunchMsaViewDialog({
|
|
21
17
|
handleClose,
|
|
@@ -26,42 +22,53 @@ export default function LaunchMsaViewDialog({
|
|
|
26
22
|
feature: Feature
|
|
27
23
|
model: AbstractTrackModel
|
|
28
24
|
}) {
|
|
29
|
-
const
|
|
25
|
+
const session = getSession(model)
|
|
26
|
+
const { jbrowse } = session
|
|
27
|
+
const datasets = readConfObject(jbrowse, ['msa', 'datasets']) as
|
|
28
|
+
| Dataset[]
|
|
29
|
+
| undefined
|
|
30
|
+
const hasPreloadedDatasets = datasets && datasets.length > 0
|
|
31
|
+
|
|
32
|
+
const [value, setValue] = useState('ncbi_blast')
|
|
30
33
|
|
|
31
|
-
const handleChange = (_event: React.SyntheticEvent, newValue:
|
|
34
|
+
const handleChange = (_event: React.SyntheticEvent, newValue: string) => {
|
|
32
35
|
setValue(newValue)
|
|
33
36
|
}
|
|
34
37
|
|
|
35
38
|
return (
|
|
36
39
|
<Dialog maxWidth="xl" title="Launch MSA view" open onClose={handleClose}>
|
|
37
40
|
<Tabs value={value} onChange={handleChange}>
|
|
38
|
-
<Tab label="NCBI BLAST query" value=
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
<Tab label="NCBI BLAST query" value="ncbi_blast" />
|
|
42
|
+
{hasPreloadedDatasets ? (
|
|
43
|
+
<Tab label="Pre-loaded MSA datasets" value="preloaded_msa" />
|
|
44
|
+
) : null}
|
|
45
|
+
<Tab label="Ensembl GeneTree" value="ensembl_genetree" />
|
|
46
|
+
<Tab label="Manual upload" value="manual_msa" />
|
|
42
47
|
</Tabs>
|
|
43
|
-
<TabPanel value={value} index=
|
|
48
|
+
<TabPanel value={value} index="ncbi_blast">
|
|
44
49
|
<NCBIBlastPanel
|
|
45
50
|
handleClose={handleClose}
|
|
46
51
|
feature={feature}
|
|
47
52
|
model={model}
|
|
48
53
|
/>
|
|
49
54
|
</TabPanel>
|
|
50
|
-
|
|
51
|
-
<
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
{hasPreloadedDatasets ? (
|
|
56
|
+
<TabPanel value={value} index="preloaded_msa">
|
|
57
|
+
<PreLoadedMSA
|
|
58
|
+
model={model}
|
|
59
|
+
feature={feature}
|
|
60
|
+
handleClose={handleClose}
|
|
61
|
+
/>
|
|
62
|
+
</TabPanel>
|
|
63
|
+
) : null}
|
|
64
|
+
<TabPanel value={value} index="ensembl_genetree">
|
|
58
65
|
<EnsemblGeneTree
|
|
59
66
|
model={model}
|
|
60
67
|
feature={feature}
|
|
61
68
|
handleClose={handleClose}
|
|
62
69
|
/>
|
|
63
70
|
</TabPanel>
|
|
64
|
-
<TabPanel value={value} index=
|
|
71
|
+
<TabPanel value={value} index="manual_msa">
|
|
65
72
|
<ManualMSALoader
|
|
66
73
|
model={model}
|
|
67
74
|
feature={feature}
|
|
@@ -8,8 +8,8 @@ import {
|
|
|
8
8
|
getContainingView,
|
|
9
9
|
getSession,
|
|
10
10
|
} from '@jbrowse/core/util'
|
|
11
|
-
import { openLocation } from '@jbrowse/core/util/io'
|
|
12
11
|
import {
|
|
12
|
+
Alert,
|
|
13
13
|
Button,
|
|
14
14
|
DialogActions,
|
|
15
15
|
DialogContent,
|
|
@@ -23,9 +23,9 @@ import { makeStyles } from 'tss-react/mui'
|
|
|
23
23
|
|
|
24
24
|
import { launchView } from './launchView'
|
|
25
25
|
import TextField2 from '../../../components/TextField2'
|
|
26
|
-
import { getGeneDisplayName
|
|
26
|
+
import { getGeneDisplayName } from '../../util'
|
|
27
27
|
import TranscriptSelector from '../TranscriptSelector'
|
|
28
|
-
import {
|
|
28
|
+
import { useTranscriptSelection } from '../useTranscriptSelection'
|
|
29
29
|
|
|
30
30
|
import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
|
|
31
31
|
|
|
@@ -56,14 +56,14 @@ const ManualMSALoader = observer(function PreLoadedMSA2({
|
|
|
56
56
|
const [treeText, setTreeText] = useState('')
|
|
57
57
|
const [msaFileLocation, setMsaFileLocation] = useState<FileLocation>()
|
|
58
58
|
const [treeFileLocation, setTreeFileLocation] = useState<FileLocation>()
|
|
59
|
-
const
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
})
|
|
59
|
+
const [querySeqName, setQuerySeqName] = useState('')
|
|
60
|
+
const {
|
|
61
|
+
options,
|
|
62
|
+
setSelectedId,
|
|
63
|
+
selectedTranscript,
|
|
64
|
+
proteinSequence,
|
|
65
|
+
error: error2,
|
|
66
|
+
} = useTranscriptSelection({ feature, view })
|
|
67
67
|
|
|
68
68
|
const e = launchViewError ?? error2
|
|
69
69
|
return (
|
|
@@ -143,10 +143,32 @@ const ManualMSALoader = observer(function PreLoadedMSA2({
|
|
|
143
143
|
<TranscriptSelector
|
|
144
144
|
feature={feature}
|
|
145
145
|
options={options}
|
|
146
|
-
|
|
147
|
-
onTranscriptChange={
|
|
146
|
+
selectedTranscript={selectedTranscript}
|
|
147
|
+
onTranscriptChange={setSelectedId}
|
|
148
148
|
proteinSequence={proteinSequence}
|
|
149
149
|
/>
|
|
150
|
+
|
|
151
|
+
<TextField2
|
|
152
|
+
variant="outlined"
|
|
153
|
+
name="MSA row name"
|
|
154
|
+
fullWidth
|
|
155
|
+
required
|
|
156
|
+
style={{ marginTop: 20 }}
|
|
157
|
+
placeholder="Row name in MSA that corresponds to the selected transcript"
|
|
158
|
+
helperText="Required: Specify the name of the row in your MSA that should be aligned with the selected transcript"
|
|
159
|
+
value={querySeqName}
|
|
160
|
+
onChange={event => {
|
|
161
|
+
setQuerySeqName(event.target.value)
|
|
162
|
+
}}
|
|
163
|
+
/>
|
|
164
|
+
|
|
165
|
+
{!querySeqName.trim() && (
|
|
166
|
+
<Alert severity="warning" style={{ marginTop: 10 }}>
|
|
167
|
+
Without specifying the MSA row name, clicking on the MSA will not
|
|
168
|
+
navigate to the corresponding genome position, and hovering
|
|
169
|
+
highlights will not work.
|
|
170
|
+
</Alert>
|
|
171
|
+
)}
|
|
150
172
|
</DialogContent>
|
|
151
173
|
|
|
152
174
|
<DialogActions>
|
|
@@ -154,50 +176,41 @@ const ManualMSALoader = observer(function PreLoadedMSA2({
|
|
|
154
176
|
color="primary"
|
|
155
177
|
variant="contained"
|
|
156
178
|
disabled={
|
|
157
|
-
!
|
|
179
|
+
!selectedTranscript ||
|
|
158
180
|
(inputMethod === 'file' && !msaFileLocation) ||
|
|
159
181
|
(inputMethod === 'text' && !msaText.trim())
|
|
160
182
|
}
|
|
161
183
|
onClick={() => {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
return
|
|
167
|
-
}
|
|
184
|
+
try {
|
|
185
|
+
if (!selectedTranscript) {
|
|
186
|
+
return
|
|
187
|
+
}
|
|
168
188
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
}
|
|
189
|
-
: {
|
|
190
|
-
msa: msaText,
|
|
191
|
-
tree: treeText,
|
|
192
|
-
},
|
|
193
|
-
})
|
|
189
|
+
setLaunchViewError(undefined)
|
|
190
|
+
launchView({
|
|
191
|
+
session,
|
|
192
|
+
newViewTitle: getGeneDisplayName(selectedTranscript),
|
|
193
|
+
view,
|
|
194
|
+
feature: selectedTranscript,
|
|
195
|
+
querySeqName: querySeqName.trim() || undefined,
|
|
196
|
+
...(inputMethod === 'file'
|
|
197
|
+
? {
|
|
198
|
+
msaFilehandle: msaFileLocation,
|
|
199
|
+
treeFilehandle: treeFileLocation,
|
|
200
|
+
}
|
|
201
|
+
: {
|
|
202
|
+
data: {
|
|
203
|
+
msa: msaText,
|
|
204
|
+
tree: treeText || undefined,
|
|
205
|
+
},
|
|
206
|
+
}),
|
|
207
|
+
})
|
|
194
208
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
})()
|
|
209
|
+
handleClose()
|
|
210
|
+
} catch (e) {
|
|
211
|
+
console.error(e)
|
|
212
|
+
setLaunchViewError(e)
|
|
213
|
+
}
|
|
201
214
|
}}
|
|
202
215
|
>
|
|
203
216
|
Submit
|
|
@@ -7,16 +7,18 @@ export function launchView({
|
|
|
7
7
|
newViewTitle,
|
|
8
8
|
view,
|
|
9
9
|
feature,
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
msaFilehandle,
|
|
11
|
+
treeFilehandle,
|
|
12
|
+
querySeqName,
|
|
12
13
|
data,
|
|
13
14
|
}: {
|
|
14
15
|
session: AbstractSessionModel
|
|
15
16
|
newViewTitle: string
|
|
16
17
|
view: LinearGenomeViewModel
|
|
17
18
|
feature: Feature
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
msaFilehandle?: FileLocation
|
|
20
|
+
treeFilehandle?: FileLocation
|
|
21
|
+
querySeqName?: string
|
|
20
22
|
data?: {
|
|
21
23
|
msa: string
|
|
22
24
|
tree?: string
|
|
@@ -27,8 +29,9 @@ export function launchView({
|
|
|
27
29
|
displayName: newViewTitle,
|
|
28
30
|
connectedViewId: view.id,
|
|
29
31
|
connectedFeature: feature.toJSON(),
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
msaFilehandle,
|
|
33
|
+
treeFilehandle,
|
|
34
|
+
querySeqName,
|
|
32
35
|
data,
|
|
33
36
|
})
|
|
34
37
|
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react'
|
|
2
|
+
|
|
3
|
+
import { Feature, getContainingView } from '@jbrowse/core/util'
|
|
4
|
+
import DeleteIcon from '@mui/icons-material/Delete'
|
|
5
|
+
import {
|
|
6
|
+
Button,
|
|
7
|
+
IconButton,
|
|
8
|
+
List,
|
|
9
|
+
ListItem,
|
|
10
|
+
ListItemButton,
|
|
11
|
+
ListItemText,
|
|
12
|
+
Typography,
|
|
13
|
+
} from '@mui/material'
|
|
14
|
+
import { observer } from 'mobx-react'
|
|
15
|
+
|
|
16
|
+
import { blastLaunchViewFromCache } from './blastLaunchView'
|
|
17
|
+
import {
|
|
18
|
+
clearAllCachedResults,
|
|
19
|
+
deleteCachedResult,
|
|
20
|
+
getAllCachedResults,
|
|
21
|
+
} from '../../../utils/blastCache'
|
|
22
|
+
|
|
23
|
+
import type { CachedBlastResult } from '../../../utils/blastCache'
|
|
24
|
+
import type { AbstractTrackModel } from '@jbrowse/core/util'
|
|
25
|
+
import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
|
|
26
|
+
|
|
27
|
+
const CachedBlastResults = observer(function ({
|
|
28
|
+
model,
|
|
29
|
+
handleClose,
|
|
30
|
+
feature,
|
|
31
|
+
}: {
|
|
32
|
+
model: AbstractTrackModel
|
|
33
|
+
handleClose: () => void
|
|
34
|
+
feature: Feature
|
|
35
|
+
}) {
|
|
36
|
+
const [results, setResults] = useState<CachedBlastResult[]>([])
|
|
37
|
+
const [loading, setLoading] = useState(true)
|
|
38
|
+
const view = getContainingView(model) as LinearGenomeViewModel
|
|
39
|
+
|
|
40
|
+
const geneId = feature.get('id')
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
43
|
+
;(async () => {
|
|
44
|
+
try {
|
|
45
|
+
const cached = await getAllCachedResults()
|
|
46
|
+
setResults(cached.filter(r => r.geneId === geneId))
|
|
47
|
+
setLoading(false)
|
|
48
|
+
} catch (e) {
|
|
49
|
+
console.error(e)
|
|
50
|
+
}
|
|
51
|
+
})()
|
|
52
|
+
}, [geneId])
|
|
53
|
+
|
|
54
|
+
const handleDelete = async (id: string) => {
|
|
55
|
+
await deleteCachedResult(id)
|
|
56
|
+
setResults(r => r.filter(result => result.id !== id))
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const handleClearAll = async () => {
|
|
60
|
+
await clearAllCachedResults()
|
|
61
|
+
setResults([])
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const handleUseCached = (cached: CachedBlastResult) => {
|
|
65
|
+
blastLaunchViewFromCache({
|
|
66
|
+
view,
|
|
67
|
+
cached,
|
|
68
|
+
newViewTitle: `BLAST - ${cached.geneId ?? cached.transcriptId ?? 'Unknown gene'}`,
|
|
69
|
+
})
|
|
70
|
+
handleClose()
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (loading) {
|
|
74
|
+
return <Typography>Loading cached results...</Typography>
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (results.length === 0) {
|
|
78
|
+
return (
|
|
79
|
+
<Typography color="textSecondary">
|
|
80
|
+
No cached BLAST results found for this gene. Run a BLAST query to cache
|
|
81
|
+
results.
|
|
82
|
+
</Typography>
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<div>
|
|
88
|
+
<div
|
|
89
|
+
style={{
|
|
90
|
+
display: 'flex',
|
|
91
|
+
justifyContent: 'space-between',
|
|
92
|
+
alignItems: 'center',
|
|
93
|
+
marginBottom: 8,
|
|
94
|
+
}}
|
|
95
|
+
>
|
|
96
|
+
<Typography variant="subtitle1">
|
|
97
|
+
Cached BLAST Results ({results.length})
|
|
98
|
+
</Typography>
|
|
99
|
+
<Button
|
|
100
|
+
size="small"
|
|
101
|
+
color="error"
|
|
102
|
+
onClick={() => {
|
|
103
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
104
|
+
handleClearAll()
|
|
105
|
+
}}
|
|
106
|
+
>
|
|
107
|
+
Clear All
|
|
108
|
+
</Button>
|
|
109
|
+
</div>
|
|
110
|
+
<List dense style={{ maxHeight: 300, overflow: 'auto' }}>
|
|
111
|
+
{results.map(result => (
|
|
112
|
+
<ListItem
|
|
113
|
+
key={result.id}
|
|
114
|
+
disablePadding
|
|
115
|
+
secondaryAction={
|
|
116
|
+
<IconButton
|
|
117
|
+
edge="end"
|
|
118
|
+
size="small"
|
|
119
|
+
onClick={e => {
|
|
120
|
+
e.stopPropagation()
|
|
121
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
122
|
+
handleDelete(result.id)
|
|
123
|
+
}}
|
|
124
|
+
>
|
|
125
|
+
<DeleteIcon fontSize="small" />
|
|
126
|
+
</IconButton>
|
|
127
|
+
}
|
|
128
|
+
>
|
|
129
|
+
<ListItemButton
|
|
130
|
+
onClick={() => {
|
|
131
|
+
handleUseCached(result)
|
|
132
|
+
}}
|
|
133
|
+
>
|
|
134
|
+
<ListItemText
|
|
135
|
+
primary={`${result.geneId ?? result.transcriptId ?? 'Unknown'} - ${result.blastDatabase}/${result.blastProgram} (${result.msaAlgorithm})`}
|
|
136
|
+
secondary={`${new Date(result.timestamp).toLocaleString()} - Seq: ${result.proteinSequence.slice(0, 30)}...`}
|
|
137
|
+
/>
|
|
138
|
+
</ListItemButton>
|
|
139
|
+
</ListItem>
|
|
140
|
+
))}
|
|
141
|
+
</List>
|
|
142
|
+
</div>
|
|
143
|
+
)
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
export default CachedBlastResults
|
|
@@ -6,8 +6,11 @@ import {
|
|
|
6
6
|
Feature,
|
|
7
7
|
getContainingView,
|
|
8
8
|
} from '@jbrowse/core/util'
|
|
9
|
+
import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
|
|
9
10
|
import {
|
|
10
|
-
|
|
11
|
+
Accordion,
|
|
12
|
+
AccordionDetails,
|
|
13
|
+
AccordionSummary,
|
|
11
14
|
Button,
|
|
12
15
|
DialogActions,
|
|
13
16
|
DialogContent,
|
|
@@ -17,16 +20,13 @@ import {
|
|
|
17
20
|
import { observer } from 'mobx-react'
|
|
18
21
|
import { makeStyles } from 'tss-react/mui'
|
|
19
22
|
|
|
23
|
+
import CachedBlastResults from './CachedBlastResults'
|
|
20
24
|
import { blastLaunchView } from './blastLaunchView'
|
|
21
25
|
import TextField2 from '../../../components/TextField2'
|
|
22
|
-
import {
|
|
23
|
-
|
|
24
|
-
getId,
|
|
25
|
-
getTranscriptDisplayName,
|
|
26
|
-
getTranscriptFeatures,
|
|
27
|
-
} from '../../util'
|
|
26
|
+
import { getAllCachedResults } from '../../../utils/blastCache'
|
|
27
|
+
import { getGeneDisplayName, getTranscriptDisplayName } from '../../util'
|
|
28
28
|
import TranscriptSelector from '../TranscriptSelector'
|
|
29
|
-
import {
|
|
29
|
+
import { useTranscriptSelection } from '../useTranscriptSelection'
|
|
30
30
|
|
|
31
31
|
import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
|
|
32
32
|
|
|
@@ -67,26 +67,39 @@ const NCBIBlastAutomaticPanel = observer(function ({
|
|
|
67
67
|
useState<blastDatabaseOptionsT>('nr')
|
|
68
68
|
const [selectedMsaAlgorithm, setSelectedMsaAlgorithm] =
|
|
69
69
|
useState<msaAlgorithmsT>('clustalo')
|
|
70
|
-
const options = getTranscriptFeatures(feature)
|
|
71
|
-
const [selectedTranscriptId, setSelectedTranscriptId] = useState(
|
|
72
|
-
getId(options[0]),
|
|
73
|
-
)
|
|
74
70
|
const [selectedBlastProgram, setSelectedBlastProgram] =
|
|
75
71
|
useState<blastProgramsT>('quick-blastp')
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
72
|
+
const [hasCachedResults, setHasCachedResults] = useState(false)
|
|
73
|
+
const [error, setError] = useState<unknown>()
|
|
74
|
+
|
|
75
|
+
const geneId = feature.get('id')
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
78
|
+
;(async () => {
|
|
79
|
+
try {
|
|
80
|
+
const results = await getAllCachedResults()
|
|
81
|
+
setHasCachedResults(results.some(r => r.geneId === geneId))
|
|
82
|
+
} catch (e) {
|
|
83
|
+
console.error(e)
|
|
84
|
+
setError(e)
|
|
85
|
+
}
|
|
86
|
+
})()
|
|
87
|
+
}, [geneId])
|
|
88
|
+
|
|
89
|
+
const {
|
|
90
|
+
options,
|
|
91
|
+
setSelectedId,
|
|
92
|
+
selectedTranscript,
|
|
93
|
+
proteinSequence,
|
|
94
|
+
error: proteinSequenceError,
|
|
95
|
+
} = useTranscriptSelection({ feature, view })
|
|
83
96
|
|
|
84
97
|
useEffect(() => {
|
|
85
98
|
if (selectedBlastDatabase === 'nr_cluster_seq') {
|
|
86
99
|
setSelectedBlastProgram('blastp')
|
|
87
100
|
}
|
|
88
101
|
}, [selectedBlastDatabase])
|
|
89
|
-
const e = proteinSequenceError ?? launchViewError
|
|
102
|
+
const e = proteinSequenceError ?? launchViewError ?? error
|
|
90
103
|
const style = { width: 150 }
|
|
91
104
|
return (
|
|
92
105
|
<>
|
|
@@ -167,8 +180,8 @@ const NCBIBlastAutomaticPanel = observer(function ({
|
|
|
167
180
|
<TranscriptSelector
|
|
168
181
|
feature={feature}
|
|
169
182
|
options={options}
|
|
170
|
-
|
|
171
|
-
onTranscriptChange={
|
|
183
|
+
selectedTranscript={selectedTranscript}
|
|
184
|
+
onTranscriptChange={setSelectedId}
|
|
172
185
|
proteinSequence={proteinSequence}
|
|
173
186
|
/>
|
|
174
187
|
|
|
@@ -182,6 +195,21 @@ const NCBIBlastAutomaticPanel = observer(function ({
|
|
|
182
195
|
you need a COBALT alignment, please use the manual approach of
|
|
183
196
|
submitting BLAST yourself and downloading the resulting files
|
|
184
197
|
</Typography>
|
|
198
|
+
|
|
199
|
+
{hasCachedResults ? (
|
|
200
|
+
<Accordion style={{ marginTop: 20 }}>
|
|
201
|
+
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
|
202
|
+
<Typography>Previous BLAST Results</Typography>
|
|
203
|
+
</AccordionSummary>
|
|
204
|
+
<AccordionDetails>
|
|
205
|
+
<CachedBlastResults
|
|
206
|
+
model={model}
|
|
207
|
+
handleClose={handleClose}
|
|
208
|
+
feature={feature}
|
|
209
|
+
/>
|
|
210
|
+
</AccordionDetails>
|
|
211
|
+
</Accordion>
|
|
212
|
+
) : null}
|
|
185
213
|
</DialogContent>
|
|
186
214
|
<DialogActions>
|
|
187
215
|
<Button
|
|
@@ -189,6 +217,9 @@ const NCBIBlastAutomaticPanel = observer(function ({
|
|
|
189
217
|
variant="contained"
|
|
190
218
|
onClick={() => {
|
|
191
219
|
try {
|
|
220
|
+
if (!selectedTranscript) {
|
|
221
|
+
return
|
|
222
|
+
}
|
|
192
223
|
setLaunchViewError(undefined)
|
|
193
224
|
blastLaunchView({
|
|
194
225
|
feature: selectedTranscript,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react'
|
|
2
2
|
|
|
3
3
|
import { ErrorMessage } from '@jbrowse/core/ui'
|
|
4
4
|
import { getContainingView, shorten2 } from '@jbrowse/core/util'
|
|
@@ -7,9 +7,9 @@ import { observer } from 'mobx-react'
|
|
|
7
7
|
import { makeStyles } from 'tss-react/mui'
|
|
8
8
|
|
|
9
9
|
import ExternalLink from '../../../components/ExternalLink'
|
|
10
|
-
import {
|
|
10
|
+
import { cleanProteinSequence } from '../../util'
|
|
11
11
|
import TranscriptSelector from '../TranscriptSelector'
|
|
12
|
-
import {
|
|
12
|
+
import { useTranscriptSelection } from '../useTranscriptSelection'
|
|
13
13
|
|
|
14
14
|
import type { AbstractTrackModel, Feature } from '@jbrowse/core/util'
|
|
15
15
|
import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
|
|
@@ -43,15 +43,10 @@ const NCBIBlastManualPanel = observer(function ({
|
|
|
43
43
|
}) {
|
|
44
44
|
const { classes } = useStyles()
|
|
45
45
|
const view = getContainingView(model) as LinearGenomeViewModel
|
|
46
|
-
const options =
|
|
47
|
-
|
|
48
|
-
const selectedTranscript = options.find(val => getId(val) === userSelection)!
|
|
49
|
-
const { proteinSequence, error } = useFeatureSequence({
|
|
50
|
-
view,
|
|
51
|
-
feature: selectedTranscript,
|
|
52
|
-
})
|
|
46
|
+
const { options, setSelectedId, selectedTranscript, proteinSequence, error } =
|
|
47
|
+
useTranscriptSelection({ feature, view })
|
|
53
48
|
|
|
54
|
-
const s2 = proteinSequence
|
|
49
|
+
const s2 = cleanProteinSequence(proteinSequence)
|
|
55
50
|
const link = `${baseUrl}?PAGE_TYPE=BlastSearch&PAGE=Proteins&PROGRAM=blastp&QUERY=${s2}`
|
|
56
51
|
const link2 = `${baseUrl}?PAGE_TYPE=BlastSearch&PAGE=Proteins&PROGRAM=blastp&QUERY=${shorten2(s2, 10)}`
|
|
57
52
|
|
|
@@ -64,8 +59,8 @@ const NCBIBlastManualPanel = observer(function ({
|
|
|
64
59
|
<TranscriptSelector
|
|
65
60
|
feature={feature}
|
|
66
61
|
options={options}
|
|
67
|
-
|
|
68
|
-
onTranscriptChange={
|
|
62
|
+
selectedTranscript={selectedTranscript}
|
|
63
|
+
onTranscriptChange={setSelectedId}
|
|
69
64
|
proteinSequence={proteinSequence}
|
|
70
65
|
/>
|
|
71
66
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Feature, getSession } from '@jbrowse/core/util'
|
|
2
2
|
|
|
3
3
|
import type { JBrowsePluginMsaViewModel } from '../../../MsaViewPanel/model'
|
|
4
|
+
import type { CachedBlastResult } from '../../../utils/blastCache'
|
|
4
5
|
import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
|
|
5
6
|
|
|
6
7
|
export function blastLaunchView({
|
|
@@ -25,3 +26,27 @@ export function blastLaunchView({
|
|
|
25
26
|
blastParams,
|
|
26
27
|
}) as JBrowsePluginMsaViewModel
|
|
27
28
|
}
|
|
29
|
+
|
|
30
|
+
export function blastLaunchViewFromCache({
|
|
31
|
+
newViewTitle,
|
|
32
|
+
view,
|
|
33
|
+
cached,
|
|
34
|
+
}: {
|
|
35
|
+
newViewTitle: string
|
|
36
|
+
view: LinearGenomeViewModel
|
|
37
|
+
cached: CachedBlastResult
|
|
38
|
+
}) {
|
|
39
|
+
return getSession(view).addView('MsaView', {
|
|
40
|
+
type: 'MsaView',
|
|
41
|
+
displayName: newViewTitle,
|
|
42
|
+
connectedViewId: view.id,
|
|
43
|
+
drawNodeBubbles: true,
|
|
44
|
+
colWidth: 10,
|
|
45
|
+
rowHeight: 12,
|
|
46
|
+
data: {
|
|
47
|
+
msa: cached.msa,
|
|
48
|
+
tree: cached.tree,
|
|
49
|
+
treeMetadata: cached.treeMetadata,
|
|
50
|
+
},
|
|
51
|
+
}) as JBrowsePluginMsaViewModel
|
|
52
|
+
}
|