@jbrowse/plugin-bed 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/BedAdapter/BedAdapter.js +9 -9
- package/dist/BedpeAdapter/BedpeAdapter.d.ts +2 -2
- package/dist/BedpeAdapter/BedpeAdapter.js +12 -16
- package/dist/BigBedAdapter/BigBedAdapter.d.ts +1 -1
- package/dist/BigBedAdapter/BigBedAdapter.js +4 -4
- package/dist/index.js +1 -1
- package/dist/util.d.ts +2 -2
- package/dist/util.js +16 -15
- package/esm/BedAdapter/BedAdapter.js +6 -6
- package/esm/BedpeAdapter/BedpeAdapter.d.ts +2 -2
- package/esm/BedpeAdapter/BedpeAdapter.js +12 -16
- package/esm/BigBedAdapter/BigBedAdapter.d.ts +1 -1
- package/esm/BigBedAdapter/BigBedAdapter.js +4 -4
- package/esm/index.js +1 -1
- package/esm/util.d.ts +2 -2
- package/esm/util.js +16 -15
- package/package.json +4 -4
|
@@ -7,13 +7,11 @@ const bed_1 = __importDefault(require("@gmod/bed"));
|
|
|
7
7
|
const BaseAdapter_1 = require("@jbrowse/core/data_adapters/BaseAdapter");
|
|
8
8
|
const io_1 = require("@jbrowse/core/util/io");
|
|
9
9
|
const rxjs_1 = require("@jbrowse/core/util/rxjs");
|
|
10
|
+
const util_1 = require("@jbrowse/core/util");
|
|
10
11
|
const interval_tree_1 = __importDefault(require("@flatten-js/interval-tree"));
|
|
11
12
|
const bgzf_filehandle_1 = require("@gmod/bgzf-filehandle");
|
|
12
13
|
// locals
|
|
13
|
-
const
|
|
14
|
-
function isGzip(buf) {
|
|
15
|
-
return buf[0] === 31 && buf[1] === 139 && buf[2] === 8;
|
|
16
|
-
}
|
|
14
|
+
const util_2 = require("../util");
|
|
17
15
|
class BedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
18
16
|
constructor() {
|
|
19
17
|
super(...arguments);
|
|
@@ -23,7 +21,7 @@ class BedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
23
21
|
const pm = this.pluginManager;
|
|
24
22
|
const bedLoc = this.getConf('bedLocation');
|
|
25
23
|
const buf = await (0, io_1.openLocation)(bedLoc, pm).readFile(opts);
|
|
26
|
-
const buffer = isGzip(buf) ? await (0, bgzf_filehandle_1.unzip)(buf) : buf;
|
|
24
|
+
const buffer = (0, util_1.isGzip)(buf) ? await (0, bgzf_filehandle_1.unzip)(buf) : buf;
|
|
27
25
|
// 512MB max chrome string length is 512MB
|
|
28
26
|
if (buffer.length > 536870888) {
|
|
29
27
|
throw new Error('Data exceeds maximum string length (512MB)');
|
|
@@ -66,7 +64,7 @@ class BedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
66
64
|
}
|
|
67
65
|
async loadData(opts = {}) {
|
|
68
66
|
if (!this.bedFeatures) {
|
|
69
|
-
this.bedFeatures = this.loadDataP(opts).catch(e => {
|
|
67
|
+
this.bedFeatures = this.loadDataP(opts).catch((e) => {
|
|
70
68
|
this.bedFeatures = undefined;
|
|
71
69
|
throw e;
|
|
72
70
|
});
|
|
@@ -105,7 +103,7 @@ class BedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
105
103
|
const intervalTree = new interval_tree_1.default();
|
|
106
104
|
const ret = lines.map((f, i) => {
|
|
107
105
|
const uniqueId = `${this.id}-${refName}-${i}`;
|
|
108
|
-
return (0,
|
|
106
|
+
return (0, util_2.featureData)(f, colRef, colStart, colEnd, scoreColumn, parser, uniqueId, names);
|
|
109
107
|
});
|
|
110
108
|
for (const obj of ret) {
|
|
111
109
|
intervalTree.insert([obj.get('start'), obj.get('end')], obj);
|
|
@@ -114,7 +112,7 @@ class BedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
114
112
|
}
|
|
115
113
|
async loadFeatureIntervalTree(refName) {
|
|
116
114
|
if (!this.intervalTrees[refName]) {
|
|
117
|
-
this.intervalTrees[refName] = this.loadFeatureIntervalTreeHelper(refName).catch(e => {
|
|
115
|
+
this.intervalTrees[refName] = this.loadFeatureIntervalTreeHelper(refName).catch((e) => {
|
|
118
116
|
this.intervalTrees[refName] = undefined;
|
|
119
117
|
throw e;
|
|
120
118
|
});
|
|
@@ -125,7 +123,9 @@ class BedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
125
123
|
return (0, rxjs_1.ObservableCreate)(async (observer) => {
|
|
126
124
|
const { start, end, refName } = query;
|
|
127
125
|
const intervalTree = await this.loadFeatureIntervalTree(refName);
|
|
128
|
-
intervalTree === null || intervalTree === void 0 ? void 0 : intervalTree.search([start, end]).forEach(f =>
|
|
126
|
+
intervalTree === null || intervalTree === void 0 ? void 0 : intervalTree.search([start, end]).forEach(f => {
|
|
127
|
+
observer.next(f);
|
|
128
|
+
});
|
|
129
129
|
observer.complete();
|
|
130
130
|
}, opts.signal);
|
|
131
131
|
}
|
|
@@ -5,8 +5,8 @@ export declare function featureData(line: string, uniqueId: string, flip: boolea
|
|
|
5
5
|
export default class BedpeAdapter extends BaseFeatureDataAdapter {
|
|
6
6
|
protected bedpeFeatures?: Promise<{
|
|
7
7
|
header: string;
|
|
8
|
-
feats1: Record<string, string[]
|
|
9
|
-
feats2: Record<string, string[]
|
|
8
|
+
feats1: Record<string, string[]>;
|
|
9
|
+
feats2: Record<string, string[]>;
|
|
10
10
|
columnNames: string[];
|
|
11
11
|
}>;
|
|
12
12
|
protected intervalTrees: Record<string, Promise<IntervalTree | undefined> | undefined>;
|
|
@@ -10,9 +10,6 @@ const rxjs_1 = require("@jbrowse/core/util/rxjs");
|
|
|
10
10
|
const util_1 = require("@jbrowse/core/util");
|
|
11
11
|
const interval_tree_1 = __importDefault(require("@flatten-js/interval-tree"));
|
|
12
12
|
const bgzf_filehandle_1 = require("@gmod/bgzf-filehandle");
|
|
13
|
-
function isGzip(buf) {
|
|
14
|
-
return buf[0] === 31 && buf[1] === 139 && buf[2] === 8;
|
|
15
|
-
}
|
|
16
13
|
function featureData(line, uniqueId, flip, names) {
|
|
17
14
|
const l = line.split('\t');
|
|
18
15
|
const ref1 = l[flip ? 3 : 0];
|
|
@@ -29,10 +26,9 @@ function featureData(line, uniqueId, flip, names) {
|
|
|
29
26
|
const rest = names
|
|
30
27
|
? Object.fromEntries(names.slice(10).map((n, idx) => [n, extra[idx]]))
|
|
31
28
|
: extra;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
29
|
+
const ALT = ['DUP', 'TRA', 'INV', 'CNV', 'DEL'].includes(extra[0])
|
|
30
|
+
? `<${extra[0]}>`
|
|
31
|
+
: undefined;
|
|
36
32
|
return new util_1.SimpleFeature({
|
|
37
33
|
start: start1,
|
|
38
34
|
end: end1,
|
|
@@ -50,15 +46,13 @@ function parseStrand(strand) {
|
|
|
50
46
|
if (strand === '+') {
|
|
51
47
|
return 1;
|
|
52
48
|
}
|
|
53
|
-
|
|
49
|
+
if (strand === '-') {
|
|
54
50
|
return -1;
|
|
55
51
|
}
|
|
56
|
-
|
|
52
|
+
if (strand === '.') {
|
|
57
53
|
return 0;
|
|
58
54
|
}
|
|
59
|
-
|
|
60
|
-
return undefined;
|
|
61
|
-
}
|
|
55
|
+
return undefined;
|
|
62
56
|
}
|
|
63
57
|
class BedpeAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
64
58
|
constructor() {
|
|
@@ -69,7 +63,7 @@ class BedpeAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
69
63
|
const pm = this.pluginManager;
|
|
70
64
|
const bedLoc = this.getConf('bedpeLocation');
|
|
71
65
|
const buf = await (0, io_1.openLocation)(bedLoc, pm).readFile(opts);
|
|
72
|
-
const buffer = isGzip(buf) ? await (0, bgzf_filehandle_1.unzip)(buf) : buf;
|
|
66
|
+
const buffer = (0, util_1.isGzip)(buf) ? await (0, bgzf_filehandle_1.unzip)(buf) : buf;
|
|
73
67
|
// 512MB max chrome string length is 512MB
|
|
74
68
|
if (buffer.length > 536870888) {
|
|
75
69
|
throw new Error('Data exceeds maximum string length (512MB)');
|
|
@@ -108,7 +102,7 @@ class BedpeAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
108
102
|
}
|
|
109
103
|
async loadData(opts = {}) {
|
|
110
104
|
if (!this.bedpeFeatures) {
|
|
111
|
-
this.bedpeFeatures = this.loadDataP(opts).catch(e => {
|
|
105
|
+
this.bedpeFeatures = this.loadDataP(opts).catch((e) => {
|
|
112
106
|
this.bedpeFeatures = undefined;
|
|
113
107
|
throw e;
|
|
114
108
|
});
|
|
@@ -151,7 +145,7 @@ class BedpeAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
151
145
|
}
|
|
152
146
|
async loadFeatureTree(refName) {
|
|
153
147
|
if (!this.intervalTrees[refName]) {
|
|
154
|
-
this.intervalTrees[refName] = this.loadFeatureTreeP(refName).catch(e => {
|
|
148
|
+
this.intervalTrees[refName] = this.loadFeatureTreeP(refName).catch((e) => {
|
|
155
149
|
this.intervalTrees[refName] = undefined;
|
|
156
150
|
throw e;
|
|
157
151
|
});
|
|
@@ -162,7 +156,9 @@ class BedpeAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
162
156
|
return (0, rxjs_1.ObservableCreate)(async (observer) => {
|
|
163
157
|
const { start, end, refName } = query;
|
|
164
158
|
const intervalTree = await this.loadFeatureTree(refName);
|
|
165
|
-
intervalTree === null || intervalTree === void 0 ? void 0 : intervalTree.search([start, end]).forEach(f =>
|
|
159
|
+
intervalTree === null || intervalTree === void 0 ? void 0 : intervalTree.search([start, end]).forEach(f => {
|
|
160
|
+
observer.next(f);
|
|
161
|
+
});
|
|
166
162
|
observer.complete();
|
|
167
163
|
}, opts.signal);
|
|
168
164
|
}
|
|
@@ -25,7 +25,7 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
25
25
|
[k: string]: string;
|
|
26
26
|
};
|
|
27
27
|
}>;
|
|
28
|
-
getFeaturesHelper(query: Region, opts: BaseOptions
|
|
28
|
+
getFeaturesHelper(query: Region, opts: BaseOptions, observer: Observer<Feature>, allowRedispatch: boolean, originalQuery?: Region): Promise<void>;
|
|
29
29
|
getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
|
|
30
30
|
freeResources(): void;
|
|
31
31
|
}
|
|
@@ -23,7 +23,7 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
23
23
|
}
|
|
24
24
|
async configure(opts) {
|
|
25
25
|
if (!this.cached) {
|
|
26
|
-
this.cached = this.configurePre(opts).catch(e => {
|
|
26
|
+
this.cached = this.configurePre(opts).catch((e) => {
|
|
27
27
|
this.cached = undefined;
|
|
28
28
|
throw e;
|
|
29
29
|
});
|
|
@@ -45,7 +45,7 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
45
45
|
fields: Object.fromEntries(fields.map(({ name, comment }) => [name, comment])),
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
|
-
async getFeaturesHelper(query, opts
|
|
48
|
+
async getFeaturesHelper(query, opts, observer, allowRedispatch, originalQuery = query) {
|
|
49
49
|
const { signal } = opts;
|
|
50
50
|
const scoreColumn = this.getConf('scoreColumn');
|
|
51
51
|
const aggregateField = this.getConf('aggregateField');
|
|
@@ -55,8 +55,8 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
55
55
|
basesPerSpan: query.end - query.start,
|
|
56
56
|
});
|
|
57
57
|
if (allowRedispatch && feats.length) {
|
|
58
|
-
let minStart =
|
|
59
|
-
let maxEnd =
|
|
58
|
+
let minStart = Number.POSITIVE_INFINITY;
|
|
59
|
+
let maxEnd = Number.NEGATIVE_INFINITY;
|
|
60
60
|
for (const feat of feats) {
|
|
61
61
|
if (feat.start < minStart) {
|
|
62
62
|
minStart = feat.start;
|
package/dist/index.js
CHANGED
|
@@ -31,7 +31,7 @@ class BedPlugin extends Plugin_1.default {
|
|
|
31
31
|
if (regexGuess.test(fileName) && !adapterHint) {
|
|
32
32
|
return obj;
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
if (adapterHint === adapterName) {
|
|
35
35
|
return obj;
|
|
36
36
|
}
|
|
37
37
|
return adapterGuesser(file, index, adapterHint);
|
package/dist/util.d.ts
CHANGED
|
@@ -30,9 +30,9 @@ export declare function makeBlocks({ start, uniqueId, refName, chromStarts, bloc
|
|
|
30
30
|
start: number;
|
|
31
31
|
uniqueId: string;
|
|
32
32
|
refName: string;
|
|
33
|
-
chromStarts
|
|
33
|
+
chromStarts?: number[];
|
|
34
34
|
blockSizes: number[];
|
|
35
|
-
blockStarts
|
|
35
|
+
blockStarts?: number[];
|
|
36
36
|
}): {
|
|
37
37
|
uniqueId: string;
|
|
38
38
|
start: number;
|
package/dist/util.js
CHANGED
|
@@ -6,15 +6,15 @@ exports.featureData = featureData;
|
|
|
6
6
|
exports.isUcscProcessedTranscript = isUcscProcessedTranscript;
|
|
7
7
|
const util_1 = require("@jbrowse/core/util");
|
|
8
8
|
function ucscProcessedTranscript(feature) {
|
|
9
|
-
var _a;
|
|
10
9
|
const { subfeatures: oldSubfeatures, thickStart, thickEnd, blockCount, blockSizes, chromStarts, refName, strand = 0, ...rest } = feature;
|
|
11
10
|
if (!thickStart || !thickEnd || !strand) {
|
|
12
11
|
return feature;
|
|
13
12
|
}
|
|
14
13
|
const subfeatures = [];
|
|
15
|
-
|
|
14
|
+
oldSubfeatures
|
|
16
15
|
.filter(child => child.type === 'block')
|
|
17
|
-
.sort((a, b) => a.start - b.start)
|
|
16
|
+
.sort((a, b) => a.start - b.start)
|
|
17
|
+
.forEach(block => {
|
|
18
18
|
const start = block.start;
|
|
19
19
|
const end = block.end;
|
|
20
20
|
if (thickStart >= end) {
|
|
@@ -61,7 +61,7 @@ function ucscProcessedTranscript(feature) {
|
|
|
61
61
|
end: thickStart,
|
|
62
62
|
refName,
|
|
63
63
|
}, {
|
|
64
|
-
type:
|
|
64
|
+
type: 'CDS',
|
|
65
65
|
start: thickStart,
|
|
66
66
|
end: thickEnd,
|
|
67
67
|
refName,
|
|
@@ -76,7 +76,7 @@ function ucscProcessedTranscript(feature) {
|
|
|
76
76
|
// CDS | UTR
|
|
77
77
|
const prime = strand > 0 ? 'three' : 'five';
|
|
78
78
|
subfeatures.push({
|
|
79
|
-
type:
|
|
79
|
+
type: 'CDS',
|
|
80
80
|
start,
|
|
81
81
|
end: thickEnd,
|
|
82
82
|
refName,
|
|
@@ -101,15 +101,16 @@ function ucscProcessedTranscript(feature) {
|
|
|
101
101
|
return { ...rest, strand, type: 'mRNA', refName, subfeatures };
|
|
102
102
|
}
|
|
103
103
|
function defaultParser(fields, line) {
|
|
104
|
-
const
|
|
104
|
+
const obj = Object.fromEntries(line.split('\t').map((f, i) => [fields[i], f]));
|
|
105
|
+
const { blockStarts, blockCount, chromStarts, thickEnd, thickStart, blockSizes, ...rest } = obj;
|
|
105
106
|
return {
|
|
106
107
|
...rest,
|
|
107
108
|
blockStarts: blockStarts === null || blockStarts === void 0 ? void 0 : blockStarts.split(',').map(r => +r),
|
|
108
109
|
chromStarts: chromStarts === null || chromStarts === void 0 ? void 0 : chromStarts.split(',').map(r => +r),
|
|
109
110
|
blockSizes: blockSizes === null || blockSizes === void 0 ? void 0 : blockSizes.split(',').map(r => +r),
|
|
110
|
-
thickStart: +thickStart,
|
|
111
|
-
thickEnd: +thickEnd,
|
|
112
|
-
blockCount: +blockCount,
|
|
111
|
+
thickStart: thickStart ? +thickStart : undefined,
|
|
112
|
+
thickEnd: thickEnd ? +thickEnd : undefined,
|
|
113
|
+
blockCount: blockCount ? +blockCount : undefined,
|
|
113
114
|
};
|
|
114
115
|
}
|
|
115
116
|
function makeBlocks({ start, uniqueId, refName, chromStarts, blockCount, blockSizes, blockStarts, }) {
|
|
@@ -117,7 +118,7 @@ function makeBlocks({ start, uniqueId, refName, chromStarts, blockCount, blockSi
|
|
|
117
118
|
const starts = chromStarts || blockStarts || [];
|
|
118
119
|
for (let b = 0; b < blockCount; b++) {
|
|
119
120
|
const bmin = (starts[b] || 0) + start;
|
|
120
|
-
const bmax = bmin + (
|
|
121
|
+
const bmax = bmin + (blockSizes[b] || 0);
|
|
121
122
|
subfeatures.push({
|
|
122
123
|
uniqueId: `${uniqueId}-${b}`,
|
|
123
124
|
start: bmin,
|
|
@@ -163,11 +164,11 @@ function featureData(line, colRef, colStart, colEnd, scoreColumn, parser, unique
|
|
|
163
164
|
id: uniqueId,
|
|
164
165
|
data: isUcscProcessedTranscript(data)
|
|
165
166
|
? ucscProcessedTranscript({
|
|
166
|
-
thickStart,
|
|
167
|
-
thickEnd,
|
|
168
|
-
blockCount,
|
|
169
|
-
blockSizes,
|
|
170
|
-
chromStarts,
|
|
167
|
+
thickStart: thickStart,
|
|
168
|
+
thickEnd: thickEnd,
|
|
169
|
+
blockCount: blockCount,
|
|
170
|
+
blockSizes: blockSizes,
|
|
171
|
+
chromStarts: chromStarts,
|
|
171
172
|
...f,
|
|
172
173
|
})
|
|
173
174
|
: f,
|
|
@@ -2,13 +2,11 @@ import BED from '@gmod/bed';
|
|
|
2
2
|
import { BaseFeatureDataAdapter, } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
3
3
|
import { openLocation } from '@jbrowse/core/util/io';
|
|
4
4
|
import { ObservableCreate } from '@jbrowse/core/util/rxjs';
|
|
5
|
+
import { isGzip } from '@jbrowse/core/util';
|
|
5
6
|
import IntervalTree from '@flatten-js/interval-tree';
|
|
6
7
|
import { unzip } from '@gmod/bgzf-filehandle';
|
|
7
8
|
// locals
|
|
8
9
|
import { featureData } from '../util';
|
|
9
|
-
function isGzip(buf) {
|
|
10
|
-
return buf[0] === 31 && buf[1] === 139 && buf[2] === 8;
|
|
11
|
-
}
|
|
12
10
|
class BedAdapter extends BaseFeatureDataAdapter {
|
|
13
11
|
constructor() {
|
|
14
12
|
super(...arguments);
|
|
@@ -61,7 +59,7 @@ class BedAdapter extends BaseFeatureDataAdapter {
|
|
|
61
59
|
}
|
|
62
60
|
async loadData(opts = {}) {
|
|
63
61
|
if (!this.bedFeatures) {
|
|
64
|
-
this.bedFeatures = this.loadDataP(opts).catch(e => {
|
|
62
|
+
this.bedFeatures = this.loadDataP(opts).catch((e) => {
|
|
65
63
|
this.bedFeatures = undefined;
|
|
66
64
|
throw e;
|
|
67
65
|
});
|
|
@@ -109,7 +107,7 @@ class BedAdapter extends BaseFeatureDataAdapter {
|
|
|
109
107
|
}
|
|
110
108
|
async loadFeatureIntervalTree(refName) {
|
|
111
109
|
if (!this.intervalTrees[refName]) {
|
|
112
|
-
this.intervalTrees[refName] = this.loadFeatureIntervalTreeHelper(refName).catch(e => {
|
|
110
|
+
this.intervalTrees[refName] = this.loadFeatureIntervalTreeHelper(refName).catch((e) => {
|
|
113
111
|
this.intervalTrees[refName] = undefined;
|
|
114
112
|
throw e;
|
|
115
113
|
});
|
|
@@ -120,7 +118,9 @@ class BedAdapter extends BaseFeatureDataAdapter {
|
|
|
120
118
|
return ObservableCreate(async (observer) => {
|
|
121
119
|
const { start, end, refName } = query;
|
|
122
120
|
const intervalTree = await this.loadFeatureIntervalTree(refName);
|
|
123
|
-
intervalTree === null || intervalTree === void 0 ? void 0 : intervalTree.search([start, end]).forEach(f =>
|
|
121
|
+
intervalTree === null || intervalTree === void 0 ? void 0 : intervalTree.search([start, end]).forEach(f => {
|
|
122
|
+
observer.next(f);
|
|
123
|
+
});
|
|
124
124
|
observer.complete();
|
|
125
125
|
}, opts.signal);
|
|
126
126
|
}
|
|
@@ -5,8 +5,8 @@ export declare function featureData(line: string, uniqueId: string, flip: boolea
|
|
|
5
5
|
export default class BedpeAdapter extends BaseFeatureDataAdapter {
|
|
6
6
|
protected bedpeFeatures?: Promise<{
|
|
7
7
|
header: string;
|
|
8
|
-
feats1: Record<string, string[]
|
|
9
|
-
feats2: Record<string, string[]
|
|
8
|
+
feats1: Record<string, string[]>;
|
|
9
|
+
feats2: Record<string, string[]>;
|
|
10
10
|
columnNames: string[];
|
|
11
11
|
}>;
|
|
12
12
|
protected intervalTrees: Record<string, Promise<IntervalTree | undefined> | undefined>;
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import { BaseFeatureDataAdapter, } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
2
2
|
import { openLocation } from '@jbrowse/core/util/io';
|
|
3
3
|
import { ObservableCreate } from '@jbrowse/core/util/rxjs';
|
|
4
|
-
import { SimpleFeature } from '@jbrowse/core/util';
|
|
4
|
+
import { SimpleFeature, isGzip } from '@jbrowse/core/util';
|
|
5
5
|
import IntervalTree from '@flatten-js/interval-tree';
|
|
6
6
|
import { unzip } from '@gmod/bgzf-filehandle';
|
|
7
|
-
function isGzip(buf) {
|
|
8
|
-
return buf[0] === 31 && buf[1] === 139 && buf[2] === 8;
|
|
9
|
-
}
|
|
10
7
|
export function featureData(line, uniqueId, flip, names) {
|
|
11
8
|
const l = line.split('\t');
|
|
12
9
|
const ref1 = l[flip ? 3 : 0];
|
|
@@ -23,10 +20,9 @@ export function featureData(line, uniqueId, flip, names) {
|
|
|
23
20
|
const rest = names
|
|
24
21
|
? Object.fromEntries(names.slice(10).map((n, idx) => [n, extra[idx]]))
|
|
25
22
|
: extra;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
23
|
+
const ALT = ['DUP', 'TRA', 'INV', 'CNV', 'DEL'].includes(extra[0])
|
|
24
|
+
? `<${extra[0]}>`
|
|
25
|
+
: undefined;
|
|
30
26
|
return new SimpleFeature({
|
|
31
27
|
start: start1,
|
|
32
28
|
end: end1,
|
|
@@ -44,15 +40,13 @@ function parseStrand(strand) {
|
|
|
44
40
|
if (strand === '+') {
|
|
45
41
|
return 1;
|
|
46
42
|
}
|
|
47
|
-
|
|
43
|
+
if (strand === '-') {
|
|
48
44
|
return -1;
|
|
49
45
|
}
|
|
50
|
-
|
|
46
|
+
if (strand === '.') {
|
|
51
47
|
return 0;
|
|
52
48
|
}
|
|
53
|
-
|
|
54
|
-
return undefined;
|
|
55
|
-
}
|
|
49
|
+
return undefined;
|
|
56
50
|
}
|
|
57
51
|
class BedpeAdapter extends BaseFeatureDataAdapter {
|
|
58
52
|
constructor() {
|
|
@@ -102,7 +96,7 @@ class BedpeAdapter extends BaseFeatureDataAdapter {
|
|
|
102
96
|
}
|
|
103
97
|
async loadData(opts = {}) {
|
|
104
98
|
if (!this.bedpeFeatures) {
|
|
105
|
-
this.bedpeFeatures = this.loadDataP(opts).catch(e => {
|
|
99
|
+
this.bedpeFeatures = this.loadDataP(opts).catch((e) => {
|
|
106
100
|
this.bedpeFeatures = undefined;
|
|
107
101
|
throw e;
|
|
108
102
|
});
|
|
@@ -145,7 +139,7 @@ class BedpeAdapter extends BaseFeatureDataAdapter {
|
|
|
145
139
|
}
|
|
146
140
|
async loadFeatureTree(refName) {
|
|
147
141
|
if (!this.intervalTrees[refName]) {
|
|
148
|
-
this.intervalTrees[refName] = this.loadFeatureTreeP(refName).catch(e => {
|
|
142
|
+
this.intervalTrees[refName] = this.loadFeatureTreeP(refName).catch((e) => {
|
|
149
143
|
this.intervalTrees[refName] = undefined;
|
|
150
144
|
throw e;
|
|
151
145
|
});
|
|
@@ -156,7 +150,9 @@ class BedpeAdapter extends BaseFeatureDataAdapter {
|
|
|
156
150
|
return ObservableCreate(async (observer) => {
|
|
157
151
|
const { start, end, refName } = query;
|
|
158
152
|
const intervalTree = await this.loadFeatureTree(refName);
|
|
159
|
-
intervalTree === null || intervalTree === void 0 ? void 0 : intervalTree.search([start, end]).forEach(f =>
|
|
153
|
+
intervalTree === null || intervalTree === void 0 ? void 0 : intervalTree.search([start, end]).forEach(f => {
|
|
154
|
+
observer.next(f);
|
|
155
|
+
});
|
|
160
156
|
observer.complete();
|
|
161
157
|
}, opts.signal);
|
|
162
158
|
}
|
|
@@ -25,7 +25,7 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
25
25
|
[k: string]: string;
|
|
26
26
|
};
|
|
27
27
|
}>;
|
|
28
|
-
getFeaturesHelper(query: Region, opts: BaseOptions
|
|
28
|
+
getFeaturesHelper(query: Region, opts: BaseOptions, observer: Observer<Feature>, allowRedispatch: boolean, originalQuery?: Region): Promise<void>;
|
|
29
29
|
getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
|
|
30
30
|
freeResources(): void;
|
|
31
31
|
}
|
|
@@ -18,7 +18,7 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
18
18
|
}
|
|
19
19
|
async configure(opts) {
|
|
20
20
|
if (!this.cached) {
|
|
21
|
-
this.cached = this.configurePre(opts).catch(e => {
|
|
21
|
+
this.cached = this.configurePre(opts).catch((e) => {
|
|
22
22
|
this.cached = undefined;
|
|
23
23
|
throw e;
|
|
24
24
|
});
|
|
@@ -40,7 +40,7 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
40
40
|
fields: Object.fromEntries(fields.map(({ name, comment }) => [name, comment])),
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
|
-
async getFeaturesHelper(query, opts
|
|
43
|
+
async getFeaturesHelper(query, opts, observer, allowRedispatch, originalQuery = query) {
|
|
44
44
|
const { signal } = opts;
|
|
45
45
|
const scoreColumn = this.getConf('scoreColumn');
|
|
46
46
|
const aggregateField = this.getConf('aggregateField');
|
|
@@ -50,8 +50,8 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
50
50
|
basesPerSpan: query.end - query.start,
|
|
51
51
|
});
|
|
52
52
|
if (allowRedispatch && feats.length) {
|
|
53
|
-
let minStart =
|
|
54
|
-
let maxEnd =
|
|
53
|
+
let minStart = Number.POSITIVE_INFINITY;
|
|
54
|
+
let maxEnd = Number.NEGATIVE_INFINITY;
|
|
55
55
|
for (const feat of feats) {
|
|
56
56
|
if (feat.start < minStart) {
|
|
57
57
|
minStart = feat.start;
|
package/esm/index.js
CHANGED
|
@@ -26,7 +26,7 @@ export default class BedPlugin extends Plugin {
|
|
|
26
26
|
if (regexGuess.test(fileName) && !adapterHint) {
|
|
27
27
|
return obj;
|
|
28
28
|
}
|
|
29
|
-
|
|
29
|
+
if (adapterHint === adapterName) {
|
|
30
30
|
return obj;
|
|
31
31
|
}
|
|
32
32
|
return adapterGuesser(file, index, adapterHint);
|
package/esm/util.d.ts
CHANGED
|
@@ -30,9 +30,9 @@ export declare function makeBlocks({ start, uniqueId, refName, chromStarts, bloc
|
|
|
30
30
|
start: number;
|
|
31
31
|
uniqueId: string;
|
|
32
32
|
refName: string;
|
|
33
|
-
chromStarts
|
|
33
|
+
chromStarts?: number[];
|
|
34
34
|
blockSizes: number[];
|
|
35
|
-
blockStarts
|
|
35
|
+
blockStarts?: number[];
|
|
36
36
|
}): {
|
|
37
37
|
uniqueId: string;
|
|
38
38
|
start: number;
|
package/esm/util.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { SimpleFeature } from '@jbrowse/core/util';
|
|
2
2
|
export function ucscProcessedTranscript(feature) {
|
|
3
|
-
var _a;
|
|
4
3
|
const { subfeatures: oldSubfeatures, thickStart, thickEnd, blockCount, blockSizes, chromStarts, refName, strand = 0, ...rest } = feature;
|
|
5
4
|
if (!thickStart || !thickEnd || !strand) {
|
|
6
5
|
return feature;
|
|
7
6
|
}
|
|
8
7
|
const subfeatures = [];
|
|
9
|
-
|
|
8
|
+
oldSubfeatures
|
|
10
9
|
.filter(child => child.type === 'block')
|
|
11
|
-
.sort((a, b) => a.start - b.start)
|
|
10
|
+
.sort((a, b) => a.start - b.start)
|
|
11
|
+
.forEach(block => {
|
|
12
12
|
const start = block.start;
|
|
13
13
|
const end = block.end;
|
|
14
14
|
if (thickStart >= end) {
|
|
@@ -55,7 +55,7 @@ export function ucscProcessedTranscript(feature) {
|
|
|
55
55
|
end: thickStart,
|
|
56
56
|
refName,
|
|
57
57
|
}, {
|
|
58
|
-
type:
|
|
58
|
+
type: 'CDS',
|
|
59
59
|
start: thickStart,
|
|
60
60
|
end: thickEnd,
|
|
61
61
|
refName,
|
|
@@ -70,7 +70,7 @@ export function ucscProcessedTranscript(feature) {
|
|
|
70
70
|
// CDS | UTR
|
|
71
71
|
const prime = strand > 0 ? 'three' : 'five';
|
|
72
72
|
subfeatures.push({
|
|
73
|
-
type:
|
|
73
|
+
type: 'CDS',
|
|
74
74
|
start,
|
|
75
75
|
end: thickEnd,
|
|
76
76
|
refName,
|
|
@@ -95,15 +95,16 @@ export function ucscProcessedTranscript(feature) {
|
|
|
95
95
|
return { ...rest, strand, type: 'mRNA', refName, subfeatures };
|
|
96
96
|
}
|
|
97
97
|
function defaultParser(fields, line) {
|
|
98
|
-
const
|
|
98
|
+
const obj = Object.fromEntries(line.split('\t').map((f, i) => [fields[i], f]));
|
|
99
|
+
const { blockStarts, blockCount, chromStarts, thickEnd, thickStart, blockSizes, ...rest } = obj;
|
|
99
100
|
return {
|
|
100
101
|
...rest,
|
|
101
102
|
blockStarts: blockStarts === null || blockStarts === void 0 ? void 0 : blockStarts.split(',').map(r => +r),
|
|
102
103
|
chromStarts: chromStarts === null || chromStarts === void 0 ? void 0 : chromStarts.split(',').map(r => +r),
|
|
103
104
|
blockSizes: blockSizes === null || blockSizes === void 0 ? void 0 : blockSizes.split(',').map(r => +r),
|
|
104
|
-
thickStart: +thickStart,
|
|
105
|
-
thickEnd: +thickEnd,
|
|
106
|
-
blockCount: +blockCount,
|
|
105
|
+
thickStart: thickStart ? +thickStart : undefined,
|
|
106
|
+
thickEnd: thickEnd ? +thickEnd : undefined,
|
|
107
|
+
blockCount: blockCount ? +blockCount : undefined,
|
|
107
108
|
};
|
|
108
109
|
}
|
|
109
110
|
export function makeBlocks({ start, uniqueId, refName, chromStarts, blockCount, blockSizes, blockStarts, }) {
|
|
@@ -111,7 +112,7 @@ export function makeBlocks({ start, uniqueId, refName, chromStarts, blockCount,
|
|
|
111
112
|
const starts = chromStarts || blockStarts || [];
|
|
112
113
|
for (let b = 0; b < blockCount; b++) {
|
|
113
114
|
const bmin = (starts[b] || 0) + start;
|
|
114
|
-
const bmax = bmin + (
|
|
115
|
+
const bmax = bmin + (blockSizes[b] || 0);
|
|
115
116
|
subfeatures.push({
|
|
116
117
|
uniqueId: `${uniqueId}-${b}`,
|
|
117
118
|
start: bmin,
|
|
@@ -157,11 +158,11 @@ export function featureData(line, colRef, colStart, colEnd, scoreColumn, parser,
|
|
|
157
158
|
id: uniqueId,
|
|
158
159
|
data: isUcscProcessedTranscript(data)
|
|
159
160
|
? ucscProcessedTranscript({
|
|
160
|
-
thickStart,
|
|
161
|
-
thickEnd,
|
|
162
|
-
blockCount,
|
|
163
|
-
blockSizes,
|
|
164
|
-
chromStarts,
|
|
161
|
+
thickStart: thickStart,
|
|
162
|
+
thickEnd: thickEnd,
|
|
163
|
+
blockCount: blockCount,
|
|
164
|
+
blockSizes: blockSizes,
|
|
165
|
+
chromStarts: chromStarts,
|
|
165
166
|
...f,
|
|
166
167
|
})
|
|
167
168
|
: f,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/plugin-bed",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.14.0",
|
|
4
4
|
"description": "JBrowse 2 bed adapters, tracks, etc.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jbrowse",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
],
|
|
25
25
|
"scripts": {
|
|
26
26
|
"build": "npm-run-all build:*",
|
|
27
|
-
"test": "cd ../..; jest plugins/bed",
|
|
27
|
+
"test": "cd ../..; jest --passWithNoTests plugins/bed",
|
|
28
28
|
"prepublishOnly": "yarn test",
|
|
29
29
|
"prepack": "yarn build && yarn useDist",
|
|
30
30
|
"postpack": "yarn useSrc",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@flatten-js/interval-tree": "^1.0.15",
|
|
40
|
-
"@gmod/bbi": "^
|
|
40
|
+
"@gmod/bbi": "^5.0.0",
|
|
41
41
|
"@gmod/bed": "^2.1.2",
|
|
42
42
|
"@gmod/bgzf-filehandle": "^1.4.3",
|
|
43
43
|
"@gmod/tabix": "^1.5.6"
|
|
@@ -55,5 +55,5 @@
|
|
|
55
55
|
"distModule": "esm/index.js",
|
|
56
56
|
"srcModule": "src/index.ts",
|
|
57
57
|
"module": "esm/index.js",
|
|
58
|
-
"gitHead": "
|
|
58
|
+
"gitHead": "9fb8231d932db40adf0a283081765431756c66ff"
|
|
59
59
|
}
|