@jbrowse/plugin-bed 3.2.0 → 3.4.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.d.ts +0 -1
- package/dist/BedAdapter/BedAdapter.js +30 -21
- package/dist/BedAdapter/configSchema.d.ts +1 -0
- package/dist/BedAdapter/configSchema.js +1 -0
- package/dist/BedGraphAdapter/BedGraphAdapter.d.ts +0 -1
- package/dist/BedGraphAdapter/BedGraphAdapter.js +0 -1
- package/dist/BedGraphTabixAdapter/BedGraphTabixAdapter.d.ts +0 -1
- package/dist/BedGraphTabixAdapter/BedGraphTabixAdapter.js +0 -1
- package/dist/BedTabixAdapter/BedTabixAdapter.d.ts +0 -1
- package/dist/BedTabixAdapter/BedTabixAdapter.js +0 -1
- package/dist/BedpeAdapter/BedpeAdapter.d.ts +0 -1
- package/dist/BedpeAdapter/BedpeAdapter.js +0 -1
- package/dist/BedpeAdapter/configSchema.d.ts +1 -0
- package/dist/BedpeAdapter/configSchema.js +1 -0
- package/dist/BigBedAdapter/BigBedAdapter.d.ts +3 -1
- package/dist/BigBedAdapter/BigBedAdapter.js +37 -35
- package/esm/BedAdapter/BedAdapter.d.ts +0 -1
- package/esm/BedAdapter/BedAdapter.js +31 -22
- package/esm/BedAdapter/configSchema.d.ts +1 -0
- package/esm/BedAdapter/configSchema.js +1 -0
- package/esm/BedGraphAdapter/BedGraphAdapter.d.ts +0 -1
- package/esm/BedGraphAdapter/BedGraphAdapter.js +0 -1
- package/esm/BedGraphTabixAdapter/BedGraphTabixAdapter.d.ts +0 -1
- package/esm/BedGraphTabixAdapter/BedGraphTabixAdapter.js +0 -1
- package/esm/BedTabixAdapter/BedTabixAdapter.d.ts +0 -1
- package/esm/BedTabixAdapter/BedTabixAdapter.js +0 -1
- package/esm/BedpeAdapter/BedpeAdapter.d.ts +0 -1
- package/esm/BedpeAdapter/BedpeAdapter.js +0 -1
- package/esm/BedpeAdapter/configSchema.d.ts +1 -0
- package/esm/BedpeAdapter/configSchema.js +1 -0
- package/esm/BigBedAdapter/BigBedAdapter.d.ts +3 -1
- package/esm/BigBedAdapter/BigBedAdapter.js +37 -35
- package/package.json +6 -6
|
@@ -33,5 +33,4 @@ export default class BedAdapter extends BaseFeatureDataAdapter {
|
|
|
33
33
|
private loadFeatureIntervalTreeHelper;
|
|
34
34
|
loadFeatureIntervalTree(refName: string): Promise<IntervalTree<any> | undefined>;
|
|
35
35
|
getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
|
|
36
|
-
freeResources(): void;
|
|
37
36
|
}
|
|
@@ -15,31 +15,41 @@ class BedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
15
15
|
super(...arguments);
|
|
16
16
|
this.intervalTrees = {};
|
|
17
17
|
}
|
|
18
|
-
async loadDataP(opts
|
|
19
|
-
const
|
|
18
|
+
async loadDataP(opts) {
|
|
19
|
+
const { statusCallback = () => { } } = opts || {};
|
|
20
20
|
const bedLoc = this.getConf('bedLocation');
|
|
21
|
-
const buffer = await (0, util_1.fetchAndMaybeUnzip)((0, io_1.openLocation)(bedLoc,
|
|
22
|
-
if (buffer.length > 536870888) {
|
|
23
|
-
throw new Error('Data exceeds maximum string length (512MB)');
|
|
24
|
-
}
|
|
25
|
-
const data = new TextDecoder('utf8', { fatal: true }).decode(buffer);
|
|
26
|
-
const lines = data.split(/\n|\r\n|\r/).filter(f => !!f);
|
|
21
|
+
const buffer = await (0, util_1.fetchAndMaybeUnzip)((0, io_1.openLocation)(bedLoc, this.pluginManager), opts);
|
|
27
22
|
const headerLines = [];
|
|
28
|
-
let i = 0;
|
|
29
|
-
for (; i < lines.length && lines[i].startsWith('#'); i++) {
|
|
30
|
-
headerLines.push(lines[i]);
|
|
31
|
-
}
|
|
32
|
-
const header = headerLines.join('\n');
|
|
33
23
|
const features = {};
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
24
|
+
let blockStart = 0;
|
|
25
|
+
let i = 0;
|
|
26
|
+
const decoder = new TextDecoder('utf8');
|
|
27
|
+
while (blockStart < buffer.length) {
|
|
28
|
+
const n = buffer.indexOf(10, blockStart);
|
|
29
|
+
const b = n === -1 ? buffer.subarray(blockStart) : buffer.subarray(blockStart, n);
|
|
30
|
+
const line = decoder.decode(b).trim();
|
|
31
|
+
if (line) {
|
|
32
|
+
if (line.startsWith('#')) {
|
|
33
|
+
headerLines.push(line);
|
|
34
|
+
}
|
|
35
|
+
else if (line.startsWith('>')) {
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
const tab = line.indexOf('\t');
|
|
40
|
+
const refName = line.slice(0, tab);
|
|
41
|
+
if (!features[refName]) {
|
|
42
|
+
features[refName] = [];
|
|
43
|
+
}
|
|
44
|
+
features[refName].push(line);
|
|
45
|
+
}
|
|
40
46
|
}
|
|
41
|
-
|
|
47
|
+
if (i++ % 10000 === 0) {
|
|
48
|
+
statusCallback(`Loading ${(0, util_1.getProgressDisplayStr)(blockStart, buffer.length)}`);
|
|
49
|
+
}
|
|
50
|
+
blockStart = n + 1;
|
|
42
51
|
}
|
|
52
|
+
const header = headerLines.join('\n');
|
|
43
53
|
const autoSql = this.getConf('autoSql');
|
|
44
54
|
const parser = new bed_1.default({ autoSql });
|
|
45
55
|
const columnNames = this.getConf('columnNames');
|
|
@@ -136,7 +146,6 @@ class BedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
136
146
|
observer.complete();
|
|
137
147
|
}, opts.stopToken);
|
|
138
148
|
}
|
|
139
|
-
freeResources() { }
|
|
140
149
|
}
|
|
141
150
|
BedAdapter.capabilities = ['getFeatures', 'getRefNames'];
|
|
142
151
|
exports.default = BedAdapter;
|
|
@@ -5,6 +5,7 @@ function x() { }
|
|
|
5
5
|
const BedAdapter = (0, configuration_1.ConfigurationSchema)('BedAdapter', {
|
|
6
6
|
bedLocation: {
|
|
7
7
|
type: 'fileLocation',
|
|
8
|
+
description: 'path to bed file, also allows gzipped bed',
|
|
8
9
|
defaultValue: {
|
|
9
10
|
uri: '/path/to/my.bed.gz',
|
|
10
11
|
locationType: 'UriLocation',
|
|
@@ -14,5 +14,4 @@ export default class BedGraphAdapter extends BaseFeatureDataAdapter {
|
|
|
14
14
|
getRefNames(opts?: BaseOptions): Promise<string[]>;
|
|
15
15
|
getHeader(): Promise<string>;
|
|
16
16
|
getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
|
|
17
|
-
freeResources(): void;
|
|
18
17
|
}
|
|
@@ -5,6 +5,7 @@ function x() { }
|
|
|
5
5
|
const BedpeAdapter = (0, configuration_1.ConfigurationSchema)('BedpeAdapter', {
|
|
6
6
|
bedpeLocation: {
|
|
7
7
|
type: 'fileLocation',
|
|
8
|
+
description: 'can be plaintext or gzipped, not indexed so loaded into memory on startup',
|
|
8
9
|
defaultValue: {
|
|
9
10
|
uri: '/path/to/my.bedpe.gz',
|
|
10
11
|
locationType: 'UriLocation',
|
|
@@ -32,6 +32,9 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
32
32
|
[k: string]: string;
|
|
33
33
|
};
|
|
34
34
|
}>;
|
|
35
|
+
getMetadata(opts?: BaseOptions): Promise<{
|
|
36
|
+
[k: string]: string;
|
|
37
|
+
}>;
|
|
35
38
|
getFeaturesHelper({ query, opts, observer, allowRedispatch, originalQuery, }: {
|
|
36
39
|
query: Region;
|
|
37
40
|
opts: BaseOptions;
|
|
@@ -40,5 +43,4 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
40
43
|
originalQuery?: Region;
|
|
41
44
|
}): Promise<void>;
|
|
42
45
|
getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
|
|
43
|
-
freeResources(): void;
|
|
44
46
|
}
|
|
@@ -78,9 +78,14 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
78
78
|
version,
|
|
79
79
|
fileType,
|
|
80
80
|
autoSql: { ...rest },
|
|
81
|
-
fields:
|
|
81
|
+
fields: await this.getMetadata(opts),
|
|
82
82
|
};
|
|
83
83
|
}
|
|
84
|
+
async getMetadata(opts) {
|
|
85
|
+
const { parser } = await this.configure(opts);
|
|
86
|
+
const { fields } = parser.autoSql;
|
|
87
|
+
return Object.fromEntries(fields.map(({ name, comment }) => [name, comment]));
|
|
88
|
+
}
|
|
84
89
|
async getFeaturesHelper({ query, opts, observer, allowRedispatch, originalQuery = query, }) {
|
|
85
90
|
var _a;
|
|
86
91
|
const { statusCallback = () => { } } = opts;
|
|
@@ -90,38 +95,8 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
90
95
|
const feats = await (0, util_1.updateStatus)('Downloading features', statusCallback, () => bigbed.getFeatures(query.refName, query.start, query.end, {
|
|
91
96
|
basesPerSpan: query.end - query.start,
|
|
92
97
|
}));
|
|
93
|
-
if (allowRedispatch && feats.length) {
|
|
94
|
-
let minStart = Number.POSITIVE_INFINITY;
|
|
95
|
-
let maxEnd = Number.NEGATIVE_INFINITY;
|
|
96
|
-
let hasAnyAggregationField = false;
|
|
97
|
-
for (const feat of feats) {
|
|
98
|
-
if (feat.start < minStart) {
|
|
99
|
-
minStart = feat.start;
|
|
100
|
-
}
|
|
101
|
-
if (feat.end > maxEnd) {
|
|
102
|
-
maxEnd = feat.end;
|
|
103
|
-
}
|
|
104
|
-
if (feat[aggregateField]) {
|
|
105
|
-
hasAnyAggregationField = true;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
if (hasAnyAggregationField &&
|
|
109
|
-
(maxEnd > query.end || minStart < query.start)) {
|
|
110
|
-
await this.getFeaturesHelper({
|
|
111
|
-
query: {
|
|
112
|
-
...query,
|
|
113
|
-
start: minStart - 500000,
|
|
114
|
-
end: maxEnd + 500000,
|
|
115
|
-
},
|
|
116
|
-
opts,
|
|
117
|
-
observer,
|
|
118
|
-
allowRedispatch: false,
|
|
119
|
-
originalQuery: query,
|
|
120
|
-
});
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
98
|
const parentAggregation = {};
|
|
99
|
+
const parentAggregationFlat = [];
|
|
125
100
|
if (feats.some(f => f.uniqueId === undefined)) {
|
|
126
101
|
throw new Error('found uniqueId undefined');
|
|
127
102
|
}
|
|
@@ -136,7 +111,8 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
136
111
|
uniqueId: feat.uniqueId,
|
|
137
112
|
});
|
|
138
113
|
const aggr = data[aggregateField];
|
|
139
|
-
|
|
114
|
+
const aggrIsNotNone = aggr && aggr !== 'none';
|
|
115
|
+
if (aggrIsNotNone && !parentAggregation[aggr]) {
|
|
140
116
|
parentAggregation[aggr] = [];
|
|
141
117
|
}
|
|
142
118
|
const { uniqueId, type, chrom, chromStart, chromEnd, description, chromStarts: chromStarts2, blockStarts: blockStarts2, blockSizes: blockSizes2, score: score2, blockCount, thickStart, thickEnd, strand, ...rest } = data;
|
|
@@ -150,8 +126,9 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
150
126
|
end: feat.end,
|
|
151
127
|
refName: query.refName,
|
|
152
128
|
});
|
|
153
|
-
if (
|
|
129
|
+
if (aggrIsNotNone) {
|
|
154
130
|
parentAggregation[aggr].push(f);
|
|
131
|
+
parentAggregationFlat.push(f);
|
|
155
132
|
}
|
|
156
133
|
else {
|
|
157
134
|
if ((0, util_1.doesIntersect2)(f.start, f.end, originalQuery.start, originalQuery.end)) {
|
|
@@ -162,6 +139,32 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
162
139
|
}
|
|
163
140
|
}
|
|
164
141
|
}
|
|
142
|
+
if (allowRedispatch && parentAggregationFlat.length) {
|
|
143
|
+
let minStart = Number.POSITIVE_INFINITY;
|
|
144
|
+
let maxEnd = Number.NEGATIVE_INFINITY;
|
|
145
|
+
for (const feat of parentAggregationFlat) {
|
|
146
|
+
if (feat.start < minStart) {
|
|
147
|
+
minStart = feat.start;
|
|
148
|
+
}
|
|
149
|
+
if (feat.end > maxEnd) {
|
|
150
|
+
maxEnd = feat.end;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (maxEnd > query.end || minStart < query.start) {
|
|
154
|
+
await this.getFeaturesHelper({
|
|
155
|
+
query: {
|
|
156
|
+
...query,
|
|
157
|
+
start: minStart - 500000,
|
|
158
|
+
end: maxEnd + 500000,
|
|
159
|
+
},
|
|
160
|
+
opts,
|
|
161
|
+
observer,
|
|
162
|
+
allowRedispatch: false,
|
|
163
|
+
originalQuery: query,
|
|
164
|
+
});
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
165
168
|
Object.entries(parentAggregation).map(([name, subfeatures]) => {
|
|
166
169
|
var _a, _b;
|
|
167
170
|
const s = (0, util_1.min)(subfeatures.map(f => f.start));
|
|
@@ -203,6 +206,5 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
203
206
|
}
|
|
204
207
|
}, opts.stopToken);
|
|
205
208
|
}
|
|
206
|
-
freeResources() { }
|
|
207
209
|
}
|
|
208
210
|
exports.default = BigBedAdapter;
|
|
@@ -33,5 +33,4 @@ export default class BedAdapter extends BaseFeatureDataAdapter {
|
|
|
33
33
|
private loadFeatureIntervalTreeHelper;
|
|
34
34
|
loadFeatureIntervalTree(refName: string): Promise<IntervalTree<any> | undefined>;
|
|
35
35
|
getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
|
|
36
|
-
freeResources(): void;
|
|
37
36
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import IntervalTree from '@flatten-js/interval-tree';
|
|
2
2
|
import BED from '@gmod/bed';
|
|
3
3
|
import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
4
|
-
import { SimpleFeature, fetchAndMaybeUnzip } from '@jbrowse/core/util';
|
|
4
|
+
import { SimpleFeature, fetchAndMaybeUnzip, getProgressDisplayStr, } from '@jbrowse/core/util';
|
|
5
5
|
import { openLocation } from '@jbrowse/core/util/io';
|
|
6
6
|
import { ObservableCreate } from '@jbrowse/core/util/rxjs';
|
|
7
7
|
import { featureData } from '../util';
|
|
@@ -10,31 +10,41 @@ class BedAdapter extends BaseFeatureDataAdapter {
|
|
|
10
10
|
super(...arguments);
|
|
11
11
|
this.intervalTrees = {};
|
|
12
12
|
}
|
|
13
|
-
async loadDataP(opts
|
|
14
|
-
const
|
|
13
|
+
async loadDataP(opts) {
|
|
14
|
+
const { statusCallback = () => { } } = opts || {};
|
|
15
15
|
const bedLoc = this.getConf('bedLocation');
|
|
16
|
-
const buffer = await fetchAndMaybeUnzip(openLocation(bedLoc,
|
|
17
|
-
if (buffer.length > 536870888) {
|
|
18
|
-
throw new Error('Data exceeds maximum string length (512MB)');
|
|
19
|
-
}
|
|
20
|
-
const data = new TextDecoder('utf8', { fatal: true }).decode(buffer);
|
|
21
|
-
const lines = data.split(/\n|\r\n|\r/).filter(f => !!f);
|
|
16
|
+
const buffer = await fetchAndMaybeUnzip(openLocation(bedLoc, this.pluginManager), opts);
|
|
22
17
|
const headerLines = [];
|
|
23
|
-
let i = 0;
|
|
24
|
-
for (; i < lines.length && lines[i].startsWith('#'); i++) {
|
|
25
|
-
headerLines.push(lines[i]);
|
|
26
|
-
}
|
|
27
|
-
const header = headerLines.join('\n');
|
|
28
18
|
const features = {};
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
19
|
+
let blockStart = 0;
|
|
20
|
+
let i = 0;
|
|
21
|
+
const decoder = new TextDecoder('utf8');
|
|
22
|
+
while (blockStart < buffer.length) {
|
|
23
|
+
const n = buffer.indexOf(10, blockStart);
|
|
24
|
+
const b = n === -1 ? buffer.subarray(blockStart) : buffer.subarray(blockStart, n);
|
|
25
|
+
const line = decoder.decode(b).trim();
|
|
26
|
+
if (line) {
|
|
27
|
+
if (line.startsWith('#')) {
|
|
28
|
+
headerLines.push(line);
|
|
29
|
+
}
|
|
30
|
+
else if (line.startsWith('>')) {
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
const tab = line.indexOf('\t');
|
|
35
|
+
const refName = line.slice(0, tab);
|
|
36
|
+
if (!features[refName]) {
|
|
37
|
+
features[refName] = [];
|
|
38
|
+
}
|
|
39
|
+
features[refName].push(line);
|
|
40
|
+
}
|
|
35
41
|
}
|
|
36
|
-
|
|
42
|
+
if (i++ % 10000 === 0) {
|
|
43
|
+
statusCallback(`Loading ${getProgressDisplayStr(blockStart, buffer.length)}`);
|
|
44
|
+
}
|
|
45
|
+
blockStart = n + 1;
|
|
37
46
|
}
|
|
47
|
+
const header = headerLines.join('\n');
|
|
38
48
|
const autoSql = this.getConf('autoSql');
|
|
39
49
|
const parser = new BED({ autoSql });
|
|
40
50
|
const columnNames = this.getConf('columnNames');
|
|
@@ -131,7 +141,6 @@ class BedAdapter extends BaseFeatureDataAdapter {
|
|
|
131
141
|
observer.complete();
|
|
132
142
|
}, opts.stopToken);
|
|
133
143
|
}
|
|
134
|
-
freeResources() { }
|
|
135
144
|
}
|
|
136
145
|
BedAdapter.capabilities = ['getFeatures', 'getRefNames'];
|
|
137
146
|
export default BedAdapter;
|
|
@@ -14,5 +14,4 @@ export default class BedGraphAdapter extends BaseFeatureDataAdapter {
|
|
|
14
14
|
getRefNames(opts?: BaseOptions): Promise<string[]>;
|
|
15
15
|
getHeader(): Promise<string>;
|
|
16
16
|
getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
|
|
17
|
-
freeResources(): void;
|
|
18
17
|
}
|
|
@@ -3,6 +3,7 @@ function x() { }
|
|
|
3
3
|
const BedpeAdapter = ConfigurationSchema('BedpeAdapter', {
|
|
4
4
|
bedpeLocation: {
|
|
5
5
|
type: 'fileLocation',
|
|
6
|
+
description: 'can be plaintext or gzipped, not indexed so loaded into memory on startup',
|
|
6
7
|
defaultValue: {
|
|
7
8
|
uri: '/path/to/my.bedpe.gz',
|
|
8
9
|
locationType: 'UriLocation',
|
|
@@ -32,6 +32,9 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
32
32
|
[k: string]: string;
|
|
33
33
|
};
|
|
34
34
|
}>;
|
|
35
|
+
getMetadata(opts?: BaseOptions): Promise<{
|
|
36
|
+
[k: string]: string;
|
|
37
|
+
}>;
|
|
35
38
|
getFeaturesHelper({ query, opts, observer, allowRedispatch, originalQuery, }: {
|
|
36
39
|
query: Region;
|
|
37
40
|
opts: BaseOptions;
|
|
@@ -40,5 +43,4 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
40
43
|
originalQuery?: Region;
|
|
41
44
|
}): Promise<void>;
|
|
42
45
|
getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
|
|
43
|
-
freeResources(): void;
|
|
44
46
|
}
|
|
@@ -73,9 +73,14 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
73
73
|
version,
|
|
74
74
|
fileType,
|
|
75
75
|
autoSql: { ...rest },
|
|
76
|
-
fields:
|
|
76
|
+
fields: await this.getMetadata(opts),
|
|
77
77
|
};
|
|
78
78
|
}
|
|
79
|
+
async getMetadata(opts) {
|
|
80
|
+
const { parser } = await this.configure(opts);
|
|
81
|
+
const { fields } = parser.autoSql;
|
|
82
|
+
return Object.fromEntries(fields.map(({ name, comment }) => [name, comment]));
|
|
83
|
+
}
|
|
79
84
|
async getFeaturesHelper({ query, opts, observer, allowRedispatch, originalQuery = query, }) {
|
|
80
85
|
var _a;
|
|
81
86
|
const { statusCallback = () => { } } = opts;
|
|
@@ -85,38 +90,8 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
85
90
|
const feats = await updateStatus('Downloading features', statusCallback, () => bigbed.getFeatures(query.refName, query.start, query.end, {
|
|
86
91
|
basesPerSpan: query.end - query.start,
|
|
87
92
|
}));
|
|
88
|
-
if (allowRedispatch && feats.length) {
|
|
89
|
-
let minStart = Number.POSITIVE_INFINITY;
|
|
90
|
-
let maxEnd = Number.NEGATIVE_INFINITY;
|
|
91
|
-
let hasAnyAggregationField = false;
|
|
92
|
-
for (const feat of feats) {
|
|
93
|
-
if (feat.start < minStart) {
|
|
94
|
-
minStart = feat.start;
|
|
95
|
-
}
|
|
96
|
-
if (feat.end > maxEnd) {
|
|
97
|
-
maxEnd = feat.end;
|
|
98
|
-
}
|
|
99
|
-
if (feat[aggregateField]) {
|
|
100
|
-
hasAnyAggregationField = true;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
if (hasAnyAggregationField &&
|
|
104
|
-
(maxEnd > query.end || minStart < query.start)) {
|
|
105
|
-
await this.getFeaturesHelper({
|
|
106
|
-
query: {
|
|
107
|
-
...query,
|
|
108
|
-
start: minStart - 500000,
|
|
109
|
-
end: maxEnd + 500000,
|
|
110
|
-
},
|
|
111
|
-
opts,
|
|
112
|
-
observer,
|
|
113
|
-
allowRedispatch: false,
|
|
114
|
-
originalQuery: query,
|
|
115
|
-
});
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
93
|
const parentAggregation = {};
|
|
94
|
+
const parentAggregationFlat = [];
|
|
120
95
|
if (feats.some(f => f.uniqueId === undefined)) {
|
|
121
96
|
throw new Error('found uniqueId undefined');
|
|
122
97
|
}
|
|
@@ -131,7 +106,8 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
131
106
|
uniqueId: feat.uniqueId,
|
|
132
107
|
});
|
|
133
108
|
const aggr = data[aggregateField];
|
|
134
|
-
|
|
109
|
+
const aggrIsNotNone = aggr && aggr !== 'none';
|
|
110
|
+
if (aggrIsNotNone && !parentAggregation[aggr]) {
|
|
135
111
|
parentAggregation[aggr] = [];
|
|
136
112
|
}
|
|
137
113
|
const { uniqueId, type, chrom, chromStart, chromEnd, description, chromStarts: chromStarts2, blockStarts: blockStarts2, blockSizes: blockSizes2, score: score2, blockCount, thickStart, thickEnd, strand, ...rest } = data;
|
|
@@ -145,8 +121,9 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
145
121
|
end: feat.end,
|
|
146
122
|
refName: query.refName,
|
|
147
123
|
});
|
|
148
|
-
if (
|
|
124
|
+
if (aggrIsNotNone) {
|
|
149
125
|
parentAggregation[aggr].push(f);
|
|
126
|
+
parentAggregationFlat.push(f);
|
|
150
127
|
}
|
|
151
128
|
else {
|
|
152
129
|
if (doesIntersect2(f.start, f.end, originalQuery.start, originalQuery.end)) {
|
|
@@ -157,6 +134,32 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
157
134
|
}
|
|
158
135
|
}
|
|
159
136
|
}
|
|
137
|
+
if (allowRedispatch && parentAggregationFlat.length) {
|
|
138
|
+
let minStart = Number.POSITIVE_INFINITY;
|
|
139
|
+
let maxEnd = Number.NEGATIVE_INFINITY;
|
|
140
|
+
for (const feat of parentAggregationFlat) {
|
|
141
|
+
if (feat.start < minStart) {
|
|
142
|
+
minStart = feat.start;
|
|
143
|
+
}
|
|
144
|
+
if (feat.end > maxEnd) {
|
|
145
|
+
maxEnd = feat.end;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (maxEnd > query.end || minStart < query.start) {
|
|
149
|
+
await this.getFeaturesHelper({
|
|
150
|
+
query: {
|
|
151
|
+
...query,
|
|
152
|
+
start: minStart - 500000,
|
|
153
|
+
end: maxEnd + 500000,
|
|
154
|
+
},
|
|
155
|
+
opts,
|
|
156
|
+
observer,
|
|
157
|
+
allowRedispatch: false,
|
|
158
|
+
originalQuery: query,
|
|
159
|
+
});
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
160
163
|
Object.entries(parentAggregation).map(([name, subfeatures]) => {
|
|
161
164
|
var _a, _b;
|
|
162
165
|
const s = min(subfeatures.map(f => f.start));
|
|
@@ -198,5 +201,4 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
198
201
|
}
|
|
199
202
|
}, opts.stopToken);
|
|
200
203
|
}
|
|
201
|
-
freeResources() { }
|
|
202
204
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/plugin-bed",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0",
|
|
4
4
|
"description": "JBrowse 2 bed adapters, tracks, etc.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jbrowse",
|
|
@@ -37,11 +37,11 @@
|
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@flatten-js/interval-tree": "^1.0.15",
|
|
40
|
-
"@gmod/bbi": "^
|
|
40
|
+
"@gmod/bbi": "^7.0.0",
|
|
41
41
|
"@gmod/bed": "^2.1.2",
|
|
42
|
-
"@gmod/bgzf-filehandle": "^
|
|
43
|
-
"@gmod/tabix": "^
|
|
44
|
-
"@jbrowse/core": "^3.
|
|
42
|
+
"@gmod/bgzf-filehandle": "^3.0.2",
|
|
43
|
+
"@gmod/tabix": "^3.0.1",
|
|
44
|
+
"@jbrowse/core": "^3.4.0",
|
|
45
45
|
"mobx": "^6.0.0",
|
|
46
46
|
"mobx-react": "^9.0.0",
|
|
47
47
|
"mobx-state-tree": "^5.0.0",
|
|
@@ -53,5 +53,5 @@
|
|
|
53
53
|
"distModule": "esm/index.js",
|
|
54
54
|
"srcModule": "src/index.ts",
|
|
55
55
|
"module": "esm/index.js",
|
|
56
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "a9f1ac35fc2dd810bae92cdaf1fc19995bee4413"
|
|
57
57
|
}
|