@jbrowse/plugin-bed 3.4.0 → 3.5.1
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.js +111 -88
- package/dist/generateUcscTranscript.d.ts +7 -2
- package/dist/generateUcscTranscript.js +98 -74
- package/dist/util.d.ts +12 -2
- package/esm/BigBedAdapter/BigBedAdapter.js +111 -88
- package/esm/generateUcscTranscript.d.ts +7 -2
- package/esm/generateUcscTranscript.js +98 -74
- package/esm/util.d.ts +12 -2
- package/package.json +4 -4
|
@@ -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,11 +73,11 @@ 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
|
|
80
|
+
autoSql,
|
|
81
81
|
fields: await this.getMetadata(opts),
|
|
82
82
|
};
|
|
83
83
|
}
|
|
@@ -87,7 +87,6 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
87
87
|
return Object.fromEntries(fields.map(({ name, comment }) => [name, comment]));
|
|
88
88
|
}
|
|
89
89
|
async getFeaturesHelper({ query, opts, observer, allowRedispatch, originalQuery = query, }) {
|
|
90
|
-
var _a;
|
|
91
90
|
const { statusCallback = () => { } } = opts;
|
|
92
91
|
const scoreColumn = this.getConf('scoreColumn');
|
|
93
92
|
const aggregateField = this.getConf('aggregateField');
|
|
@@ -95,95 +94,119 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
95
94
|
const feats = await (0, util_1.updateStatus)('Downloading features', statusCallback, () => bigbed.getFeatures(query.refName, query.start, query.end, {
|
|
96
95
|
basesPerSpan: query.end - query.start,
|
|
97
96
|
}));
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const splitLine = [
|
|
105
|
-
query.refName,
|
|
106
|
-
`${feat.start}`,
|
|
107
|
-
`${feat.end}`,
|
|
108
|
-
...(((_a = feat.rest) === null || _a === void 0 ? void 0 : _a.split('\t')) || []),
|
|
109
|
-
];
|
|
110
|
-
const data = parser.parseLine(splitLine, {
|
|
111
|
-
uniqueId: feat.uniqueId,
|
|
112
|
-
});
|
|
113
|
-
const aggr = data[aggregateField];
|
|
114
|
-
const aggrIsNotNone = aggr && aggr !== 'none';
|
|
115
|
-
if (aggrIsNotNone && !parentAggregation[aggr]) {
|
|
116
|
-
parentAggregation[aggr] = [];
|
|
117
|
-
}
|
|
118
|
-
const { uniqueId, type, chrom, chromStart, chromEnd, description, chromStarts: chromStarts2, blockStarts: blockStarts2, blockSizes: blockSizes2, score: score2, blockCount, thickStart, thickEnd, strand, ...rest } = data;
|
|
119
|
-
const f = (0, util_2.featureData2)({
|
|
120
|
-
...rest,
|
|
121
|
-
scoreColumn,
|
|
122
|
-
splitLine,
|
|
123
|
-
parser,
|
|
124
|
-
uniqueId,
|
|
125
|
-
start: feat.start,
|
|
126
|
-
end: feat.end,
|
|
127
|
-
refName: query.refName,
|
|
128
|
-
});
|
|
129
|
-
if (aggrIsNotNone) {
|
|
130
|
-
parentAggregation[aggr].push(f);
|
|
131
|
-
parentAggregationFlat.push(f);
|
|
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');
|
|
132
103
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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] = [];
|
|
139
118
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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);
|
|
148
133
|
}
|
|
149
|
-
|
|
150
|
-
|
|
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
|
+
}
|
|
151
141
|
}
|
|
152
142
|
}
|
|
153
|
-
if (
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
subfeatures: subs,
|
|
179
|
-
strand: ((_b = subs[0]) === null || _b === void 0 ? void 0 : _b.strand) || 1,
|
|
180
|
-
name,
|
|
181
|
-
start: s,
|
|
182
|
-
end: e,
|
|
183
|
-
refName: query.refName,
|
|
184
|
-
},
|
|
185
|
-
}));
|
|
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
|
+
}
|
|
186
168
|
}
|
|
169
|
+
Object.entries(parentAggregation).map(([name, subfeatures]) => {
|
|
170
|
+
var _a, _b, _c;
|
|
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
|
+
if (subs.every(s => {
|
|
176
|
+
var _a;
|
|
177
|
+
return s.strand === (((_a = subs[0]) === null || _a === void 0 ? void 0 : _a.strand) || 1);
|
|
178
|
+
})) {
|
|
179
|
+
observer.next(new util_1.SimpleFeature({
|
|
180
|
+
id: `${this.id}-${(_a = subs[0]) === null || _a === void 0 ? void 0 : _a.uniqueId}-parent`,
|
|
181
|
+
data: {
|
|
182
|
+
type: 'gene',
|
|
183
|
+
subfeatures: subs,
|
|
184
|
+
strand: ((_b = subs[0]) === null || _b === void 0 ? void 0 : _b.strand) || 1,
|
|
185
|
+
name,
|
|
186
|
+
start: s,
|
|
187
|
+
end: e,
|
|
188
|
+
refName: query.refName,
|
|
189
|
+
},
|
|
190
|
+
}));
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
for (const sub of subs) {
|
|
194
|
+
observer.next(new util_1.SimpleFeature({
|
|
195
|
+
id: `${this.id}-${sub.uniqueId}-parent`,
|
|
196
|
+
data: {
|
|
197
|
+
type: 'gene',
|
|
198
|
+
subfeatures: [sub],
|
|
199
|
+
strand: ((_c = subs[0]) === null || _c === void 0 ? void 0 : _c.strand) || 1,
|
|
200
|
+
name,
|
|
201
|
+
start: sub.start,
|
|
202
|
+
end: sub.end,
|
|
203
|
+
refName: query.refName,
|
|
204
|
+
},
|
|
205
|
+
}));
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
});
|
|
187
210
|
});
|
|
188
211
|
observer.complete();
|
|
189
212
|
}
|
|
@@ -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
|
} | {
|
|
@@ -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,11 +68,11 @@ 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
|
|
75
|
+
autoSql,
|
|
76
76
|
fields: await this.getMetadata(opts),
|
|
77
77
|
};
|
|
78
78
|
}
|
|
@@ -82,7 +82,6 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
82
82
|
return Object.fromEntries(fields.map(({ name, comment }) => [name, comment]));
|
|
83
83
|
}
|
|
84
84
|
async getFeaturesHelper({ query, opts, observer, allowRedispatch, originalQuery = query, }) {
|
|
85
|
-
var _a;
|
|
86
85
|
const { statusCallback = () => { } } = opts;
|
|
87
86
|
const scoreColumn = this.getConf('scoreColumn');
|
|
88
87
|
const aggregateField = this.getConf('aggregateField');
|
|
@@ -90,95 +89,119 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
90
89
|
const feats = await updateStatus('Downloading features', statusCallback, () => bigbed.getFeatures(query.refName, query.start, query.end, {
|
|
91
90
|
basesPerSpan: query.end - query.start,
|
|
92
91
|
}));
|
|
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
|
-
const aggrIsNotNone = aggr && aggr !== 'none';
|
|
110
|
-
if (aggrIsNotNone && !parentAggregation[aggr]) {
|
|
111
|
-
parentAggregation[aggr] = [];
|
|
112
|
-
}
|
|
113
|
-
const { uniqueId, type, chrom, chromStart, chromEnd, description, chromStarts: chromStarts2, blockStarts: blockStarts2, blockSizes: blockSizes2, score: score2, blockCount, thickStart, thickEnd, strand, ...rest } = data;
|
|
114
|
-
const f = featureData2({
|
|
115
|
-
...rest,
|
|
116
|
-
scoreColumn,
|
|
117
|
-
splitLine,
|
|
118
|
-
parser,
|
|
119
|
-
uniqueId,
|
|
120
|
-
start: feat.start,
|
|
121
|
-
end: feat.end,
|
|
122
|
-
refName: query.refName,
|
|
123
|
-
});
|
|
124
|
-
if (aggrIsNotNone) {
|
|
125
|
-
parentAggregation[aggr].push(f);
|
|
126
|
-
parentAggregationFlat.push(f);
|
|
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');
|
|
127
98
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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] = [];
|
|
134
113
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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);
|
|
143
128
|
}
|
|
144
|
-
|
|
145
|
-
|
|
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
|
+
}
|
|
146
136
|
}
|
|
147
137
|
}
|
|
148
|
-
if (
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
subfeatures: subs,
|
|
174
|
-
strand: ((_b = subs[0]) === null || _b === void 0 ? void 0 : _b.strand) || 1,
|
|
175
|
-
name,
|
|
176
|
-
start: s,
|
|
177
|
-
end: e,
|
|
178
|
-
refName: query.refName,
|
|
179
|
-
},
|
|
180
|
-
}));
|
|
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
|
+
}
|
|
181
163
|
}
|
|
164
|
+
Object.entries(parentAggregation).map(([name, subfeatures]) => {
|
|
165
|
+
var _a, _b, _c;
|
|
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
|
+
if (subs.every(s => {
|
|
171
|
+
var _a;
|
|
172
|
+
return s.strand === (((_a = subs[0]) === null || _a === void 0 ? void 0 : _a.strand) || 1);
|
|
173
|
+
})) {
|
|
174
|
+
observer.next(new SimpleFeature({
|
|
175
|
+
id: `${this.id}-${(_a = subs[0]) === null || _a === void 0 ? void 0 : _a.uniqueId}-parent`,
|
|
176
|
+
data: {
|
|
177
|
+
type: 'gene',
|
|
178
|
+
subfeatures: subs,
|
|
179
|
+
strand: ((_b = subs[0]) === null || _b === void 0 ? void 0 : _b.strand) || 1,
|
|
180
|
+
name,
|
|
181
|
+
start: s,
|
|
182
|
+
end: e,
|
|
183
|
+
refName: query.refName,
|
|
184
|
+
},
|
|
185
|
+
}));
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
for (const sub of subs) {
|
|
189
|
+
observer.next(new SimpleFeature({
|
|
190
|
+
id: `${this.id}-${sub.uniqueId}-parent`,
|
|
191
|
+
data: {
|
|
192
|
+
type: 'gene',
|
|
193
|
+
subfeatures: [sub],
|
|
194
|
+
strand: ((_c = subs[0]) === null || _c === void 0 ? void 0 : _c.strand) || 1,
|
|
195
|
+
name,
|
|
196
|
+
start: sub.start,
|
|
197
|
+
end: sub.end,
|
|
198
|
+
refName: query.refName,
|
|
199
|
+
},
|
|
200
|
+
}));
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
});
|
|
182
205
|
});
|
|
183
206
|
observer.complete();
|
|
184
207
|
}
|
|
@@ -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.1",
|
|
4
4
|
"description": "JBrowse 2 bed adapters, tracks, etc.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jbrowse",
|
|
@@ -39,9 +39,9 @@
|
|
|
39
39
|
"@flatten-js/interval-tree": "^1.0.15",
|
|
40
40
|
"@gmod/bbi": "^7.0.0",
|
|
41
41
|
"@gmod/bed": "^2.1.2",
|
|
42
|
-
"@gmod/bgzf-filehandle": "^
|
|
42
|
+
"@gmod/bgzf-filehandle": "^4.0.0",
|
|
43
43
|
"@gmod/tabix": "^3.0.1",
|
|
44
|
-
"@jbrowse/core": "^3.
|
|
44
|
+
"@jbrowse/core": "^3.5.1",
|
|
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": "cb8859da9d838ad2594964777c5c54f385d98f5e"
|
|
57
57
|
}
|