@jbrowse/plugin-bed 4.3.0 → 5.0.0-beta.10
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 +5 -22
- package/esm/BedAdapter/BedAdapter.js +29 -93
- package/esm/BedAdapter/configSchema.d.ts +59 -32
- package/esm/BedAdapter/configSchema.js +64 -14
- package/esm/BedAdapter/index.js +4 -2
- package/esm/BedGraphAdapter/BedGraphAdapter.d.ts +5 -12
- package/esm/BedGraphAdapter/BedGraphAdapter.js +33 -89
- package/esm/BedGraphAdapter/configSchema.d.ts +35 -11
- package/esm/BedGraphAdapter/configSchema.js +43 -13
- package/esm/BedGraphAdapter/index.js +3 -2
- package/esm/BedGraphTabixAdapter/BedGraphTabixAdapter.d.ts +5 -5
- package/esm/BedGraphTabixAdapter/BedGraphTabixAdapter.js +65 -57
- package/esm/BedGraphTabixAdapter/configSchema.d.ts +46 -22
- package/esm/BedGraphTabixAdapter/configSchema.js +50 -34
- package/esm/BedGraphTabixAdapter/index.js +3 -2
- package/esm/BedTabixAdapter/BedTabixAdapter.d.ts +34 -38
- package/esm/BedTabixAdapter/BedTabixAdapter.js +82 -72
- package/esm/BedTabixAdapter/configSchema.d.ts +55 -31
- package/esm/BedTabixAdapter/configSchema.js +58 -35
- package/esm/BedTabixAdapter/index.js +4 -2
- package/esm/BedpeAdapter/BedpeAdapter.d.ts +6 -13
- package/esm/BedpeAdapter/BedpeAdapter.js +26 -74
- package/esm/BedpeAdapter/configSchema.d.ts +31 -12
- package/esm/BedpeAdapter/configSchema.js +37 -13
- package/esm/BedpeAdapter/index.js +4 -2
- package/esm/BedpeAdapter/util.js +25 -25
- package/esm/BigBedAdapter/BigBedAdapter.d.ts +8 -7
- package/esm/BigBedAdapter/BigBedAdapter.js +99 -107
- package/esm/BigBedAdapter/configSchema.d.ts +38 -16
- package/esm/BigBedAdapter/configSchema.js +46 -13
- package/esm/BigBedAdapter/index.js +3 -2
- package/esm/BigBedTextSearchAdapter/BigBedTextSearchAdapter.d.ts +27 -0
- package/esm/BigBedTextSearchAdapter/BigBedTextSearchAdapter.js +128 -0
- package/esm/BigBedTextSearchAdapter/configSchema.d.ts +51 -0
- package/esm/BigBedTextSearchAdapter/configSchema.js +57 -0
- package/esm/BigBedTextSearchAdapter/index.d.ts +2 -0
- package/esm/BigBedTextSearchAdapter/index.js +11 -0
- package/esm/StarFusionAdapter/StarFusionAdapter.d.ts +14 -0
- package/esm/StarFusionAdapter/StarFusionAdapter.js +66 -0
- package/esm/StarFusionAdapter/configSchema.d.ts +30 -0
- package/esm/StarFusionAdapter/configSchema.js +43 -0
- package/esm/StarFusionAdapter/index.d.ts +2 -0
- package/esm/StarFusionAdapter/index.js +12 -0
- package/esm/adapterUtil.d.ts +5 -0
- package/esm/adapterUtil.js +43 -0
- package/esm/bedGraphUtil.d.ts +11 -0
- package/esm/bedGraphUtil.js +20 -0
- package/esm/copyExcept.d.ts +1 -0
- package/esm/copyExcept.js +11 -0
- package/esm/generateBedMethylFeature.d.ts +1 -1
- package/esm/generateBedMethylFeature.js +24 -6
- package/esm/generateRastairMethylFeature.d.ts +28 -0
- package/esm/generateRastairMethylFeature.js +38 -0
- package/esm/generateRepeatMaskerFeature.d.ts +17 -51
- package/esm/generateRepeatMaskerFeature.js +27 -37
- package/esm/generateUcscTranscript.d.ts +15 -7
- package/esm/generateUcscTranscript.js +106 -29
- package/esm/index.d.ts +2 -0
- package/esm/index.js +12 -8
- package/esm/util.d.ts +32 -27
- package/esm/util.js +139 -98
- package/package.json +10 -13
- package/esm/GuessAdapter/index.d.ts +0 -2
- package/esm/GuessAdapter/index.js +0 -71
|
@@ -1,36 +1,19 @@
|
|
|
1
|
-
import BED from '@gmod/bed';
|
|
2
1
|
import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
3
|
-
import {
|
|
2
|
+
import type { BedAdapterConfig } from './configSchema.ts';
|
|
4
3
|
import type { BaseOptions } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
5
4
|
import type { Feature, Region } from '@jbrowse/core/util';
|
|
6
|
-
export default class BedAdapter extends BaseFeatureDataAdapter {
|
|
7
|
-
|
|
5
|
+
export default class BedAdapter extends BaseFeatureDataAdapter<BedAdapterConfig> {
|
|
6
|
+
loadData: (opts?: BaseOptions) => Promise<{
|
|
8
7
|
header: string;
|
|
9
8
|
features: Record<string, string[]>;
|
|
10
|
-
parser: BED;
|
|
11
|
-
columnNames: string[];
|
|
12
|
-
scoreColumn: string;
|
|
13
|
-
colRef: number;
|
|
14
|
-
colStart: number;
|
|
15
|
-
colEnd: number;
|
|
16
9
|
}>;
|
|
17
|
-
|
|
10
|
+
private getParser;
|
|
18
11
|
static capabilities: string[];
|
|
19
12
|
private loadDataP;
|
|
20
|
-
loadData(opts?: BaseOptions): Promise<{
|
|
21
|
-
header: string;
|
|
22
|
-
features: Record<string, string[]>;
|
|
23
|
-
parser: BED;
|
|
24
|
-
columnNames: string[];
|
|
25
|
-
scoreColumn: string;
|
|
26
|
-
colRef: number;
|
|
27
|
-
colStart: number;
|
|
28
|
-
colEnd: number;
|
|
29
|
-
}>;
|
|
30
13
|
getRefNames(opts?: BaseOptions): Promise<string[]>;
|
|
31
14
|
getHeader(opts?: BaseOptions): Promise<string>;
|
|
32
15
|
getNames(): Promise<string[] | undefined>;
|
|
33
16
|
private loadFeatureIntervalTreeHelper;
|
|
34
|
-
|
|
17
|
+
private treeFeatures;
|
|
35
18
|
getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
|
|
36
19
|
}
|
|
@@ -1,60 +1,23 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
1
|
+
import { BaseFeatureDataAdapter, cachedSetup, } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
3
2
|
import { IntervalTree, SimpleFeature, fetchAndMaybeUnzip, } from '@jbrowse/core/util';
|
|
4
3
|
import { openLocation } from '@jbrowse/core/util/io';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { featureData } from "../util.js";
|
|
4
|
+
import { intervalTreeFeatures } from '../adapterUtil.js';
|
|
5
|
+
import { bedFeatureLocus, bucketBedLines, featureData, makeParser, resolveColumnNames, } from '../util.js';
|
|
8
6
|
export default class BedAdapter extends BaseFeatureDataAdapter {
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
// No `label`: `fetchAndMaybeUnzip` narrates the download from inside.
|
|
8
|
+
loadData = cachedSetup({ setup: opts => this.loadDataP(opts) });
|
|
9
|
+
// the parser needs the column names, which come from the header, so it can
|
|
10
|
+
// only be built once the file is loaded
|
|
11
|
+
getParser = cachedSetup({
|
|
12
|
+
setup: async () => makeParser({
|
|
13
|
+
autoSql: this.getConf('autoSql'),
|
|
14
|
+
columnNames: await this.getNames(),
|
|
15
|
+
}),
|
|
16
|
+
});
|
|
11
17
|
static capabilities = ['getFeatures', 'getRefNames'];
|
|
12
18
|
async loadDataP(opts) {
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
const headerLines = [];
|
|
16
|
-
const features = {};
|
|
17
|
-
parseLineByLine(buffer, line => {
|
|
18
|
-
if (line.startsWith('#')) {
|
|
19
|
-
headerLines.push(line);
|
|
20
|
-
}
|
|
21
|
-
else {
|
|
22
|
-
const tab = line.indexOf('\t');
|
|
23
|
-
const refName = line.slice(0, tab);
|
|
24
|
-
if (!features[refName]) {
|
|
25
|
-
features[refName] = [];
|
|
26
|
-
}
|
|
27
|
-
features[refName].push(line);
|
|
28
|
-
}
|
|
29
|
-
return true;
|
|
30
|
-
}, opts?.statusCallback);
|
|
31
|
-
const header = headerLines.join('\n');
|
|
32
|
-
const autoSql = this.getConf('autoSql');
|
|
33
|
-
const parser = new BED({ autoSql });
|
|
34
|
-
const columnNames = this.getConf('columnNames');
|
|
35
|
-
const scoreColumn = this.getConf('scoreColumn');
|
|
36
|
-
const colRef = this.getConf('colRef');
|
|
37
|
-
const colStart = this.getConf('colStart');
|
|
38
|
-
const colEnd = this.getConf('colEnd');
|
|
39
|
-
return {
|
|
40
|
-
header,
|
|
41
|
-
features,
|
|
42
|
-
parser,
|
|
43
|
-
columnNames,
|
|
44
|
-
scoreColumn,
|
|
45
|
-
colRef,
|
|
46
|
-
colStart,
|
|
47
|
-
colEnd,
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
async loadData(opts = {}) {
|
|
51
|
-
if (!this.bedFeatures) {
|
|
52
|
-
this.bedFeatures = this.loadDataP(opts).catch((e) => {
|
|
53
|
-
this.bedFeatures = undefined;
|
|
54
|
-
throw e;
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
return this.bedFeatures;
|
|
19
|
+
const buffer = await fetchAndMaybeUnzip(openLocation(this.getConf('bedLocation'), this.pluginManager), opts);
|
|
20
|
+
return bucketBedLines(buffer, opts?.statusCallback);
|
|
58
21
|
}
|
|
59
22
|
async getRefNames(opts = {}) {
|
|
60
23
|
const { features } = await this.loadData(opts);
|
|
@@ -65,39 +28,30 @@ export default class BedAdapter extends BaseFeatureDataAdapter {
|
|
|
65
28
|
return header;
|
|
66
29
|
}
|
|
67
30
|
async getNames() {
|
|
68
|
-
|
|
69
|
-
if (columnNames.length) {
|
|
70
|
-
return columnNames;
|
|
71
|
-
}
|
|
72
|
-
const defs = header.split(/\n|\r\n|\r/).filter(f => !!f);
|
|
73
|
-
const defline = defs.at(-1);
|
|
74
|
-
return defline?.includes('\t')
|
|
75
|
-
? defline
|
|
76
|
-
.slice(1)
|
|
77
|
-
.split('\t')
|
|
78
|
-
.map(field => field.trim())
|
|
79
|
-
: undefined;
|
|
31
|
+
return resolveColumnNames(this.getConf('columnNames'), async () => (await this.loadData()).header);
|
|
80
32
|
}
|
|
81
33
|
async loadFeatureIntervalTreeHelper(refName) {
|
|
82
|
-
const {
|
|
34
|
+
const { features } = await this.loadData();
|
|
83
35
|
const lines = features[refName];
|
|
84
36
|
if (!lines) {
|
|
85
37
|
return undefined;
|
|
86
38
|
}
|
|
87
39
|
const names = await this.getNames();
|
|
40
|
+
const parser = await this.getParser();
|
|
41
|
+
const scoreColumn = this.getConf('scoreColumn');
|
|
42
|
+
const colRef = this.getConf('colRef');
|
|
43
|
+
const colStart = this.getConf('colStart');
|
|
44
|
+
const colEnd = this.getConf('colEnd');
|
|
88
45
|
const disableGeneHeuristic = this.getConf('disableGeneHeuristic');
|
|
89
46
|
const intervalTree = new IntervalTree();
|
|
90
47
|
for (let i = 0; i < lines.length; i++) {
|
|
91
|
-
const
|
|
92
|
-
const uniqueId = `${this.id}-${refName}-${i}`;
|
|
48
|
+
const splitLine = lines[i].split('\t');
|
|
93
49
|
const feat = new SimpleFeature(featureData({
|
|
94
|
-
|
|
95
|
-
colRef,
|
|
96
|
-
colStart,
|
|
97
|
-
colEnd,
|
|
50
|
+
splitLine,
|
|
51
|
+
...bedFeatureLocus({ splitLine, colRef, colStart, colEnd }),
|
|
98
52
|
scoreColumn,
|
|
99
53
|
parser,
|
|
100
|
-
uniqueId
|
|
54
|
+
uniqueId: `${this.id}-${refName}-${i}`,
|
|
101
55
|
names,
|
|
102
56
|
disableGeneHeuristic,
|
|
103
57
|
}));
|
|
@@ -105,26 +59,8 @@ export default class BedAdapter extends BaseFeatureDataAdapter {
|
|
|
105
59
|
}
|
|
106
60
|
return intervalTree;
|
|
107
61
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
this.intervalTrees[refName] = undefined;
|
|
112
|
-
throw e;
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
return this.intervalTrees[refName];
|
|
116
|
-
}
|
|
117
|
-
getFeatures(query, opts = {}) {
|
|
118
|
-
return ObservableCreate(async (observer) => {
|
|
119
|
-
const { start, end, refName } = query;
|
|
120
|
-
const intervalTree = await this.loadFeatureIntervalTree(refName);
|
|
121
|
-
const features = intervalTree?.search([start, end]);
|
|
122
|
-
if (features) {
|
|
123
|
-
for (const f of features) {
|
|
124
|
-
observer.next(f);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
observer.complete();
|
|
128
|
-
}, opts.stopToken);
|
|
62
|
+
treeFeatures = intervalTreeFeatures(opts => this.loadData(opts), refName => this.loadFeatureIntervalTreeHelper(refName));
|
|
63
|
+
getFeatures(query, opts) {
|
|
64
|
+
return this.treeFeatures(query, opts);
|
|
129
65
|
}
|
|
130
66
|
}
|
|
@@ -1,46 +1,73 @@
|
|
|
1
|
+
import type { Instance } from '@jbrowse/mobx-state-tree';
|
|
2
|
+
export declare function normalizeSnapshot(snap: Record<string, unknown>): Record<string, unknown>;
|
|
3
|
+
/**
|
|
4
|
+
* #config BedAdapter
|
|
5
|
+
* #trackType FeatureTrack
|
|
6
|
+
* #fileFormat feature | BED (plain) | Loaded entirely into memory; for small files
|
|
7
|
+
* #gotcha Named BED columns past `name`/`score`/`strand` (`itemRgb`,
|
|
8
|
+
* `thickStart`, ...) are only guaranteed for BED12 or a track with an
|
|
9
|
+
* `autoSql`/`columnNames`. For a BED7-BED11 file JBrowse cannot know what the
|
|
10
|
+
* extra columns mean, so it exposes them generically as `field6`, `field7`,
|
|
11
|
+
* ... and a jexl callback reading `feature.itemRgb` gets `undefined`. Set
|
|
12
|
+
* `columnNames` to refer to them by name.
|
|
13
|
+
*
|
|
14
|
+
* used to load plain-text BED files. Loads the whole file into memory, so
|
|
15
|
+
* prefer the BedTabixAdapter for large files.
|
|
16
|
+
*
|
|
17
|
+
* #example
|
|
18
|
+
* ```js
|
|
19
|
+
* {
|
|
20
|
+
* type: 'BedAdapter',
|
|
21
|
+
* uri: 'https://example.com/features.bed',
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
1
25
|
declare const BedAdapter: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
|
|
2
|
-
|
|
3
|
-
type: string;
|
|
4
|
-
|
|
5
|
-
defaultValue: {
|
|
6
|
-
uri: string;
|
|
7
|
-
locationType: string;
|
|
8
|
-
};
|
|
9
|
-
};
|
|
10
|
-
columnNames: {
|
|
11
|
-
type: string;
|
|
12
|
-
description: string;
|
|
13
|
-
defaultValue: never[];
|
|
14
|
-
};
|
|
15
|
-
scoreColumn: {
|
|
16
|
-
type: string;
|
|
17
|
-
description: string;
|
|
26
|
+
type: {
|
|
27
|
+
type: "string";
|
|
28
|
+
} & {
|
|
18
29
|
defaultValue: string;
|
|
19
30
|
};
|
|
20
|
-
|
|
21
|
-
type:
|
|
22
|
-
|
|
31
|
+
readonly bedLocation: {
|
|
32
|
+
type: "fileLocation";
|
|
33
|
+
} & {
|
|
34
|
+
defaultValue: unknown;
|
|
35
|
+
};
|
|
36
|
+
readonly columnNames: {
|
|
37
|
+
type: "stringArray";
|
|
38
|
+
} & {
|
|
39
|
+
defaultValue: unknown;
|
|
40
|
+
};
|
|
41
|
+
readonly scoreColumn: {
|
|
42
|
+
type: "string";
|
|
43
|
+
} & {
|
|
44
|
+
defaultValue: string;
|
|
45
|
+
};
|
|
46
|
+
readonly autoSql: {
|
|
47
|
+
type: "string";
|
|
48
|
+
} & {
|
|
23
49
|
defaultValue: string;
|
|
24
50
|
};
|
|
25
|
-
colRef: {
|
|
26
|
-
type:
|
|
27
|
-
|
|
51
|
+
readonly colRef: {
|
|
52
|
+
type: "number";
|
|
53
|
+
} & {
|
|
28
54
|
defaultValue: number;
|
|
29
55
|
};
|
|
30
|
-
colStart: {
|
|
31
|
-
type:
|
|
32
|
-
|
|
56
|
+
readonly colStart: {
|
|
57
|
+
type: "number";
|
|
58
|
+
} & {
|
|
33
59
|
defaultValue: number;
|
|
34
60
|
};
|
|
35
|
-
colEnd: {
|
|
36
|
-
type:
|
|
37
|
-
|
|
61
|
+
readonly colEnd: {
|
|
62
|
+
type: "number";
|
|
63
|
+
} & {
|
|
38
64
|
defaultValue: number;
|
|
39
65
|
};
|
|
40
|
-
disableGeneHeuristic: {
|
|
41
|
-
type:
|
|
42
|
-
|
|
66
|
+
readonly disableGeneHeuristic: {
|
|
67
|
+
type: "boolean";
|
|
68
|
+
} & {
|
|
43
69
|
defaultValue: boolean;
|
|
44
70
|
};
|
|
45
|
-
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
|
|
71
|
+
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined, true, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>, any>>;
|
|
72
|
+
export type BedAdapterConfig = Instance<typeof BedAdapter>;
|
|
46
73
|
export default BedAdapter;
|
|
@@ -1,6 +1,33 @@
|
|
|
1
|
-
import { ConfigurationSchema } from '@jbrowse/core/configuration';
|
|
2
|
-
function
|
|
1
|
+
import { ConfigurationSchema, expandUriShorthand, } from '@jbrowse/core/configuration';
|
|
2
|
+
export function normalizeSnapshot(snap) {
|
|
3
|
+
return expandUriShorthand(snap, 'bedLocation');
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* #config BedAdapter
|
|
7
|
+
* #trackType FeatureTrack
|
|
8
|
+
* #fileFormat feature | BED (plain) | Loaded entirely into memory; for small files
|
|
9
|
+
* #gotcha Named BED columns past `name`/`score`/`strand` (`itemRgb`,
|
|
10
|
+
* `thickStart`, ...) are only guaranteed for BED12 or a track with an
|
|
11
|
+
* `autoSql`/`columnNames`. For a BED7-BED11 file JBrowse cannot know what the
|
|
12
|
+
* extra columns mean, so it exposes them generically as `field6`, `field7`,
|
|
13
|
+
* ... and a jexl callback reading `feature.itemRgb` gets `undefined`. Set
|
|
14
|
+
* `columnNames` to refer to them by name.
|
|
15
|
+
*
|
|
16
|
+
* used to load plain-text BED files. Loads the whole file into memory, so
|
|
17
|
+
* prefer the BedTabixAdapter for large files.
|
|
18
|
+
*
|
|
19
|
+
* #example
|
|
20
|
+
* ```js
|
|
21
|
+
* {
|
|
22
|
+
* type: 'BedAdapter',
|
|
23
|
+
* uri: 'https://example.com/features.bed',
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
3
27
|
const BedAdapter = ConfigurationSchema('BedAdapter', {
|
|
28
|
+
/**
|
|
29
|
+
* #slot
|
|
30
|
+
*/
|
|
4
31
|
bedLocation: {
|
|
5
32
|
type: 'fileLocation',
|
|
6
33
|
description: 'path to bed file, also allows gzipped bed',
|
|
@@ -9,36 +36,57 @@ const BedAdapter = ConfigurationSchema('BedAdapter', {
|
|
|
9
36
|
locationType: 'UriLocation',
|
|
10
37
|
},
|
|
11
38
|
},
|
|
39
|
+
/**
|
|
40
|
+
* #slot
|
|
41
|
+
*/
|
|
12
42
|
columnNames: {
|
|
13
43
|
type: 'stringArray',
|
|
14
|
-
description:
|
|
44
|
+
description: "List of column names. A column named like a standard BED column is parsed as that column's type (chromStart numeric, blockSizes a numeric list); any other column is text",
|
|
15
45
|
defaultValue: [],
|
|
16
46
|
},
|
|
47
|
+
/**
|
|
48
|
+
* #slot
|
|
49
|
+
*/
|
|
17
50
|
scoreColumn: {
|
|
18
51
|
type: 'string',
|
|
19
52
|
description: 'The column to use as a "score" attribute',
|
|
20
53
|
defaultValue: '',
|
|
21
54
|
},
|
|
55
|
+
/**
|
|
56
|
+
* #slot
|
|
57
|
+
*/
|
|
22
58
|
autoSql: {
|
|
23
59
|
type: 'string',
|
|
24
60
|
description: 'The autoSql definition for the data fields in the file',
|
|
25
61
|
defaultValue: '',
|
|
26
62
|
},
|
|
63
|
+
/**
|
|
64
|
+
* #slot
|
|
65
|
+
*/
|
|
27
66
|
colRef: {
|
|
28
67
|
type: 'number',
|
|
29
68
|
description: 'The column to use as a "refName" attribute',
|
|
30
69
|
defaultValue: 0,
|
|
31
70
|
},
|
|
71
|
+
/**
|
|
72
|
+
* #slot
|
|
73
|
+
*/
|
|
32
74
|
colStart: {
|
|
33
75
|
type: 'number',
|
|
34
76
|
description: 'The column to use as a "start" attribute',
|
|
35
77
|
defaultValue: 1,
|
|
36
78
|
},
|
|
79
|
+
/**
|
|
80
|
+
* #slot
|
|
81
|
+
*/
|
|
37
82
|
colEnd: {
|
|
38
83
|
type: 'number',
|
|
39
84
|
description: 'The column to use as a "end" attribute',
|
|
40
85
|
defaultValue: 2,
|
|
41
86
|
},
|
|
87
|
+
/**
|
|
88
|
+
* #slot
|
|
89
|
+
*/
|
|
42
90
|
disableGeneHeuristic: {
|
|
43
91
|
type: 'boolean',
|
|
44
92
|
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)',
|
|
@@ -46,16 +94,18 @@ const BedAdapter = ConfigurationSchema('BedAdapter', {
|
|
|
46
94
|
},
|
|
47
95
|
}, {
|
|
48
96
|
explicitlyTyped: true,
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
97
|
+
/**
|
|
98
|
+
* #preProcessSnapshot
|
|
99
|
+
*
|
|
100
|
+
*
|
|
101
|
+
* preprocessor to allow minimal config:
|
|
102
|
+
* ```json
|
|
103
|
+
* {
|
|
104
|
+
* "type": "BedAdapter",
|
|
105
|
+
* "uri": "yourfile.bed"
|
|
106
|
+
* }
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
preProcessSnapshot: normalizeSnapshot,
|
|
60
110
|
});
|
|
61
111
|
export default BedAdapter;
|
package/esm/BedAdapter/index.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import AdapterType from '@jbrowse/core/pluggableElementTypes/AdapterType';
|
|
2
|
-
import configSchema from
|
|
2
|
+
import configSchema, { normalizeSnapshot } from './configSchema.js';
|
|
3
3
|
export default function BedAdapterF(pluginManager) {
|
|
4
4
|
pluginManager.addAdapterType(() => new AdapterType({
|
|
5
5
|
name: 'BedAdapter',
|
|
6
6
|
displayName: 'BED adapter',
|
|
7
7
|
configSchema,
|
|
8
|
-
getAdapterClass: () => import(
|
|
8
|
+
getAdapterClass: () => import('./BedAdapter.js').then(r => r.default),
|
|
9
|
+
locationKey: 'bedLocation',
|
|
10
|
+
normalizeSnapshot,
|
|
9
11
|
}));
|
|
10
12
|
}
|
|
@@ -1,23 +1,16 @@
|
|
|
1
1
|
import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
2
|
-
import {
|
|
2
|
+
import type { BedGraphAdapterConfig } from './configSchema.ts';
|
|
3
3
|
import type { BaseOptions } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
4
4
|
import type { Feature, Region } from '@jbrowse/core/util';
|
|
5
|
-
export default class BedGraphAdapter extends BaseFeatureDataAdapter {
|
|
6
|
-
|
|
5
|
+
export default class BedGraphAdapter extends BaseFeatureDataAdapter<BedGraphAdapterConfig> {
|
|
6
|
+
loadData: (opts?: BaseOptions) => Promise<{
|
|
7
7
|
header: string;
|
|
8
8
|
features: Record<string, string[]>;
|
|
9
|
-
columnNames: string[];
|
|
10
9
|
}>;
|
|
11
|
-
protected intervalTrees: Record<string, Promise<IntervalTree<Feature> | undefined> | undefined>;
|
|
12
10
|
getNames(): Promise<string[] | undefined>;
|
|
13
11
|
private loadFeatureIntervalTreeHelper;
|
|
14
12
|
getRefNames(opts?: BaseOptions): Promise<string[]>;
|
|
15
13
|
private loadDataP;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
header: string;
|
|
19
|
-
features: Record<string, string[]>;
|
|
20
|
-
columnNames: string[];
|
|
21
|
-
}>;
|
|
22
|
-
getFeatures(query: Region, _opts?: BaseOptions): import("rxjs").Observable<Feature>;
|
|
14
|
+
private treeFeatures;
|
|
15
|
+
getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
|
|
23
16
|
}
|
|
@@ -1,24 +1,14 @@
|
|
|
1
|
-
import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
2
|
-
import { IntervalTree,
|
|
1
|
+
import { BaseFeatureDataAdapter, cachedSetup, } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
2
|
+
import { IntervalTree, fetchAndMaybeUnzip } from '@jbrowse/core/util';
|
|
3
3
|
import { openLocation } from '@jbrowse/core/util/io';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { intervalTreeFeatures } from '../adapterUtil.js';
|
|
5
|
+
import { makeBedGraphFeature } from '../bedGraphUtil.js';
|
|
6
|
+
import { bucketBedLines, resolveColumnNames } from '../util.js';
|
|
6
7
|
export default class BedGraphAdapter extends BaseFeatureDataAdapter {
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
// No `label`: `fetchAndMaybeUnzip` narrates the download from inside.
|
|
9
|
+
loadData = cachedSetup({ setup: opts => this.loadDataP(opts) });
|
|
9
10
|
async getNames() {
|
|
10
|
-
|
|
11
|
-
if (columnNames.length) {
|
|
12
|
-
return columnNames;
|
|
13
|
-
}
|
|
14
|
-
const defs = header.split(/\n|\r\n|\r/).filter(f => !!f);
|
|
15
|
-
const defline = defs.at(-1);
|
|
16
|
-
return defline?.includes('\t')
|
|
17
|
-
? defline
|
|
18
|
-
.slice(1)
|
|
19
|
-
.split('\t')
|
|
20
|
-
.map(field => field.trim())
|
|
21
|
-
: undefined;
|
|
11
|
+
return resolveColumnNames(this.getConf('columnNames'), async () => (await this.loadData()).header);
|
|
22
12
|
}
|
|
23
13
|
async loadFeatureIntervalTreeHelper(refName) {
|
|
24
14
|
const { features } = await this.loadData();
|
|
@@ -26,28 +16,29 @@ export default class BedGraphAdapter extends BaseFeatureDataAdapter {
|
|
|
26
16
|
if (!lines) {
|
|
27
17
|
return undefined;
|
|
28
18
|
}
|
|
29
|
-
const names = (await this.getNames())?.slice(3)
|
|
19
|
+
const names = (await this.getNames())?.slice(3) ?? [];
|
|
20
|
+
const sourceColumn = names.indexOf('source');
|
|
30
21
|
const intervalTree = new IntervalTree();
|
|
31
22
|
for (let i = 0, l = lines.length; i < l; i++) {
|
|
32
|
-
const
|
|
33
|
-
const
|
|
23
|
+
const [refName, s, e, ...rest] = lines[i].split('\t');
|
|
24
|
+
const start = +s;
|
|
25
|
+
const end = +e;
|
|
34
26
|
for (let j = 0, l2 = rest.length; j < l2; j++) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}));
|
|
27
|
+
if (j === sourceColumn) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const feat = makeBedGraphFeature({
|
|
31
|
+
uniqueId: `${this.id}-${refName}-${i}-${j}`,
|
|
32
|
+
refName: refName,
|
|
33
|
+
start,
|
|
34
|
+
end,
|
|
35
|
+
names,
|
|
36
|
+
j,
|
|
37
|
+
value: rest[j],
|
|
38
|
+
rowSource: rest[sourceColumn],
|
|
39
|
+
});
|
|
40
|
+
if (feat) {
|
|
41
|
+
intervalTree.insert([start, end], feat);
|
|
51
42
|
}
|
|
52
43
|
}
|
|
53
44
|
}
|
|
@@ -58,58 +49,11 @@ export default class BedGraphAdapter extends BaseFeatureDataAdapter {
|
|
|
58
49
|
return Object.keys(features);
|
|
59
50
|
}
|
|
60
51
|
async loadDataP(opts = {}) {
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
const buffer = await fetchAndMaybeUnzip(openLocation(bedLoc, pm), opts);
|
|
64
|
-
const features = {};
|
|
65
|
-
const headerLines = [];
|
|
66
|
-
parseLineByLine(buffer, line => {
|
|
67
|
-
if (line.startsWith('#')) {
|
|
68
|
-
headerLines.push(line);
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
const tab = line.indexOf('\t');
|
|
72
|
-
const refName = line.slice(0, tab);
|
|
73
|
-
if (!features[refName]) {
|
|
74
|
-
features[refName] = [];
|
|
75
|
-
}
|
|
76
|
-
features[refName].push(line);
|
|
77
|
-
}
|
|
78
|
-
return true;
|
|
79
|
-
}, opts.statusCallback);
|
|
80
|
-
const columnNames = this.getConf('columnNames');
|
|
81
|
-
return {
|
|
82
|
-
header: headerLines.join('\n'),
|
|
83
|
-
features,
|
|
84
|
-
columnNames,
|
|
85
|
-
};
|
|
52
|
+
const buffer = await fetchAndMaybeUnzip(openLocation(this.getConf('bedGraphLocation'), this.pluginManager), opts);
|
|
53
|
+
return bucketBedLines(buffer, opts.statusCallback);
|
|
86
54
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
this.intervalTrees[refName] = undefined;
|
|
91
|
-
throw e;
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
return this.intervalTrees[refName];
|
|
95
|
-
}
|
|
96
|
-
async loadData(opts = {}) {
|
|
97
|
-
if (!this.bedFeatures) {
|
|
98
|
-
this.bedFeatures = this.loadDataP(opts).catch((e) => {
|
|
99
|
-
this.bedFeatures = undefined;
|
|
100
|
-
throw e;
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
return this.bedFeatures;
|
|
104
|
-
}
|
|
105
|
-
getFeatures(query, _opts = {}) {
|
|
106
|
-
return ObservableCreate(async (observer) => {
|
|
107
|
-
const { start, end, refName } = query;
|
|
108
|
-
const intervalTree = await this.loadFeatureIntervalTree(refName);
|
|
109
|
-
for (const feature of intervalTree?.search([start, end]) || []) {
|
|
110
|
-
observer.next(feature);
|
|
111
|
-
}
|
|
112
|
-
observer.complete();
|
|
113
|
-
});
|
|
55
|
+
treeFeatures = intervalTreeFeatures(opts => this.loadData(opts), refName => this.loadFeatureIntervalTreeHelper(refName));
|
|
56
|
+
getFeatures(query, opts) {
|
|
57
|
+
return this.treeFeatures(query, opts);
|
|
114
58
|
}
|
|
115
59
|
}
|
|
@@ -1,15 +1,39 @@
|
|
|
1
|
+
import type { Instance } from '@jbrowse/mobx-state-tree';
|
|
2
|
+
export declare function normalizeSnapshot(snap: Record<string, unknown>): Record<string, unknown>;
|
|
3
|
+
/**
|
|
4
|
+
* #config BedGraphAdapter
|
|
5
|
+
* #trackType QuantitativeTrack
|
|
6
|
+
* #fileFormat quantitative | BedGraph (plain) | Loaded entirely into memory; for small files
|
|
7
|
+
* used to load plain-text bedGraph signal files. Loads the whole file into
|
|
8
|
+
* memory, so prefer the BedGraphTabixAdapter for large files.
|
|
9
|
+
* Several signals in one file are a `MultiQuantitativeTrack`'s subtracks:
|
|
10
|
+
* one value column each, named by the header, or a `source` column naming each
|
|
11
|
+
* row's, which is the form Save track data writes.
|
|
12
|
+
*
|
|
13
|
+
* #example
|
|
14
|
+
* ```js
|
|
15
|
+
* {
|
|
16
|
+
* type: 'BedGraphAdapter',
|
|
17
|
+
* uri: 'https://example.com/signal.bedGraph',
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
1
21
|
declare const BedGraphAdapter: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
|
|
2
|
-
|
|
3
|
-
type: string;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
locationType: string;
|
|
7
|
-
};
|
|
22
|
+
type: {
|
|
23
|
+
type: "string";
|
|
24
|
+
} & {
|
|
25
|
+
defaultValue: string;
|
|
8
26
|
};
|
|
9
|
-
|
|
10
|
-
type:
|
|
11
|
-
|
|
12
|
-
defaultValue:
|
|
27
|
+
readonly bedGraphLocation: {
|
|
28
|
+
type: "fileLocation";
|
|
29
|
+
} & {
|
|
30
|
+
defaultValue: unknown;
|
|
13
31
|
};
|
|
14
|
-
|
|
32
|
+
readonly columnNames: {
|
|
33
|
+
type: "stringArray";
|
|
34
|
+
} & {
|
|
35
|
+
defaultValue: unknown;
|
|
36
|
+
};
|
|
37
|
+
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined, true, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>, any>>;
|
|
38
|
+
export type BedGraphAdapterConfig = Instance<typeof BedGraphAdapter>;
|
|
15
39
|
export default BedGraphAdapter;
|