@jbrowse/plugin-bed 2.16.1 → 2.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/BedAdapter/BedAdapter.js +12 -5
- package/dist/BedTabixAdapter/BedTabixAdapter.js +12 -5
- package/dist/BedpeAdapter/BedpeAdapter.js +3 -4
- package/dist/BigBedAdapter/BigBedAdapter.d.ts +9 -2
- package/dist/BigBedAdapter/BigBedAdapter.js +62 -57
- package/dist/generateBedMethylFeature.d.ts +31 -0
- package/dist/generateBedMethylFeature.js +32 -0
- package/dist/generateRepeatMaskerFeature.d.ts +51 -0
- package/dist/generateRepeatMaskerFeature.js +41 -0
- package/dist/generateUcscTranscript.d.ts +15 -0
- package/dist/generateUcscTranscript.js +101 -0
- package/dist/types.d.ts +18 -0
- package/dist/types.js +2 -0
- package/dist/util.d.ts +23 -33
- package/dist/util.js +124 -150
- package/esm/BedAdapter/BedAdapter.js +13 -6
- package/esm/BedTabixAdapter/BedTabixAdapter.js +11 -4
- package/esm/BedpeAdapter/BedpeAdapter.js +4 -5
- package/esm/BigBedAdapter/BigBedAdapter.d.ts +9 -2
- package/esm/BigBedAdapter/BigBedAdapter.js +63 -58
- package/esm/generateBedMethylFeature.d.ts +31 -0
- package/esm/generateBedMethylFeature.js +28 -0
- package/esm/generateRepeatMaskerFeature.d.ts +51 -0
- package/esm/generateRepeatMaskerFeature.js +37 -0
- package/esm/generateUcscTranscript.d.ts +15 -0
- package/esm/generateUcscTranscript.js +97 -0
- package/esm/types.d.ts +18 -0
- package/esm/types.js +1 -0
- package/esm/util.d.ts +23 -33
- package/esm/util.js +122 -148
- package/package.json +2 -2
|
@@ -9,7 +9,6 @@ const io_1 = require("@jbrowse/core/util/io");
|
|
|
9
9
|
const rxjs_1 = require("@jbrowse/core/util/rxjs");
|
|
10
10
|
const util_1 = require("@jbrowse/core/util");
|
|
11
11
|
const interval_tree_1 = __importDefault(require("@flatten-js/interval-tree"));
|
|
12
|
-
const bgzf_filehandle_1 = require("@gmod/bgzf-filehandle");
|
|
13
12
|
// locals
|
|
14
13
|
const util_2 = require("../util");
|
|
15
14
|
class BedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
@@ -20,8 +19,7 @@ class BedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
20
19
|
async loadDataP(opts = {}) {
|
|
21
20
|
const pm = this.pluginManager;
|
|
22
21
|
const bedLoc = this.getConf('bedLocation');
|
|
23
|
-
const
|
|
24
|
-
const buffer = (0, util_1.isGzip)(buf) ? await (0, bgzf_filehandle_1.unzip)(buf) : buf;
|
|
22
|
+
const buffer = await (0, util_1.fetchAndMaybeUnzip)((0, io_1.openLocation)(bedLoc, pm), opts);
|
|
25
23
|
// 512MB max chrome string length is 512MB
|
|
26
24
|
if (buffer.length > 536870888) {
|
|
27
25
|
throw new Error('Data exceeds maximum string length (512MB)');
|
|
@@ -101,9 +99,18 @@ class BedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
101
99
|
}
|
|
102
100
|
const names = await this.getNames();
|
|
103
101
|
const intervalTree = new interval_tree_1.default();
|
|
104
|
-
const ret = lines.map((
|
|
102
|
+
const ret = lines.map((line, i) => {
|
|
105
103
|
const uniqueId = `${this.id}-${refName}-${i}`;
|
|
106
|
-
return (0, util_2.featureData)(
|
|
104
|
+
return new util_1.SimpleFeature((0, util_2.featureData)({
|
|
105
|
+
line,
|
|
106
|
+
colRef,
|
|
107
|
+
colStart,
|
|
108
|
+
colEnd,
|
|
109
|
+
scoreColumn,
|
|
110
|
+
parser,
|
|
111
|
+
uniqueId,
|
|
112
|
+
names,
|
|
113
|
+
}));
|
|
107
114
|
});
|
|
108
115
|
for (const obj of ret) {
|
|
109
116
|
intervalTree.insert([obj.get('start'), obj.get('end')], obj);
|
|
@@ -7,9 +7,10 @@ const bed_1 = __importDefault(require("@gmod/bed"));
|
|
|
7
7
|
const BaseAdapter_1 = require("@jbrowse/core/data_adapters/BaseAdapter");
|
|
8
8
|
const io_1 = require("@jbrowse/core/util/io");
|
|
9
9
|
const rxjs_1 = require("@jbrowse/core/util/rxjs");
|
|
10
|
+
const util_1 = require("@jbrowse/core/util");
|
|
10
11
|
const tabix_1 = require("@gmod/tabix");
|
|
11
12
|
// locals
|
|
12
|
-
const
|
|
13
|
+
const util_2 = require("../util");
|
|
13
14
|
class BedTabixAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
14
15
|
constructor(config, getSubAdapter, pluginManager) {
|
|
15
16
|
super(config, getSubAdapter, pluginManager);
|
|
@@ -55,13 +56,19 @@ class BedTabixAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
55
56
|
const colRef = columnNumbers.ref - 1;
|
|
56
57
|
const colStart = columnNumbers.start - 1;
|
|
57
58
|
const colEnd = columnNumbers.end - 1;
|
|
58
|
-
// colSame handles special case for tabix where a single column is both
|
|
59
|
-
// the start and end, this is assumed to be covering the base at this
|
|
60
|
-
// position (e.g. tabix -s 1 -b 2 -e 2) begin and end are same
|
|
61
59
|
const names = await this.getNames();
|
|
62
60
|
await this.bed.getLines(query.refName, query.start, query.end, {
|
|
63
61
|
lineCallback: (line, fileOffset) => {
|
|
64
|
-
observer.next((0,
|
|
62
|
+
observer.next(new util_1.SimpleFeature((0, util_2.featureData)({
|
|
63
|
+
line,
|
|
64
|
+
colRef,
|
|
65
|
+
colStart,
|
|
66
|
+
colEnd,
|
|
67
|
+
scoreColumn: this.scoreColumn,
|
|
68
|
+
parser: this.parser,
|
|
69
|
+
uniqueId: `${this.id}-${fileOffset}`,
|
|
70
|
+
names,
|
|
71
|
+
})));
|
|
65
72
|
},
|
|
66
73
|
signal: opts.signal,
|
|
67
74
|
});
|
|
@@ -9,7 +9,6 @@ const io_1 = require("@jbrowse/core/util/io");
|
|
|
9
9
|
const rxjs_1 = require("@jbrowse/core/util/rxjs");
|
|
10
10
|
const util_1 = require("@jbrowse/core/util");
|
|
11
11
|
const interval_tree_1 = __importDefault(require("@flatten-js/interval-tree"));
|
|
12
|
-
const bgzf_filehandle_1 = require("@gmod/bgzf-filehandle");
|
|
13
12
|
const svTypes = new Set(['DUP', 'TRA', 'INV', 'CNV', 'DEL']);
|
|
14
13
|
function featureData(line, uniqueId, flip, names) {
|
|
15
14
|
const l = line.split('\t');
|
|
@@ -64,11 +63,11 @@ class BedpeAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
64
63
|
super(...arguments);
|
|
65
64
|
this.intervalTrees = {};
|
|
66
65
|
}
|
|
67
|
-
async loadDataP(opts
|
|
66
|
+
async loadDataP(opts) {
|
|
68
67
|
const pm = this.pluginManager;
|
|
69
68
|
const bedLoc = this.getConf('bedpeLocation');
|
|
70
|
-
const
|
|
71
|
-
const buffer = (0, util_1.
|
|
69
|
+
const loc = (0, io_1.openLocation)(bedLoc, pm);
|
|
70
|
+
const buffer = await (0, util_1.fetchAndMaybeUnzip)(loc, opts);
|
|
72
71
|
// 512MB max chrome string length is 512MB
|
|
73
72
|
if (buffer.length > 536870888) {
|
|
74
73
|
throw new Error('Data exceeds maximum string length (512MB)');
|
|
@@ -5,7 +5,7 @@ import { Region } from '@jbrowse/core/util/types';
|
|
|
5
5
|
import { Feature } from '@jbrowse/core/util';
|
|
6
6
|
import { Observer } from 'rxjs';
|
|
7
7
|
export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
8
|
-
private
|
|
8
|
+
private cachedP?;
|
|
9
9
|
configurePre(opts?: BaseOptions): Promise<{
|
|
10
10
|
bigbed: BigBed;
|
|
11
11
|
header: import("@gmod/bbi").Header;
|
|
@@ -17,6 +17,7 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
17
17
|
parser: BED;
|
|
18
18
|
}>;
|
|
19
19
|
getRefNames(opts?: BaseOptions): Promise<string[]>;
|
|
20
|
+
getData(): Promise<Feature[]>;
|
|
20
21
|
getHeader(opts?: BaseOptions): Promise<{
|
|
21
22
|
version: number;
|
|
22
23
|
fileType: string;
|
|
@@ -25,7 +26,13 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
25
26
|
[k: string]: string;
|
|
26
27
|
};
|
|
27
28
|
}>;
|
|
28
|
-
getFeaturesHelper(query
|
|
29
|
+
getFeaturesHelper({ query, opts, observer, allowRedispatch, originalQuery, }: {
|
|
30
|
+
query: Region;
|
|
31
|
+
opts: BaseOptions;
|
|
32
|
+
observer: Observer<Feature>;
|
|
33
|
+
allowRedispatch: boolean;
|
|
34
|
+
originalQuery?: Region;
|
|
35
|
+
}): Promise<void>;
|
|
29
36
|
getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
|
|
30
37
|
freeResources(): void;
|
|
31
38
|
}
|
|
@@ -9,6 +9,7 @@ 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
11
|
const util_1 = require("@jbrowse/core/util");
|
|
12
|
+
const rxjs_2 = require("rxjs");
|
|
12
13
|
// locals
|
|
13
14
|
const util_2 = require("../util");
|
|
14
15
|
class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
@@ -18,22 +19,42 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
18
19
|
filehandle: (0, io_1.openLocation)(this.getConf('bigBedLocation'), pm),
|
|
19
20
|
});
|
|
20
21
|
const header = await bigbed.getHeader(opts);
|
|
21
|
-
const parser = new bed_1.default({
|
|
22
|
-
|
|
22
|
+
const parser = new bed_1.default({
|
|
23
|
+
autoSql: header.autoSql,
|
|
24
|
+
});
|
|
25
|
+
return {
|
|
26
|
+
bigbed,
|
|
27
|
+
header,
|
|
28
|
+
parser,
|
|
29
|
+
};
|
|
23
30
|
}
|
|
24
31
|
async configure(opts) {
|
|
25
|
-
if (!this.
|
|
26
|
-
this.
|
|
27
|
-
this.
|
|
32
|
+
if (!this.cachedP) {
|
|
33
|
+
this.cachedP = this.configurePre(opts).catch((e) => {
|
|
34
|
+
this.cachedP = undefined;
|
|
28
35
|
throw e;
|
|
29
36
|
});
|
|
30
37
|
}
|
|
31
|
-
return this.
|
|
38
|
+
return this.cachedP;
|
|
32
39
|
}
|
|
33
40
|
async getRefNames(opts) {
|
|
34
41
|
const { header } = await this.configure(opts);
|
|
35
42
|
return Object.keys(header.refsByName);
|
|
36
43
|
}
|
|
44
|
+
async getData() {
|
|
45
|
+
const refNames = await this.getRefNames();
|
|
46
|
+
const features = [];
|
|
47
|
+
for (const refName of refNames) {
|
|
48
|
+
const f = await (0, rxjs_2.firstValueFrom)(this.getFeatures({
|
|
49
|
+
assemblyName: 'unknown',
|
|
50
|
+
refName,
|
|
51
|
+
start: 0,
|
|
52
|
+
end: Number.MAX_SAFE_INTEGER,
|
|
53
|
+
}).pipe((0, rxjs_2.toArray)()));
|
|
54
|
+
features.push(f);
|
|
55
|
+
}
|
|
56
|
+
return features.flat();
|
|
57
|
+
}
|
|
37
58
|
async getHeader(opts) {
|
|
38
59
|
const { parser, header } = await this.configure(opts);
|
|
39
60
|
const { version, fileType } = header;
|
|
@@ -45,7 +66,7 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
45
66
|
fields: Object.fromEntries(fields.map(({ name, comment }) => [name, comment])),
|
|
46
67
|
};
|
|
47
68
|
}
|
|
48
|
-
async getFeaturesHelper(query, opts, observer, allowRedispatch, originalQuery = query) {
|
|
69
|
+
async getFeaturesHelper({ query, opts, observer, allowRedispatch, originalQuery = query, }) {
|
|
49
70
|
const { signal } = opts;
|
|
50
71
|
const scoreColumn = this.getConf('scoreColumn');
|
|
51
72
|
const aggregateField = this.getConf('aggregateField');
|
|
@@ -66,7 +87,17 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
66
87
|
}
|
|
67
88
|
}
|
|
68
89
|
if (maxEnd > query.end || minStart < query.start) {
|
|
69
|
-
await this.getFeaturesHelper({
|
|
90
|
+
await this.getFeaturesHelper({
|
|
91
|
+
query: {
|
|
92
|
+
...query,
|
|
93
|
+
start: minStart,
|
|
94
|
+
end: maxEnd,
|
|
95
|
+
},
|
|
96
|
+
opts,
|
|
97
|
+
observer,
|
|
98
|
+
allowRedispatch: false,
|
|
99
|
+
originalQuery: query,
|
|
100
|
+
});
|
|
70
101
|
return;
|
|
71
102
|
}
|
|
72
103
|
}
|
|
@@ -75,62 +106,31 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
75
106
|
throw new Error('found uniqueId undefined');
|
|
76
107
|
}
|
|
77
108
|
for (const feat of feats) {
|
|
78
|
-
const
|
|
109
|
+
const line = `${query.refName}\t${feat.start}\t${feat.end}\t${feat.rest}`;
|
|
110
|
+
const data = parser.parseLine(line, { uniqueId: feat.uniqueId });
|
|
79
111
|
const aggr = data[aggregateField];
|
|
80
112
|
if (!parentAggregation[aggr]) {
|
|
81
113
|
parentAggregation[aggr] = [];
|
|
82
114
|
}
|
|
83
|
-
const { uniqueId, type, chromStart, chromStarts, blockStarts
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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,
|
|
110
|
-
});
|
|
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 }));
|
|
117
|
-
}
|
|
118
|
-
}
|
|
115
|
+
const { uniqueId, type, chrom, chromStart, chromEnd, description, chromStarts: chromStarts2, blockStarts: blockStarts2, blockSizes: blockSizes2, score: score2, blockCount, thickStart, thickEnd, strand, ...rest } = data;
|
|
116
|
+
const f = (0, util_2.featureData2)({
|
|
117
|
+
...rest,
|
|
118
|
+
scoreColumn,
|
|
119
|
+
line,
|
|
120
|
+
parser,
|
|
121
|
+
uniqueId,
|
|
122
|
+
start: feat.start,
|
|
123
|
+
end: feat.end,
|
|
124
|
+
refName: query.refName,
|
|
125
|
+
});
|
|
126
|
+
if (aggr) {
|
|
127
|
+
parentAggregation[aggr].push(f);
|
|
119
128
|
}
|
|
120
129
|
else {
|
|
121
|
-
if ((0, util_1.doesIntersect2)(
|
|
130
|
+
if ((0, util_1.doesIntersect2)(f.start, f.end, originalQuery.start, originalQuery.end)) {
|
|
122
131
|
observer.next(new util_1.SimpleFeature({
|
|
123
132
|
id: `${this.id}-${uniqueId}`,
|
|
124
|
-
data:
|
|
125
|
-
...rest,
|
|
126
|
-
uniqueId,
|
|
127
|
-
type,
|
|
128
|
-
start: feat.start,
|
|
129
|
-
score: scoreColumn ? +data[scoreColumn] : score,
|
|
130
|
-
end: feat.end,
|
|
131
|
-
refName: query.refName,
|
|
132
|
-
subfeatures,
|
|
133
|
-
},
|
|
133
|
+
data: f,
|
|
134
134
|
}));
|
|
135
135
|
}
|
|
136
136
|
}
|
|
@@ -159,7 +159,12 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
|
|
|
159
159
|
getFeatures(query, opts = {}) {
|
|
160
160
|
return (0, rxjs_1.ObservableCreate)(async (observer) => {
|
|
161
161
|
try {
|
|
162
|
-
await this.getFeaturesHelper(
|
|
162
|
+
await this.getFeaturesHelper({
|
|
163
|
+
query,
|
|
164
|
+
opts,
|
|
165
|
+
observer,
|
|
166
|
+
allowRedispatch: true,
|
|
167
|
+
});
|
|
163
168
|
}
|
|
164
169
|
catch (e) {
|
|
165
170
|
observer.error(e);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export declare function isBedMethylFeature({ splitLine, start, end, }: {
|
|
2
|
+
splitLine: string[];
|
|
3
|
+
start: number;
|
|
4
|
+
end: number;
|
|
5
|
+
}): boolean;
|
|
6
|
+
export declare function generateBedMethylFeature({ line, uniqueId, refName, start, end, }: {
|
|
7
|
+
line: string;
|
|
8
|
+
uniqueId: string;
|
|
9
|
+
refName: string;
|
|
10
|
+
start: number;
|
|
11
|
+
end: number;
|
|
12
|
+
}): {
|
|
13
|
+
uniqueId: string;
|
|
14
|
+
refName: string;
|
|
15
|
+
start: number;
|
|
16
|
+
end: number;
|
|
17
|
+
code: string | undefined;
|
|
18
|
+
score: string | undefined;
|
|
19
|
+
strand: string | undefined;
|
|
20
|
+
color: string | undefined;
|
|
21
|
+
source: string | undefined;
|
|
22
|
+
n_valid_cov: string | undefined;
|
|
23
|
+
fraction_modified: string | undefined;
|
|
24
|
+
n_mod: string | undefined;
|
|
25
|
+
n_canonical: string | undefined;
|
|
26
|
+
n_other_mod: string | undefined;
|
|
27
|
+
n_delete: string | undefined;
|
|
28
|
+
n_fail: string | undefined;
|
|
29
|
+
n_diff: string | undefined;
|
|
30
|
+
n_nocall: string | undefined;
|
|
31
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isBedMethylFeature = isBedMethylFeature;
|
|
4
|
+
exports.generateBedMethylFeature = generateBedMethylFeature;
|
|
5
|
+
function isBedMethylFeature({ splitLine, start, end, }) {
|
|
6
|
+
return +(splitLine[6] || 0) === start && +(splitLine[7] || 0) === end;
|
|
7
|
+
}
|
|
8
|
+
function generateBedMethylFeature({ line, uniqueId, refName, start, end, }) {
|
|
9
|
+
// see
|
|
10
|
+
// https://github.com/nanoporetech/modkit?tab=readme-ov-file#description-of-bedmethyl-output
|
|
11
|
+
const [, , , code, , strand, , , color, n_valid_cov, fraction_modified, n_mod, n_canonical, n_other_mod, n_delete, n_fail, n_diff, n_nocall,] = line.split('\t');
|
|
12
|
+
return {
|
|
13
|
+
uniqueId,
|
|
14
|
+
refName,
|
|
15
|
+
start,
|
|
16
|
+
end,
|
|
17
|
+
code,
|
|
18
|
+
score: fraction_modified,
|
|
19
|
+
strand,
|
|
20
|
+
color,
|
|
21
|
+
source: code,
|
|
22
|
+
n_valid_cov,
|
|
23
|
+
fraction_modified,
|
|
24
|
+
n_mod,
|
|
25
|
+
n_canonical,
|
|
26
|
+
n_other_mod,
|
|
27
|
+
n_delete,
|
|
28
|
+
n_fail,
|
|
29
|
+
n_diff,
|
|
30
|
+
n_nocall,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export declare function isRepeatMaskerDescriptionField(desc?: string): desc is string;
|
|
2
|
+
export declare function generateRepeatMaskerFeature({ uniqueId, refName, start, end, description, ...rest }: {
|
|
3
|
+
uniqueId: string;
|
|
4
|
+
refName: string;
|
|
5
|
+
start: number;
|
|
6
|
+
end: number;
|
|
7
|
+
description: string;
|
|
8
|
+
[key: string]: unknown;
|
|
9
|
+
}): {
|
|
10
|
+
uniqueId: string;
|
|
11
|
+
refName: string;
|
|
12
|
+
start: number;
|
|
13
|
+
end: number;
|
|
14
|
+
bitsw_score: string | undefined;
|
|
15
|
+
percent_div: string | undefined;
|
|
16
|
+
percent_del: string | undefined;
|
|
17
|
+
percent_ins: string | undefined;
|
|
18
|
+
query_chr: string | undefined;
|
|
19
|
+
query_begin: string | undefined;
|
|
20
|
+
query_end: string | undefined;
|
|
21
|
+
query_remaining: string | undefined;
|
|
22
|
+
orientation: string | undefined;
|
|
23
|
+
matching_repeat_name: string | undefined;
|
|
24
|
+
matching_repeat_class: string | undefined;
|
|
25
|
+
matching_repeat_begin: string | undefined;
|
|
26
|
+
matching_repeat_end: string | undefined;
|
|
27
|
+
matching_repeat_remaining: string | undefined;
|
|
28
|
+
repeat_id: string | undefined;
|
|
29
|
+
description?: undefined;
|
|
30
|
+
} | {
|
|
31
|
+
uniqueId: string;
|
|
32
|
+
refName: string;
|
|
33
|
+
start: number;
|
|
34
|
+
end: number;
|
|
35
|
+
description: undefined;
|
|
36
|
+
bitsw_score?: undefined;
|
|
37
|
+
percent_div?: undefined;
|
|
38
|
+
percent_del?: undefined;
|
|
39
|
+
percent_ins?: undefined;
|
|
40
|
+
query_chr?: undefined;
|
|
41
|
+
query_begin?: undefined;
|
|
42
|
+
query_end?: undefined;
|
|
43
|
+
query_remaining?: undefined;
|
|
44
|
+
orientation?: undefined;
|
|
45
|
+
matching_repeat_name?: undefined;
|
|
46
|
+
matching_repeat_class?: undefined;
|
|
47
|
+
matching_repeat_begin?: undefined;
|
|
48
|
+
matching_repeat_end?: undefined;
|
|
49
|
+
matching_repeat_remaining?: undefined;
|
|
50
|
+
repeat_id?: undefined;
|
|
51
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isRepeatMaskerDescriptionField = isRepeatMaskerDescriptionField;
|
|
4
|
+
exports.generateRepeatMaskerFeature = generateRepeatMaskerFeature;
|
|
5
|
+
function isRepeatMaskerDescriptionField(desc) {
|
|
6
|
+
const ret = desc === null || desc === void 0 ? void 0 : desc.trim().split(' ');
|
|
7
|
+
return [0, 1, 2, 3, 5, 6].every(s => (ret === null || ret === void 0 ? void 0 : ret[s]) !== undefined ? !Number.isNaN(+ret[s]) : false);
|
|
8
|
+
}
|
|
9
|
+
function makeRepeatTrackDescription(description) {
|
|
10
|
+
if (isRepeatMaskerDescriptionField(description)) {
|
|
11
|
+
const [bitsw_score, percent_div, percent_del, percent_ins, query_chr, query_begin, query_end, query_remaining, orientation, matching_repeat_name, matching_repeat_class, matching_repeat_begin, matching_repeat_end, matching_repeat_remaining, repeat_id,] = description.trim().split(' ');
|
|
12
|
+
return {
|
|
13
|
+
bitsw_score,
|
|
14
|
+
percent_div,
|
|
15
|
+
percent_del,
|
|
16
|
+
percent_ins,
|
|
17
|
+
query_chr,
|
|
18
|
+
query_begin,
|
|
19
|
+
query_end,
|
|
20
|
+
query_remaining,
|
|
21
|
+
orientation,
|
|
22
|
+
matching_repeat_name,
|
|
23
|
+
matching_repeat_class,
|
|
24
|
+
matching_repeat_begin,
|
|
25
|
+
matching_repeat_end,
|
|
26
|
+
matching_repeat_remaining,
|
|
27
|
+
repeat_id,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
return { description };
|
|
31
|
+
}
|
|
32
|
+
function generateRepeatMaskerFeature({ uniqueId, refName, start, end, description, ...rest }) {
|
|
33
|
+
return {
|
|
34
|
+
...rest,
|
|
35
|
+
...makeRepeatTrackDescription(description),
|
|
36
|
+
uniqueId,
|
|
37
|
+
refName,
|
|
38
|
+
start,
|
|
39
|
+
end,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { MinimalFeature, TranscriptFeat } from './types';
|
|
2
|
+
export declare function isUcscTranscript({ thickStart, blockCount, strand, }: {
|
|
3
|
+
thickStart?: number;
|
|
4
|
+
blockCount?: number;
|
|
5
|
+
strand?: number;
|
|
6
|
+
}): boolean | 0 | undefined;
|
|
7
|
+
export declare function generateUcscTranscript(data: TranscriptFeat): {
|
|
8
|
+
uniqueId: string;
|
|
9
|
+
strand: number;
|
|
10
|
+
type: string;
|
|
11
|
+
refName: string;
|
|
12
|
+
subfeatures: MinimalFeature[];
|
|
13
|
+
start: number;
|
|
14
|
+
end: number;
|
|
15
|
+
};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isUcscTranscript = isUcscTranscript;
|
|
4
|
+
exports.generateUcscTranscript = generateUcscTranscript;
|
|
5
|
+
function isUcscTranscript({ thickStart, blockCount, strand, }) {
|
|
6
|
+
return thickStart && blockCount && strand !== 0;
|
|
7
|
+
}
|
|
8
|
+
function generateUcscTranscript(data) {
|
|
9
|
+
const { strand = 0, chrom: _1, chromStart: _2, chromEnd: _3, chromStarts, blockStarts, blockSizes, uniqueId, ...rest } = data;
|
|
10
|
+
const { subfeatures: oldSubfeatures, thickStart, thickEnd, blockCount, refName, ...rest2 } = rest;
|
|
11
|
+
const subfeatures = [];
|
|
12
|
+
const feats = oldSubfeatures
|
|
13
|
+
.filter(child => child.type === 'block')
|
|
14
|
+
.sort((a, b) => a.start - b.start);
|
|
15
|
+
for (const block of feats) {
|
|
16
|
+
const start = block.start;
|
|
17
|
+
const end = block.end;
|
|
18
|
+
if (thickStart >= end) {
|
|
19
|
+
// left-side UTR
|
|
20
|
+
subfeatures.push({
|
|
21
|
+
type: `${strand > 0 ? 'five' : 'three'}_prime_UTR`,
|
|
22
|
+
start,
|
|
23
|
+
end,
|
|
24
|
+
refName,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
else if (thickStart > start && thickStart < end && thickEnd >= end) {
|
|
28
|
+
// UTR | CDS
|
|
29
|
+
subfeatures.push({
|
|
30
|
+
type: `${strand > 0 ? 'five' : 'three'}_prime_UTR`,
|
|
31
|
+
start,
|
|
32
|
+
end: thickStart,
|
|
33
|
+
refName,
|
|
34
|
+
}, {
|
|
35
|
+
type: 'CDS',
|
|
36
|
+
start: thickStart,
|
|
37
|
+
end,
|
|
38
|
+
refName,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
else if (thickStart <= start && thickEnd >= end) {
|
|
42
|
+
// CDS
|
|
43
|
+
subfeatures.push({
|
|
44
|
+
type: 'CDS',
|
|
45
|
+
start,
|
|
46
|
+
end,
|
|
47
|
+
refName,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
else if (thickStart > start && thickStart < end && thickEnd < end) {
|
|
51
|
+
// UTR | CDS | UTR
|
|
52
|
+
subfeatures.push({
|
|
53
|
+
type: `${strand > 0 ? 'five' : 'three'}_prime_UTR`,
|
|
54
|
+
start,
|
|
55
|
+
end: thickStart,
|
|
56
|
+
refName,
|
|
57
|
+
}, {
|
|
58
|
+
type: 'CDS',
|
|
59
|
+
start: thickStart,
|
|
60
|
+
end: thickEnd,
|
|
61
|
+
refName,
|
|
62
|
+
}, {
|
|
63
|
+
type: `${strand > 0 ? 'three' : 'five'}_prime_UTR`,
|
|
64
|
+
start: thickEnd,
|
|
65
|
+
end,
|
|
66
|
+
refName,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
else if (thickStart <= start && thickEnd > start && thickEnd < end) {
|
|
70
|
+
// CDS | UTR
|
|
71
|
+
subfeatures.push({
|
|
72
|
+
type: 'CDS',
|
|
73
|
+
start,
|
|
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 (thickEnd <= start) {
|
|
84
|
+
// right-side UTR
|
|
85
|
+
subfeatures.push({
|
|
86
|
+
type: `${strand > 0 ? 'three' : 'five'}_prime_UTR`,
|
|
87
|
+
start,
|
|
88
|
+
end,
|
|
89
|
+
refName,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
...rest2,
|
|
95
|
+
uniqueId,
|
|
96
|
+
strand,
|
|
97
|
+
type: 'mRNA',
|
|
98
|
+
refName,
|
|
99
|
+
subfeatures,
|
|
100
|
+
};
|
|
101
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface MinimalFeature {
|
|
2
|
+
type: string;
|
|
3
|
+
start: number;
|
|
4
|
+
end: number;
|
|
5
|
+
refName: string;
|
|
6
|
+
[key: string]: unknown;
|
|
7
|
+
}
|
|
8
|
+
export interface TranscriptFeat extends MinimalFeature {
|
|
9
|
+
uniqueId: string;
|
|
10
|
+
thickStart: number;
|
|
11
|
+
thickEnd: number;
|
|
12
|
+
blockCount: number;
|
|
13
|
+
blockSizes: number[];
|
|
14
|
+
chromStarts: number[];
|
|
15
|
+
refName: string;
|
|
16
|
+
strand?: number;
|
|
17
|
+
subfeatures: MinimalFeature[];
|
|
18
|
+
}
|
package/dist/types.js
ADDED