jbrowse-plugin-msaview 2.5.2 → 2.6.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/LaunchMsaViewExtensionPoint/index.js +5 -2
- package/dist/MsaViewPanel/afterCreateAutoruns.js +21 -1
- package/dist/MsaViewPanel/fetchTabixMsa.d.ts +12 -0
- package/dist/MsaViewPanel/fetchTabixMsa.js +33 -0
- package/dist/MsaViewPanel/types.d.ts +7 -0
- package/dist/jbrowse-plugin-msaview.umd.production.min.js +28 -26
- package/dist/jbrowse-plugin-msaview.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/LaunchMsaViewExtensionPoint/index.ts +10 -1
- package/src/MsaViewPanel/afterCreateAutoruns.ts +30 -1
- package/src/MsaViewPanel/fetchTabixMsa.ts +50 -0
- package/src/MsaViewPanel/types.ts +8 -0
- package/src/version.ts +1 -1
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "2.
|
|
1
|
+
export declare const version = "2.6.0";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '2.
|
|
1
|
+
export const version = '2.6.0';
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "2.
|
|
2
|
+
"version": "2.6.0",
|
|
3
3
|
"license": "MIT",
|
|
4
4
|
"name": "jbrowse-plugin-msaview",
|
|
5
5
|
"repository": {
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"@emotion/styled": "^11.14.1",
|
|
20
|
+
"@gmod/tabix": "^3.0.1",
|
|
20
21
|
"g2p_mapper": "^2.1.5",
|
|
21
22
|
"idb": "^8.0.3",
|
|
22
23
|
"pako-esm2": "^2.0.2",
|
|
@@ -11,6 +11,9 @@ export default function LaunchMsaViewExtensionPointF(
|
|
|
11
11
|
session,
|
|
12
12
|
data,
|
|
13
13
|
msaFileLocation,
|
|
14
|
+
msaTabixLocation,
|
|
15
|
+
msaIndexLocation,
|
|
16
|
+
msaId,
|
|
14
17
|
treeFileLocation,
|
|
15
18
|
connectedViewId,
|
|
16
19
|
connectedFeature,
|
|
@@ -29,6 +32,9 @@ export default function LaunchMsaViewExtensionPointF(
|
|
|
29
32
|
session: AbstractSessionModel
|
|
30
33
|
data?: { msa: string; tree?: string }
|
|
31
34
|
msaFileLocation?: { uri: string }
|
|
35
|
+
msaTabixLocation?: { uri: string }
|
|
36
|
+
msaIndexLocation?: { uri: string }
|
|
37
|
+
msaId?: string
|
|
32
38
|
treeFileLocation?: { uri: string }
|
|
33
39
|
connectedViewId?: string
|
|
34
40
|
connectedFeature?: Record<string, unknown>
|
|
@@ -44,7 +50,7 @@ export default function LaunchMsaViewExtensionPointF(
|
|
|
44
50
|
querySeqName?: string
|
|
45
51
|
highlightColumns?: number[]
|
|
46
52
|
}) => {
|
|
47
|
-
if (!data && !msaFileLocation) {
|
|
53
|
+
if (!data && !msaFileLocation && !msaTabixLocation) {
|
|
48
54
|
throw new Error(
|
|
49
55
|
'No MSA data or file location provided when launching MSA view',
|
|
50
56
|
)
|
|
@@ -68,6 +74,9 @@ export default function LaunchMsaViewExtensionPointF(
|
|
|
68
74
|
msaData: data?.msa,
|
|
69
75
|
treeData: data?.tree,
|
|
70
76
|
msaUrl: msaFileLocation?.uri,
|
|
77
|
+
msaTabixLocation,
|
|
78
|
+
msaIndexLocation,
|
|
79
|
+
msaId,
|
|
71
80
|
treeUrl: treeFileLocation?.uri,
|
|
72
81
|
querySeqName,
|
|
73
82
|
},
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { getSession } from '@jbrowse/core/util'
|
|
2
2
|
|
|
3
3
|
import { doLaunchBlast } from './doLaunchBlast'
|
|
4
|
+
import { fetchTabixMsa } from './fetchTabixMsa'
|
|
4
5
|
import { genomeToMSA } from './genomeToMSA'
|
|
5
6
|
import { loadProteinDomains } from './loadProteinDomains'
|
|
6
7
|
import {
|
|
@@ -133,7 +134,16 @@ export function processInit(self: JBrowsePluginMsaViewModel) {
|
|
|
133
134
|
void (async () => {
|
|
134
135
|
try {
|
|
135
136
|
self.setError(undefined)
|
|
136
|
-
const {
|
|
137
|
+
const {
|
|
138
|
+
msaData,
|
|
139
|
+
msaUrl,
|
|
140
|
+
msaTabixLocation,
|
|
141
|
+
msaIndexLocation,
|
|
142
|
+
msaId,
|
|
143
|
+
treeData,
|
|
144
|
+
treeUrl,
|
|
145
|
+
querySeqName,
|
|
146
|
+
} = init
|
|
137
147
|
|
|
138
148
|
if (msaUrl) {
|
|
139
149
|
const id = getUniprotIdFromAlphaFoldUrl(msaUrl)
|
|
@@ -156,6 +166,25 @@ export function processInit(self: JBrowsePluginMsaViewModel) {
|
|
|
156
166
|
}
|
|
157
167
|
const data = await response.text()
|
|
158
168
|
self.setMSA(data)
|
|
169
|
+
} else if (msaTabixLocation) {
|
|
170
|
+
const feature = self.connectedFeature
|
|
171
|
+
if (feature) {
|
|
172
|
+
const fasta = await fetchTabixMsa({
|
|
173
|
+
location: msaTabixLocation,
|
|
174
|
+
indexLocation: msaIndexLocation,
|
|
175
|
+
msaId: msaId ?? String(feature.name),
|
|
176
|
+
refName: String(feature.refName),
|
|
177
|
+
start: Number(feature.start),
|
|
178
|
+
end: Number(feature.end),
|
|
179
|
+
})
|
|
180
|
+
if (fasta) {
|
|
181
|
+
self.setMSA(fasta)
|
|
182
|
+
} else {
|
|
183
|
+
throw new Error(
|
|
184
|
+
`No alignment for ${msaId ?? String(feature.name)} in ${msaTabixLocation.uri}`,
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
}
|
|
159
188
|
}
|
|
160
189
|
|
|
161
190
|
if (treeData) {
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { TabixIndexedFile } from '@gmod/tabix'
|
|
2
|
+
import { openLocation } from '@jbrowse/core/util/io'
|
|
3
|
+
|
|
4
|
+
// Pull one transcript's whole multiple-alignment out of a locus-keyed tabix
|
|
5
|
+
// file. Each line is `refName<TAB>start<TAB>end<TAB>msaId<TAB>packed`, where
|
|
6
|
+
// `packed` is `name:SEQ;name:SEQ;...` — no newlines, so the alignment survives
|
|
7
|
+
// as a single tabix column. We query the transcript's genomic locus, then pick
|
|
8
|
+
// the line whose msaId matches, and rebuild a FASTA string.
|
|
9
|
+
export async function fetchTabixMsa({
|
|
10
|
+
location,
|
|
11
|
+
indexLocation,
|
|
12
|
+
msaId,
|
|
13
|
+
refName,
|
|
14
|
+
start,
|
|
15
|
+
end,
|
|
16
|
+
}: {
|
|
17
|
+
location: { uri: string }
|
|
18
|
+
indexLocation?: { uri: string }
|
|
19
|
+
msaId: string
|
|
20
|
+
refName: string
|
|
21
|
+
start: number
|
|
22
|
+
end: number
|
|
23
|
+
}) {
|
|
24
|
+
const uri = (loc: { uri: string }) =>
|
|
25
|
+
openLocation({ uri: loc.uri, locationType: 'UriLocation' as const })
|
|
26
|
+
const file = new TabixIndexedFile({
|
|
27
|
+
filehandle: uri(location),
|
|
28
|
+
csiFilehandle: uri(indexLocation ?? { uri: `${location.uri}.csi` }),
|
|
29
|
+
})
|
|
30
|
+
const lines: string[] = []
|
|
31
|
+
await file.getLines(refName, start, end, {
|
|
32
|
+
lineCallback: line => {
|
|
33
|
+
lines.push(line)
|
|
34
|
+
},
|
|
35
|
+
})
|
|
36
|
+
const line = lines.find(l => l.split('\t')[3] === msaId)
|
|
37
|
+
return line ? unpack(line) : undefined
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function unpack(line: string) {
|
|
41
|
+
const packed = line.split('\t')[4] ?? ''
|
|
42
|
+
return packed
|
|
43
|
+
.split(';')
|
|
44
|
+
.filter(Boolean)
|
|
45
|
+
.map(pair => {
|
|
46
|
+
const colon = pair.indexOf(':')
|
|
47
|
+
return `>${pair.slice(0, colon)}\n${pair.slice(colon + 1)}`
|
|
48
|
+
})
|
|
49
|
+
.join('\n')
|
|
50
|
+
}
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
export interface MsaViewInitState {
|
|
2
2
|
msaData?: string
|
|
3
3
|
msaUrl?: string
|
|
4
|
+
// a tabix file keyed by genomic locus, where each line packs one transcript's
|
|
5
|
+
// whole multiple-alignment (`name:SEQ;name:SEQ;...`). The transcript's locus
|
|
6
|
+
// comes from the view's connectedFeature, and `msaId` (default the feature's
|
|
7
|
+
// name) selects its line. Lets one genome-scale alignment serve any gene
|
|
8
|
+
// without per-gene files. See react-msaview's gene-explorer.
|
|
9
|
+
msaTabixLocation?: { uri: string }
|
|
10
|
+
msaIndexLocation?: { uri: string }
|
|
11
|
+
msaId?: string
|
|
4
12
|
treeData?: string
|
|
5
13
|
treeUrl?: string
|
|
6
14
|
querySeqName?: string
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '2.
|
|
1
|
+
export const version = '2.6.0'
|