jbrowse-plugin-msaview 2.7.2 → 2.7.3
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/MsaToGenomeHighlight.js +6 -5
- package/dist/LaunchMsaView/components/NCBIBlastQuery/CachedBlastResults.js +1 -1
- package/dist/LaunchMsaView/components/NCBIBlastQuery/useCachedBlastResults.d.ts +1 -1
- package/dist/LaunchMsaView/components/NCBIBlastQuery/useCachedBlastResults.js +5 -2
- package/dist/MsaViewPanel/doLaunchBlast.js +10 -22
- package/dist/MsaViewPanel/genomeToMSA.js +13 -6
- package/dist/MsaViewPanel/genomeToMSA.test.js +35 -6
- package/dist/MsaViewPanel/model.d.ts +68 -66
- package/dist/MsaViewPanel/model.js +14 -12
- package/dist/MsaViewPanel/msaCoordToGenomeCoord.d.ts +32 -13
- package/dist/MsaViewPanel/msaCoordToGenomeCoord.js +43 -14
- package/dist/MsaViewPanel/msaCoordToGenomeCoord.test.js +108 -18
- package/dist/MsaViewPanel/msaDataStore.js +8 -17
- package/dist/MsaViewPanel/syncGenomeHoverToMsaColumn.test.js +8 -6
- package/dist/jbrowse-plugin-msaview.umd.production.min.js +31 -31
- package/dist/jbrowse-plugin-msaview.umd.production.min.js.map +4 -4
- package/dist/utils/blastCache.d.ts +1 -2
- package/dist/utils/blastCache.js +9 -22
- package/dist/utils/domainCache.js +6 -15
- package/dist/utils/idb.d.ts +12 -0
- package/dist/utils/idb.js +21 -0
- package/dist/utils/taxonomyNames.js +13 -18
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
- package/src/AddHighlightModel/MsaToGenomeHighlight.tsx +6 -8
- package/src/LaunchMsaView/components/NCBIBlastQuery/CachedBlastResults.tsx +1 -1
- package/src/LaunchMsaView/components/NCBIBlastQuery/useCachedBlastResults.ts +4 -2
- package/src/MsaViewPanel/doLaunchBlast.ts +20 -29
- package/src/MsaViewPanel/genomeToMSA.test.ts +38 -6
- package/src/MsaViewPanel/genomeToMSA.ts +14 -6
- package/src/MsaViewPanel/model.ts +17 -12
- package/src/MsaViewPanel/msaCoordToGenomeCoord.test.ts +117 -18
- package/src/MsaViewPanel/msaCoordToGenomeCoord.ts +70 -26
- package/src/MsaViewPanel/msaDataStore.ts +17 -17
- package/src/MsaViewPanel/syncGenomeHoverToMsaColumn.test.ts +8 -6
- package/src/utils/blastCache.ts +20 -23
- package/src/utils/domainCache.ts +14 -18
- package/src/utils/idb.ts +28 -0
- package/src/utils/taxonomyNames.ts +22 -24
- package/src/version.ts +1 -1
- package/dist/MsaViewPanel/blosum62.d.ts +0 -2
- package/dist/MsaViewPanel/blosum62.js +0 -627
- package/src/MsaViewPanel/blosum62.ts +0 -628
|
@@ -11,11 +11,12 @@ const MsaToGenomeHighlight = observer(function MsaToGenomeHighlight2({ model, })
|
|
|
11
11
|
// The persistent click selection always shows. The hover codon is suppressed
|
|
12
12
|
// while hovering the LGV — GenomeMouseoverHighlight handles the single-bp
|
|
13
13
|
// display in that case, so we don't stack a wider codon band on top of it.
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
const highlights = [
|
|
15
|
+
...(msaView?.connectedClickHighlights ?? []),
|
|
16
|
+
...(hasHoverPosition(hovered)
|
|
17
|
+
? []
|
|
18
|
+
: (msaView?.connectedHoverHighlights ?? [])),
|
|
19
|
+
];
|
|
19
20
|
return highlights.length ? (React.createElement(MsaToGenomeHighlightRenderer, { model: model, highlights: highlights })) : null;
|
|
20
21
|
});
|
|
21
22
|
// Inner component: handles the scroll-dependent rendering
|
|
@@ -68,7 +68,7 @@ const CachedBlastResults = observer(function ({ model, handleClose, feature, })
|
|
|
68
68
|
catch (e) {
|
|
69
69
|
setOperationError(e);
|
|
70
70
|
}
|
|
71
|
-
} }, "Clear
|
|
71
|
+
} }, "Clear results for this gene")),
|
|
72
72
|
React.createElement(List, { dense: true, className: classes.resultList }, results.map(result => (React.createElement(ListItem, { key: result.id, disablePadding: true, secondaryAction: React.createElement(IconButton, { edge: "end", size: "small", onClick: async (e) => {
|
|
73
73
|
e.stopPropagation();
|
|
74
74
|
try {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import useSWR from 'swr';
|
|
2
|
-
import {
|
|
2
|
+
import { deleteCachedResult, getAllCachedResults, } from '../../../utils/blastCache';
|
|
3
3
|
import { staticSwrConfig } from '../../../utils/swrConfig';
|
|
4
4
|
export function useCachedBlastResults(geneIds) {
|
|
5
5
|
const { data: results, error, isLoading, mutate, } = useSWR(`cached-blast-${geneIds.join(',')}`, async () => {
|
|
@@ -10,8 +10,11 @@ export function useCachedBlastResults(geneIds) {
|
|
|
10
10
|
await deleteCachedResult(id);
|
|
11
11
|
await mutate(results => results?.filter(result => result.id !== id) ?? [], false);
|
|
12
12
|
};
|
|
13
|
+
// deletes only what this hook listed, i.e. the results for these gene ids.
|
|
14
|
+
// The list the user is looking at is gene-scoped, so a store-wide clear here
|
|
15
|
+
// would silently throw away every other gene's cached alignments too
|
|
13
16
|
const handleClearAll = async () => {
|
|
14
|
-
await
|
|
17
|
+
await Promise.all((results ?? []).map(r => deleteCachedResult(r.id)));
|
|
15
18
|
await mutate([], false);
|
|
16
19
|
};
|
|
17
20
|
return {
|
|
@@ -7,36 +7,26 @@ import { fetchTaxonomyInfo } from '../utils/taxonomyNames';
|
|
|
7
7
|
export async function doLaunchBlast({ self, }) {
|
|
8
8
|
const { baseUrl, blastDatabase, blastProgram, msaAlgorithm, proteinSequence, selectedTranscript, rid: existingRid, } = self.blastParams;
|
|
9
9
|
const cleanedSeq = cleanProteinSequence(proteinSequence);
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
const onProgress = (arg) => {
|
|
11
|
+
self.setProgress(arg);
|
|
12
|
+
};
|
|
12
13
|
if (existingRid) {
|
|
14
|
+
// publish it before the first poll so the view can link out to NCBI while
|
|
15
|
+
// the job is still running
|
|
13
16
|
self.setRid(existingRid);
|
|
14
|
-
const result = await queryBlastFromRid({
|
|
15
|
-
rid: existingRid,
|
|
16
|
-
baseUrl,
|
|
17
|
-
onProgress: arg => {
|
|
18
|
-
self.setProgress(arg);
|
|
19
|
-
},
|
|
20
|
-
});
|
|
21
|
-
hits = result.hits;
|
|
22
|
-
rid = result.rid;
|
|
23
17
|
}
|
|
24
|
-
|
|
25
|
-
|
|
18
|
+
const { hits, rid } = existingRid
|
|
19
|
+
? await queryBlastFromRid({ rid: existingRid, baseUrl, onProgress })
|
|
20
|
+
: await queryBlast({
|
|
26
21
|
query: cleanedSeq,
|
|
27
22
|
blastDatabase,
|
|
28
23
|
blastProgram,
|
|
29
24
|
baseUrl,
|
|
30
|
-
onProgress
|
|
31
|
-
self.setProgress(arg);
|
|
32
|
-
},
|
|
25
|
+
onProgress,
|
|
33
26
|
onRid: r => {
|
|
34
27
|
self.setRid(r);
|
|
35
28
|
},
|
|
36
29
|
});
|
|
37
|
-
hits = result.hits;
|
|
38
|
-
rid = result.rid;
|
|
39
|
-
}
|
|
40
30
|
self.setProgress('Fetching species taxonomy info...');
|
|
41
31
|
const taxids = hits
|
|
42
32
|
.map(h => h.description[0]?.taxid)
|
|
@@ -57,9 +47,7 @@ export async function doLaunchBlast({ self, }) {
|
|
|
57
47
|
const result = await launchMSA({
|
|
58
48
|
algorithm: msaAlgorithm,
|
|
59
49
|
sequence: [`>QUERY\n${cleanedSeq}`, ...sequences].join('\n'),
|
|
60
|
-
onProgress
|
|
61
|
-
self.setProgress(arg);
|
|
62
|
-
},
|
|
50
|
+
onProgress,
|
|
63
51
|
});
|
|
64
52
|
const treeMetadataJson = JSON.stringify(treeMetadata);
|
|
65
53
|
await saveBlastResult({
|
|
@@ -6,18 +6,25 @@ export function genomeToMSA({ model }) {
|
|
|
6
6
|
if (!connectedView?.initialized || !hasHoverPosition(hovered)) {
|
|
7
7
|
return undefined;
|
|
8
8
|
}
|
|
9
|
-
const { coord
|
|
9
|
+
const { coord, refName } = hovered.hoverPosition;
|
|
10
|
+
// hoverPosition.coord is a 1-based display coordinate (core's pxToBp adds the
|
|
11
|
+
// +1), while g2p and mafRegion are keyed by 0-based genome position
|
|
12
|
+
const genomePos = coord - 1;
|
|
10
13
|
if (mafRegion) {
|
|
11
14
|
if (refName !== mafRegion.refName ||
|
|
12
15
|
!connectedView.assemblyNames.includes(mafRegion.assemblyName) ||
|
|
13
|
-
|
|
14
|
-
|
|
16
|
+
genomePos < mafRegion.start ||
|
|
17
|
+
genomePos >= mafRegion.end) {
|
|
15
18
|
return undefined;
|
|
16
19
|
}
|
|
17
|
-
return model.seqPosToVisibleCol(querySeqName,
|
|
20
|
+
return model.seqPosToVisibleCol(querySeqName, genomePos - mafRegion.start);
|
|
18
21
|
}
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
// session.hovered is global -- set by whichever LinearGenomeView the cursor
|
|
23
|
+
// was last over, on any assembly -- so the refName gate is load bearing:
|
|
24
|
+
// without it the same numeric coordinate on an unrelated chromosome matches a
|
|
25
|
+
// g2p key and lights up a column for a different locus
|
|
26
|
+
if (refName === transcriptToMsaMap?.refName) {
|
|
27
|
+
const seqPos = transcriptToMsaMap.g2p[genomePos];
|
|
21
28
|
if (seqPos !== undefined) {
|
|
22
29
|
return model.seqPosToVisibleCol(querySeqName, seqPos);
|
|
23
30
|
}
|
|
@@ -76,8 +76,9 @@ describe('genomeToMSA', () => {
|
|
|
76
76
|
seqPosToVisibleCol: mockSeqPosToVisibleCol,
|
|
77
77
|
};
|
|
78
78
|
const result = genomeToMSA({ model });
|
|
79
|
-
// coord 1005 -
|
|
80
|
-
|
|
79
|
+
// hover coord 1005 is 1-based, so the 0-based genome position is 1004,
|
|
80
|
+
// which is ungapped position 4 of a region starting at 1000
|
|
81
|
+
expect(mockSeqPosToVisibleCol).toHaveBeenCalledWith('hg38.chr1', 4);
|
|
81
82
|
expect(result).toBe(5);
|
|
82
83
|
});
|
|
83
84
|
test('returns undefined when hover refName does not match mafRegion', () => {
|
|
@@ -106,10 +107,11 @@ describe('genomeToMSA', () => {
|
|
|
106
107
|
expect(result).toBeUndefined();
|
|
107
108
|
});
|
|
108
109
|
test('returns undefined when hover coord is before mafRegion start', () => {
|
|
110
|
+
// 1-based coord 1000 is the 0-based base 999, one before the region
|
|
109
111
|
mockGetSession.mockReturnValue({
|
|
110
112
|
hovered: {
|
|
111
113
|
hoverFeature: {},
|
|
112
|
-
hoverPosition: { coord:
|
|
114
|
+
hoverPosition: { coord: 1000, refName: 'chr1' },
|
|
113
115
|
},
|
|
114
116
|
});
|
|
115
117
|
const model = {
|
|
@@ -131,10 +133,11 @@ describe('genomeToMSA', () => {
|
|
|
131
133
|
expect(result).toBeUndefined();
|
|
132
134
|
});
|
|
133
135
|
test('returns undefined when hover coord is at or after mafRegion end', () => {
|
|
136
|
+
// 1-based coord 1011 is the 0-based base 1010, one past the region
|
|
134
137
|
mockGetSession.mockReturnValue({
|
|
135
138
|
hovered: {
|
|
136
139
|
hoverFeature: {},
|
|
137
|
-
hoverPosition: { coord:
|
|
140
|
+
hoverPosition: { coord: 1011, refName: 'chr1' },
|
|
138
141
|
},
|
|
139
142
|
});
|
|
140
143
|
const model = {
|
|
@@ -193,7 +196,9 @@ describe('genomeToMSA', () => {
|
|
|
193
196
|
const model = {
|
|
194
197
|
querySeqName: 'QUERY',
|
|
195
198
|
transcriptToMsaMap: {
|
|
196
|
-
|
|
199
|
+
refName: 'chr1',
|
|
200
|
+
// g2p is keyed by 0-based genome position, the hover coord is 1-based
|
|
201
|
+
g2p: { 1004: 10 },
|
|
197
202
|
},
|
|
198
203
|
mafRegion: undefined,
|
|
199
204
|
connectedView: { initialized: true },
|
|
@@ -203,6 +208,29 @@ describe('genomeToMSA', () => {
|
|
|
203
208
|
expect(mockSeqPosToVisibleCol).toHaveBeenCalledWith('QUERY', 10);
|
|
204
209
|
expect(result).toBe(10);
|
|
205
210
|
});
|
|
211
|
+
test('returns undefined when the hover is on another refName', () => {
|
|
212
|
+
// session.hovered is global, so a hover on an unrelated chromosome can
|
|
213
|
+
// carry a coordinate that happens to be a g2p key
|
|
214
|
+
mockGetSession.mockReturnValue({
|
|
215
|
+
hovered: {
|
|
216
|
+
hoverFeature: {},
|
|
217
|
+
hoverPosition: { coord: 1005, refName: 'chr2' },
|
|
218
|
+
},
|
|
219
|
+
});
|
|
220
|
+
const mockSeqPosToVisibleCol = vi.fn();
|
|
221
|
+
const model = {
|
|
222
|
+
querySeqName: 'QUERY',
|
|
223
|
+
transcriptToMsaMap: {
|
|
224
|
+
refName: 'chr1',
|
|
225
|
+
g2p: { 1004: 10 },
|
|
226
|
+
},
|
|
227
|
+
mafRegion: undefined,
|
|
228
|
+
connectedView: { initialized: true },
|
|
229
|
+
seqPosToVisibleCol: mockSeqPosToVisibleCol,
|
|
230
|
+
};
|
|
231
|
+
expect(genomeToMSA({ model })).toBeUndefined();
|
|
232
|
+
expect(mockSeqPosToVisibleCol).not.toHaveBeenCalled();
|
|
233
|
+
});
|
|
206
234
|
test('returns undefined when g2p has no mapping for coord', () => {
|
|
207
235
|
mockGetSession.mockReturnValue({
|
|
208
236
|
hovered: {
|
|
@@ -213,7 +241,8 @@ describe('genomeToMSA', () => {
|
|
|
213
241
|
const model = {
|
|
214
242
|
querySeqName: 'QUERY',
|
|
215
243
|
transcriptToMsaMap: {
|
|
216
|
-
|
|
244
|
+
refName: 'chr1',
|
|
245
|
+
g2p: { 1000: 0 }, // No entry for 1004
|
|
217
246
|
},
|
|
218
247
|
mafRegion: undefined,
|
|
219
248
|
connectedView: { initialized: true },
|
|
@@ -29,7 +29,7 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
29
29
|
id: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
30
30
|
displayName: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
|
|
31
31
|
minimized: import("@jbrowse/mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
|
|
32
|
-
}, "height" | "id" | "type" | "
|
|
32
|
+
}, "height" | "id" | "type" | "autoTreeAreaWidth" | "drawLabels" | "drawNodeBubbles" | "drawTree" | "labelsAlignRight" | "showBranchLen" | "treeAreaWidth" | "treeWidth" | "bgColor" | "colorSchemeName" | "msaFormat" | "showColumnStats" | "allowedGappyness" | "colWidth" | "collapsed" | "currentAlignment" | "data" | "drawMsaLetters" | "featureFilters" | "gffFilehandle" | "hideGaps" | "highlightColumns" | "msaFilehandle" | "relativeTo" | "rowHeight" | "scrollX" | "scrollY" | "scrollZoom" | "showDomains" | "showOnly" | "subFeatureRows" | "treeFilehandle" | "treeMetadataFilehandle" | "turnedOffTracks"> & Omit<Omit<Omit<{}, "autoTreeAreaWidth" | "drawLabels" | "drawNodeBubbles" | "drawTree" | "labelsAlignRight" | "showBranchLen" | "treeAreaWidth" | "treeWidth"> & {
|
|
33
33
|
drawLabels: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
34
34
|
labelsAlignRight: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
35
35
|
treeAreaWidth: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<number>, [undefined]>;
|
|
@@ -38,12 +38,12 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
38
38
|
drawTree: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
39
39
|
drawNodeBubbles: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
40
40
|
autoTreeAreaWidth: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
41
|
-
}, "bgColor" | "colorSchemeName" | "
|
|
41
|
+
}, "bgColor" | "colorSchemeName" | "msaFormat" | "showColumnStats"> & {
|
|
42
42
|
bgColor: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
43
43
|
colorSchemeName: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
44
44
|
showColumnStats: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
45
45
|
msaFormat: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<import("react-msaview").MSAFormat>>;
|
|
46
|
-
}, "height" | "id" | "type" | "
|
|
46
|
+
}, "height" | "id" | "type" | "allowedGappyness" | "colWidth" | "collapsed" | "currentAlignment" | "data" | "drawMsaLetters" | "featureFilters" | "gffFilehandle" | "hideGaps" | "highlightColumns" | "msaFilehandle" | "relativeTo" | "rowHeight" | "scrollX" | "scrollY" | "scrollZoom" | "showDomains" | "showOnly" | "subFeatureRows" | "treeFilehandle" | "treeMetadataFilehandle" | "turnedOffTracks"> & {
|
|
47
47
|
id: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
48
48
|
showDomains: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
49
49
|
hideGaps: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
@@ -97,18 +97,6 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
97
97
|
authInfo: import("@jbrowse/mobx-state-tree").IType<any, any, any>;
|
|
98
98
|
}> | undefined;
|
|
99
99
|
}, ({
|
|
100
|
-
locationType: "UriLocation";
|
|
101
|
-
uri: string;
|
|
102
|
-
} & Partial<{
|
|
103
|
-
locationType: "UriLocation";
|
|
104
|
-
uri: string;
|
|
105
|
-
baseUri: string | undefined;
|
|
106
|
-
internetAccountId: string | undefined;
|
|
107
|
-
internetAccountPreAuthorization: import("@jbrowse/mobx-state-tree").ModelCreationType<{
|
|
108
|
-
internetAccountType: string;
|
|
109
|
-
authInfo: any;
|
|
110
|
-
}> | undefined;
|
|
111
|
-
}>) | ({
|
|
112
100
|
blobId: string;
|
|
113
101
|
locationType: "BlobLocation";
|
|
114
102
|
name: string;
|
|
@@ -130,6 +118,18 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
130
118
|
} & Partial<{
|
|
131
119
|
locationType: "LocalPathLocation";
|
|
132
120
|
localPath: string;
|
|
121
|
+
}>) | ({
|
|
122
|
+
locationType: "UriLocation";
|
|
123
|
+
uri: string;
|
|
124
|
+
} & Partial<{
|
|
125
|
+
locationType: "UriLocation";
|
|
126
|
+
uri: string;
|
|
127
|
+
baseUri: string | undefined;
|
|
128
|
+
internetAccountId: string | undefined;
|
|
129
|
+
internetAccountPreAuthorization: import("@jbrowse/mobx-state-tree").ModelCreationType<{
|
|
130
|
+
internetAccountType: string;
|
|
131
|
+
authInfo: any;
|
|
132
|
+
}> | undefined;
|
|
133
133
|
}>)>, import("@jbrowse/core/util/types/mst").LegacyFileLocation | import("@jbrowse/mobx-state-tree").ModelCreationType<{
|
|
134
134
|
locationType: "LocalPathLocation";
|
|
135
135
|
localPath: string;
|
|
@@ -191,18 +191,6 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
191
191
|
authInfo: import("@jbrowse/mobx-state-tree").IType<any, any, any>;
|
|
192
192
|
}> | undefined;
|
|
193
193
|
}, ({
|
|
194
|
-
locationType: "UriLocation";
|
|
195
|
-
uri: string;
|
|
196
|
-
} & Partial<{
|
|
197
|
-
locationType: "UriLocation";
|
|
198
|
-
uri: string;
|
|
199
|
-
baseUri: string | undefined;
|
|
200
|
-
internetAccountId: string | undefined;
|
|
201
|
-
internetAccountPreAuthorization: import("@jbrowse/mobx-state-tree").ModelCreationType<{
|
|
202
|
-
internetAccountType: string;
|
|
203
|
-
authInfo: any;
|
|
204
|
-
}> | undefined;
|
|
205
|
-
}>) | ({
|
|
206
194
|
blobId: string;
|
|
207
195
|
locationType: "BlobLocation";
|
|
208
196
|
name: string;
|
|
@@ -224,6 +212,18 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
224
212
|
} & Partial<{
|
|
225
213
|
locationType: "LocalPathLocation";
|
|
226
214
|
localPath: string;
|
|
215
|
+
}>) | ({
|
|
216
|
+
locationType: "UriLocation";
|
|
217
|
+
uri: string;
|
|
218
|
+
} & Partial<{
|
|
219
|
+
locationType: "UriLocation";
|
|
220
|
+
uri: string;
|
|
221
|
+
baseUri: string | undefined;
|
|
222
|
+
internetAccountId: string | undefined;
|
|
223
|
+
internetAccountPreAuthorization: import("@jbrowse/mobx-state-tree").ModelCreationType<{
|
|
224
|
+
internetAccountType: string;
|
|
225
|
+
authInfo: any;
|
|
226
|
+
}> | undefined;
|
|
227
227
|
}>)>, import("@jbrowse/core/util/types/mst").LegacyFileLocation | import("@jbrowse/mobx-state-tree").ModelCreationType<{
|
|
228
228
|
locationType: "LocalPathLocation";
|
|
229
229
|
localPath: string;
|
|
@@ -285,18 +285,6 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
285
285
|
authInfo: import("@jbrowse/mobx-state-tree").IType<any, any, any>;
|
|
286
286
|
}> | undefined;
|
|
287
287
|
}, ({
|
|
288
|
-
locationType: "UriLocation";
|
|
289
|
-
uri: string;
|
|
290
|
-
} & Partial<{
|
|
291
|
-
locationType: "UriLocation";
|
|
292
|
-
uri: string;
|
|
293
|
-
baseUri: string | undefined;
|
|
294
|
-
internetAccountId: string | undefined;
|
|
295
|
-
internetAccountPreAuthorization: import("@jbrowse/mobx-state-tree").ModelCreationType<{
|
|
296
|
-
internetAccountType: string;
|
|
297
|
-
authInfo: any;
|
|
298
|
-
}> | undefined;
|
|
299
|
-
}>) | ({
|
|
300
288
|
blobId: string;
|
|
301
289
|
locationType: "BlobLocation";
|
|
302
290
|
name: string;
|
|
@@ -318,6 +306,18 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
318
306
|
} & Partial<{
|
|
319
307
|
locationType: "LocalPathLocation";
|
|
320
308
|
localPath: string;
|
|
309
|
+
}>) | ({
|
|
310
|
+
locationType: "UriLocation";
|
|
311
|
+
uri: string;
|
|
312
|
+
} & Partial<{
|
|
313
|
+
locationType: "UriLocation";
|
|
314
|
+
uri: string;
|
|
315
|
+
baseUri: string | undefined;
|
|
316
|
+
internetAccountId: string | undefined;
|
|
317
|
+
internetAccountPreAuthorization: import("@jbrowse/mobx-state-tree").ModelCreationType<{
|
|
318
|
+
internetAccountType: string;
|
|
319
|
+
authInfo: any;
|
|
320
|
+
}> | undefined;
|
|
321
321
|
}>)>, import("@jbrowse/core/util/types/mst").LegacyFileLocation | import("@jbrowse/mobx-state-tree").ModelCreationType<{
|
|
322
322
|
locationType: "LocalPathLocation";
|
|
323
323
|
localPath: string;
|
|
@@ -379,18 +379,6 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
379
379
|
authInfo: import("@jbrowse/mobx-state-tree").IType<any, any, any>;
|
|
380
380
|
}> | undefined;
|
|
381
381
|
}, ({
|
|
382
|
-
locationType: "UriLocation";
|
|
383
|
-
uri: string;
|
|
384
|
-
} & Partial<{
|
|
385
|
-
locationType: "UriLocation";
|
|
386
|
-
uri: string;
|
|
387
|
-
baseUri: string | undefined;
|
|
388
|
-
internetAccountId: string | undefined;
|
|
389
|
-
internetAccountPreAuthorization: import("@jbrowse/mobx-state-tree").ModelCreationType<{
|
|
390
|
-
internetAccountType: string;
|
|
391
|
-
authInfo: any;
|
|
392
|
-
}> | undefined;
|
|
393
|
-
}>) | ({
|
|
394
382
|
blobId: string;
|
|
395
383
|
locationType: "BlobLocation";
|
|
396
384
|
name: string;
|
|
@@ -412,6 +400,18 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
412
400
|
} & Partial<{
|
|
413
401
|
locationType: "LocalPathLocation";
|
|
414
402
|
localPath: string;
|
|
403
|
+
}>) | ({
|
|
404
|
+
locationType: "UriLocation";
|
|
405
|
+
uri: string;
|
|
406
|
+
} & Partial<{
|
|
407
|
+
locationType: "UriLocation";
|
|
408
|
+
uri: string;
|
|
409
|
+
baseUri: string | undefined;
|
|
410
|
+
internetAccountId: string | undefined;
|
|
411
|
+
internetAccountPreAuthorization: import("@jbrowse/mobx-state-tree").ModelCreationType<{
|
|
412
|
+
internetAccountType: string;
|
|
413
|
+
authInfo: any;
|
|
414
|
+
}> | undefined;
|
|
415
415
|
}>)>, import("@jbrowse/core/util/types/mst").LegacyFileLocation | import("@jbrowse/mobx-state-tree").ModelCreationType<{
|
|
416
416
|
locationType: "LocalPathLocation";
|
|
417
417
|
localPath: string;
|
|
@@ -581,7 +581,7 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
581
581
|
readonly noTree: boolean;
|
|
582
582
|
readonly noDomains: boolean;
|
|
583
583
|
menuItems(): never[];
|
|
584
|
-
readonly treeMetadata:
|
|
584
|
+
readonly treeMetadata: Record<string, Record<string, string> | undefined>;
|
|
585
585
|
readonly MSA: import("react-msaview").MSAParserType | null;
|
|
586
586
|
readonly numColumns: number;
|
|
587
587
|
readonly tree: import("react-msaview").NodeWithIds;
|
|
@@ -789,7 +789,7 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
789
789
|
accession?: string;
|
|
790
790
|
dbxref?: string;
|
|
791
791
|
} | undefined;
|
|
792
|
-
treeMetadata:
|
|
792
|
+
treeMetadata: Record<string, string> | undefined;
|
|
793
793
|
};
|
|
794
794
|
} & {
|
|
795
795
|
setHeaderHeight(arg: number): void;
|
|
@@ -841,19 +841,21 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
841
841
|
} & {
|
|
842
842
|
/**
|
|
843
843
|
* #getter
|
|
844
|
-
* Genome
|
|
844
|
+
* Genome regions under the current MSA hover column. Suppressed on the LGV
|
|
845
845
|
* while it's being hovered (GenomeMouseoverHighlight shows the crisp 1bp
|
|
846
846
|
* marker there instead of this wider codon band).
|
|
847
847
|
*/
|
|
848
|
-
readonly
|
|
848
|
+
readonly connectedHoverHighlights: IRegion[];
|
|
849
849
|
/**
|
|
850
850
|
* #getter
|
|
851
|
-
* Genome
|
|
851
|
+
* Genome regions under the persistent MSA click selection. Shown
|
|
852
852
|
* regardless of LGV hover, so hovering the genome doesn't hide it.
|
|
853
853
|
*/
|
|
854
|
-
readonly
|
|
854
|
+
readonly connectedClickHighlights: IRegion[];
|
|
855
855
|
/**
|
|
856
856
|
* #getter
|
|
857
|
+
* cross-plugin contract: jbrowse-plugin-mafviewer reads this off the view
|
|
858
|
+
* to draw the same highlights in its own display
|
|
857
859
|
*/
|
|
858
860
|
readonly connectedHighlights: IRegion[];
|
|
859
861
|
} & {
|
|
@@ -935,11 +937,10 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
935
937
|
displayName: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
|
|
936
938
|
minimized: import("@jbrowse/mobx-state-tree").IType<boolean | undefined, boolean, boolean>;
|
|
937
939
|
}> & {
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
};
|
|
940
|
+
bgColor: boolean;
|
|
941
|
+
colorSchemeName: string;
|
|
942
|
+
showColumnStats: boolean;
|
|
943
|
+
msaFormat: import("react-msaview").MSAFormat | undefined;
|
|
943
944
|
drawLabels: boolean;
|
|
944
945
|
labelsAlignRight: boolean;
|
|
945
946
|
treeAreaWidth: number;
|
|
@@ -948,10 +949,6 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
948
949
|
drawTree: boolean;
|
|
949
950
|
drawNodeBubbles: boolean;
|
|
950
951
|
autoTreeAreaWidth: boolean;
|
|
951
|
-
bgColor: boolean;
|
|
952
|
-
colorSchemeName: string;
|
|
953
|
-
showColumnStats: boolean;
|
|
954
|
-
msaFormat: import("react-msaview").MSAFormat | undefined;
|
|
955
952
|
id: string;
|
|
956
953
|
showDomains: boolean;
|
|
957
954
|
hideGaps: boolean;
|
|
@@ -1052,6 +1049,11 @@ export default function stateModelFactory(): import("@jbrowse/mobx-state-tree").
|
|
|
1052
1049
|
featureFilters: import("mobx").IKeyValueMap<boolean>;
|
|
1053
1050
|
relativeTo: string | undefined;
|
|
1054
1051
|
highlightColumns: number[] | undefined;
|
|
1052
|
+
data: {
|
|
1053
|
+
tree?: string | undefined;
|
|
1054
|
+
msa?: string | undefined;
|
|
1055
|
+
treeMetadata?: string | undefined;
|
|
1056
|
+
};
|
|
1055
1057
|
} & import("@jbrowse/mobx-state-tree")._NotCustomized>;
|
|
1056
1058
|
export type JBrowsePluginMsaViewStateModel = ReturnType<typeof stateModelFactory>;
|
|
1057
1059
|
export type JBrowsePluginMsaViewModel = Instance<JBrowsePluginMsaViewStateModel>;
|
|
@@ -5,7 +5,7 @@ import { genomeToTranscriptSeqMapping } from 'g2p_mapper';
|
|
|
5
5
|
import { autorun } from 'mobx';
|
|
6
6
|
import { MSAModelF } from 'react-msaview';
|
|
7
7
|
import { autoLoadProteinDomains, launchBlastIfNeeded, loadStoredData, observeProteinHighlights, processInit, runCleanup, storeDataToIndexedDB, syncGenomeHoverToMsaColumn, } from './afterCreateAutoruns';
|
|
8
|
-
import { msaCoordToGenomeCoord } from './msaCoordToGenomeCoord';
|
|
8
|
+
import { msaCoordToGenomeCoord, msaCoordToGenomeRegions, } from './msaCoordToGenomeCoord';
|
|
9
9
|
/**
|
|
10
10
|
* #stateModel MsaViewPlugin
|
|
11
11
|
* extends
|
|
@@ -119,35 +119,37 @@ export default function stateModelFactory() {
|
|
|
119
119
|
.views(self => ({
|
|
120
120
|
/**
|
|
121
121
|
* #getter
|
|
122
|
-
* Genome
|
|
122
|
+
* Genome regions under the current MSA hover column. Suppressed on the LGV
|
|
123
123
|
* while it's being hovered (GenomeMouseoverHighlight shows the crisp 1bp
|
|
124
124
|
* marker there instead of this wider codon band).
|
|
125
125
|
*/
|
|
126
|
-
get
|
|
126
|
+
get connectedHoverHighlights() {
|
|
127
127
|
const { mouseCol } = self;
|
|
128
128
|
return mouseCol === undefined
|
|
129
|
-
?
|
|
130
|
-
:
|
|
129
|
+
? []
|
|
130
|
+
: msaCoordToGenomeRegions({ model: self, coord: mouseCol });
|
|
131
131
|
},
|
|
132
132
|
/**
|
|
133
133
|
* #getter
|
|
134
|
-
* Genome
|
|
134
|
+
* Genome regions under the persistent MSA click selection. Shown
|
|
135
135
|
* regardless of LGV hover, so hovering the genome doesn't hide it.
|
|
136
136
|
*/
|
|
137
|
-
get
|
|
137
|
+
get connectedClickHighlights() {
|
|
138
138
|
const { mouseClickCol } = self;
|
|
139
139
|
return mouseClickCol === undefined
|
|
140
|
-
?
|
|
141
|
-
:
|
|
140
|
+
? []
|
|
141
|
+
: msaCoordToGenomeRegions({ model: self, coord: mouseClickCol });
|
|
142
142
|
},
|
|
143
143
|
/**
|
|
144
144
|
* #getter
|
|
145
|
+
* cross-plugin contract: jbrowse-plugin-mafviewer reads this off the view
|
|
146
|
+
* to draw the same highlights in its own display
|
|
145
147
|
*/
|
|
146
148
|
get connectedHighlights() {
|
|
147
149
|
return [
|
|
148
|
-
this.
|
|
149
|
-
this.
|
|
150
|
-
]
|
|
150
|
+
...this.connectedHoverHighlights,
|
|
151
|
+
...this.connectedClickHighlights,
|
|
152
|
+
];
|
|
151
153
|
},
|
|
152
154
|
}))
|
|
153
155
|
.actions(self => ({
|
|
@@ -1,17 +1,36 @@
|
|
|
1
1
|
import type { MafRegion } from './types';
|
|
2
|
-
|
|
3
|
-
model: {
|
|
4
|
-
querySeqName: string;
|
|
5
|
-
transcriptToMsaMap: {
|
|
6
|
-
refName: string;
|
|
7
|
-
p2g: Record<number, number>;
|
|
8
|
-
} | undefined;
|
|
9
|
-
mafRegion?: MafRegion;
|
|
10
|
-
rows: string[][];
|
|
11
|
-
};
|
|
12
|
-
coord: number;
|
|
13
|
-
}): {
|
|
2
|
+
interface GenomeRegion {
|
|
14
3
|
refName: string;
|
|
15
4
|
start: number;
|
|
16
5
|
end: number;
|
|
17
|
-
}
|
|
6
|
+
}
|
|
7
|
+
interface CoordModel {
|
|
8
|
+
querySeqName: string;
|
|
9
|
+
transcriptToMsaMap: {
|
|
10
|
+
refName: string;
|
|
11
|
+
p2gCodon: Record<number, number[]>;
|
|
12
|
+
} | undefined;
|
|
13
|
+
mafRegion?: MafRegion;
|
|
14
|
+
rows: string[][];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The genome regions covered by MSA column `coord` of the query row, in 0-based
|
|
18
|
+
* half-open coordinates (what bpToPx and navTo take).
|
|
19
|
+
*
|
|
20
|
+
* Usually one region -- one codon, or one base in a MAF alignment -- but a
|
|
21
|
+
* codon split across an exon boundary yields one region per contiguous piece,
|
|
22
|
+
* which is why this returns a list.
|
|
23
|
+
*/
|
|
24
|
+
export declare function msaCoordToGenomeRegions({ model, coord: mouseCol, }: {
|
|
25
|
+
model: CoordModel;
|
|
26
|
+
coord: number;
|
|
27
|
+
}): GenomeRegion[];
|
|
28
|
+
/**
|
|
29
|
+
* A single region spanning the codon at MSA column `coord`, for navigation. For
|
|
30
|
+
* a codon split across an exon boundary this spans the intervening intron.
|
|
31
|
+
*/
|
|
32
|
+
export declare function msaCoordToGenomeCoord(args: {
|
|
33
|
+
model: CoordModel;
|
|
34
|
+
coord: number;
|
|
35
|
+
}): GenomeRegion | undefined;
|
|
36
|
+
export {};
|