@jbrowse/plugin-bed 3.3.0 → 3.5.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/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/BedpeAdapter/BedpeAdapter.d.ts +0 -1
- package/dist/BedpeAdapter/BedpeAdapter.js +0 -1
- package/dist/BigBedAdapter/BigBedAdapter.d.ts +3 -1
- package/dist/BigBedAdapter/BigBedAdapter.js +96 -89
- package/dist/generateUcscTranscript.d.ts +7 -2
- package/dist/generateUcscTranscript.js +98 -74
- package/dist/util.d.ts +12 -2
- package/esm/BedAdapter/BedAdapter.d.ts +0 -1
- package/esm/BedAdapter/BedAdapter.js +31 -22
- 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/BedpeAdapter/BedpeAdapter.d.ts +0 -1
- package/esm/BedpeAdapter/BedpeAdapter.js +0 -1
- package/esm/BigBedAdapter/BigBedAdapter.d.ts +3 -1
- package/esm/BigBedAdapter/BigBedAdapter.js +96 -89
- package/esm/generateUcscTranscript.d.ts +7 -2
- package/esm/generateUcscTranscript.js +98 -74
- package/esm/util.d.ts +12 -2
- 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;
|
|
@@ -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
|
}
|
|
@@ -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
|
}
|
|
@@ -42,9 +42,9 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
42
42
|
}
|
|
43
43
|
async getRefNameAliases(opts) {
|
|
44
44
|
const { header } = await this.configure(opts);
|
|
45
|
-
const ret = await Promise.all(Object.keys(header.refsByName).map(async (
|
|
45
|
+
const ret = await Promise.all(Object.keys(header.refsByName).map(async (refName) => (await (0, rxjs_2.firstValueFrom)(this.getFeatures({
|
|
46
46
|
assemblyName: '',
|
|
47
|
-
refName
|
|
47
|
+
refName,
|
|
48
48
|
start: 0,
|
|
49
49
|
end: 1,
|
|
50
50
|
}).pipe((0, rxjs_2.toArray)())))[0]));
|
|
@@ -73,16 +73,20 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
73
73
|
async getHeader(opts) {
|
|
74
74
|
const { parser, header } = await this.configure(opts);
|
|
75
75
|
const { version, fileType } = header;
|
|
76
|
-
const { fields, ...
|
|
76
|
+
const { fields, ...autoSql } = parser.autoSql;
|
|
77
77
|
return {
|
|
78
78
|
version,
|
|
79
79
|
fileType,
|
|
80
|
-
autoSql
|
|
81
|
-
fields:
|
|
80
|
+
autoSql,
|
|
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
|
-
var _a;
|
|
86
90
|
const { statusCallback = () => { } } = opts;
|
|
87
91
|
const scoreColumn = this.getConf('scoreColumn');
|
|
88
92
|
const aggregateField = this.getConf('aggregateField');
|
|
@@ -90,94 +94,98 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
90
94
|
const feats = await (0, util_1.updateStatus)('Downloading features', statusCallback, () => bigbed.getFeatures(query.refName, query.start, query.end, {
|
|
91
95
|
basesPerSpan: query.end - query.start,
|
|
92
96
|
}));
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const splitLine = [
|
|
100
|
-
query.refName,
|
|
101
|
-
`${feat.start}`,
|
|
102
|
-
`${feat.end}`,
|
|
103
|
-
...(((_a = feat.rest) === null || _a === void 0 ? void 0 : _a.split('\t')) || []),
|
|
104
|
-
];
|
|
105
|
-
const data = parser.parseLine(splitLine, {
|
|
106
|
-
uniqueId: feat.uniqueId,
|
|
107
|
-
});
|
|
108
|
-
const aggr = data[aggregateField];
|
|
109
|
-
if (!parentAggregation[aggr]) {
|
|
110
|
-
parentAggregation[aggr] = [];
|
|
97
|
+
await (0, util_1.updateStatus)('Processing features', statusCallback, async () => {
|
|
98
|
+
var _a;
|
|
99
|
+
const parentAggregation = {};
|
|
100
|
+
const parentAggregationFlat = [];
|
|
101
|
+
if (feats.some(f => f.uniqueId === undefined)) {
|
|
102
|
+
throw new Error('found uniqueId undefined');
|
|
111
103
|
}
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
parentAggregation[aggr]
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
if ((0, util_1.doesIntersect2)(f.start, f.end, originalQuery.start, originalQuery.end)) {
|
|
129
|
-
observer.next(new util_1.SimpleFeature({
|
|
130
|
-
id: `${this.id}-${uniqueId}`,
|
|
131
|
-
data: f,
|
|
132
|
-
}));
|
|
104
|
+
for (const feat of feats) {
|
|
105
|
+
const splitLine = [
|
|
106
|
+
query.refName,
|
|
107
|
+
`${feat.start}`,
|
|
108
|
+
`${feat.end}`,
|
|
109
|
+
...(((_a = feat.rest) === null || _a === void 0 ? void 0 : _a.split('\t')) || []),
|
|
110
|
+
];
|
|
111
|
+
const data = parser.parseLine(splitLine, {
|
|
112
|
+
uniqueId: feat.uniqueId,
|
|
113
|
+
});
|
|
114
|
+
const aggr = data[aggregateField];
|
|
115
|
+
const aggrIsNotNone = aggr && aggr !== 'none';
|
|
116
|
+
if (aggrIsNotNone && !parentAggregation[aggr]) {
|
|
117
|
+
parentAggregation[aggr] = [];
|
|
133
118
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
119
|
+
const { uniqueId, type, chrom, chromStart, chromEnd, description, chromStarts: chromStarts2, blockStarts: blockStarts2, blockSizes: blockSizes2, score: score2, blockCount, thickStart, thickEnd, strand, ...rest } = data;
|
|
120
|
+
const f = (0, util_2.featureData2)({
|
|
121
|
+
...rest,
|
|
122
|
+
scoreColumn,
|
|
123
|
+
splitLine,
|
|
124
|
+
parser,
|
|
125
|
+
uniqueId,
|
|
126
|
+
start: feat.start,
|
|
127
|
+
end: feat.end,
|
|
128
|
+
refName: query.refName,
|
|
129
|
+
});
|
|
130
|
+
if (aggrIsNotNone) {
|
|
131
|
+
parentAggregation[aggr].push(f);
|
|
132
|
+
parentAggregationFlat.push(f);
|
|
142
133
|
}
|
|
143
|
-
|
|
144
|
-
|
|
134
|
+
else {
|
|
135
|
+
if ((0, util_1.doesIntersect2)(f.start, f.end, originalQuery.start, originalQuery.end)) {
|
|
136
|
+
observer.next(new util_1.SimpleFeature({
|
|
137
|
+
id: `${this.id}-${uniqueId}`,
|
|
138
|
+
data: f,
|
|
139
|
+
}));
|
|
140
|
+
}
|
|
145
141
|
}
|
|
146
142
|
}
|
|
147
|
-
if (
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
subfeatures: subs,
|
|
173
|
-
strand: ((_b = subs[0]) === null || _b === void 0 ? void 0 : _b.strand) || 1,
|
|
174
|
-
name,
|
|
175
|
-
start: s,
|
|
176
|
-
end: e,
|
|
177
|
-
refName: query.refName,
|
|
178
|
-
},
|
|
179
|
-
}));
|
|
143
|
+
if (allowRedispatch && parentAggregationFlat.length) {
|
|
144
|
+
let minStart = Number.POSITIVE_INFINITY;
|
|
145
|
+
let maxEnd = Number.NEGATIVE_INFINITY;
|
|
146
|
+
for (const feat of parentAggregationFlat) {
|
|
147
|
+
if (feat.start < minStart) {
|
|
148
|
+
minStart = feat.start;
|
|
149
|
+
}
|
|
150
|
+
if (feat.end > maxEnd) {
|
|
151
|
+
maxEnd = feat.end;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (maxEnd > query.end || minStart < query.start) {
|
|
155
|
+
await this.getFeaturesHelper({
|
|
156
|
+
query: {
|
|
157
|
+
...query,
|
|
158
|
+
start: minStart - 500000,
|
|
159
|
+
end: maxEnd + 500000,
|
|
160
|
+
},
|
|
161
|
+
opts,
|
|
162
|
+
observer,
|
|
163
|
+
allowRedispatch: false,
|
|
164
|
+
originalQuery: query,
|
|
165
|
+
});
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
180
168
|
}
|
|
169
|
+
Object.entries(parentAggregation).map(([name, subfeatures]) => {
|
|
170
|
+
var _a, _b;
|
|
171
|
+
const s = (0, util_1.min)(subfeatures.map(f => f.start));
|
|
172
|
+
const e = (0, util_1.max)(subfeatures.map(f => f.end));
|
|
173
|
+
if ((0, util_1.doesIntersect2)(s, e, originalQuery.start, originalQuery.end)) {
|
|
174
|
+
const subs = subfeatures.sort((a, b) => a.uniqueId.localeCompare(b.uniqueId));
|
|
175
|
+
observer.next(new util_1.SimpleFeature({
|
|
176
|
+
id: `${this.id}-${(_a = subs[0]) === null || _a === void 0 ? void 0 : _a.uniqueId}-parent`,
|
|
177
|
+
data: {
|
|
178
|
+
type: 'gene',
|
|
179
|
+
subfeatures: subs,
|
|
180
|
+
strand: ((_b = subs[0]) === null || _b === void 0 ? void 0 : _b.strand) || 1,
|
|
181
|
+
name,
|
|
182
|
+
start: s,
|
|
183
|
+
end: e,
|
|
184
|
+
refName: query.refName,
|
|
185
|
+
},
|
|
186
|
+
}));
|
|
187
|
+
}
|
|
188
|
+
});
|
|
181
189
|
});
|
|
182
190
|
observer.complete();
|
|
183
191
|
}
|
|
@@ -200,6 +208,5 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
200
208
|
}
|
|
201
209
|
}, opts.stopToken);
|
|
202
210
|
}
|
|
203
|
-
freeResources() { }
|
|
204
211
|
}
|
|
205
212
|
exports.default = BigBedAdapter;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { TranscriptFeat } from './types';
|
|
2
2
|
export declare function isUcscTranscript({ thickStart, blockCount, strand, }: {
|
|
3
3
|
thickStart?: number;
|
|
4
4
|
blockCount?: number;
|
|
@@ -9,7 +9,12 @@ export declare function generateUcscTranscript(data: TranscriptFeat): {
|
|
|
9
9
|
strand: number;
|
|
10
10
|
type: string;
|
|
11
11
|
refName: string;
|
|
12
|
-
subfeatures:
|
|
12
|
+
subfeatures: {
|
|
13
|
+
type: string;
|
|
14
|
+
start: number;
|
|
15
|
+
end: number;
|
|
16
|
+
refName: string;
|
|
17
|
+
}[];
|
|
13
18
|
start: number;
|
|
14
19
|
end: number;
|
|
15
20
|
};
|
|
@@ -12,81 +12,105 @@ function generateUcscTranscript(data) {
|
|
|
12
12
|
const feats = oldSubfeatures
|
|
13
13
|
.filter(child => child.type === 'block')
|
|
14
14
|
.sort((a, b) => a.start - b.start);
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
15
|
+
const { cdsEndStat, cdsStartStat } = rest2;
|
|
16
|
+
if (cdsStartStat === 'none' && cdsEndStat === 'none') {
|
|
17
|
+
return {
|
|
18
|
+
...rest2,
|
|
19
|
+
uniqueId,
|
|
20
|
+
strand,
|
|
21
|
+
type: 'transcript',
|
|
22
|
+
refName,
|
|
23
|
+
subfeatures: feats.map(e => ({
|
|
24
|
+
...e,
|
|
25
|
+
type: 'exon',
|
|
26
|
+
})),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
for (const block of feats) {
|
|
31
|
+
const start = block.start;
|
|
32
|
+
const end = block.end;
|
|
33
|
+
if (thickStart >= end) {
|
|
34
|
+
subfeatures.push({
|
|
35
|
+
type: `${strand > 0 ? 'five' : 'three'}_prime_UTR`,
|
|
36
|
+
start,
|
|
37
|
+
end,
|
|
38
|
+
refName,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
else if (thickStart > start && thickStart < end && thickEnd >= end) {
|
|
42
|
+
subfeatures.push({
|
|
43
|
+
type: `${strand > 0 ? 'five' : 'three'}_prime_UTR`,
|
|
44
|
+
start,
|
|
45
|
+
end: thickStart,
|
|
46
|
+
refName,
|
|
47
|
+
}, {
|
|
48
|
+
type: 'CDS',
|
|
49
|
+
phase: 0,
|
|
50
|
+
start: thickStart,
|
|
51
|
+
end,
|
|
52
|
+
refName,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
else if (thickStart <= start && thickEnd >= end) {
|
|
56
|
+
subfeatures.push({
|
|
57
|
+
type: 'CDS',
|
|
58
|
+
phase: 0,
|
|
59
|
+
start,
|
|
60
|
+
end,
|
|
61
|
+
refName,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
else if (thickStart > start && thickStart < end && thickEnd < end) {
|
|
65
|
+
subfeatures.push({
|
|
66
|
+
type: `${strand > 0 ? 'five' : 'three'}_prime_UTR`,
|
|
67
|
+
start,
|
|
68
|
+
end: thickStart,
|
|
69
|
+
refName,
|
|
70
|
+
}, {
|
|
71
|
+
type: 'CDS',
|
|
72
|
+
phase: 0,
|
|
73
|
+
start: thickStart,
|
|
74
|
+
end: thickEnd,
|
|
75
|
+
refName,
|
|
76
|
+
}, {
|
|
77
|
+
type: `${strand > 0 ? 'three' : 'five'}_prime_UTR`,
|
|
78
|
+
start: thickEnd,
|
|
79
|
+
end,
|
|
80
|
+
refName,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
else if (thickStart <= start && thickEnd > start && thickEnd < end) {
|
|
84
|
+
subfeatures.push({
|
|
85
|
+
type: 'CDS',
|
|
86
|
+
phase: 0,
|
|
87
|
+
start,
|
|
88
|
+
end: thickEnd,
|
|
89
|
+
refName,
|
|
90
|
+
}, {
|
|
91
|
+
type: `${strand > 0 ? 'three' : 'five'}_prime_UTR`,
|
|
92
|
+
start: thickEnd,
|
|
93
|
+
end,
|
|
94
|
+
refName,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
else if (thickEnd <= start) {
|
|
98
|
+
subfeatures.push({
|
|
99
|
+
type: `${strand > 0 ? 'three' : 'five'}_prime_UTR`,
|
|
100
|
+
start,
|
|
101
|
+
end,
|
|
102
|
+
refName,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
89
105
|
}
|
|
106
|
+
return {
|
|
107
|
+
...rest2,
|
|
108
|
+
uniqueId,
|
|
109
|
+
strand,
|
|
110
|
+
type: 'mRNA',
|
|
111
|
+
refName,
|
|
112
|
+
subfeatures,
|
|
113
|
+
};
|
|
90
114
|
}
|
|
91
115
|
return {
|
|
92
116
|
...rest2,
|
package/dist/util.d.ts
CHANGED
|
@@ -89,7 +89,12 @@ export declare function featureData({ line, colRef, colStart, colEnd, scoreColum
|
|
|
89
89
|
strand: number;
|
|
90
90
|
type: string;
|
|
91
91
|
refName: string;
|
|
92
|
-
subfeatures:
|
|
92
|
+
subfeatures: {
|
|
93
|
+
type: string;
|
|
94
|
+
start: number;
|
|
95
|
+
end: number;
|
|
96
|
+
refName: string;
|
|
97
|
+
}[];
|
|
93
98
|
start: number;
|
|
94
99
|
end: number;
|
|
95
100
|
} | {
|
|
@@ -182,7 +187,12 @@ export declare function featureData2({ splitLine, refName, start, end, parser, u
|
|
|
182
187
|
strand: number;
|
|
183
188
|
type: string;
|
|
184
189
|
refName: string;
|
|
185
|
-
subfeatures:
|
|
190
|
+
subfeatures: {
|
|
191
|
+
type: string;
|
|
192
|
+
start: number;
|
|
193
|
+
end: number;
|
|
194
|
+
refName: string;
|
|
195
|
+
}[];
|
|
186
196
|
start: number;
|
|
187
197
|
end: number;
|
|
188
198
|
} | {
|
|
@@ -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
|
}
|
|
@@ -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
|
}
|
|
@@ -37,9 +37,9 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
37
37
|
}
|
|
38
38
|
async getRefNameAliases(opts) {
|
|
39
39
|
const { header } = await this.configure(opts);
|
|
40
|
-
const ret = await Promise.all(Object.keys(header.refsByName).map(async (
|
|
40
|
+
const ret = await Promise.all(Object.keys(header.refsByName).map(async (refName) => (await firstValueFrom(this.getFeatures({
|
|
41
41
|
assemblyName: '',
|
|
42
|
-
refName
|
|
42
|
+
refName,
|
|
43
43
|
start: 0,
|
|
44
44
|
end: 1,
|
|
45
45
|
}).pipe(toArray())))[0]));
|
|
@@ -68,16 +68,20 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
68
68
|
async getHeader(opts) {
|
|
69
69
|
const { parser, header } = await this.configure(opts);
|
|
70
70
|
const { version, fileType } = header;
|
|
71
|
-
const { fields, ...
|
|
71
|
+
const { fields, ...autoSql } = parser.autoSql;
|
|
72
72
|
return {
|
|
73
73
|
version,
|
|
74
74
|
fileType,
|
|
75
|
-
autoSql
|
|
76
|
-
fields:
|
|
75
|
+
autoSql,
|
|
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
|
-
var _a;
|
|
81
85
|
const { statusCallback = () => { } } = opts;
|
|
82
86
|
const scoreColumn = this.getConf('scoreColumn');
|
|
83
87
|
const aggregateField = this.getConf('aggregateField');
|
|
@@ -85,94 +89,98 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
85
89
|
const feats = await updateStatus('Downloading features', statusCallback, () => bigbed.getFeatures(query.refName, query.start, query.end, {
|
|
86
90
|
basesPerSpan: query.end - query.start,
|
|
87
91
|
}));
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
const splitLine = [
|
|
95
|
-
query.refName,
|
|
96
|
-
`${feat.start}`,
|
|
97
|
-
`${feat.end}`,
|
|
98
|
-
...(((_a = feat.rest) === null || _a === void 0 ? void 0 : _a.split('\t')) || []),
|
|
99
|
-
];
|
|
100
|
-
const data = parser.parseLine(splitLine, {
|
|
101
|
-
uniqueId: feat.uniqueId,
|
|
102
|
-
});
|
|
103
|
-
const aggr = data[aggregateField];
|
|
104
|
-
if (!parentAggregation[aggr]) {
|
|
105
|
-
parentAggregation[aggr] = [];
|
|
92
|
+
await updateStatus('Processing features', statusCallback, async () => {
|
|
93
|
+
var _a;
|
|
94
|
+
const parentAggregation = {};
|
|
95
|
+
const parentAggregationFlat = [];
|
|
96
|
+
if (feats.some(f => f.uniqueId === undefined)) {
|
|
97
|
+
throw new Error('found uniqueId undefined');
|
|
106
98
|
}
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
parentAggregation[aggr]
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
else {
|
|
123
|
-
if (doesIntersect2(f.start, f.end, originalQuery.start, originalQuery.end)) {
|
|
124
|
-
observer.next(new SimpleFeature({
|
|
125
|
-
id: `${this.id}-${uniqueId}`,
|
|
126
|
-
data: f,
|
|
127
|
-
}));
|
|
99
|
+
for (const feat of feats) {
|
|
100
|
+
const splitLine = [
|
|
101
|
+
query.refName,
|
|
102
|
+
`${feat.start}`,
|
|
103
|
+
`${feat.end}`,
|
|
104
|
+
...(((_a = feat.rest) === null || _a === void 0 ? void 0 : _a.split('\t')) || []),
|
|
105
|
+
];
|
|
106
|
+
const data = parser.parseLine(splitLine, {
|
|
107
|
+
uniqueId: feat.uniqueId,
|
|
108
|
+
});
|
|
109
|
+
const aggr = data[aggregateField];
|
|
110
|
+
const aggrIsNotNone = aggr && aggr !== 'none';
|
|
111
|
+
if (aggrIsNotNone && !parentAggregation[aggr]) {
|
|
112
|
+
parentAggregation[aggr] = [];
|
|
128
113
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
114
|
+
const { uniqueId, type, chrom, chromStart, chromEnd, description, chromStarts: chromStarts2, blockStarts: blockStarts2, blockSizes: blockSizes2, score: score2, blockCount, thickStart, thickEnd, strand, ...rest } = data;
|
|
115
|
+
const f = featureData2({
|
|
116
|
+
...rest,
|
|
117
|
+
scoreColumn,
|
|
118
|
+
splitLine,
|
|
119
|
+
parser,
|
|
120
|
+
uniqueId,
|
|
121
|
+
start: feat.start,
|
|
122
|
+
end: feat.end,
|
|
123
|
+
refName: query.refName,
|
|
124
|
+
});
|
|
125
|
+
if (aggrIsNotNone) {
|
|
126
|
+
parentAggregation[aggr].push(f);
|
|
127
|
+
parentAggregationFlat.push(f);
|
|
137
128
|
}
|
|
138
|
-
|
|
139
|
-
|
|
129
|
+
else {
|
|
130
|
+
if (doesIntersect2(f.start, f.end, originalQuery.start, originalQuery.end)) {
|
|
131
|
+
observer.next(new SimpleFeature({
|
|
132
|
+
id: `${this.id}-${uniqueId}`,
|
|
133
|
+
data: f,
|
|
134
|
+
}));
|
|
135
|
+
}
|
|
140
136
|
}
|
|
141
137
|
}
|
|
142
|
-
if (
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
subfeatures: subs,
|
|
168
|
-
strand: ((_b = subs[0]) === null || _b === void 0 ? void 0 : _b.strand) || 1,
|
|
169
|
-
name,
|
|
170
|
-
start: s,
|
|
171
|
-
end: e,
|
|
172
|
-
refName: query.refName,
|
|
173
|
-
},
|
|
174
|
-
}));
|
|
138
|
+
if (allowRedispatch && parentAggregationFlat.length) {
|
|
139
|
+
let minStart = Number.POSITIVE_INFINITY;
|
|
140
|
+
let maxEnd = Number.NEGATIVE_INFINITY;
|
|
141
|
+
for (const feat of parentAggregationFlat) {
|
|
142
|
+
if (feat.start < minStart) {
|
|
143
|
+
minStart = feat.start;
|
|
144
|
+
}
|
|
145
|
+
if (feat.end > maxEnd) {
|
|
146
|
+
maxEnd = feat.end;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (maxEnd > query.end || minStart < query.start) {
|
|
150
|
+
await this.getFeaturesHelper({
|
|
151
|
+
query: {
|
|
152
|
+
...query,
|
|
153
|
+
start: minStart - 500000,
|
|
154
|
+
end: maxEnd + 500000,
|
|
155
|
+
},
|
|
156
|
+
opts,
|
|
157
|
+
observer,
|
|
158
|
+
allowRedispatch: false,
|
|
159
|
+
originalQuery: query,
|
|
160
|
+
});
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
175
163
|
}
|
|
164
|
+
Object.entries(parentAggregation).map(([name, subfeatures]) => {
|
|
165
|
+
var _a, _b;
|
|
166
|
+
const s = min(subfeatures.map(f => f.start));
|
|
167
|
+
const e = max(subfeatures.map(f => f.end));
|
|
168
|
+
if (doesIntersect2(s, e, originalQuery.start, originalQuery.end)) {
|
|
169
|
+
const subs = subfeatures.sort((a, b) => a.uniqueId.localeCompare(b.uniqueId));
|
|
170
|
+
observer.next(new SimpleFeature({
|
|
171
|
+
id: `${this.id}-${(_a = subs[0]) === null || _a === void 0 ? void 0 : _a.uniqueId}-parent`,
|
|
172
|
+
data: {
|
|
173
|
+
type: 'gene',
|
|
174
|
+
subfeatures: subs,
|
|
175
|
+
strand: ((_b = subs[0]) === null || _b === void 0 ? void 0 : _b.strand) || 1,
|
|
176
|
+
name,
|
|
177
|
+
start: s,
|
|
178
|
+
end: e,
|
|
179
|
+
refName: query.refName,
|
|
180
|
+
},
|
|
181
|
+
}));
|
|
182
|
+
}
|
|
183
|
+
});
|
|
176
184
|
});
|
|
177
185
|
observer.complete();
|
|
178
186
|
}
|
|
@@ -195,5 +203,4 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
195
203
|
}
|
|
196
204
|
}, opts.stopToken);
|
|
197
205
|
}
|
|
198
|
-
freeResources() { }
|
|
199
206
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { TranscriptFeat } from './types';
|
|
2
2
|
export declare function isUcscTranscript({ thickStart, blockCount, strand, }: {
|
|
3
3
|
thickStart?: number;
|
|
4
4
|
blockCount?: number;
|
|
@@ -9,7 +9,12 @@ export declare function generateUcscTranscript(data: TranscriptFeat): {
|
|
|
9
9
|
strand: number;
|
|
10
10
|
type: string;
|
|
11
11
|
refName: string;
|
|
12
|
-
subfeatures:
|
|
12
|
+
subfeatures: {
|
|
13
|
+
type: string;
|
|
14
|
+
start: number;
|
|
15
|
+
end: number;
|
|
16
|
+
refName: string;
|
|
17
|
+
}[];
|
|
13
18
|
start: number;
|
|
14
19
|
end: number;
|
|
15
20
|
};
|
|
@@ -8,81 +8,105 @@ export function generateUcscTranscript(data) {
|
|
|
8
8
|
const feats = oldSubfeatures
|
|
9
9
|
.filter(child => child.type === 'block')
|
|
10
10
|
.sort((a, b) => a.start - b.start);
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
11
|
+
const { cdsEndStat, cdsStartStat } = rest2;
|
|
12
|
+
if (cdsStartStat === 'none' && cdsEndStat === 'none') {
|
|
13
|
+
return {
|
|
14
|
+
...rest2,
|
|
15
|
+
uniqueId,
|
|
16
|
+
strand,
|
|
17
|
+
type: 'transcript',
|
|
18
|
+
refName,
|
|
19
|
+
subfeatures: feats.map(e => ({
|
|
20
|
+
...e,
|
|
21
|
+
type: 'exon',
|
|
22
|
+
})),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
for (const block of feats) {
|
|
27
|
+
const start = block.start;
|
|
28
|
+
const end = block.end;
|
|
29
|
+
if (thickStart >= end) {
|
|
30
|
+
subfeatures.push({
|
|
31
|
+
type: `${strand > 0 ? 'five' : 'three'}_prime_UTR`,
|
|
32
|
+
start,
|
|
33
|
+
end,
|
|
34
|
+
refName,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
else if (thickStart > start && thickStart < end && thickEnd >= end) {
|
|
38
|
+
subfeatures.push({
|
|
39
|
+
type: `${strand > 0 ? 'five' : 'three'}_prime_UTR`,
|
|
40
|
+
start,
|
|
41
|
+
end: thickStart,
|
|
42
|
+
refName,
|
|
43
|
+
}, {
|
|
44
|
+
type: 'CDS',
|
|
45
|
+
phase: 0,
|
|
46
|
+
start: thickStart,
|
|
47
|
+
end,
|
|
48
|
+
refName,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
else if (thickStart <= start && thickEnd >= end) {
|
|
52
|
+
subfeatures.push({
|
|
53
|
+
type: 'CDS',
|
|
54
|
+
phase: 0,
|
|
55
|
+
start,
|
|
56
|
+
end,
|
|
57
|
+
refName,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
else if (thickStart > start && thickStart < end && thickEnd < end) {
|
|
61
|
+
subfeatures.push({
|
|
62
|
+
type: `${strand > 0 ? 'five' : 'three'}_prime_UTR`,
|
|
63
|
+
start,
|
|
64
|
+
end: thickStart,
|
|
65
|
+
refName,
|
|
66
|
+
}, {
|
|
67
|
+
type: 'CDS',
|
|
68
|
+
phase: 0,
|
|
69
|
+
start: thickStart,
|
|
70
|
+
end: thickEnd,
|
|
71
|
+
refName,
|
|
72
|
+
}, {
|
|
73
|
+
type: `${strand > 0 ? 'three' : 'five'}_prime_UTR`,
|
|
74
|
+
start: thickEnd,
|
|
75
|
+
end,
|
|
76
|
+
refName,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
else if (thickStart <= start && thickEnd > start && thickEnd < end) {
|
|
80
|
+
subfeatures.push({
|
|
81
|
+
type: 'CDS',
|
|
82
|
+
phase: 0,
|
|
83
|
+
start,
|
|
84
|
+
end: thickEnd,
|
|
85
|
+
refName,
|
|
86
|
+
}, {
|
|
87
|
+
type: `${strand > 0 ? 'three' : 'five'}_prime_UTR`,
|
|
88
|
+
start: thickEnd,
|
|
89
|
+
end,
|
|
90
|
+
refName,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
else if (thickEnd <= start) {
|
|
94
|
+
subfeatures.push({
|
|
95
|
+
type: `${strand > 0 ? 'three' : 'five'}_prime_UTR`,
|
|
96
|
+
start,
|
|
97
|
+
end,
|
|
98
|
+
refName,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
85
101
|
}
|
|
102
|
+
return {
|
|
103
|
+
...rest2,
|
|
104
|
+
uniqueId,
|
|
105
|
+
strand,
|
|
106
|
+
type: 'mRNA',
|
|
107
|
+
refName,
|
|
108
|
+
subfeatures,
|
|
109
|
+
};
|
|
86
110
|
}
|
|
87
111
|
return {
|
|
88
112
|
...rest2,
|
package/esm/util.d.ts
CHANGED
|
@@ -89,7 +89,12 @@ export declare function featureData({ line, colRef, colStart, colEnd, scoreColum
|
|
|
89
89
|
strand: number;
|
|
90
90
|
type: string;
|
|
91
91
|
refName: string;
|
|
92
|
-
subfeatures:
|
|
92
|
+
subfeatures: {
|
|
93
|
+
type: string;
|
|
94
|
+
start: number;
|
|
95
|
+
end: number;
|
|
96
|
+
refName: string;
|
|
97
|
+
}[];
|
|
93
98
|
start: number;
|
|
94
99
|
end: number;
|
|
95
100
|
} | {
|
|
@@ -182,7 +187,12 @@ export declare function featureData2({ splitLine, refName, start, end, parser, u
|
|
|
182
187
|
strand: number;
|
|
183
188
|
type: string;
|
|
184
189
|
refName: string;
|
|
185
|
-
subfeatures:
|
|
190
|
+
subfeatures: {
|
|
191
|
+
type: string;
|
|
192
|
+
start: number;
|
|
193
|
+
end: number;
|
|
194
|
+
refName: string;
|
|
195
|
+
}[];
|
|
186
196
|
start: number;
|
|
187
197
|
end: number;
|
|
188
198
|
} | {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/plugin-bed",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.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": "^4.0.0",
|
|
43
|
+
"@gmod/tabix": "^3.0.1",
|
|
44
|
+
"@jbrowse/core": "^3.5.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": "8a8aa0aab2229dece106a5715a767e649e2fe92b"
|
|
57
57
|
}
|