@jbrowse/plugin-bed 5.0.0-beta.13 → 5.0.0-beta.14
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/esm/BedAdapter/BedAdapter.d.ts +11 -0
- package/esm/BedAdapter/BedAdapter.js +4 -0
- package/esm/BedAdapter/configSchema.d.ts +2 -2
- package/esm/BedAdapter/configSchema.js +3 -2
- package/esm/BedGraphAdapter/configSchema.d.ts +3 -2
- package/esm/BedGraphAdapter/configSchema.js +4 -2
- package/esm/BedGraphTabixAdapter/BedGraphTabixAdapter.d.ts +2 -0
- package/esm/BedGraphTabixAdapter/BedGraphTabixAdapter.js +7 -2
- package/esm/BedGraphTabixAdapter/configSchema.d.ts +2 -1
- package/esm/BedGraphTabixAdapter/configSchema.js +4 -2
- package/esm/BedTabixAdapter/BedTabixAdapter.d.ts +12 -0
- package/esm/BedTabixAdapter/BedTabixAdapter.js +52 -28
- package/esm/BedTabixAdapter/configSchema.d.ts +1 -3
- package/esm/BedTabixAdapter/configSchema.js +3 -3
- package/esm/BedpeAdapter/configSchema.d.ts +2 -1
- package/esm/BedpeAdapter/configSchema.js +3 -1
- package/esm/BigBedAdapter/BigBedAdapter.d.ts +24 -1
- package/esm/BigBedAdapter/BigBedAdapter.js +25 -1
- package/esm/BigBedAdapter/configSchema.d.ts +1 -3
- package/esm/BigBedAdapter/configSchema.js +2 -2
- package/esm/StarFusionAdapter/configSchema.d.ts +2 -1
- package/esm/StarFusionAdapter/configSchema.js +3 -1
- package/esm/generateUcscTranscript.js +2 -6
- package/esm/numberColumns.d.ts +4 -0
- package/esm/numberColumns.js +17 -0
- package/esm/util.js +10 -8
- package/package.json +7 -7
|
@@ -10,6 +10,17 @@ export default class BedAdapter extends BaseFeatureDataAdapter<BedAdapterConfig>
|
|
|
10
10
|
private getParser;
|
|
11
11
|
static capabilities: string[];
|
|
12
12
|
private loadDataP;
|
|
13
|
+
/** Each column the parser reads, as its autoSql or the header declares it. */
|
|
14
|
+
getAutoSqlFields(): Promise<{
|
|
15
|
+
isArray: boolean;
|
|
16
|
+
arrayIsNumeric: boolean;
|
|
17
|
+
isNumeric: boolean;
|
|
18
|
+
size?: number | string;
|
|
19
|
+
type: string;
|
|
20
|
+
name: string;
|
|
21
|
+
comment: string;
|
|
22
|
+
vals?: string[];
|
|
23
|
+
}[]>;
|
|
13
24
|
getRefNames(opts?: BaseOptions): Promise<string[]>;
|
|
14
25
|
getHeader(opts?: BaseOptions): Promise<string>;
|
|
15
26
|
getNames(): Promise<string[] | undefined>;
|
|
@@ -19,6 +19,10 @@ export default class BedAdapter extends BaseFeatureDataAdapter {
|
|
|
19
19
|
const buffer = await fetchAndMaybeUnzip(openLocation(this.getConf('bedLocation'), this.pluginManager), opts);
|
|
20
20
|
return bucketBedLines(buffer, opts?.statusCallback);
|
|
21
21
|
}
|
|
22
|
+
/** Each column the parser reads, as its autoSql or the header declares it. */
|
|
23
|
+
async getAutoSqlFields() {
|
|
24
|
+
return (await this.getParser()).autoSql.fields;
|
|
25
|
+
}
|
|
22
26
|
async getRefNames(opts = {}) {
|
|
23
27
|
const { features } = await this.loadData(opts);
|
|
24
28
|
return Object.keys(features);
|
|
@@ -11,8 +11,8 @@ export declare function normalizeSnapshot(snap: Record<string, unknown>): Record
|
|
|
11
11
|
* ... and a jexl callback reading `feature.itemRgb` gets `undefined`. Set
|
|
12
12
|
* `columnNames` to refer to them by name.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
14
|
+
* Reads plain-text BED files. The adapter loads the whole file into memory, so
|
|
15
|
+
* use `BedTabixAdapter` for large files.
|
|
16
16
|
*
|
|
17
17
|
* #example
|
|
18
18
|
* ```js
|
|
@@ -13,8 +13,8 @@ export function normalizeSnapshot(snap) {
|
|
|
13
13
|
* ... and a jexl callback reading `feature.itemRgb` gets `undefined`. Set
|
|
14
14
|
* `columnNames` to refer to them by name.
|
|
15
15
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
16
|
+
* Reads plain-text BED files. The adapter loads the whole file into memory, so
|
|
17
|
+
* use `BedTabixAdapter` for large files.
|
|
18
18
|
*
|
|
19
19
|
* #example
|
|
20
20
|
* ```js
|
|
@@ -94,6 +94,7 @@ const BedAdapter = ConfigurationSchema('BedAdapter', {
|
|
|
94
94
|
},
|
|
95
95
|
}, {
|
|
96
96
|
explicitlyTyped: true,
|
|
97
|
+
closed: true,
|
|
97
98
|
/**
|
|
98
99
|
* #preProcessSnapshot
|
|
99
100
|
*
|
|
@@ -4,8 +4,9 @@ export declare function normalizeSnapshot(snap: Record<string, unknown>): Record
|
|
|
4
4
|
* #config BedGraphAdapter
|
|
5
5
|
* #trackType QuantitativeTrack
|
|
6
6
|
* #fileFormat quantitative | BedGraph (plain) | Loaded entirely into memory; for small files
|
|
7
|
-
*
|
|
8
|
-
* memory, so
|
|
7
|
+
* Reads plain-text bedGraph signal files. The adapter loads the whole file into
|
|
8
|
+
* memory, so use `BedGraphTabixAdapter` for large files.
|
|
9
|
+
*
|
|
9
10
|
* Several signals in one file are a `MultiQuantitativeTrack`'s subtracks:
|
|
10
11
|
* one value column each, named by the header, or a `source` column naming each
|
|
11
12
|
* row's, which is the form Save track data writes.
|
|
@@ -6,8 +6,9 @@ export function normalizeSnapshot(snap) {
|
|
|
6
6
|
* #config BedGraphAdapter
|
|
7
7
|
* #trackType QuantitativeTrack
|
|
8
8
|
* #fileFormat quantitative | BedGraph (plain) | Loaded entirely into memory; for small files
|
|
9
|
-
*
|
|
10
|
-
* memory, so
|
|
9
|
+
* Reads plain-text bedGraph signal files. The adapter loads the whole file into
|
|
10
|
+
* memory, so use `BedGraphTabixAdapter` for large files.
|
|
11
|
+
*
|
|
11
12
|
* Several signals in one file are a `MultiQuantitativeTrack`'s subtracks:
|
|
12
13
|
* one value column each, named by the header, or a `source` column naming each
|
|
13
14
|
* row's, which is the form Save track data writes.
|
|
@@ -43,6 +44,7 @@ const BedGraphAdapter = ConfigurationSchema('BedGraphAdapter', {
|
|
|
43
44
|
},
|
|
44
45
|
}, {
|
|
45
46
|
explicitlyTyped: true,
|
|
47
|
+
closed: true,
|
|
46
48
|
/**
|
|
47
49
|
* #preProcessSnapshot
|
|
48
50
|
*
|
|
@@ -4,6 +4,8 @@ import type { BedGraphTabixAdapterConfig } from './configSchema.ts';
|
|
|
4
4
|
import type { BaseOptions } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
5
5
|
import type { Feature, Region } from '@jbrowse/core/util';
|
|
6
6
|
export default class BedGraphTabixAdapter extends BaseFeatureDataAdapter<BedGraphTabixAdapterConfig> {
|
|
7
|
+
private file?;
|
|
8
|
+
freeResources(): void;
|
|
7
9
|
protected configure: (opts?: BaseOptions) => Promise<{
|
|
8
10
|
columnNames: string[];
|
|
9
11
|
bedGraph: TabixIndexedFile;
|
|
@@ -9,6 +9,11 @@ import { readTabixHeaderLines } from '@jbrowse/core/util/tabix';
|
|
|
9
9
|
import { makeBedGraphFeature } from '../bedGraphUtil.js';
|
|
10
10
|
import { parseNamesFromHeader } from '../util.js';
|
|
11
11
|
export default class BedGraphTabixAdapter extends BaseFeatureDataAdapter {
|
|
12
|
+
// set once the file is open, for dataAdapterCache's eviction to clear
|
|
13
|
+
file;
|
|
14
|
+
freeResources() {
|
|
15
|
+
this.file?.clearChunkCache();
|
|
16
|
+
}
|
|
12
17
|
// `label` because the index setup narrates nothing itself; the helper shows
|
|
13
18
|
// it only while the first attempt is in flight, so pan/zoom re-entry (every
|
|
14
19
|
// getFeatures/byte-estimate awaits it) doesn't re-flash "Downloading index"
|
|
@@ -27,6 +32,7 @@ export default class BedGraphTabixAdapter extends BaseFeatureDataAdapter {
|
|
|
27
32
|
chunkCacheBudget: decompressedBytesBudget,
|
|
28
33
|
bgzfWorkerPool: sharedBgzfWorkerPool(),
|
|
29
34
|
});
|
|
35
|
+
this.file = bedGraph;
|
|
30
36
|
const columnNames = this.getConf('columnNames');
|
|
31
37
|
// Not bedGraph.getHeader(): that returns only a `#`-commented header, so a
|
|
32
38
|
// file whose header is a plain row skipped via `tabix -S 1` reported none
|
|
@@ -53,8 +59,7 @@ export default class BedGraphTabixAdapter extends BaseFeatureDataAdapter {
|
|
|
53
59
|
getFeatures(query, opts = {}) {
|
|
54
60
|
return ObservableCreate(async (observer) => {
|
|
55
61
|
const { bedGraph } = await this.configure(opts);
|
|
56
|
-
const
|
|
57
|
-
const { columnNumbers } = meta;
|
|
62
|
+
const { columnNumbers } = await bedGraph.getMetadata();
|
|
58
63
|
const colRef = columnNumbers.ref - 1;
|
|
59
64
|
const colStart = columnNumbers.start - 1;
|
|
60
65
|
const colEnd = columnNumbers.end - 1;
|
|
@@ -4,7 +4,8 @@ export declare function normalizeSnapshot(snap: Record<string, unknown>): Record
|
|
|
4
4
|
* #config BedGraphTabixAdapter
|
|
5
5
|
* #trackType QuantitativeTrack
|
|
6
6
|
* #fileFormat quantitative | BedGraph (tabix)
|
|
7
|
-
*
|
|
7
|
+
* Reads bgzip-compressed, tabix-indexed bedGraph signal files.
|
|
8
|
+
*
|
|
8
9
|
* Several signals in one file are a `MultiQuantitativeTrack`'s subtracks:
|
|
9
10
|
* one value column each, named by the header, or a `source` column naming each
|
|
10
11
|
* row's, which is the form Save track data writes.
|
|
@@ -6,7 +6,8 @@ export function normalizeSnapshot(snap) {
|
|
|
6
6
|
* #config BedGraphTabixAdapter
|
|
7
7
|
* #trackType QuantitativeTrack
|
|
8
8
|
* #fileFormat quantitative | BedGraph (tabix)
|
|
9
|
-
*
|
|
9
|
+
* Reads bgzip-compressed, tabix-indexed bedGraph signal files.
|
|
10
|
+
*
|
|
10
11
|
* Several signals in one file are a `MultiQuantitativeTrack`'s subtracks:
|
|
11
12
|
* one value column each, named by the header, or a `source` column naming each
|
|
12
13
|
* row's, which is the form Save track data writes.
|
|
@@ -36,7 +37,7 @@ const BedGraphTabixAdapter = ConfigurationSchema('BedGraphTabixAdapter', {
|
|
|
36
37
|
},
|
|
37
38
|
/**
|
|
38
39
|
* #slot
|
|
39
|
-
*
|
|
40
|
+
* The tabix index location and its kind. The `uri` shorthand derives
|
|
40
41
|
* both, so a config using it states neither.
|
|
41
42
|
*/
|
|
42
43
|
index: tabixIndexSchema(),
|
|
@@ -50,6 +51,7 @@ const BedGraphTabixAdapter = ConfigurationSchema('BedGraphTabixAdapter', {
|
|
|
50
51
|
},
|
|
51
52
|
}, {
|
|
52
53
|
explicitlyTyped: true,
|
|
54
|
+
closed: true,
|
|
53
55
|
/**
|
|
54
56
|
* #preProcessSnapshot
|
|
55
57
|
*
|
|
@@ -34,6 +34,18 @@ export default class BedTabixAdapter extends BaseFeatureDataAdapter<BedTabixAdap
|
|
|
34
34
|
}>;
|
|
35
35
|
getNames: (opts?: BaseOptions) => Promise<string[] | undefined>;
|
|
36
36
|
constructor(config: BedTabixAdapterConfig, getSubAdapter?: getSubAdapterType, pluginManager?: PluginManager);
|
|
37
|
+
freeResources(): void;
|
|
38
|
+
/** Each column the parser reads, as its autoSql or the header declares it. */
|
|
39
|
+
getAutoSqlFields(): Promise<{
|
|
40
|
+
isArray: boolean;
|
|
41
|
+
arrayIsNumeric: boolean;
|
|
42
|
+
isNumeric: boolean;
|
|
43
|
+
size?: number | string;
|
|
44
|
+
type: string;
|
|
45
|
+
name: string;
|
|
46
|
+
comment: string;
|
|
47
|
+
vals?: string[];
|
|
48
|
+
}[]>;
|
|
37
49
|
getRefNames(opts?: BaseOptions): Promise<string[]>;
|
|
38
50
|
getHeader(opts?: BaseOptions): Promise<string>;
|
|
39
51
|
/**
|
|
@@ -47,6 +47,13 @@ export default class BedTabixAdapter extends BaseFeatureDataAdapter {
|
|
|
47
47
|
bgzfWorkerPool: sharedBgzfWorkerPool(),
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
|
+
freeResources() {
|
|
51
|
+
this.bed.clearChunkCache();
|
|
52
|
+
}
|
|
53
|
+
/** Each column the parser reads, as its autoSql or the header declares it. */
|
|
54
|
+
async getAutoSqlFields() {
|
|
55
|
+
return (await this.getParser()).autoSql.fields;
|
|
56
|
+
}
|
|
50
57
|
async getRefNames(opts = {}) {
|
|
51
58
|
return downloadStatus('Downloading index', opts.statusCallback, onProgress => this.bed.getReferenceSequenceNames({ ...opts, onProgress }));
|
|
52
59
|
}
|
|
@@ -77,37 +84,54 @@ export default class BedTabixAdapter extends BaseFeatureDataAdapter {
|
|
|
77
84
|
// warms the index under its own status label — getLines would otherwise
|
|
78
85
|
// download it under "Downloading features"
|
|
79
86
|
await this.getMetadata(opts);
|
|
80
|
-
const names = await this.getNames();
|
|
81
|
-
const parser = await this.getParser();
|
|
82
87
|
const scoreColumn = readConfObject(this.config, 'scoreColumn');
|
|
83
88
|
const disableGeneHeuristic = readConfObject(this.config, 'disableGeneHeuristic');
|
|
89
|
+
let ready;
|
|
90
|
+
const early = [];
|
|
91
|
+
const emit = ({ names, parser }, { splitLine, start, end, offset }) => {
|
|
92
|
+
observer.next(new SimpleFeature(featureData({
|
|
93
|
+
splitLine,
|
|
94
|
+
refName: query.refName,
|
|
95
|
+
start,
|
|
96
|
+
end,
|
|
97
|
+
scoreColumn,
|
|
98
|
+
parser,
|
|
99
|
+
uniqueId: `${this.id}-${offset}`,
|
|
100
|
+
names,
|
|
101
|
+
disableGeneHeuristic,
|
|
102
|
+
})));
|
|
103
|
+
};
|
|
104
|
+
const loaded = Promise.all([this.getNames(), this.getParser()]).then(([names, parser]) => {
|
|
105
|
+
ready = { names, parser };
|
|
106
|
+
for (const row of early.splice(0)) {
|
|
107
|
+
emit(ready, row);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
84
110
|
checkAbortSignal(signal);
|
|
85
|
-
await
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
splitLine,
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
},
|
|
108
|
-
|
|
109
|
-
signal,
|
|
110
|
-
}));
|
|
111
|
+
await Promise.all([
|
|
112
|
+
loaded,
|
|
113
|
+
downloadStatus('Downloading features', statusCallback, onProgress =>
|
|
114
|
+
// start/end come from @gmod/tabix rather than being re-derived from
|
|
115
|
+
// the line: it located the coordinate columns to find these lines at
|
|
116
|
+
// all, and already applied the index's coordinate offset (-1 for a
|
|
117
|
+
// 1-based-closed preset) and its no-end-column convention (a single
|
|
118
|
+
// position becomes start..start+1). refName is likewise the query's
|
|
119
|
+
// — getLines only calls back for lines whose ref column matches it.
|
|
120
|
+
this.bed.getLines(query.refName, query.start, query.end, {
|
|
121
|
+
lineCallback: (line, offset, start, end) => {
|
|
122
|
+
checkAbortSignal(signal);
|
|
123
|
+
const row = { splitLine: line.split('\t'), start, end, offset };
|
|
124
|
+
if (ready) {
|
|
125
|
+
emit(ready, row);
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
early.push(row);
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
onProgress,
|
|
132
|
+
signal,
|
|
133
|
+
})),
|
|
134
|
+
]);
|
|
111
135
|
observer.complete();
|
|
112
136
|
}, signal);
|
|
113
137
|
}
|
|
@@ -4,6 +4,7 @@ export declare function normalizeSnapshot(snap: Record<string, unknown>): Record
|
|
|
4
4
|
* #config BedTabixAdapter
|
|
5
5
|
* #trackType FeatureTrack
|
|
6
6
|
* #fileFormat feature | BED (tabix)
|
|
7
|
+
* Reads bgzip-compressed, tabix-indexed BED files.
|
|
7
8
|
*
|
|
8
9
|
* #example
|
|
9
10
|
* The `uri` shorthand auto-resolves the `.tbi` index; add `csi: true` for a
|
|
@@ -16,9 +17,6 @@ export declare function normalizeSnapshot(snap: Record<string, unknown>): Record
|
|
|
16
17
|
* ```
|
|
17
18
|
*/
|
|
18
19
|
declare const BedTabixAdapter: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
|
|
19
|
-
readonly densityAdapter: {
|
|
20
|
-
type: "maybeFrozen";
|
|
21
|
-
};
|
|
22
20
|
type: {
|
|
23
21
|
type: "string";
|
|
24
22
|
} & {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { ConfigurationSchema, expandTabixShorthand, tabixIndexSchema, } from '@jbrowse/core/configuration';
|
|
2
|
-
import { densityAdapterConfigSchemaFields } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
3
2
|
export function normalizeSnapshot(snap) {
|
|
4
3
|
return expandTabixShorthand(snap, 'bedGzLocation');
|
|
5
4
|
}
|
|
@@ -7,6 +6,7 @@ export function normalizeSnapshot(snap) {
|
|
|
7
6
|
* #config BedTabixAdapter
|
|
8
7
|
* #trackType FeatureTrack
|
|
9
8
|
* #fileFormat feature | BED (tabix)
|
|
9
|
+
* Reads bgzip-compressed, tabix-indexed BED files.
|
|
10
10
|
*
|
|
11
11
|
* #example
|
|
12
12
|
* The `uri` shorthand auto-resolves the `.tbi` index; add `csi: true` for a
|
|
@@ -33,7 +33,7 @@ const BedTabixAdapter = ConfigurationSchema('BedTabixAdapter', {
|
|
|
33
33
|
},
|
|
34
34
|
/**
|
|
35
35
|
* #slot
|
|
36
|
-
*
|
|
36
|
+
* The tabix index location and its kind. The `uri` shorthand derives
|
|
37
37
|
* both, so a config using it states neither.
|
|
38
38
|
*/
|
|
39
39
|
index: tabixIndexSchema(),
|
|
@@ -69,9 +69,9 @@ const BedTabixAdapter = ConfigurationSchema('BedTabixAdapter', {
|
|
|
69
69
|
description: 'Disable the heuristic that auto-detects BED12 features as gene/transcript structures. Useful for files that have BED12-like structure but are not genes (e.g. tandem duplications)',
|
|
70
70
|
defaultValue: false,
|
|
71
71
|
},
|
|
72
|
-
...densityAdapterConfigSchemaFields,
|
|
73
72
|
}, {
|
|
74
73
|
explicitlyTyped: true,
|
|
74
|
+
closed: true,
|
|
75
75
|
/**
|
|
76
76
|
* #preProcessSnapshot
|
|
77
77
|
*
|
|
@@ -4,7 +4,8 @@ export declare function normalizeSnapshot(snap: Record<string, unknown>): Record
|
|
|
4
4
|
* #config BedpeAdapter
|
|
5
5
|
* #trackType VariantTrack
|
|
6
6
|
* #fileFormat variants | BEDPE | Paired/breakend records, e.g. SV calls or Hi-C loops
|
|
7
|
-
*
|
|
7
|
+
* Reads BEDPE files of paired breakends, such as structural variant calls
|
|
8
|
+
* within a single assembly.
|
|
8
9
|
*
|
|
9
10
|
* #example
|
|
10
11
|
* ```js
|
|
@@ -6,7 +6,8 @@ export function normalizeSnapshot(snap) {
|
|
|
6
6
|
* #config BedpeAdapter
|
|
7
7
|
* #trackType VariantTrack
|
|
8
8
|
* #fileFormat variants | BEDPE | Paired/breakend records, e.g. SV calls or Hi-C loops
|
|
9
|
-
*
|
|
9
|
+
* Reads BEDPE files of paired breakends, such as structural variant calls
|
|
10
|
+
* within a single assembly.
|
|
10
11
|
*
|
|
11
12
|
* #example
|
|
12
13
|
* ```js
|
|
@@ -38,6 +39,7 @@ const BedpeAdapter = ConfigurationSchema('BedpeAdapter', {
|
|
|
38
39
|
},
|
|
39
40
|
}, {
|
|
40
41
|
explicitlyTyped: true,
|
|
42
|
+
closed: true,
|
|
41
43
|
/**
|
|
42
44
|
* #preProcessSnapshot
|
|
43
45
|
*
|
|
@@ -11,13 +11,21 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter<BigBedAdapterC
|
|
|
11
11
|
bigbed: BigBed;
|
|
12
12
|
header: import("@gmod/bbi").BigWigHeaderWithRefNames;
|
|
13
13
|
parser: BED;
|
|
14
|
+
positionalItemRgb: string | undefined;
|
|
14
15
|
}>;
|
|
15
16
|
configurePre(opts?: BaseOptions): Promise<{
|
|
16
17
|
bigbed: BigBed;
|
|
17
18
|
header: import("@gmod/bbi").BigWigHeaderWithRefNames;
|
|
18
19
|
parser: BED;
|
|
20
|
+
positionalItemRgb: string | undefined;
|
|
19
21
|
}>;
|
|
20
22
|
getRefNames(opts?: BaseOptions): Promise<string[]>;
|
|
23
|
+
/** Each contig's length off the chrom table, which lists empty contigs too. */
|
|
24
|
+
getContigs(opts?: BaseOptions): Promise<{
|
|
25
|
+
refName: string;
|
|
26
|
+
length: number | undefined;
|
|
27
|
+
hasData: null;
|
|
28
|
+
}[]>;
|
|
21
29
|
getRegionByteSize(regions: Region[], opts?: BaseOptions): Promise<number>;
|
|
22
30
|
getRefNameAliases(opts?: BaseOptions): Promise<{
|
|
23
31
|
refName: unknown;
|
|
@@ -28,11 +36,26 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter<BigBedAdapterC
|
|
|
28
36
|
getHeader(opts?: BaseOptions): Promise<{
|
|
29
37
|
version: number;
|
|
30
38
|
fileType: "bigbed" | "bigwig";
|
|
31
|
-
autoSql: {
|
|
39
|
+
autoSql: {
|
|
40
|
+
type?: string;
|
|
41
|
+
name?: string;
|
|
42
|
+
comment?: string;
|
|
43
|
+
};
|
|
32
44
|
fields: {
|
|
33
45
|
[k: string]: string;
|
|
34
46
|
};
|
|
35
47
|
}>;
|
|
48
|
+
/** Each column the file's autoSql declares, with its type and comment. */
|
|
49
|
+
getAutoSqlFields(opts?: BaseOptions): Promise<{
|
|
50
|
+
isArray: boolean;
|
|
51
|
+
arrayIsNumeric: boolean;
|
|
52
|
+
isNumeric: boolean;
|
|
53
|
+
size?: number | string;
|
|
54
|
+
type: string;
|
|
55
|
+
name: string;
|
|
56
|
+
comment: string;
|
|
57
|
+
vals?: string[];
|
|
58
|
+
}[]>;
|
|
36
59
|
getMetadata(opts?: BaseOptions): Promise<{
|
|
37
60
|
[k: string]: string;
|
|
38
61
|
}>;
|
|
@@ -6,6 +6,12 @@ import { openLocation } from '@jbrowse/core/util/io';
|
|
|
6
6
|
import { ObservableCreate } from '@jbrowse/core/util/rxjs';
|
|
7
7
|
import { firstValueFrom, toArray } from 'rxjs';
|
|
8
8
|
import { featureData } from '../util.js';
|
|
9
|
+
// UCSC reads column 9 of a bed9+ bigBed as itemRgb whatever its autoSql calls
|
|
10
|
+
// it (spliceVarDb calls it `color`); colorBits reads only the standard names.
|
|
11
|
+
function positionalItemRgbField(definedFieldCount, fields) {
|
|
12
|
+
const name = definedFieldCount >= 9 ? fields[8]?.name : undefined;
|
|
13
|
+
return name && name !== 'itemRgb' && name !== 'reserved' ? name : undefined;
|
|
14
|
+
}
|
|
9
15
|
export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
10
16
|
// `label` on cachedSetup so "Downloading header" shows only while the first
|
|
11
17
|
// fetch is in flight; every later getFeatures resolves from the memo with no
|
|
@@ -27,12 +33,22 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
27
33
|
bigbed,
|
|
28
34
|
header,
|
|
29
35
|
parser,
|
|
36
|
+
positionalItemRgb: positionalItemRgbField(header.definedFieldCount, parser.autoSql.fields),
|
|
30
37
|
};
|
|
31
38
|
}
|
|
32
39
|
async getRefNames(opts) {
|
|
33
40
|
const { header } = await this.configure(opts);
|
|
34
41
|
return Object.keys(header.refsByName);
|
|
35
42
|
}
|
|
43
|
+
/** Each contig's length off the chrom table, which lists empty contigs too. */
|
|
44
|
+
async getContigs(opts) {
|
|
45
|
+
const { header } = await this.configure(opts);
|
|
46
|
+
return Object.entries(header.refsByName).map(([refName, id]) => ({
|
|
47
|
+
refName,
|
|
48
|
+
length: header.refsByNumber[id]?.length,
|
|
49
|
+
hasData: null,
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
36
52
|
// Compressed download-size estimate straight from the bbi R-tree index (block
|
|
37
53
|
// byte lengths, no data blocks read), so a display can byte-gate an over-large
|
|
38
54
|
// BigBed fetch before it starts. Overrides the base no-estimate default, which
|
|
@@ -81,6 +97,11 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
81
97
|
fields: await this.getMetadata(opts),
|
|
82
98
|
};
|
|
83
99
|
}
|
|
100
|
+
/** Each column the file's autoSql declares, with its type and comment. */
|
|
101
|
+
async getAutoSqlFields(opts) {
|
|
102
|
+
const { parser } = await this.configure(opts);
|
|
103
|
+
return parser.autoSql.fields;
|
|
104
|
+
}
|
|
84
105
|
async getMetadata(opts) {
|
|
85
106
|
const { parser } = await this.configure(opts);
|
|
86
107
|
const { fields } = parser.autoSql;
|
|
@@ -91,7 +112,7 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
91
112
|
const scoreColumn = this.getConf('scoreColumn');
|
|
92
113
|
const aggregateField = this.getConf('aggregateField');
|
|
93
114
|
const disableGeneHeuristic = this.getConf('disableGeneHeuristic');
|
|
94
|
-
const { parser, bigbed } = await this.configure(opts);
|
|
115
|
+
const { parser, bigbed, positionalItemRgb } = await this.configure(opts);
|
|
95
116
|
// downloadStatus, not updateStatus: bbi knows the total block bytes up front
|
|
96
117
|
// (they come from the R-tree index) so this reports a determinate fraction
|
|
97
118
|
// rather than an indeterminate spinner. Matters most here — BigBed is a
|
|
@@ -121,6 +142,9 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
121
142
|
refName: query.refName,
|
|
122
143
|
disableGeneHeuristic,
|
|
123
144
|
});
|
|
145
|
+
if (positionalItemRgb) {
|
|
146
|
+
f.itemRgb ??= f[positionalItemRgb];
|
|
147
|
+
}
|
|
124
148
|
const aggr = f[aggregateField];
|
|
125
149
|
const aggrIsNotNone = typeof aggr === 'string' && aggr && aggr !== 'none';
|
|
126
150
|
if (aggrIsNotNone) {
|
|
@@ -4,6 +4,7 @@ export declare function normalizeSnapshot(snap: Record<string, unknown>): Record
|
|
|
4
4
|
* #config BigBedAdapter
|
|
5
5
|
* #trackType FeatureTrack
|
|
6
6
|
* #fileFormat feature | BigBed
|
|
7
|
+
* Reads BigBed files, the indexed binary form of BED.
|
|
7
8
|
*
|
|
8
9
|
* #example
|
|
9
10
|
* ```js
|
|
@@ -14,9 +15,6 @@ export declare function normalizeSnapshot(snap: Record<string, unknown>): Record
|
|
|
14
15
|
* ```
|
|
15
16
|
*/
|
|
16
17
|
declare const BigBedAdapter: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
|
|
17
|
-
readonly densityAdapter: {
|
|
18
|
-
type: "maybeFrozen";
|
|
19
|
-
};
|
|
20
18
|
type: {
|
|
21
19
|
type: "string";
|
|
22
20
|
} & {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { ConfigurationSchema, expandUriShorthand, } from '@jbrowse/core/configuration';
|
|
2
|
-
import { densityAdapterConfigSchemaFields } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
3
2
|
export function normalizeSnapshot(snap) {
|
|
4
3
|
return expandUriShorthand(snap, 'bigBedLocation');
|
|
5
4
|
}
|
|
@@ -7,6 +6,7 @@ export function normalizeSnapshot(snap) {
|
|
|
7
6
|
* #config BigBedAdapter
|
|
8
7
|
* #trackType FeatureTrack
|
|
9
8
|
* #fileFormat feature | BigBed
|
|
9
|
+
* Reads BigBed files, the indexed binary form of BED.
|
|
10
10
|
*
|
|
11
11
|
* #example
|
|
12
12
|
* ```js
|
|
@@ -53,9 +53,9 @@ const BigBedAdapter = ConfigurationSchema('BigBedAdapter', {
|
|
|
53
53
|
description: 'Disable the heuristic that auto-detects BED12 features as gene/transcript structures. Useful for files that have BED12-like structure but are not genes (e.g. tandem duplications)',
|
|
54
54
|
defaultValue: false,
|
|
55
55
|
},
|
|
56
|
-
...densityAdapterConfigSchemaFields,
|
|
57
56
|
}, {
|
|
58
57
|
explicitlyTyped: true,
|
|
58
|
+
closed: true,
|
|
59
59
|
/**
|
|
60
60
|
* #preProcessSnapshot
|
|
61
61
|
*
|
|
@@ -4,7 +4,8 @@ export declare function normalizeSnapshot(snap: Record<string, unknown>): Record
|
|
|
4
4
|
* #config StarFusionAdapter
|
|
5
5
|
* #trackType VariantTrack
|
|
6
6
|
* #fileFormat variants | STAR-Fusion
|
|
7
|
-
*
|
|
7
|
+
* Reads the gene fusions that STAR-Fusion predicts, from its
|
|
8
|
+
* `star-fusion.fusion_predictions.tsv` output.
|
|
8
9
|
*
|
|
9
10
|
* #example
|
|
10
11
|
* ```js
|
|
@@ -6,7 +6,8 @@ export function normalizeSnapshot(snap) {
|
|
|
6
6
|
* #config StarFusionAdapter
|
|
7
7
|
* #trackType VariantTrack
|
|
8
8
|
* #fileFormat variants | STAR-Fusion
|
|
9
|
-
*
|
|
9
|
+
* Reads the gene fusions that STAR-Fusion predicts, from its
|
|
10
|
+
* `star-fusion.fusion_predictions.tsv` output.
|
|
10
11
|
*
|
|
11
12
|
* #example
|
|
12
13
|
* ```js
|
|
@@ -30,6 +31,7 @@ const StarFusionAdapter = ConfigurationSchema('StarFusionAdapter', {
|
|
|
30
31
|
},
|
|
31
32
|
}, {
|
|
32
33
|
explicitlyTyped: true,
|
|
34
|
+
closed: true,
|
|
33
35
|
/**
|
|
34
36
|
* #preProcessSnapshot
|
|
35
37
|
*
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { copyExcept } from './copyExcept.js';
|
|
2
|
+
import { toNumberList } from './numberColumns.js';
|
|
2
3
|
// type guard: narrows input fields to required when true
|
|
3
4
|
// strand===0 means unstranded — likely not a gene
|
|
4
5
|
//
|
|
@@ -42,11 +43,6 @@ function calculatePhasesFromCds(cdsRegions, strand) {
|
|
|
42
43
|
function frameToPhase(frame) {
|
|
43
44
|
return (3 - frame) % 3;
|
|
44
45
|
}
|
|
45
|
-
function parseFrames(frames) {
|
|
46
|
-
return typeof frames === 'string'
|
|
47
|
-
? frames.replace(/,$/, '').split(',').map(Number)
|
|
48
|
-
: frames;
|
|
49
|
-
}
|
|
50
46
|
const TRANSCRIPT_OWN = new Set([
|
|
51
47
|
'strand',
|
|
52
48
|
'uniqueId',
|
|
@@ -70,7 +66,7 @@ export function generateUcscTranscript(data) {
|
|
|
70
66
|
// exonFrames from bigGenePred - the @gmod/bed parser returns it in genomic order.
|
|
71
67
|
// _exonFrames fallback supports BED files that use the underscore-prefixed column
|
|
72
68
|
// name, which the parser leaves as raw text because it is not a standard column.
|
|
73
|
-
const exonFrames =
|
|
69
|
+
const exonFrames = toNumberList((rest.exonFrames ?? rest._exonFrames));
|
|
74
70
|
const feats = oldSubfeatures
|
|
75
71
|
.filter(child => child.type === 'block')
|
|
76
72
|
.sort((a, b) => a.start - b.start);
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export type NumberColumn = number | string;
|
|
2
|
+
export type NumberListColumn = number[] | string[] | string;
|
|
3
|
+
export declare function toNumber(value: NumberColumn | undefined): number | undefined;
|
|
4
|
+
export declare function toNumberList(value: NumberListColumn | undefined): number[] | undefined;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export function toNumber(value) {
|
|
2
|
+
if (value === undefined || value === '') {
|
|
3
|
+
return undefined;
|
|
4
|
+
}
|
|
5
|
+
const n = Number(value);
|
|
6
|
+
return Number.isNaN(n) ? undefined : n;
|
|
7
|
+
}
|
|
8
|
+
export function toNumberList(value) {
|
|
9
|
+
return typeof value === 'string'
|
|
10
|
+
? value
|
|
11
|
+
.split(',')
|
|
12
|
+
.filter(s => s !== '')
|
|
13
|
+
.map(Number)
|
|
14
|
+
: typeof value?.[0] === 'string'
|
|
15
|
+
? value.map(Number)
|
|
16
|
+
: value;
|
|
17
|
+
}
|
package/esm/util.js
CHANGED
|
@@ -5,6 +5,7 @@ import { generateBedMethylFeature, isBedMethylFeature, } from './generateBedMeth
|
|
|
5
5
|
import { generateRastairMethylFeature, isRastairMethylFeature, } from './generateRastairMethylFeature.js';
|
|
6
6
|
import { parseRepeatMaskerDescription } from './generateRepeatMaskerFeature.js';
|
|
7
7
|
import { generateUcscTranscript, isUcscTranscript, } from './generateUcscTranscript.js';
|
|
8
|
+
import { toNumber, toNumberList } from './numberColumns.js';
|
|
8
9
|
// Heuristically split features and header from a buffered BED file, bucketing
|
|
9
10
|
// data lines by the first tab-separated column (refName).
|
|
10
11
|
export function bucketBedLines(buffer, statusCallback) {
|
|
@@ -151,22 +152,23 @@ export function featureData({ splitLine, refName, start, end, parser, uniqueId,
|
|
|
151
152
|
};
|
|
152
153
|
}
|
|
153
154
|
const rest = copyExcept(data, BED_OWN);
|
|
154
|
-
const
|
|
155
|
+
const blockCount = toNumber(data.blockCount);
|
|
156
|
+
const subfeatures = blockCount
|
|
155
157
|
? makeBlocks({
|
|
156
158
|
start,
|
|
157
159
|
uniqueId,
|
|
158
160
|
refName,
|
|
159
|
-
chromStarts: data.chromStarts,
|
|
160
|
-
blockCount
|
|
161
|
-
blockSizes: data.blockSizes,
|
|
162
|
-
blockStarts: data.blockStarts,
|
|
161
|
+
chromStarts: toNumberList(data.chromStarts),
|
|
162
|
+
blockCount,
|
|
163
|
+
blockSizes: toNumberList(data.blockSizes),
|
|
164
|
+
blockStarts: toNumberList(data.blockStarts),
|
|
163
165
|
})
|
|
164
166
|
: undefined;
|
|
165
167
|
const transcriptCheck = {
|
|
166
168
|
strand,
|
|
167
|
-
blockCount
|
|
168
|
-
thickStart: data.thickStart,
|
|
169
|
-
thickEnd: data.thickEnd,
|
|
169
|
+
blockCount,
|
|
170
|
+
thickStart: toNumber(data.thickStart),
|
|
171
|
+
thickEnd: toNumber(data.thickEnd),
|
|
170
172
|
};
|
|
171
173
|
if (!disableGeneHeuristic &&
|
|
172
174
|
subfeatures &&
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/plugin-bed",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.14",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "JBrowse 2 bed adapters, tracks, etc.",
|
|
6
6
|
"keywords": [
|
|
@@ -21,14 +21,14 @@
|
|
|
21
21
|
"esm"
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@gmod/bbi": "^11.3.
|
|
25
|
-
"@gmod/bed": "^2.3.
|
|
26
|
-
"@gmod/tabix": "^3.
|
|
27
|
-
"@gmod/trix": "^3.0
|
|
28
|
-
"@jbrowse/mobx-state-tree": "^6.
|
|
24
|
+
"@gmod/bbi": "^11.3.2",
|
|
25
|
+
"@gmod/bed": "^2.3.3",
|
|
26
|
+
"@gmod/tabix": "^3.11.0",
|
|
27
|
+
"@gmod/trix": "^3.1.0",
|
|
28
|
+
"@jbrowse/mobx-state-tree": "^6.9.0",
|
|
29
29
|
"mobx": "^7.0.6",
|
|
30
30
|
"rxjs": "^7.8.2",
|
|
31
|
-
"@jbrowse/core": "^5.0.0-beta.
|
|
31
|
+
"@jbrowse/core": "^5.0.0-beta.14"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
34
|
"react": ">=19.0.0",
|