@jbrowse/plugin-bed 2.11.1 → 2.12.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/BigBedAdapter/BigBedAdapter.d.ts +8 -6
- package/dist/BigBedAdapter/BigBedAdapter.js +111 -60
- package/dist/BigBedAdapter/configSchema.d.ts +8 -0
- package/dist/BigBedAdapter/configSchema.js +8 -0
- package/dist/util.d.ts +6 -5
- package/dist/util.js +4 -4
- package/esm/BigBedAdapter/BigBedAdapter.d.ts +8 -6
- package/esm/BigBedAdapter/BigBedAdapter.js +111 -60
- package/esm/BigBedAdapter/configSchema.d.ts +8 -0
- package/esm/BigBedAdapter/configSchema.js +8 -0
- package/esm/util.d.ts +6 -5
- package/esm/util.js +2 -2
- package/package.json +2 -2
|
@@ -1,29 +1,31 @@
|
|
|
1
|
-
import { BigBed
|
|
1
|
+
import { BigBed } from '@gmod/bbi';
|
|
2
2
|
import BED from '@gmod/bed';
|
|
3
3
|
import { BaseFeatureDataAdapter, BaseOptions } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
4
4
|
import { Region } from '@jbrowse/core/util/types';
|
|
5
|
-
import { Feature } from '@jbrowse/core/util
|
|
5
|
+
import { Feature } from '@jbrowse/core/util';
|
|
6
|
+
import { Observer } from 'rxjs';
|
|
6
7
|
export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
7
8
|
private cached?;
|
|
8
9
|
configurePre(opts?: BaseOptions): Promise<{
|
|
9
10
|
bigbed: BigBed;
|
|
10
|
-
header: Header;
|
|
11
|
+
header: import("@gmod/bbi").Header;
|
|
11
12
|
parser: BED;
|
|
12
13
|
}>;
|
|
13
14
|
configure(opts?: BaseOptions): Promise<{
|
|
14
15
|
bigbed: BigBed;
|
|
15
|
-
header: Header;
|
|
16
|
+
header: import("@gmod/bbi").Header;
|
|
16
17
|
parser: BED;
|
|
17
18
|
}>;
|
|
18
19
|
getRefNames(opts?: BaseOptions): Promise<string[]>;
|
|
19
20
|
getHeader(opts?: BaseOptions): Promise<{
|
|
20
|
-
version:
|
|
21
|
+
version: number;
|
|
21
22
|
fileType: string;
|
|
22
23
|
autoSql: {};
|
|
23
24
|
fields: {
|
|
24
25
|
[k: string]: string;
|
|
25
26
|
};
|
|
26
27
|
}>;
|
|
27
|
-
|
|
28
|
+
getFeaturesHelper(query: Region, opts: BaseOptions | undefined, observer: Observer<Feature>, allowRedispatch: boolean, originalQuery?: Region): Promise<void>;
|
|
29
|
+
getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
|
|
28
30
|
freeResources(): void;
|
|
29
31
|
}
|
|
@@ -8,10 +8,9 @@ const bed_1 = __importDefault(require("@gmod/bed"));
|
|
|
8
8
|
const BaseAdapter_1 = require("@jbrowse/core/data_adapters/BaseAdapter");
|
|
9
9
|
const io_1 = require("@jbrowse/core/util/io");
|
|
10
10
|
const rxjs_1 = require("@jbrowse/core/util/rxjs");
|
|
11
|
-
const
|
|
12
|
-
const operators_1 = require("rxjs/operators");
|
|
11
|
+
const util_1 = require("@jbrowse/core/util");
|
|
13
12
|
// locals
|
|
14
|
-
const
|
|
13
|
+
const util_2 = require("../util");
|
|
15
14
|
class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
16
15
|
async configurePre(opts) {
|
|
17
16
|
const pm = this.pluginManager;
|
|
@@ -37,7 +36,6 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
37
36
|
}
|
|
38
37
|
async getHeader(opts) {
|
|
39
38
|
const { parser, header } = await this.configure(opts);
|
|
40
|
-
// @ts-expect-error
|
|
41
39
|
const { version, fileType } = header;
|
|
42
40
|
const { fields, ...rest } = parser.autoSql;
|
|
43
41
|
return {
|
|
@@ -47,68 +45,121 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
47
45
|
fields: Object.fromEntries(fields.map(({ name, comment }) => [name, comment])),
|
|
48
46
|
};
|
|
49
47
|
}
|
|
50
|
-
|
|
48
|
+
async getFeaturesHelper(query, opts = {}, observer, allowRedispatch, originalQuery = query) {
|
|
51
49
|
const { signal } = opts;
|
|
52
50
|
const scoreColumn = this.getConf('scoreColumn');
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
51
|
+
const aggregateField = this.getConf('aggregateField');
|
|
52
|
+
const { parser, bigbed } = await this.configure(opts);
|
|
53
|
+
const feats = await bigbed.getFeatures(query.refName, query.start, query.end, {
|
|
54
|
+
signal,
|
|
55
|
+
basesPerSpan: query.end - query.start,
|
|
56
|
+
});
|
|
57
|
+
if (allowRedispatch && feats.length) {
|
|
58
|
+
let minStart = Infinity;
|
|
59
|
+
let maxEnd = -Infinity;
|
|
60
|
+
for (const feat of feats) {
|
|
61
|
+
if (feat.start < minStart) {
|
|
62
|
+
minStart = feat.start;
|
|
63
|
+
}
|
|
64
|
+
if (feat.end > maxEnd) {
|
|
65
|
+
maxEnd = feat.end;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (maxEnd > query.end || minStart < query.start) {
|
|
69
|
+
await this.getFeaturesHelper({ ...query, start: minStart, end: maxEnd }, opts, observer, false, query);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const parentAggregation = {};
|
|
74
|
+
if (feats.some(f => f.uniqueId === undefined)) {
|
|
75
|
+
throw new Error('found uniqueId undefined');
|
|
76
|
+
}
|
|
77
|
+
for (const feat of feats) {
|
|
78
|
+
const data = parser.parseLine(`${query.refName}\t${feat.start}\t${feat.end}\t${feat.rest}`, { uniqueId: feat.uniqueId });
|
|
79
|
+
const aggr = data[aggregateField];
|
|
80
|
+
if (!parentAggregation[aggr]) {
|
|
81
|
+
parentAggregation[aggr] = [];
|
|
82
|
+
}
|
|
83
|
+
const { uniqueId, type, chromStart, chromStarts, blockStarts, blockCount, blockSizes, chromEnd, thickStart, thickEnd, chrom, score, ...rest } = data;
|
|
84
|
+
const subfeatures = blockCount
|
|
85
|
+
? (0, util_2.makeBlocks)({
|
|
86
|
+
chromStarts,
|
|
87
|
+
blockStarts,
|
|
88
|
+
blockCount,
|
|
89
|
+
blockSizes,
|
|
90
|
+
uniqueId,
|
|
91
|
+
refName: query.refName,
|
|
92
|
+
start: feat.start,
|
|
93
|
+
})
|
|
94
|
+
: [];
|
|
95
|
+
if ((0, util_2.isUcscProcessedTranscript)(data)) {
|
|
96
|
+
const f = (0, util_2.ucscProcessedTranscript)({
|
|
97
|
+
...rest,
|
|
98
|
+
uniqueId,
|
|
99
|
+
type,
|
|
100
|
+
start: feat.start,
|
|
101
|
+
end: feat.end,
|
|
102
|
+
refName: query.refName,
|
|
103
|
+
score: scoreColumn ? +data[scoreColumn] : score,
|
|
104
|
+
chromStarts,
|
|
105
|
+
blockCount,
|
|
106
|
+
blockSizes,
|
|
107
|
+
thickStart,
|
|
108
|
+
thickEnd,
|
|
109
|
+
subfeatures,
|
|
59
110
|
});
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if (
|
|
65
|
-
|
|
111
|
+
if (aggr) {
|
|
112
|
+
parentAggregation[aggr].push(f);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
if ((0, util_1.doesIntersect2)(f.start, f.end, originalQuery.start, originalQuery.end)) {
|
|
116
|
+
observer.next(new util_1.SimpleFeature({ id: `${this.id}-${uniqueId}`, data: f }));
|
|
66
117
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
if ((0, util_1.doesIntersect2)(feat.start, feat.end, originalQuery.start, originalQuery.end)) {
|
|
122
|
+
observer.next(new util_1.SimpleFeature({
|
|
123
|
+
id: `${this.id}-${uniqueId}`,
|
|
124
|
+
data: {
|
|
125
|
+
...rest,
|
|
74
126
|
uniqueId,
|
|
75
|
-
|
|
127
|
+
type,
|
|
76
128
|
start: feat.start,
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
})).subscribe(observer);
|
|
129
|
+
score: scoreColumn ? +data[scoreColumn] : score,
|
|
130
|
+
end: feat.end,
|
|
131
|
+
refName: query.refName,
|
|
132
|
+
subfeatures,
|
|
133
|
+
},
|
|
134
|
+
}));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
Object.entries(parentAggregation).map(([name, subfeatures]) => {
|
|
139
|
+
const s = (0, util_1.min)(subfeatures.map(f => f.start));
|
|
140
|
+
const e = (0, util_1.max)(subfeatures.map(f => f.end));
|
|
141
|
+
if ((0, util_1.doesIntersect2)(s, e, originalQuery.start, originalQuery.end)) {
|
|
142
|
+
const { uniqueId, strand } = subfeatures[0];
|
|
143
|
+
observer.next(new util_1.SimpleFeature({
|
|
144
|
+
id: `${this.id}-${uniqueId}-parent`,
|
|
145
|
+
data: {
|
|
146
|
+
type: 'gene',
|
|
147
|
+
subfeatures,
|
|
148
|
+
strand,
|
|
149
|
+
name,
|
|
150
|
+
start: s,
|
|
151
|
+
end: e,
|
|
152
|
+
refName: query.refName,
|
|
153
|
+
},
|
|
154
|
+
}));
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
observer.complete();
|
|
158
|
+
}
|
|
159
|
+
getFeatures(query, opts = {}) {
|
|
160
|
+
return (0, rxjs_1.ObservableCreate)(async (observer) => {
|
|
161
|
+
try {
|
|
162
|
+
await this.getFeaturesHelper(query, opts, observer, true);
|
|
112
163
|
}
|
|
113
164
|
catch (e) {
|
|
114
165
|
observer.error(e);
|
|
@@ -17,5 +17,13 @@ declare const BigBedAdapter: import("@jbrowse/core/configuration/configurationSc
|
|
|
17
17
|
description: string;
|
|
18
18
|
defaultValue: string;
|
|
19
19
|
};
|
|
20
|
+
/**
|
|
21
|
+
* #slot
|
|
22
|
+
*/
|
|
23
|
+
aggregateField: {
|
|
24
|
+
type: string;
|
|
25
|
+
description: string;
|
|
26
|
+
defaultValue: string;
|
|
27
|
+
};
|
|
20
28
|
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
|
|
21
29
|
export default BigBedAdapter;
|
|
@@ -21,5 +21,13 @@ const BigBedAdapter = (0, configuration_1.ConfigurationSchema)('BigBedAdapter',
|
|
|
21
21
|
description: 'The column to use as a "score" attribute',
|
|
22
22
|
defaultValue: '',
|
|
23
23
|
},
|
|
24
|
+
/**
|
|
25
|
+
* #slot
|
|
26
|
+
*/
|
|
27
|
+
aggregateField: {
|
|
28
|
+
type: 'string',
|
|
29
|
+
description: 'An attribute to aggregate features with',
|
|
30
|
+
defaultValue: 'geneName',
|
|
31
|
+
},
|
|
24
32
|
}, { explicitlyTyped: true });
|
|
25
33
|
exports.default = BigBedAdapter;
|
package/dist/util.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import BED from '@gmod/bed';
|
|
2
2
|
import { SimpleFeature } from '@jbrowse/core/util';
|
|
3
|
-
interface MinimalFeature {
|
|
3
|
+
export interface MinimalFeature {
|
|
4
4
|
type: string;
|
|
5
5
|
start: number;
|
|
6
6
|
end: number;
|
|
7
7
|
refName: string;
|
|
8
|
+
[key: string]: unknown;
|
|
8
9
|
}
|
|
9
|
-
interface TranscriptFeat {
|
|
10
|
+
export interface TranscriptFeat extends MinimalFeature {
|
|
10
11
|
thickStart: number;
|
|
11
12
|
thickEnd: number;
|
|
12
13
|
blockCount: number;
|
|
@@ -15,13 +16,14 @@ interface TranscriptFeat {
|
|
|
15
16
|
refName: string;
|
|
16
17
|
strand?: number;
|
|
17
18
|
subfeatures: MinimalFeature[];
|
|
18
|
-
[key: string]: unknown;
|
|
19
19
|
}
|
|
20
20
|
export declare function ucscProcessedTranscript(feature: TranscriptFeat): TranscriptFeat | {
|
|
21
21
|
strand: number;
|
|
22
22
|
type: string;
|
|
23
23
|
refName: string;
|
|
24
24
|
subfeatures: MinimalFeature[];
|
|
25
|
+
start: number;
|
|
26
|
+
end: number;
|
|
25
27
|
};
|
|
26
28
|
export declare function makeBlocks({ start, uniqueId, refName, chromStarts, blockCount, blockSizes, blockStarts, }: {
|
|
27
29
|
blockCount: number;
|
|
@@ -39,9 +41,8 @@ export declare function makeBlocks({ start, uniqueId, refName, chromStarts, bloc
|
|
|
39
41
|
type: string;
|
|
40
42
|
}[];
|
|
41
43
|
export declare function featureData(line: string, colRef: number, colStart: number, colEnd: number, scoreColumn: string, parser: BED, uniqueId: string, names?: string[]): SimpleFeature;
|
|
42
|
-
export declare function
|
|
44
|
+
export declare function isUcscProcessedTranscript(f: {
|
|
43
45
|
thickStart?: number;
|
|
44
46
|
blockCount?: number;
|
|
45
47
|
strand?: number;
|
|
46
48
|
}): boolean | 0 | undefined;
|
|
47
|
-
export {};
|
package/dist/util.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.isUcscProcessedTranscript = exports.featureData = exports.makeBlocks = exports.ucscProcessedTranscript = void 0;
|
|
4
4
|
const util_1 = require("@jbrowse/core/util");
|
|
5
5
|
function ucscProcessedTranscript(feature) {
|
|
6
6
|
var _a;
|
|
@@ -160,7 +160,7 @@ function featureData(line, colRef, colStart, colEnd, scoreColumn, parser, unique
|
|
|
160
160
|
};
|
|
161
161
|
return new util_1.SimpleFeature({
|
|
162
162
|
id: uniqueId,
|
|
163
|
-
data:
|
|
163
|
+
data: isUcscProcessedTranscript(data)
|
|
164
164
|
? ucscProcessedTranscript({
|
|
165
165
|
thickStart,
|
|
166
166
|
thickEnd,
|
|
@@ -173,7 +173,7 @@ function featureData(line, colRef, colStart, colEnd, scoreColumn, parser, unique
|
|
|
173
173
|
});
|
|
174
174
|
}
|
|
175
175
|
exports.featureData = featureData;
|
|
176
|
-
function
|
|
176
|
+
function isUcscProcessedTranscript(f) {
|
|
177
177
|
return f.thickStart && f.blockCount && f.strand !== 0;
|
|
178
178
|
}
|
|
179
|
-
exports.
|
|
179
|
+
exports.isUcscProcessedTranscript = isUcscProcessedTranscript;
|
|
@@ -1,29 +1,31 @@
|
|
|
1
|
-
import { BigBed
|
|
1
|
+
import { BigBed } from '@gmod/bbi';
|
|
2
2
|
import BED from '@gmod/bed';
|
|
3
3
|
import { BaseFeatureDataAdapter, BaseOptions } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
4
4
|
import { Region } from '@jbrowse/core/util/types';
|
|
5
|
-
import { Feature } from '@jbrowse/core/util
|
|
5
|
+
import { Feature } from '@jbrowse/core/util';
|
|
6
|
+
import { Observer } from 'rxjs';
|
|
6
7
|
export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
7
8
|
private cached?;
|
|
8
9
|
configurePre(opts?: BaseOptions): Promise<{
|
|
9
10
|
bigbed: BigBed;
|
|
10
|
-
header: Header;
|
|
11
|
+
header: import("@gmod/bbi").Header;
|
|
11
12
|
parser: BED;
|
|
12
13
|
}>;
|
|
13
14
|
configure(opts?: BaseOptions): Promise<{
|
|
14
15
|
bigbed: BigBed;
|
|
15
|
-
header: Header;
|
|
16
|
+
header: import("@gmod/bbi").Header;
|
|
16
17
|
parser: BED;
|
|
17
18
|
}>;
|
|
18
19
|
getRefNames(opts?: BaseOptions): Promise<string[]>;
|
|
19
20
|
getHeader(opts?: BaseOptions): Promise<{
|
|
20
|
-
version:
|
|
21
|
+
version: number;
|
|
21
22
|
fileType: string;
|
|
22
23
|
autoSql: {};
|
|
23
24
|
fields: {
|
|
24
25
|
[k: string]: string;
|
|
25
26
|
};
|
|
26
27
|
}>;
|
|
27
|
-
|
|
28
|
+
getFeaturesHelper(query: Region, opts: BaseOptions | undefined, observer: Observer<Feature>, allowRedispatch: boolean, originalQuery?: Region): Promise<void>;
|
|
29
|
+
getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
|
|
28
30
|
freeResources(): void;
|
|
29
31
|
}
|
|
@@ -3,10 +3,9 @@ import BED from '@gmod/bed';
|
|
|
3
3
|
import { BaseFeatureDataAdapter, } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
4
4
|
import { openLocation } from '@jbrowse/core/util/io';
|
|
5
5
|
import { ObservableCreate } from '@jbrowse/core/util/rxjs';
|
|
6
|
-
import SimpleFeature from '@jbrowse/core/util
|
|
7
|
-
import { map, mergeAll } from 'rxjs/operators';
|
|
6
|
+
import { doesIntersect2, max, min, SimpleFeature, } from '@jbrowse/core/util';
|
|
8
7
|
// locals
|
|
9
|
-
import {
|
|
8
|
+
import { isUcscProcessedTranscript, makeBlocks, ucscProcessedTranscript, } from '../util';
|
|
10
9
|
export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
11
10
|
async configurePre(opts) {
|
|
12
11
|
const pm = this.pluginManager;
|
|
@@ -32,7 +31,6 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
32
31
|
}
|
|
33
32
|
async getHeader(opts) {
|
|
34
33
|
const { parser, header } = await this.configure(opts);
|
|
35
|
-
// @ts-expect-error
|
|
36
34
|
const { version, fileType } = header;
|
|
37
35
|
const { fields, ...rest } = parser.autoSql;
|
|
38
36
|
return {
|
|
@@ -42,68 +40,121 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
42
40
|
fields: Object.fromEntries(fields.map(({ name, comment }) => [name, comment])),
|
|
43
41
|
};
|
|
44
42
|
}
|
|
45
|
-
|
|
43
|
+
async getFeaturesHelper(query, opts = {}, observer, allowRedispatch, originalQuery = query) {
|
|
46
44
|
const { signal } = opts;
|
|
47
45
|
const scoreColumn = this.getConf('scoreColumn');
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
46
|
+
const aggregateField = this.getConf('aggregateField');
|
|
47
|
+
const { parser, bigbed } = await this.configure(opts);
|
|
48
|
+
const feats = await bigbed.getFeatures(query.refName, query.start, query.end, {
|
|
49
|
+
signal,
|
|
50
|
+
basesPerSpan: query.end - query.start,
|
|
51
|
+
});
|
|
52
|
+
if (allowRedispatch && feats.length) {
|
|
53
|
+
let minStart = Infinity;
|
|
54
|
+
let maxEnd = -Infinity;
|
|
55
|
+
for (const feat of feats) {
|
|
56
|
+
if (feat.start < minStart) {
|
|
57
|
+
minStart = feat.start;
|
|
58
|
+
}
|
|
59
|
+
if (feat.end > maxEnd) {
|
|
60
|
+
maxEnd = feat.end;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (maxEnd > query.end || minStart < query.start) {
|
|
64
|
+
await this.getFeaturesHelper({ ...query, start: minStart, end: maxEnd }, opts, observer, false, query);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const parentAggregation = {};
|
|
69
|
+
if (feats.some(f => f.uniqueId === undefined)) {
|
|
70
|
+
throw new Error('found uniqueId undefined');
|
|
71
|
+
}
|
|
72
|
+
for (const feat of feats) {
|
|
73
|
+
const data = parser.parseLine(`${query.refName}\t${feat.start}\t${feat.end}\t${feat.rest}`, { uniqueId: feat.uniqueId });
|
|
74
|
+
const aggr = data[aggregateField];
|
|
75
|
+
if (!parentAggregation[aggr]) {
|
|
76
|
+
parentAggregation[aggr] = [];
|
|
77
|
+
}
|
|
78
|
+
const { uniqueId, type, chromStart, chromStarts, blockStarts, blockCount, blockSizes, chromEnd, thickStart, thickEnd, chrom, score, ...rest } = data;
|
|
79
|
+
const subfeatures = blockCount
|
|
80
|
+
? makeBlocks({
|
|
81
|
+
chromStarts,
|
|
82
|
+
blockStarts,
|
|
83
|
+
blockCount,
|
|
84
|
+
blockSizes,
|
|
85
|
+
uniqueId,
|
|
86
|
+
refName: query.refName,
|
|
87
|
+
start: feat.start,
|
|
88
|
+
})
|
|
89
|
+
: [];
|
|
90
|
+
if (isUcscProcessedTranscript(data)) {
|
|
91
|
+
const f = ucscProcessedTranscript({
|
|
92
|
+
...rest,
|
|
93
|
+
uniqueId,
|
|
94
|
+
type,
|
|
95
|
+
start: feat.start,
|
|
96
|
+
end: feat.end,
|
|
97
|
+
refName: query.refName,
|
|
98
|
+
score: scoreColumn ? +data[scoreColumn] : score,
|
|
99
|
+
chromStarts,
|
|
100
|
+
blockCount,
|
|
101
|
+
blockSizes,
|
|
102
|
+
thickStart,
|
|
103
|
+
thickEnd,
|
|
104
|
+
subfeatures,
|
|
54
105
|
});
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (
|
|
60
|
-
|
|
106
|
+
if (aggr) {
|
|
107
|
+
parentAggregation[aggr].push(f);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
if (doesIntersect2(f.start, f.end, originalQuery.start, originalQuery.end)) {
|
|
111
|
+
observer.next(new SimpleFeature({ id: `${this.id}-${uniqueId}`, data: f }));
|
|
61
112
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
if (doesIntersect2(feat.start, feat.end, originalQuery.start, originalQuery.end)) {
|
|
117
|
+
observer.next(new SimpleFeature({
|
|
118
|
+
id: `${this.id}-${uniqueId}`,
|
|
119
|
+
data: {
|
|
120
|
+
...rest,
|
|
69
121
|
uniqueId,
|
|
70
|
-
|
|
122
|
+
type,
|
|
71
123
|
start: feat.start,
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
})).subscribe(observer);
|
|
124
|
+
score: scoreColumn ? +data[scoreColumn] : score,
|
|
125
|
+
end: feat.end,
|
|
126
|
+
refName: query.refName,
|
|
127
|
+
subfeatures,
|
|
128
|
+
},
|
|
129
|
+
}));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
Object.entries(parentAggregation).map(([name, subfeatures]) => {
|
|
134
|
+
const s = min(subfeatures.map(f => f.start));
|
|
135
|
+
const e = max(subfeatures.map(f => f.end));
|
|
136
|
+
if (doesIntersect2(s, e, originalQuery.start, originalQuery.end)) {
|
|
137
|
+
const { uniqueId, strand } = subfeatures[0];
|
|
138
|
+
observer.next(new SimpleFeature({
|
|
139
|
+
id: `${this.id}-${uniqueId}-parent`,
|
|
140
|
+
data: {
|
|
141
|
+
type: 'gene',
|
|
142
|
+
subfeatures,
|
|
143
|
+
strand,
|
|
144
|
+
name,
|
|
145
|
+
start: s,
|
|
146
|
+
end: e,
|
|
147
|
+
refName: query.refName,
|
|
148
|
+
},
|
|
149
|
+
}));
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
observer.complete();
|
|
153
|
+
}
|
|
154
|
+
getFeatures(query, opts = {}) {
|
|
155
|
+
return ObservableCreate(async (observer) => {
|
|
156
|
+
try {
|
|
157
|
+
await this.getFeaturesHelper(query, opts, observer, true);
|
|
107
158
|
}
|
|
108
159
|
catch (e) {
|
|
109
160
|
observer.error(e);
|
|
@@ -17,5 +17,13 @@ declare const BigBedAdapter: import("@jbrowse/core/configuration/configurationSc
|
|
|
17
17
|
description: string;
|
|
18
18
|
defaultValue: string;
|
|
19
19
|
};
|
|
20
|
+
/**
|
|
21
|
+
* #slot
|
|
22
|
+
*/
|
|
23
|
+
aggregateField: {
|
|
24
|
+
type: string;
|
|
25
|
+
description: string;
|
|
26
|
+
defaultValue: string;
|
|
27
|
+
};
|
|
20
28
|
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
|
|
21
29
|
export default BigBedAdapter;
|
|
@@ -19,5 +19,13 @@ const BigBedAdapter = ConfigurationSchema('BigBedAdapter', {
|
|
|
19
19
|
description: 'The column to use as a "score" attribute',
|
|
20
20
|
defaultValue: '',
|
|
21
21
|
},
|
|
22
|
+
/**
|
|
23
|
+
* #slot
|
|
24
|
+
*/
|
|
25
|
+
aggregateField: {
|
|
26
|
+
type: 'string',
|
|
27
|
+
description: 'An attribute to aggregate features with',
|
|
28
|
+
defaultValue: 'geneName',
|
|
29
|
+
},
|
|
22
30
|
}, { explicitlyTyped: true });
|
|
23
31
|
export default BigBedAdapter;
|
package/esm/util.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import BED from '@gmod/bed';
|
|
2
2
|
import { SimpleFeature } from '@jbrowse/core/util';
|
|
3
|
-
interface MinimalFeature {
|
|
3
|
+
export interface MinimalFeature {
|
|
4
4
|
type: string;
|
|
5
5
|
start: number;
|
|
6
6
|
end: number;
|
|
7
7
|
refName: string;
|
|
8
|
+
[key: string]: unknown;
|
|
8
9
|
}
|
|
9
|
-
interface TranscriptFeat {
|
|
10
|
+
export interface TranscriptFeat extends MinimalFeature {
|
|
10
11
|
thickStart: number;
|
|
11
12
|
thickEnd: number;
|
|
12
13
|
blockCount: number;
|
|
@@ -15,13 +16,14 @@ interface TranscriptFeat {
|
|
|
15
16
|
refName: string;
|
|
16
17
|
strand?: number;
|
|
17
18
|
subfeatures: MinimalFeature[];
|
|
18
|
-
[key: string]: unknown;
|
|
19
19
|
}
|
|
20
20
|
export declare function ucscProcessedTranscript(feature: TranscriptFeat): TranscriptFeat | {
|
|
21
21
|
strand: number;
|
|
22
22
|
type: string;
|
|
23
23
|
refName: string;
|
|
24
24
|
subfeatures: MinimalFeature[];
|
|
25
|
+
start: number;
|
|
26
|
+
end: number;
|
|
25
27
|
};
|
|
26
28
|
export declare function makeBlocks({ start, uniqueId, refName, chromStarts, blockCount, blockSizes, blockStarts, }: {
|
|
27
29
|
blockCount: number;
|
|
@@ -39,9 +41,8 @@ export declare function makeBlocks({ start, uniqueId, refName, chromStarts, bloc
|
|
|
39
41
|
type: string;
|
|
40
42
|
}[];
|
|
41
43
|
export declare function featureData(line: string, colRef: number, colStart: number, colEnd: number, scoreColumn: string, parser: BED, uniqueId: string, names?: string[]): SimpleFeature;
|
|
42
|
-
export declare function
|
|
44
|
+
export declare function isUcscProcessedTranscript(f: {
|
|
43
45
|
thickStart?: number;
|
|
44
46
|
blockCount?: number;
|
|
45
47
|
strand?: number;
|
|
46
48
|
}): boolean | 0 | undefined;
|
|
47
|
-
export {};
|
package/esm/util.js
CHANGED
|
@@ -155,7 +155,7 @@ export function featureData(line, colRef, colStart, colEnd, scoreColumn, parser,
|
|
|
155
155
|
};
|
|
156
156
|
return new SimpleFeature({
|
|
157
157
|
id: uniqueId,
|
|
158
|
-
data:
|
|
158
|
+
data: isUcscProcessedTranscript(data)
|
|
159
159
|
? ucscProcessedTranscript({
|
|
160
160
|
thickStart,
|
|
161
161
|
thickEnd,
|
|
@@ -167,6 +167,6 @@ export function featureData(line, colRef, colStart, colEnd, scoreColumn, parser,
|
|
|
167
167
|
: f,
|
|
168
168
|
});
|
|
169
169
|
}
|
|
170
|
-
export function
|
|
170
|
+
export function isUcscProcessedTranscript(f) {
|
|
171
171
|
return f.thickStart && f.blockCount && f.strand !== 0;
|
|
172
172
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/plugin-bed",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.12.0",
|
|
4
4
|
"description": "JBrowse 2 bed adapters, tracks, etc.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jbrowse",
|
|
@@ -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": "935f2602d29abc737bb1f493a922b6218d023ae2"
|
|
59
59
|
}
|