@jbrowse/plugin-bed 2.16.0 → 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/util.d.ts CHANGED
@@ -1,37 +1,12 @@
1
1
  import BED from '@gmod/bed';
2
- import { SimpleFeature } from '@jbrowse/core/util';
3
- export interface MinimalFeature {
4
- type: string;
5
- start: number;
6
- end: number;
7
- refName: string;
8
- [key: string]: unknown;
9
- }
10
- export interface TranscriptFeat extends MinimalFeature {
11
- thickStart: number;
12
- thickEnd: number;
13
- blockCount: number;
14
- blockSizes: number[];
15
- chromStarts: number[];
16
- refName: string;
17
- strand?: number;
18
- subfeatures: MinimalFeature[];
19
- }
20
- export declare function ucscProcessedTranscript(feature: TranscriptFeat): TranscriptFeat | {
21
- strand: number;
22
- type: string;
23
- refName: string;
24
- subfeatures: MinimalFeature[];
25
- start: number;
26
- end: number;
27
- };
2
+ import { SimpleFeatureSerialized } from '@jbrowse/core/util';
28
3
  export declare function makeBlocks({ start, uniqueId, refName, chromStarts, blockCount, blockSizes, blockStarts, }: {
29
4
  blockCount: number;
30
5
  start: number;
31
6
  uniqueId: string;
32
7
  refName: string;
33
8
  chromStarts?: number[];
34
- blockSizes: number[];
9
+ blockSizes?: number[];
35
10
  blockStarts?: number[];
36
11
  }): {
37
12
  uniqueId: string;
@@ -40,9 +15,24 @@ export declare function makeBlocks({ start, uniqueId, refName, chromStarts, bloc
40
15
  refName: string;
41
16
  type: string;
42
17
  }[];
43
- export declare function featureData(line: string, colRef: number, colStart: number, colEnd: number, scoreColumn: string, parser: BED, uniqueId: string, names?: string[]): SimpleFeature;
44
- export declare function isUcscProcessedTranscript(f: {
45
- thickStart?: number;
46
- blockCount?: number;
47
- strand?: number;
48
- }): boolean | 0 | undefined;
18
+ export declare function featureData({ line, colRef, colStart, colEnd, scoreColumn, parser, uniqueId, names, }: {
19
+ line: string;
20
+ colRef: number;
21
+ colStart: number;
22
+ colEnd: number;
23
+ scoreColumn: string;
24
+ parser: BED;
25
+ uniqueId: string;
26
+ names?: string[];
27
+ }): SimpleFeatureSerialized;
28
+ export declare function featureData2({ line, refName, start, end, parser, uniqueId, scoreColumn, names, }: {
29
+ line: string;
30
+ refName: string;
31
+ start: number;
32
+ end: number;
33
+ parser: BED;
34
+ uniqueId: string;
35
+ scoreColumn: string;
36
+ names?: string[];
37
+ }): SimpleFeatureSerialized;
38
+ export declare function arrayify(f?: string | number[]): number[] | undefined;
package/dist/util.js CHANGED
@@ -1,179 +1,153 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ucscProcessedTranscript = ucscProcessedTranscript;
4
3
  exports.makeBlocks = makeBlocks;
5
4
  exports.featureData = featureData;
6
- exports.isUcscProcessedTranscript = isUcscProcessedTranscript;
7
- const util_1 = require("@jbrowse/core/util");
8
- function ucscProcessedTranscript(feature) {
9
- const { subfeatures: oldSubfeatures, thickStart, thickEnd, blockCount, blockSizes, chromStarts, refName, strand = 0, ...rest } = feature;
10
- if (!thickStart || !thickEnd || !strand) {
11
- return feature;
5
+ exports.featureData2 = featureData2;
6
+ exports.arrayify = arrayify;
7
+ const generateBedMethylFeature_1 = require("./generateBedMethylFeature");
8
+ const generateUcscTranscript_1 = require("./generateUcscTranscript");
9
+ const generateRepeatMaskerFeature_1 = require("./generateRepeatMaskerFeature");
10
+ function stringToStrand(f) {
11
+ if (f === '-1') {
12
+ return -1;
13
+ }
14
+ else if (f === '+') {
15
+ return 1;
16
+ }
17
+ else {
18
+ return 0;
12
19
  }
13
- const subfeatures = [];
14
- oldSubfeatures
15
- .filter(child => child.type === 'block')
16
- .sort((a, b) => a.start - b.start)
17
- .forEach(block => {
18
- const start = block.start;
19
- const end = block.end;
20
- if (thickStart >= end) {
21
- // left-side UTR
22
- const prime = strand > 0 ? 'five' : 'three';
23
- subfeatures.push({
24
- type: `${prime}_prime_UTR`,
25
- start,
26
- end,
27
- refName,
28
- });
29
- }
30
- else if (thickStart > start && thickStart < end && thickEnd >= end) {
31
- // UTR | CDS
32
- const prime = strand > 0 ? 'five' : 'three';
33
- subfeatures.push({
34
- type: `${prime}_prime_UTR`,
35
- start,
36
- end: thickStart,
37
- refName,
38
- }, {
39
- type: 'CDS',
40
- start: thickStart,
41
- end,
42
- refName,
43
- });
44
- }
45
- else if (thickStart <= start && thickEnd >= end) {
46
- // CDS
47
- subfeatures.push({
48
- type: 'CDS',
49
- start,
50
- end,
51
- refName,
52
- });
53
- }
54
- else if (thickStart > start && thickStart < end && thickEnd < end) {
55
- // UTR | CDS | UTR
56
- const leftPrime = strand > 0 ? 'five' : 'three';
57
- const rightPrime = strand > 0 ? 'three' : 'five';
58
- subfeatures.push({
59
- type: `${leftPrime}_prime_UTR`,
60
- start,
61
- end: thickStart,
62
- refName,
63
- }, {
64
- type: 'CDS',
65
- start: thickStart,
66
- end: thickEnd,
67
- refName,
68
- }, {
69
- type: `${rightPrime}_prime_UTR`,
70
- start: thickEnd,
71
- end,
72
- refName,
73
- });
74
- }
75
- else if (thickStart <= start && thickEnd > start && thickEnd < end) {
76
- // CDS | UTR
77
- const prime = strand > 0 ? 'three' : 'five';
78
- subfeatures.push({
79
- type: 'CDS',
80
- start,
81
- end: thickEnd,
82
- refName,
83
- }, {
84
- type: `${prime}_prime_UTR`,
85
- start: thickEnd,
86
- end,
87
- refName,
88
- });
89
- }
90
- else if (thickEnd <= start) {
91
- // right-side UTR
92
- const prime = strand > 0 ? 'three' : 'five';
93
- subfeatures.push({
94
- type: `${prime}_prime_UTR`,
95
- start,
96
- end,
97
- refName,
98
- });
99
- }
100
- });
101
- return { ...rest, strand, type: 'mRNA', refName, subfeatures };
102
20
  }
103
21
  function defaultParser(fields, line) {
104
22
  const obj = Object.fromEntries(line.split('\t').map((f, i) => [fields[i], f]));
105
23
  const { blockStarts, blockCount, chromStarts, thickEnd, thickStart, blockSizes, ...rest } = obj;
106
24
  return {
107
25
  ...rest,
108
- blockStarts: blockStarts === null || blockStarts === void 0 ? void 0 : blockStarts.split(',').map(r => +r),
109
- chromStarts: chromStarts === null || chromStarts === void 0 ? void 0 : chromStarts.split(',').map(r => +r),
110
- blockSizes: blockSizes === null || blockSizes === void 0 ? void 0 : blockSizes.split(',').map(r => +r),
26
+ blockStarts: arrayify(blockStarts),
27
+ chromStarts: arrayify(chromStarts),
28
+ blockSizes: arrayify(blockSizes),
111
29
  thickStart: thickStart ? +thickStart : undefined,
112
30
  thickEnd: thickEnd ? +thickEnd : undefined,
113
31
  blockCount: blockCount ? +blockCount : undefined,
114
32
  };
115
33
  }
116
34
  function makeBlocks({ start, uniqueId, refName, chromStarts, blockCount, blockSizes, blockStarts, }) {
117
- const subfeatures = [];
118
- const starts = chromStarts || blockStarts || [];
119
- for (let b = 0; b < blockCount; b++) {
120
- const bmin = (starts[b] || 0) + start;
121
- const bmax = bmin + (blockSizes[b] || 0);
122
- subfeatures.push({
123
- uniqueId: `${uniqueId}-${b}`,
124
- start: bmin,
125
- end: bmax,
126
- refName,
127
- type: 'block',
128
- });
35
+ if (blockCount) {
36
+ const subfeatures = [];
37
+ const starts = chromStarts || blockStarts || [];
38
+ for (let b = 0; b < blockCount; b++) {
39
+ const bmin = (starts[b] || 0) + start;
40
+ const bsize = blockSizes === null || blockSizes === void 0 ? void 0 : blockSizes[b];
41
+ if (bsize && bsize > 0) {
42
+ const bmax = bmin + bsize;
43
+ subfeatures.push({
44
+ uniqueId: `${uniqueId}-${b}`,
45
+ start: bmin,
46
+ end: bmax,
47
+ refName,
48
+ type: 'block',
49
+ });
50
+ }
51
+ }
52
+ return subfeatures;
129
53
  }
130
- return subfeatures;
54
+ return [];
131
55
  }
132
- function featureData(line, colRef, colStart, colEnd, scoreColumn, parser, uniqueId, names) {
133
- const l = line.split('\t');
134
- const refName = l[colRef];
135
- const start = +l[colStart];
136
- const colSame = colStart === colEnd ? 1 : 0;
137
- const end = +l[colEnd] + colSame;
56
+ function featureData({ line, colRef, colStart, colEnd, scoreColumn, parser, uniqueId, names, }) {
57
+ const splitLine = line.split('\t');
58
+ const refName = splitLine[colRef];
59
+ const start = +splitLine[colStart];
60
+ const end = +splitLine[colEnd] + (colStart === colEnd ? 1 : 0);
61
+ return featureData2({
62
+ line,
63
+ refName,
64
+ start,
65
+ end,
66
+ parser,
67
+ uniqueId,
68
+ scoreColumn,
69
+ names,
70
+ });
71
+ }
72
+ function featureData2({ line, refName, start, end, parser, uniqueId, scoreColumn, names, }) {
73
+ const splitLine = line.split('\t');
138
74
  const data = names
139
75
  ? defaultParser(names, line)
140
76
  : parser.parseLine(line, { uniqueId });
141
- const { blockCount, blockSizes, blockStarts, chromStarts, thickStart, thickEnd, type, score, chrom: _1, chromStart: _2, chromEnd: _3, ...rest } = data;
142
- const subfeatures = blockCount
143
- ? makeBlocks({
77
+ const { strand: strand2, score: score2, chrom: _1, chromStart: _2, chromEnd: _3, ...rest } = data;
78
+ const { chromStarts, blockSizes, blockStarts, type, blockCount, thickStart, thickEnd, description, ...rest2 } = rest;
79
+ const score = scoreColumn ? +data[scoreColumn] : score2 ? +score2 : undefined;
80
+ const strand = typeof strand2 === 'string' ? stringToStrand(strand2) : strand2;
81
+ const subfeatures = makeBlocks({
82
+ start,
83
+ uniqueId,
84
+ refName,
85
+ chromStarts,
86
+ blockCount,
87
+ blockSizes,
88
+ blockStarts,
89
+ });
90
+ if ((0, generateBedMethylFeature_1.isBedMethylFeature)({ splitLine, start, end })) {
91
+ return (0, generateBedMethylFeature_1.generateBedMethylFeature)({
92
+ line,
93
+ uniqueId,
94
+ refName,
144
95
  start,
96
+ end,
97
+ });
98
+ }
99
+ else if ((0, generateRepeatMaskerFeature_1.isRepeatMaskerDescriptionField)(description)) {
100
+ return (0, generateRepeatMaskerFeature_1.generateRepeatMaskerFeature)({
101
+ ...rest2,
145
102
  uniqueId,
103
+ description,
104
+ type,
105
+ score,
106
+ start,
107
+ end,
108
+ strand,
146
109
  refName,
110
+ subfeatures,
111
+ });
112
+ }
113
+ else if ((0, generateUcscTranscript_1.isUcscTranscript)({ strand, blockCount, thickStart })) {
114
+ return (0, generateUcscTranscript_1.generateUcscTranscript)({
115
+ ...rest,
116
+ description,
147
117
  chromStarts,
148
- blockCount,
118
+ thickStart,
119
+ thickEnd,
149
120
  blockSizes,
150
- blockStarts,
151
- })
152
- : [];
153
- const f = {
154
- ...rest,
155
- type,
156
- score: scoreColumn ? +data[scoreColumn] : score,
157
- start,
158
- end,
159
- refName,
160
- uniqueId,
161
- subfeatures,
162
- };
163
- return new util_1.SimpleFeature({
164
- id: uniqueId,
165
- data: isUcscProcessedTranscript(data)
166
- ? ucscProcessedTranscript({
167
- thickStart: thickStart,
168
- thickEnd: thickEnd,
169
- blockCount: blockCount,
170
- blockSizes: blockSizes,
171
- chromStarts: chromStarts,
172
- ...f,
173
- })
174
- : f,
175
- });
121
+ blockCount,
122
+ type,
123
+ score,
124
+ start,
125
+ end,
126
+ strand,
127
+ refName,
128
+ uniqueId,
129
+ subfeatures,
130
+ });
131
+ }
132
+ else {
133
+ return {
134
+ ...rest,
135
+ uniqueId,
136
+ description,
137
+ type,
138
+ score,
139
+ start,
140
+ end,
141
+ strand,
142
+ refName,
143
+ subfeatures,
144
+ };
145
+ }
176
146
  }
177
- function isUcscProcessedTranscript(f) {
178
- return f.thickStart && f.blockCount && f.strand !== 0;
147
+ function arrayify(f) {
148
+ return f !== undefined
149
+ ? typeof f === 'string'
150
+ ? f.split(',').map(f => +f)
151
+ : f
152
+ : undefined;
179
153
  }
@@ -2,9 +2,8 @@ import BED from '@gmod/bed';
2
2
  import { BaseFeatureDataAdapter, } from '@jbrowse/core/data_adapters/BaseAdapter';
3
3
  import { openLocation } from '@jbrowse/core/util/io';
4
4
  import { ObservableCreate } from '@jbrowse/core/util/rxjs';
5
- import { isGzip } from '@jbrowse/core/util';
5
+ import { fetchAndMaybeUnzip, SimpleFeature, } from '@jbrowse/core/util';
6
6
  import IntervalTree from '@flatten-js/interval-tree';
7
- import { unzip } from '@gmod/bgzf-filehandle';
8
7
  // locals
9
8
  import { featureData } from '../util';
10
9
  class BedAdapter extends BaseFeatureDataAdapter {
@@ -15,8 +14,7 @@ class BedAdapter extends BaseFeatureDataAdapter {
15
14
  async loadDataP(opts = {}) {
16
15
  const pm = this.pluginManager;
17
16
  const bedLoc = this.getConf('bedLocation');
18
- const buf = await openLocation(bedLoc, pm).readFile(opts);
19
- const buffer = isGzip(buf) ? await unzip(buf) : buf;
17
+ const buffer = await fetchAndMaybeUnzip(openLocation(bedLoc, pm), opts);
20
18
  // 512MB max chrome string length is 512MB
21
19
  if (buffer.length > 536870888) {
22
20
  throw new Error('Data exceeds maximum string length (512MB)');
@@ -96,9 +94,18 @@ class BedAdapter extends BaseFeatureDataAdapter {
96
94
  }
97
95
  const names = await this.getNames();
98
96
  const intervalTree = new IntervalTree();
99
- const ret = lines.map((f, i) => {
97
+ const ret = lines.map((line, i) => {
100
98
  const uniqueId = `${this.id}-${refName}-${i}`;
101
- return featureData(f, colRef, colStart, colEnd, scoreColumn, parser, uniqueId, names);
99
+ return new SimpleFeature(featureData({
100
+ line,
101
+ colRef,
102
+ colStart,
103
+ colEnd,
104
+ scoreColumn,
105
+ parser,
106
+ uniqueId,
107
+ names,
108
+ }));
102
109
  });
103
110
  for (const obj of ret) {
104
111
  intervalTree.insert([obj.get('start'), obj.get('end')], obj);
@@ -2,6 +2,7 @@ import BED from '@gmod/bed';
2
2
  import { BaseFeatureDataAdapter, } from '@jbrowse/core/data_adapters/BaseAdapter';
3
3
  import { openLocation } from '@jbrowse/core/util/io';
4
4
  import { ObservableCreate } from '@jbrowse/core/util/rxjs';
5
+ import { SimpleFeature, } from '@jbrowse/core/util';
5
6
  import { TabixIndexedFile } from '@gmod/tabix';
6
7
  // locals
7
8
  import { featureData } from '../util';
@@ -50,13 +51,19 @@ class BedTabixAdapter extends BaseFeatureDataAdapter {
50
51
  const colRef = columnNumbers.ref - 1;
51
52
  const colStart = columnNumbers.start - 1;
52
53
  const colEnd = columnNumbers.end - 1;
53
- // colSame handles special case for tabix where a single column is both
54
- // the start and end, this is assumed to be covering the base at this
55
- // position (e.g. tabix -s 1 -b 2 -e 2) begin and end are same
56
54
  const names = await this.getNames();
57
55
  await this.bed.getLines(query.refName, query.start, query.end, {
58
56
  lineCallback: (line, fileOffset) => {
59
- observer.next(featureData(line, colRef, colStart, colEnd, this.scoreColumn, this.parser, `${this.id}-${fileOffset}`, names));
57
+ observer.next(new SimpleFeature(featureData({
58
+ line,
59
+ colRef,
60
+ colStart,
61
+ colEnd,
62
+ scoreColumn: this.scoreColumn,
63
+ parser: this.parser,
64
+ uniqueId: `${this.id}-${fileOffset}`,
65
+ names,
66
+ })));
60
67
  },
61
68
  signal: opts.signal,
62
69
  });
@@ -1,9 +1,8 @@
1
1
  import { BaseFeatureDataAdapter, } from '@jbrowse/core/data_adapters/BaseAdapter';
2
2
  import { openLocation } from '@jbrowse/core/util/io';
3
3
  import { ObservableCreate } from '@jbrowse/core/util/rxjs';
4
- import { SimpleFeature, isGzip } from '@jbrowse/core/util';
4
+ import { SimpleFeature, fetchAndMaybeUnzip, } from '@jbrowse/core/util';
5
5
  import IntervalTree from '@flatten-js/interval-tree';
6
- import { unzip } from '@gmod/bgzf-filehandle';
7
6
  const svTypes = new Set(['DUP', 'TRA', 'INV', 'CNV', 'DEL']);
8
7
  export function featureData(line, uniqueId, flip, names) {
9
8
  const l = line.split('\t');
@@ -58,11 +57,11 @@ class BedpeAdapter extends BaseFeatureDataAdapter {
58
57
  super(...arguments);
59
58
  this.intervalTrees = {};
60
59
  }
61
- async loadDataP(opts = {}) {
60
+ async loadDataP(opts) {
62
61
  const pm = this.pluginManager;
63
62
  const bedLoc = this.getConf('bedpeLocation');
64
- const buf = await openLocation(bedLoc, pm).readFile(opts);
65
- const buffer = isGzip(buf) ? await unzip(buf) : buf;
63
+ const loc = openLocation(bedLoc, pm);
64
+ const buffer = await fetchAndMaybeUnzip(loc, opts);
66
65
  // 512MB max chrome string length is 512MB
67
66
  if (buffer.length > 536870888) {
68
67
  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 cached?;
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: Region, opts: BaseOptions, observer: Observer<Feature>, allowRedispatch: boolean, originalQuery?: Region): Promise<void>;
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
  }