@jbrowse/plugin-sequence 2.13.0 → 2.14.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/ChromSizesAdapter/ChromSizesAdapter.js +2 -2
- package/dist/DivSequenceRenderer/components/DivSequenceRendering.js +19 -17
- package/dist/IndexedFastaAdapter/IndexedFastaAdapter.js +2 -2
- package/dist/LinearReferenceSequenceDisplay/model.d.ts +25 -5
- package/dist/LinearReferenceSequenceDisplay/model.js +69 -29
- package/dist/ReferenceSequenceTrack/configSchema.d.ts +16 -0
- package/dist/ReferenceSequenceTrack/configSchema.js +17 -2
- package/dist/SequenceSearchAdapter/SequenceSearchAdapter.js +1 -1
- package/dist/TwoBitAdapter/TwoBitAdapter.js +4 -1
- package/dist/UnindexedFastaAdapter/UnindexedFastaAdapter.d.ts +31 -0
- package/dist/UnindexedFastaAdapter/UnindexedFastaAdapter.js +87 -0
- package/dist/UnindexedFastaAdapter/configSchema.d.ts +29 -0
- package/dist/UnindexedFastaAdapter/configSchema.js +36 -0
- package/dist/UnindexedFastaAdapter/index.d.ts +2 -0
- package/dist/UnindexedFastaAdapter/index.js +42 -0
- package/dist/createExtensionPoints.js +3 -3
- package/dist/index.js +2 -0
- package/esm/ChromSizesAdapter/ChromSizesAdapter.js +2 -2
- package/esm/DivSequenceRenderer/components/DivSequenceRendering.js +19 -17
- package/esm/IndexedFastaAdapter/IndexedFastaAdapter.js +2 -2
- package/esm/LinearReferenceSequenceDisplay/model.d.ts +25 -5
- package/esm/LinearReferenceSequenceDisplay/model.js +71 -31
- package/esm/ReferenceSequenceTrack/configSchema.d.ts +16 -0
- package/esm/ReferenceSequenceTrack/configSchema.js +17 -2
- package/esm/SequenceSearchAdapter/SequenceSearchAdapter.js +1 -1
- package/esm/TwoBitAdapter/TwoBitAdapter.js +4 -1
- package/esm/UnindexedFastaAdapter/UnindexedFastaAdapter.d.ts +31 -0
- package/esm/UnindexedFastaAdapter/UnindexedFastaAdapter.js +84 -0
- package/esm/UnindexedFastaAdapter/configSchema.d.ts +29 -0
- package/esm/UnindexedFastaAdapter/configSchema.js +34 -0
- package/esm/UnindexedFastaAdapter/index.d.ts +2 -0
- package/esm/UnindexedFastaAdapter/index.js +13 -0
- package/esm/createExtensionPoints.js +3 -3
- package/esm/index.js +2 -0
- package/package.json +4 -4
|
@@ -15,7 +15,7 @@ function ExtensionPointsF(pluginManager) {
|
|
|
15
15
|
if (regexGuess.test(fileName) && !adapterHint) {
|
|
16
16
|
return obj;
|
|
17
17
|
}
|
|
18
|
-
|
|
18
|
+
if (adapterHint === adapterName) {
|
|
19
19
|
return obj;
|
|
20
20
|
}
|
|
21
21
|
return adapterGuesser(file, index, adapterHint);
|
|
@@ -42,7 +42,7 @@ function ExtensionPointsF(pluginManager) {
|
|
|
42
42
|
if (regexGuess.test(fileName) && !adapterHint) {
|
|
43
43
|
return obj;
|
|
44
44
|
}
|
|
45
|
-
|
|
45
|
+
if (adapterHint === adapterName) {
|
|
46
46
|
return obj;
|
|
47
47
|
}
|
|
48
48
|
return adapterGuesser(file, index, adapterHint);
|
|
@@ -69,7 +69,7 @@ function ExtensionPointsF(pluginManager) {
|
|
|
69
69
|
if (regexGuess.test(fileName) && !adapterHint) {
|
|
70
70
|
return obj;
|
|
71
71
|
}
|
|
72
|
-
|
|
72
|
+
if (adapterHint === adapterName) {
|
|
73
73
|
return obj;
|
|
74
74
|
}
|
|
75
75
|
return adapterGuesser(file, index, adapterHint);
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@ const DivSequenceRenderer_1 = __importDefault(require("./DivSequenceRenderer"));
|
|
|
9
9
|
const BgzipFastaAdapter_1 = __importDefault(require("./BgzipFastaAdapter"));
|
|
10
10
|
const ChromSizesAdapter_1 = __importDefault(require("./ChromSizesAdapter"));
|
|
11
11
|
const IndexedFastaAdapter_1 = __importDefault(require("./IndexedFastaAdapter"));
|
|
12
|
+
const UnindexedFastaAdapter_1 = __importDefault(require("./UnindexedFastaAdapter"));
|
|
12
13
|
const SequenceSearchAdapter_1 = __importDefault(require("./SequenceSearchAdapter"));
|
|
13
14
|
const ReferenceSequenceTrack_1 = __importDefault(require("./ReferenceSequenceTrack"));
|
|
14
15
|
const LinearReferenceSequenceDisplay_1 = __importDefault(require("./LinearReferenceSequenceDisplay"));
|
|
@@ -24,6 +25,7 @@ class SequencePlugin extends Plugin_1.default {
|
|
|
24
25
|
(0, BgzipFastaAdapter_1.default)(pluginManager);
|
|
25
26
|
(0, ChromSizesAdapter_1.default)(pluginManager);
|
|
26
27
|
(0, IndexedFastaAdapter_1.default)(pluginManager);
|
|
28
|
+
(0, UnindexedFastaAdapter_1.default)(pluginManager);
|
|
27
29
|
(0, SequenceSearchAdapter_1.default)(pluginManager);
|
|
28
30
|
(0, ReferenceSequenceTrack_1.default)(pluginManager);
|
|
29
31
|
(0, LinearReferenceSequenceDisplay_1.default)(pluginManager);
|
|
@@ -9,14 +9,14 @@ export default class ChromSizesAdapter extends BaseAdapter {
|
|
|
9
9
|
.split(/\n|\r\n|\r/)
|
|
10
10
|
.map(f => f.trim())
|
|
11
11
|
.filter(f => !!f)
|
|
12
|
-
.map(
|
|
12
|
+
.map(line => {
|
|
13
13
|
const [name, length] = line.split('\t');
|
|
14
14
|
return [name, +length];
|
|
15
15
|
}));
|
|
16
16
|
}
|
|
17
17
|
async setup() {
|
|
18
18
|
if (!this.setupP) {
|
|
19
|
-
this.setupP = this.setupPre().catch(e => {
|
|
19
|
+
this.setupP = this.setupPre().catch((e) => {
|
|
20
20
|
this.setupP = undefined;
|
|
21
21
|
throw e;
|
|
22
22
|
});
|
|
@@ -41,34 +41,36 @@ function Translation({ codonTable, seq, frame, bpPerPx, colorByCDS, region, seqS
|
|
|
41
41
|
: defaultStops.includes(codon)
|
|
42
42
|
? theme === null || theme === void 0 ? void 0 : theme.palette.stopCodon
|
|
43
43
|
: undefined;
|
|
44
|
-
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
47
|
-
return (React.createElement(React.Fragment, { key: `${index}-${letter}` },
|
|
44
|
+
return !(renderLetter || codonFill) ? null : (React.createElement(React.Fragment, { key: `${index}-${letter}` },
|
|
48
45
|
React.createElement("rect", { x: x, y: y, width: renderLetter
|
|
49
46
|
? codonWidth
|
|
50
47
|
: codonWidth + 0.7 /* small fudge factor when zoomed out*/, height: height, stroke: renderLetter ? '#555' : 'none', fill: codonFill || 'none' }),
|
|
51
48
|
renderLetter ? (React.createElement("text", { x: x + codonWidth / 2, fontSize: height - 2, y: y + height / 2, dominantBaseline: "middle", textAnchor: "middle" }, letter)) : null));
|
|
52
49
|
})));
|
|
53
50
|
}
|
|
54
|
-
function
|
|
55
|
-
const { bpPerPx, region, feature, theme, height, seq, y } = props;
|
|
51
|
+
function Sequence({ bpPerPx, region, feature, sequenceType, theme, height, seq, y, }) {
|
|
56
52
|
const render = 1 / bpPerPx >= 12;
|
|
57
|
-
const
|
|
53
|
+
const s = feature.get('start');
|
|
54
|
+
const e = feature.get('end');
|
|
55
|
+
const [leftPx, rightPx] = bpSpanPx(s, e, region, bpPerPx);
|
|
58
56
|
const reverse = region.reversed;
|
|
59
|
-
const len =
|
|
57
|
+
const len = e - s;
|
|
60
58
|
const w = Math.max((rightPx - leftPx) / len, 0.8);
|
|
61
59
|
return (React.createElement(React.Fragment, null, seq.split('').map((letter, index) => {
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
const color = sequenceType === 'dna'
|
|
61
|
+
? // @ts-expect-error
|
|
62
|
+
theme.palette.bases[letter.toUpperCase()]
|
|
63
|
+
: undefined;
|
|
64
64
|
const x = reverse ? rightPx - (index + 1) * w : leftPx + index * w;
|
|
65
|
-
return (
|
|
65
|
+
return (
|
|
66
|
+
/* biome-ignore lint/suspicious/noArrayIndexKey: */
|
|
67
|
+
React.createElement(React.Fragment, { key: `${letter}-${index}` },
|
|
66
68
|
React.createElement("rect", { x: x, y: y, width: w, height: height, fill: color ? color.main : '#aaa', stroke: render ? '#555' : 'none' }),
|
|
67
69
|
render ? (React.createElement("text", { x: x + w / 2, y: y + height / 2, dominantBaseline: "middle", textAnchor: "middle", fontSize: height - 2, fill: color ? theme.palette.getContrastText(color.main) : 'black' }, letter)) : null));
|
|
68
70
|
})));
|
|
69
71
|
}
|
|
70
|
-
function SequenceSVG({ regions, theme: configTheme, colorByCDS, features = new Map(), showReverse = true, showForward = true, showTranslation = true, bpPerPx, rowHeight, }) {
|
|
71
|
-
const
|
|
72
|
+
function SequenceSVG({ regions, theme: configTheme, colorByCDS, features = new Map(), showReverse = true, showForward = true, showTranslation = true, sequenceType = 'dna', bpPerPx, rowHeight, }) {
|
|
73
|
+
const region = regions[0];
|
|
72
74
|
const theme = createJBrowseTheme(configTheme);
|
|
73
75
|
const codonTable = generateCodonTable(defaultCodonTable);
|
|
74
76
|
const [feature] = [...features.values()];
|
|
@@ -82,7 +84,7 @@ function SequenceSVG({ regions, theme: configTheme, colorByCDS, features = new M
|
|
|
82
84
|
// incrementer for the y-position of the current sequence being rendered
|
|
83
85
|
// (applies to both translation rows and dna rows)
|
|
84
86
|
let currY = -rowHeight;
|
|
85
|
-
const
|
|
87
|
+
const showSequence = bpPerPx <= 1;
|
|
86
88
|
const forwardFrames = showTranslation && showForward ? [3, 2, 1] : [];
|
|
87
89
|
const reverseFrames = showTranslation && showReverse ? [-1, -2, -3] : [];
|
|
88
90
|
// if region.reversed, the forward translation is on bottom, reverse on top
|
|
@@ -91,8 +93,8 @@ function SequenceSVG({ regions, theme: configTheme, colorByCDS, features = new M
|
|
|
91
93
|
: [forwardFrames, reverseFrames];
|
|
92
94
|
return (React.createElement(React.Fragment, null,
|
|
93
95
|
topFrames.map(index => (React.createElement(Translation, { key: `translation-${index}`, colorByCDS: colorByCDS, seq: seq, y: (currY += rowHeight), codonTable: codonTable, frame: index, bpPerPx: bpPerPx, region: region, seqStart: feature.get('start'), theme: theme, height: rowHeight, reverse: region.reversed }))),
|
|
94
|
-
showForward &&
|
|
95
|
-
showReverse &&
|
|
96
|
+
showForward && showSequence ? (React.createElement(Sequence, { height: rowHeight, sequenceType: sequenceType, y: (currY += rowHeight), feature: feature, region: region, seq: region.reversed ? complement(seq) : seq, bpPerPx: bpPerPx, theme: theme })) : null,
|
|
97
|
+
showReverse && showSequence ? (React.createElement(Sequence, { height: rowHeight, sequenceType: sequenceType, y: (currY += rowHeight), feature: feature, region: region, seq: region.reversed ? seq : complement(seq), bpPerPx: bpPerPx, theme: theme })) : null,
|
|
96
98
|
bottomFrames.map(index => (React.createElement(Translation, { key: `rev-translation-${index}`, colorByCDS: colorByCDS, seq: seq, y: (currY += rowHeight), codonTable: codonTable, frame: index, bpPerPx: bpPerPx, region: region, seqStart: feature.get('start'), theme: theme, height: rowHeight, reverse: !region.reversed })))));
|
|
97
99
|
}
|
|
98
100
|
function Wrapper({ exportSVG, width, totalHeight, children, }) {
|
|
@@ -106,7 +108,7 @@ function Wrapper({ exportSVG, width, totalHeight, children, }) {
|
|
|
106
108
|
}
|
|
107
109
|
const DivSequenceRendering = observer(function (props) {
|
|
108
110
|
const { regions, bpPerPx, sequenceHeight } = props;
|
|
109
|
-
const
|
|
111
|
+
const region = regions[0];
|
|
110
112
|
const width = (region.end - region.start) / bpPerPx;
|
|
111
113
|
return (React.createElement(Wrapper, { ...props, totalHeight: sequenceHeight, width: width },
|
|
112
114
|
React.createElement(SequenceSVG, { ...props })));
|
|
@@ -47,7 +47,7 @@ export default class IndexedFastaAdapter extends BaseSequenceAdapter {
|
|
|
47
47
|
}
|
|
48
48
|
async setup() {
|
|
49
49
|
if (!this.setupP) {
|
|
50
|
-
this.setupP = this.setupPre().catch(e => {
|
|
50
|
+
this.setupP = this.setupPre().catch((e) => {
|
|
51
51
|
this.setupP = undefined;
|
|
52
52
|
throw e;
|
|
53
53
|
});
|
|
@@ -59,7 +59,7 @@ export default class IndexedFastaAdapter extends BaseSequenceAdapter {
|
|
|
59
59
|
return ObservableCreate(async (observer) => {
|
|
60
60
|
const { fasta } = await this.setup();
|
|
61
61
|
const size = await fasta.getSequenceSize(refName, opts);
|
|
62
|
-
const regionEnd =
|
|
62
|
+
const regionEnd = Math.min(size, end);
|
|
63
63
|
const chunks = [];
|
|
64
64
|
const chunkSize = 128000;
|
|
65
65
|
const s = start - (start % chunkSize);
|
|
@@ -18,7 +18,9 @@ export declare function modelFactory(configSchema: AnyConfigurationSchemaType):
|
|
|
18
18
|
region: import("mobx-state-tree").IModelType<{
|
|
19
19
|
refName: import("mobx-state-tree").ISimpleType<string>;
|
|
20
20
|
start: import("mobx-state-tree").ISimpleType<number>;
|
|
21
|
-
end: import("mobx-state-tree"
|
|
21
|
+
end: import("mobx-state-tree" /**
|
|
22
|
+
* #property
|
|
23
|
+
*/).ISimpleType<number>;
|
|
22
24
|
reversed: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
23
25
|
} & {
|
|
24
26
|
assemblyName: import("mobx-state-tree").ISimpleType<string>;
|
|
@@ -123,7 +125,7 @@ export declare function modelFactory(configSchema: AnyConfigurationSchemaType):
|
|
|
123
125
|
error: unknown;
|
|
124
126
|
message: string | undefined;
|
|
125
127
|
}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
|
|
126
|
-
onHorizontalScroll?:
|
|
128
|
+
onHorizontalScroll?: () => void;
|
|
127
129
|
blockState?: Record<string, any>;
|
|
128
130
|
}>;
|
|
129
131
|
readonly DisplayBlurb: import("react").FC<{
|
|
@@ -143,9 +145,7 @@ export declare function modelFactory(configSchema: AnyConfigurationSchemaType):
|
|
|
143
145
|
rendererTypeName: string;
|
|
144
146
|
error: unknown;
|
|
145
147
|
message: string | undefined;
|
|
146
|
-
}, import("mobx-state-tree"
|
|
147
|
-
* #action
|
|
148
|
-
*/)._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
|
|
148
|
+
}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
|
|
149
149
|
}> | null;
|
|
150
150
|
readonly adapterConfig: any;
|
|
151
151
|
readonly parentTrack: any;
|
|
@@ -232,6 +232,26 @@ export declare function modelFactory(configSchema: AnyConfigurationSchemaType):
|
|
|
232
232
|
* #property
|
|
233
233
|
*/
|
|
234
234
|
rowHeight: number;
|
|
235
|
+
} & {
|
|
236
|
+
/**
|
|
237
|
+
* #getter
|
|
238
|
+
*/
|
|
239
|
+
readonly sequenceType: any;
|
|
240
|
+
/**
|
|
241
|
+
* #getter
|
|
242
|
+
* showReverse setting, it is NOT disabled for non-dna sequences
|
|
243
|
+
*/
|
|
244
|
+
readonly showForwardActual: boolean;
|
|
245
|
+
/**
|
|
246
|
+
* #getter
|
|
247
|
+
* showReverse setting, is disabled for non-dna sequences
|
|
248
|
+
*/
|
|
249
|
+
readonly showReverseActual: boolean;
|
|
250
|
+
/**
|
|
251
|
+
* #getter
|
|
252
|
+
* showTranslation setting is disabled for non-dna sequences
|
|
253
|
+
*/
|
|
254
|
+
readonly showTranslationActual: boolean;
|
|
235
255
|
} & {
|
|
236
256
|
/**
|
|
237
257
|
* #getter
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { addDisposer, types } from 'mobx-state-tree';
|
|
2
2
|
import { BaseLinearDisplay, } from '@jbrowse/plugin-linear-genome-view';
|
|
3
|
-
import { ConfigurationReference, } from '@jbrowse/core/configuration';
|
|
3
|
+
import { ConfigurationReference, getConf, } from '@jbrowse/core/configuration';
|
|
4
4
|
import { getParentRenderProps } from '@jbrowse/core/util/tracks';
|
|
5
|
-
import { getContainingView } from '@jbrowse/core/util';
|
|
5
|
+
import { getContainingTrack, getContainingView } from '@jbrowse/core/util';
|
|
6
6
|
import { autorun } from 'mobx';
|
|
7
7
|
/**
|
|
8
8
|
* #stateModel LinearReferenceSequenceDisplay
|
|
@@ -37,18 +37,47 @@ export function modelFactory(configSchema) {
|
|
|
37
37
|
* #property
|
|
38
38
|
*/
|
|
39
39
|
rowHeight: 15,
|
|
40
|
+
}))
|
|
41
|
+
.views(self => ({
|
|
42
|
+
/**
|
|
43
|
+
* #getter
|
|
44
|
+
*/
|
|
45
|
+
get sequenceType() {
|
|
46
|
+
return getConf(getContainingTrack(self), 'sequenceType');
|
|
47
|
+
},
|
|
48
|
+
/**
|
|
49
|
+
* #getter
|
|
50
|
+
* showReverse setting, it is NOT disabled for non-dna sequences
|
|
51
|
+
*/
|
|
52
|
+
get showForwardActual() {
|
|
53
|
+
return self.showForward;
|
|
54
|
+
},
|
|
55
|
+
/**
|
|
56
|
+
* #getter
|
|
57
|
+
* showReverse setting, is disabled for non-dna sequences
|
|
58
|
+
*/
|
|
59
|
+
get showReverseActual() {
|
|
60
|
+
return this.sequenceType === 'dna' ? self.showReverse : false;
|
|
61
|
+
},
|
|
62
|
+
/**
|
|
63
|
+
* #getter
|
|
64
|
+
* showTranslation setting is disabled for non-dna sequences
|
|
65
|
+
*/
|
|
66
|
+
get showTranslationActual() {
|
|
67
|
+
return this.sequenceType === 'dna' ? self.showTranslation : false;
|
|
68
|
+
},
|
|
40
69
|
}))
|
|
41
70
|
.views(self => ({
|
|
42
71
|
/**
|
|
43
72
|
* #getter
|
|
44
73
|
*/
|
|
45
74
|
get sequenceHeight() {
|
|
46
|
-
const {
|
|
47
|
-
const r1 =
|
|
48
|
-
const r2 =
|
|
75
|
+
const { rowHeight, showTranslationActual, showReverseActual, showForwardActual, } = self;
|
|
76
|
+
const r1 = showReverseActual && showTranslationActual ? rowHeight * 3 : 0;
|
|
77
|
+
const r2 = showForwardActual && showTranslationActual ? rowHeight * 3 : 0;
|
|
49
78
|
const t = r1 + r2;
|
|
50
|
-
const r =
|
|
51
|
-
const s =
|
|
79
|
+
const r = showReverseActual ? rowHeight : 0;
|
|
80
|
+
const s = showForwardActual ? rowHeight : 0;
|
|
52
81
|
return t + r + s;
|
|
53
82
|
},
|
|
54
83
|
}))
|
|
@@ -59,15 +88,16 @@ export function modelFactory(configSchema) {
|
|
|
59
88
|
* #method
|
|
60
89
|
*/
|
|
61
90
|
renderProps() {
|
|
62
|
-
const {
|
|
91
|
+
const { rpcDriverName, showForwardActual, showReverseActual, showTranslationActual, rowHeight, sequenceHeight, sequenceType, } = self;
|
|
63
92
|
return {
|
|
64
93
|
...superRenderProps(),
|
|
65
94
|
...getParentRenderProps(self),
|
|
66
95
|
config: self.configuration.renderer,
|
|
67
96
|
rpcDriverName,
|
|
68
|
-
showForward,
|
|
69
|
-
showReverse,
|
|
70
|
-
showTranslation,
|
|
97
|
+
showForward: showForwardActual,
|
|
98
|
+
showReverse: showReverseActual,
|
|
99
|
+
showTranslation: showTranslationActual,
|
|
100
|
+
sequenceType,
|
|
71
101
|
rowHeight,
|
|
72
102
|
sequenceHeight,
|
|
73
103
|
};
|
|
@@ -80,7 +110,7 @@ export function modelFactory(configSchema) {
|
|
|
80
110
|
*/
|
|
81
111
|
regionCannotBeRendered( /* region */) {
|
|
82
112
|
const view = getContainingView(self);
|
|
83
|
-
return
|
|
113
|
+
return view.bpPerPx > 3 ? 'Zoom in to see sequence' : undefined;
|
|
84
114
|
},
|
|
85
115
|
/**
|
|
86
116
|
* #getter
|
|
@@ -111,7 +141,7 @@ export function modelFactory(configSchema) {
|
|
|
111
141
|
afterAttach() {
|
|
112
142
|
addDisposer(self, autorun(() => {
|
|
113
143
|
const view = getContainingView(self);
|
|
114
|
-
if (
|
|
144
|
+
if (view.bpPerPx > 3) {
|
|
115
145
|
self.setHeight(50);
|
|
116
146
|
}
|
|
117
147
|
else {
|
|
@@ -126,24 +156,34 @@ export function modelFactory(configSchema) {
|
|
|
126
156
|
*/
|
|
127
157
|
trackMenuItems() {
|
|
128
158
|
return [
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
159
|
+
...(self.sequenceType === 'dna'
|
|
160
|
+
? [
|
|
161
|
+
{
|
|
162
|
+
label: 'Show forward',
|
|
163
|
+
type: 'checkbox',
|
|
164
|
+
checked: self.showForward,
|
|
165
|
+
onClick: () => {
|
|
166
|
+
self.toggleShowForward();
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
label: 'Show reverse',
|
|
171
|
+
type: 'checkbox',
|
|
172
|
+
checked: self.showReverse,
|
|
173
|
+
onClick: () => {
|
|
174
|
+
self.toggleShowReverse();
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
label: 'Show translation',
|
|
179
|
+
type: 'checkbox',
|
|
180
|
+
checked: self.showTranslation,
|
|
181
|
+
onClick: () => {
|
|
182
|
+
self.toggleShowTranslation();
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
]
|
|
186
|
+
: []),
|
|
147
187
|
];
|
|
148
188
|
},
|
|
149
189
|
}));
|
|
@@ -18,6 +18,22 @@ export declare function createReferenceSeqTrackConfig(pluginManager: PluginManag
|
|
|
18
18
|
description: string;
|
|
19
19
|
defaultValue: string;
|
|
20
20
|
};
|
|
21
|
+
/**
|
|
22
|
+
* #slot
|
|
23
|
+
*/
|
|
24
|
+
sequenceType: {
|
|
25
|
+
type: string;
|
|
26
|
+
description: string;
|
|
27
|
+
defaultValue: string;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* #slot
|
|
31
|
+
*/
|
|
32
|
+
description: {
|
|
33
|
+
description: string;
|
|
34
|
+
type: string;
|
|
35
|
+
defaultValue: string;
|
|
36
|
+
};
|
|
21
37
|
/**
|
|
22
38
|
* #slot
|
|
23
39
|
*/
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
1
|
import { types } from 'mobx-state-tree';
|
|
3
2
|
import { ConfigurationSchema } from '@jbrowse/core/configuration';
|
|
4
3
|
// Note: this is primarily a copy of createBaseTrackConfig, except with a
|
|
@@ -29,6 +28,22 @@ export function createReferenceSeqTrackConfig(pluginManager) {
|
|
|
29
28
|
description: 'optional track name, otherwise uses the "Reference sequence (assemblyName)"',
|
|
30
29
|
defaultValue: '',
|
|
31
30
|
},
|
|
31
|
+
/**
|
|
32
|
+
* #slot
|
|
33
|
+
*/
|
|
34
|
+
sequenceType: {
|
|
35
|
+
type: 'string',
|
|
36
|
+
description: 'either dna or pep',
|
|
37
|
+
defaultValue: 'dna',
|
|
38
|
+
},
|
|
39
|
+
/**
|
|
40
|
+
* #slot
|
|
41
|
+
*/
|
|
42
|
+
description: {
|
|
43
|
+
description: 'a description of the track',
|
|
44
|
+
type: 'string',
|
|
45
|
+
defaultValue: '',
|
|
46
|
+
},
|
|
32
47
|
/**
|
|
33
48
|
* #slot
|
|
34
49
|
*/
|
|
@@ -66,7 +81,7 @@ export function createReferenceSeqTrackConfig(pluginManager) {
|
|
|
66
81
|
// snapshot
|
|
67
82
|
displays.forEach((d) => d && displayTypes.add(d.type));
|
|
68
83
|
const trackType = pluginManager.getTrackType(snap.type);
|
|
69
|
-
trackType.displayTypes.forEach(displayType => {
|
|
84
|
+
trackType === null || trackType === void 0 ? void 0 : trackType.displayTypes.forEach(displayType => {
|
|
70
85
|
if (!displayTypes.has(displayType.name)) {
|
|
71
86
|
displays.push({
|
|
72
87
|
displayId: `${snap.trackId}-${displayType.name}`,
|
|
@@ -38,7 +38,7 @@ export default class SequenceSearchAdapter extends BaseFeatureDataAdapter {
|
|
|
38
38
|
const searchForward = this.getConf('searchForward');
|
|
39
39
|
const searchReverse = this.getConf('searchReverse');
|
|
40
40
|
const caseInsensitive = this.getConf('caseInsensitive');
|
|
41
|
-
const re = new RegExp(search,
|
|
41
|
+
const re = new RegExp(search, `g${caseInsensitive ? 'i' : ''}`);
|
|
42
42
|
if (search) {
|
|
43
43
|
if (searchForward) {
|
|
44
44
|
const matches = residues.matchAll(re);
|
|
@@ -13,7 +13,10 @@ export default class TwoBitAdapter extends BaseSequenceAdapter {
|
|
|
13
13
|
if (conf.uri !== '/path/to/default.chrom.sizes' && conf.uri !== '') {
|
|
14
14
|
const file = openLocation(conf, this.pluginManager);
|
|
15
15
|
const data = await file.readFile('utf8');
|
|
16
|
-
return Object.fromEntries(data
|
|
16
|
+
return Object.fromEntries(data
|
|
17
|
+
.split(/\n|\r\n|\r/)
|
|
18
|
+
.filter(line => !!line.trim())
|
|
19
|
+
.map(line => {
|
|
17
20
|
const [name, length] = line.split('\t');
|
|
18
21
|
return [name, +length];
|
|
19
22
|
}));
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { BaseSequenceAdapter, BaseOptions } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
2
|
+
import { NoAssemblyRegion } from '@jbrowse/core/util/types';
|
|
3
|
+
import { Feature } from '@jbrowse/core/util';
|
|
4
|
+
declare function parseSmallFasta(text: string): Map<string, {
|
|
5
|
+
readonly description: string;
|
|
6
|
+
readonly sequence: string;
|
|
7
|
+
}>;
|
|
8
|
+
export default class UnindexedFastaAdapter extends BaseSequenceAdapter {
|
|
9
|
+
protected setupP?: Promise<{
|
|
10
|
+
fasta: ReturnType<typeof parseSmallFasta>;
|
|
11
|
+
}>;
|
|
12
|
+
getRefNames(opts?: BaseOptions): Promise<string[]>;
|
|
13
|
+
getRegions(opts?: BaseOptions): Promise<{
|
|
14
|
+
refName: string;
|
|
15
|
+
start: number;
|
|
16
|
+
end: number;
|
|
17
|
+
}[]>;
|
|
18
|
+
setupPre(_opts?: BaseOptions): Promise<{
|
|
19
|
+
fasta: Map<any, {
|
|
20
|
+
readonly description: string;
|
|
21
|
+
readonly sequence: string;
|
|
22
|
+
}>;
|
|
23
|
+
}>;
|
|
24
|
+
getHeader(): Promise<string | null>;
|
|
25
|
+
setup(opts?: BaseOptions): Promise<{
|
|
26
|
+
fasta: ReturnType<typeof parseSmallFasta>;
|
|
27
|
+
}>;
|
|
28
|
+
getFeatures(region: NoAssemblyRegion, opts?: BaseOptions): import("rxjs").Observable<Feature>;
|
|
29
|
+
freeResources(): void;
|
|
30
|
+
}
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { BaseSequenceAdapter, } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
2
|
+
import { openLocation } from '@jbrowse/core/util/io';
|
|
3
|
+
import { ObservableCreate } from '@jbrowse/core/util/rxjs';
|
|
4
|
+
import { SimpleFeature } from '@jbrowse/core/util';
|
|
5
|
+
import { readConfObject } from '@jbrowse/core/configuration';
|
|
6
|
+
function parseSmallFasta(text) {
|
|
7
|
+
return new Map(text
|
|
8
|
+
.split('>')
|
|
9
|
+
.filter(t => /\S/.test(t))
|
|
10
|
+
.map(entryText => {
|
|
11
|
+
const [defLine, ...seqLines] = entryText.split('\n');
|
|
12
|
+
const [id, ...description] = defLine.split(' ');
|
|
13
|
+
const sequence = seqLines.join('').replace(/\s/g, '');
|
|
14
|
+
return [
|
|
15
|
+
id,
|
|
16
|
+
{
|
|
17
|
+
description: description.join(' '),
|
|
18
|
+
sequence,
|
|
19
|
+
},
|
|
20
|
+
];
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
export default class UnindexedFastaAdapter extends BaseSequenceAdapter {
|
|
24
|
+
async getRefNames(opts) {
|
|
25
|
+
const { fasta } = await this.setup(opts);
|
|
26
|
+
return [...fasta.keys()];
|
|
27
|
+
}
|
|
28
|
+
async getRegions(opts) {
|
|
29
|
+
const { fasta } = await this.setup(opts);
|
|
30
|
+
return [...fasta.entries()].map(([refName, data]) => ({
|
|
31
|
+
refName,
|
|
32
|
+
start: 0,
|
|
33
|
+
end: data.sequence.length,
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
36
|
+
async setupPre(_opts) {
|
|
37
|
+
const fastaLocation = this.getConf('fastaLocation');
|
|
38
|
+
const res = parseSmallFasta(await openLocation(fastaLocation, this.pluginManager).readFile('utf8'));
|
|
39
|
+
return {
|
|
40
|
+
fasta: new Map([...res.entries()].map(([refName, val]) => {
|
|
41
|
+
return [
|
|
42
|
+
readConfObject(this.config, 'rewriteRefNames', { refName }) ||
|
|
43
|
+
refName,
|
|
44
|
+
val,
|
|
45
|
+
];
|
|
46
|
+
})),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
async getHeader() {
|
|
50
|
+
const loc = this.getConf('metadataLocation');
|
|
51
|
+
return loc.uri === '' || loc.uri === '/path/to/fa.metadata.yaml'
|
|
52
|
+
? null
|
|
53
|
+
: openLocation(loc, this.pluginManager).readFile('utf8');
|
|
54
|
+
}
|
|
55
|
+
async setup(opts) {
|
|
56
|
+
if (!this.setupP) {
|
|
57
|
+
this.setupP = this.setupPre(opts).catch((e) => {
|
|
58
|
+
this.setupP = undefined;
|
|
59
|
+
throw e;
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return this.setupP;
|
|
63
|
+
}
|
|
64
|
+
getFeatures(region, opts) {
|
|
65
|
+
const { refName, start, end } = region;
|
|
66
|
+
return ObservableCreate(async (observer) => {
|
|
67
|
+
const { fasta } = await this.setup(opts);
|
|
68
|
+
const entry = fasta.get(refName);
|
|
69
|
+
if (entry) {
|
|
70
|
+
observer.next(new SimpleFeature({
|
|
71
|
+
id: `${refName}-${start}-${end}`,
|
|
72
|
+
data: {
|
|
73
|
+
refName,
|
|
74
|
+
start,
|
|
75
|
+
end,
|
|
76
|
+
seq: entry.sequence.slice(start, end),
|
|
77
|
+
},
|
|
78
|
+
}));
|
|
79
|
+
}
|
|
80
|
+
observer.complete();
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
freeResources( /* { region } */) { }
|
|
84
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
declare const UnindexedFastaAdapter: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
|
|
2
|
+
rewriteRefNames: {
|
|
3
|
+
type: string;
|
|
4
|
+
defaultValue: string;
|
|
5
|
+
contextVariable: string[];
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* #slot
|
|
9
|
+
*/
|
|
10
|
+
fastaLocation: {
|
|
11
|
+
type: string;
|
|
12
|
+
defaultValue: {
|
|
13
|
+
uri: string;
|
|
14
|
+
locationType: string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* #slot
|
|
19
|
+
*/
|
|
20
|
+
metadataLocation: {
|
|
21
|
+
description: string;
|
|
22
|
+
type: string;
|
|
23
|
+
defaultValue: {
|
|
24
|
+
uri: string;
|
|
25
|
+
locationType: string;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
|
|
29
|
+
export default UnindexedFastaAdapter;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ConfigurationSchema } from '@jbrowse/core/configuration';
|
|
2
|
+
/**
|
|
3
|
+
* #config UnindexedFastaAdapter
|
|
4
|
+
*/
|
|
5
|
+
function x() { } // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
6
|
+
const UnindexedFastaAdapter = ConfigurationSchema('UnindexedFastaAdapter', {
|
|
7
|
+
rewriteRefNames: {
|
|
8
|
+
type: 'string',
|
|
9
|
+
defaultValue: '',
|
|
10
|
+
contextVariable: ['refName'],
|
|
11
|
+
},
|
|
12
|
+
/**
|
|
13
|
+
* #slot
|
|
14
|
+
*/
|
|
15
|
+
fastaLocation: {
|
|
16
|
+
type: 'fileLocation',
|
|
17
|
+
defaultValue: {
|
|
18
|
+
uri: '/path/to/seq.fa',
|
|
19
|
+
locationType: 'UriLocation',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
/**
|
|
23
|
+
* #slot
|
|
24
|
+
*/
|
|
25
|
+
metadataLocation: {
|
|
26
|
+
description: 'Optional metadata file',
|
|
27
|
+
type: 'fileLocation',
|
|
28
|
+
defaultValue: {
|
|
29
|
+
uri: '/path/to/fa.metadata.yaml',
|
|
30
|
+
locationType: 'UriLocation',
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
}, { explicitlyTyped: true });
|
|
34
|
+
export default UnindexedFastaAdapter;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import AdapterType from '@jbrowse/core/pluggableElementTypes/AdapterType';
|
|
2
|
+
import configSchema from './configSchema';
|
|
3
|
+
export default function UnindexedFastaAdapterF(pluginManager) {
|
|
4
|
+
pluginManager.addAdapterType(() => new AdapterType({
|
|
5
|
+
name: 'UnindexedFastaAdapter',
|
|
6
|
+
displayName: 'Unindexed FASTA adapter',
|
|
7
|
+
configSchema,
|
|
8
|
+
adapterMetadata: {
|
|
9
|
+
hiddenFromGUI: true,
|
|
10
|
+
},
|
|
11
|
+
getAdapterClass: () => import('./UnindexedFastaAdapter').then(r => r.default),
|
|
12
|
+
}));
|
|
13
|
+
}
|