@jbrowse/plugin-bed 5.0.0-beta.1 → 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 +1 -3
- package/esm/BedAdapter/BedAdapter.js +3 -10
- package/esm/BedAdapter/configSchema.d.ts +30 -52
- package/esm/BedAdapter/configSchema.js +2 -4
- package/esm/BedGraphAdapter/BedGraphAdapter.d.ts +1 -3
- package/esm/BedGraphAdapter/BedGraphAdapter.js +8 -10
- package/esm/BedGraphAdapter/configSchema.d.ts +15 -17
- package/esm/BedGraphAdapter/configSchema.js +5 -10
- package/esm/BedGraphTabixAdapter/BedGraphTabixAdapter.js +8 -5
- package/esm/BedGraphTabixAdapter/configSchema.d.ts +25 -30
- package/esm/BedGraphTabixAdapter/configSchema.js +11 -3
- package/esm/BedTabixAdapter/BedTabixAdapter.js +7 -8
- package/esm/BedTabixAdapter/configSchema.d.ts +33 -46
- package/esm/BedTabixAdapter/configSchema.js +9 -2
- package/esm/BedpeAdapter/BedpeAdapter.d.ts +3 -4
- package/esm/BedpeAdapter/BedpeAdapter.js +3 -10
- package/esm/BedpeAdapter/configSchema.d.ts +12 -16
- package/esm/BedpeAdapter/configSchema.js +2 -11
- package/esm/BedpeAdapter/util.js +3 -2
- package/esm/BigBedAdapter/BigBedAdapter.js +4 -5
- package/esm/BigBedAdapter/configSchema.d.ts +21 -29
- package/esm/BigBedAdapter/configSchema.js +4 -10
- 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 +2 -3
- package/esm/StarFusionAdapter/StarFusionAdapter.js +16 -71
- package/esm/StarFusionAdapter/configSchema.d.ts +9 -10
- package/esm/StarFusionAdapter/configSchema.js +2 -11
- package/esm/adapterUtil.d.ts +1 -1
- package/esm/adapterUtil.js +20 -5
- package/esm/bedGraphUtil.d.ts +2 -1
- package/esm/bedGraphUtil.js +5 -3
- package/esm/copyExcept.d.ts +1 -0
- package/esm/copyExcept.js +11 -0
- package/esm/generateBedMethylFeature.js +12 -7
- package/esm/generateRepeatMaskerFeature.d.ts +17 -4
- package/esm/generateRepeatMaskerFeature.js +29 -26
- package/esm/generateUcscTranscript.js +51 -4
- package/esm/index.js +2 -0
- package/esm/util.js +25 -14
- package/package.json +8 -7
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { ConfigurationSchema, expandTabixShorthand,
|
|
1
|
+
import { ConfigurationSchema, expandTabixShorthand, tabixIndexSchema, } from '@jbrowse/core/configuration';
|
|
2
|
+
import { densityAdapterConfigSchemaFields } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
2
3
|
export function normalizeSnapshot(snap) {
|
|
3
4
|
return expandTabixShorthand(snap, 'bedGzLocation');
|
|
4
5
|
}
|
|
@@ -30,7 +31,12 @@ const BedTabixAdapter = ConfigurationSchema('BedTabixAdapter', {
|
|
|
30
31
|
locationType: 'UriLocation',
|
|
31
32
|
},
|
|
32
33
|
},
|
|
33
|
-
|
|
34
|
+
/**
|
|
35
|
+
* #slot
|
|
36
|
+
* where the tabix index is and which kind it is. The `uri` shorthand derives
|
|
37
|
+
* both, so a config using it states neither.
|
|
38
|
+
*/
|
|
39
|
+
index: tabixIndexSchema(),
|
|
34
40
|
/**
|
|
35
41
|
* #slot
|
|
36
42
|
*/
|
|
@@ -63,6 +69,7 @@ const BedTabixAdapter = ConfigurationSchema('BedTabixAdapter', {
|
|
|
63
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)',
|
|
64
70
|
defaultValue: false,
|
|
65
71
|
},
|
|
72
|
+
...densityAdapterConfigSchemaFields,
|
|
66
73
|
}, {
|
|
67
74
|
explicitlyTyped: true,
|
|
68
75
|
/**
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
2
2
|
import type { BedpeAdapterConfig } from './configSchema.ts';
|
|
3
3
|
import type { BaseOptions } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
4
|
-
import type {
|
|
4
|
+
import type { Region } from '@jbrowse/core/util';
|
|
5
5
|
export default class BedpeAdapter extends BaseFeatureDataAdapter<BedpeAdapterConfig> {
|
|
6
6
|
private loadData;
|
|
7
|
-
protected intervalTrees: Record<string, Promise<IntervalTree<Feature> | undefined> | undefined>;
|
|
8
7
|
static capabilities: string[];
|
|
9
8
|
private loadDataP;
|
|
10
9
|
getRefNames(opts?: BaseOptions): Promise<string[]>;
|
|
11
10
|
getHeader(opts?: BaseOptions): Promise<string>;
|
|
12
11
|
getNames(): Promise<string[] | undefined>;
|
|
13
12
|
private loadFeatureTreeP;
|
|
14
|
-
private
|
|
15
|
-
getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
|
|
13
|
+
private treeFeatures;
|
|
14
|
+
getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<import("@jbrowse/core/util").Feature>;
|
|
16
15
|
}
|
|
@@ -8,7 +8,6 @@ import { featureData } from './util.js';
|
|
|
8
8
|
export default class BedpeAdapter extends BaseFeatureDataAdapter {
|
|
9
9
|
// No `label`: `fetchAndMaybeUnzip` narrates the download from inside.
|
|
10
10
|
loadData = cachedSetup({ setup: opts => this.loadDataP(opts) });
|
|
11
|
-
intervalTrees = {};
|
|
12
11
|
static capabilities = ['getFeatures', 'getRefNames'];
|
|
13
12
|
async loadDataP(opts) {
|
|
14
13
|
const buffer = await fetchAndMaybeUnzip(openLocation(this.getConf('bedpeLocation'), this.pluginManager), opts);
|
|
@@ -50,14 +49,8 @@ export default class BedpeAdapter extends BaseFeatureDataAdapter {
|
|
|
50
49
|
const names = await this.getNames();
|
|
51
50
|
return buildPairedIntervalTree(feats1, feats2, refName, this.id, (line, uniqueId, flip) => featureData(line, uniqueId, flip, names));
|
|
52
51
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
throw e;
|
|
57
|
-
});
|
|
58
|
-
return this.intervalTrees[refName];
|
|
59
|
-
}
|
|
60
|
-
getFeatures(query, opts = {}) {
|
|
61
|
-
return intervalTreeFeatures(query, opts, refName => this.loadFeatureTree(refName));
|
|
52
|
+
treeFeatures = intervalTreeFeatures(opts => this.loadData(opts), refName => this.loadFeatureTreeP(refName));
|
|
53
|
+
getFeatures(query, opts) {
|
|
54
|
+
return this.treeFeatures(query, opts);
|
|
62
55
|
}
|
|
63
56
|
}
|
|
@@ -15,25 +15,21 @@ export declare function normalizeSnapshot(snap: Record<string, unknown>): Record
|
|
|
15
15
|
* ```
|
|
16
16
|
*/
|
|
17
17
|
declare const BedpeAdapter: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
type: {
|
|
19
|
+
type: "string";
|
|
20
|
+
} & {
|
|
21
|
+
defaultValue: string;
|
|
22
|
+
};
|
|
21
23
|
readonly bedpeLocation: {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
readonly uri: "/path/to/my.bedpe.gz";
|
|
26
|
-
readonly locationType: "UriLocation";
|
|
27
|
-
};
|
|
24
|
+
type: "fileLocation";
|
|
25
|
+
} & {
|
|
26
|
+
defaultValue: unknown;
|
|
28
27
|
};
|
|
29
|
-
/**
|
|
30
|
-
* #slot
|
|
31
|
-
*/
|
|
32
28
|
readonly columnNames: {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
type: "stringArray";
|
|
30
|
+
} & {
|
|
31
|
+
defaultValue: unknown;
|
|
36
32
|
};
|
|
37
|
-
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
|
|
33
|
+
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined, true, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>, any>>;
|
|
38
34
|
export type BedpeAdapterConfig = Instance<typeof BedpeAdapter>;
|
|
39
35
|
export default BedpeAdapter;
|
|
@@ -1,15 +1,6 @@
|
|
|
1
|
-
import { ConfigurationSchema } from '@jbrowse/core/configuration';
|
|
1
|
+
import { ConfigurationSchema, expandUriShorthand, } from '@jbrowse/core/configuration';
|
|
2
2
|
export function normalizeSnapshot(snap) {
|
|
3
|
-
return snap
|
|
4
|
-
? {
|
|
5
|
-
...snap,
|
|
6
|
-
bedpeLocation: {
|
|
7
|
-
uri: snap.uri,
|
|
8
|
-
baseUri: snap.baseUri,
|
|
9
|
-
locationType: 'UriLocation',
|
|
10
|
-
},
|
|
11
|
-
}
|
|
12
|
-
: snap;
|
|
3
|
+
return expandUriShorthand(snap, 'bedpeLocation');
|
|
13
4
|
}
|
|
14
5
|
/**
|
|
15
6
|
* #config BedpeAdapter
|
package/esm/BedpeAdapter/util.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SimpleFeature } from '@jbrowse/core/util';
|
|
2
|
+
import { svClassOfToken } from '@jbrowse/core/util/svAlt';
|
|
2
3
|
import { parseStrand } from '../util.js';
|
|
3
4
|
const svTypes = new Set(['DUP', 'TRA', 'INV', 'CNV', 'DEL']);
|
|
4
5
|
export function featureData(line, uniqueId, flip, names) {
|
|
@@ -24,7 +25,7 @@ export function featureData(line, uniqueId, flip, names) {
|
|
|
24
25
|
const rest = names
|
|
25
26
|
? Object.fromEntries(names.slice(10).map((n, idx) => [n, extra[idx]]))
|
|
26
27
|
: {};
|
|
27
|
-
const
|
|
28
|
+
const token = svTypes.has(extra[0]) ? extra[0] : undefined;
|
|
28
29
|
// `name` and `score` are spread only when the file actually sets them, which
|
|
29
30
|
// is what lets a column past 10 of the same name through. juicer's bedpe is
|
|
30
31
|
// the case that needs it: Arrowhead writes '.' in both standard columns and
|
|
@@ -46,6 +47,6 @@ export function featureData(line, uniqueId, flip, names) {
|
|
|
46
47
|
end: end2,
|
|
47
48
|
strand: strand2,
|
|
48
49
|
},
|
|
49
|
-
...(
|
|
50
|
+
...(token ? { ALT: [`<${token}>`], svType: svClassOfToken(token) } : {}),
|
|
50
51
|
});
|
|
51
52
|
}
|
|
@@ -4,7 +4,6 @@ import { BaseFeatureDataAdapter, cachedSetup, } from '@jbrowse/core/data_adapter
|
|
|
4
4
|
import { SimpleFeature, doesIntersect2, downloadStatus, max, min, updateStatus, } from '@jbrowse/core/util';
|
|
5
5
|
import { openLocation } from '@jbrowse/core/util/io';
|
|
6
6
|
import { ObservableCreate } from '@jbrowse/core/util/rxjs';
|
|
7
|
-
import { withStopTokenSignal } from '@jbrowse/core/util/stopToken';
|
|
8
7
|
import { firstValueFrom, toArray } from 'rxjs';
|
|
9
8
|
import { featureData } from '../util.js';
|
|
10
9
|
export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
@@ -97,11 +96,11 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
97
96
|
// (they come from the R-tree index) so this reports a determinate fraction
|
|
98
97
|
// rather than an indeterminate spinner. Matters most here — BigBed is a
|
|
99
98
|
// full-feature download, which is why getRegionByteSize gates it above.
|
|
100
|
-
const feats = await
|
|
99
|
+
const feats = await downloadStatus('Downloading features', statusCallback, onProgress => bigbed.getFeatures(query.refName, query.start, query.end, {
|
|
101
100
|
basesPerSpan: query.end - query.start,
|
|
102
101
|
onProgress,
|
|
103
|
-
signal,
|
|
104
|
-
}))
|
|
102
|
+
signal: opts.signal,
|
|
103
|
+
}));
|
|
105
104
|
await updateStatus('Processing features', statusCallback, async () => {
|
|
106
105
|
const parentAggregation = {};
|
|
107
106
|
const singletons = [];
|
|
@@ -214,6 +213,6 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
|
|
|
214
213
|
catch (e) {
|
|
215
214
|
observer.error(e);
|
|
216
215
|
}
|
|
217
|
-
}, opts.
|
|
216
|
+
}, opts.signal);
|
|
218
217
|
}
|
|
219
218
|
}
|
|
@@ -14,42 +14,34 @@ export declare function normalizeSnapshot(snap: Record<string, unknown>): Record
|
|
|
14
14
|
* ```
|
|
15
15
|
*/
|
|
16
16
|
declare const BigBedAdapter: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
readonly densityAdapter: {
|
|
18
|
+
type: "maybeFrozen";
|
|
19
|
+
};
|
|
20
|
+
type: {
|
|
21
|
+
type: "string";
|
|
22
|
+
} & {
|
|
23
|
+
defaultValue: string;
|
|
24
|
+
};
|
|
22
25
|
readonly bigBedLocation: {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
readonly locationType: "UriLocation";
|
|
27
|
-
};
|
|
26
|
+
type: "fileLocation";
|
|
27
|
+
} & {
|
|
28
|
+
defaultValue: unknown;
|
|
28
29
|
};
|
|
29
|
-
/**
|
|
30
|
-
* #slot
|
|
31
|
-
*/
|
|
32
30
|
readonly scoreColumn: {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
type: "string";
|
|
32
|
+
} & {
|
|
33
|
+
defaultValue: string;
|
|
36
34
|
};
|
|
37
|
-
/**
|
|
38
|
-
* #slot
|
|
39
|
-
*/
|
|
40
35
|
readonly aggregateField: {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
36
|
+
type: "string";
|
|
37
|
+
} & {
|
|
38
|
+
defaultValue: string;
|
|
44
39
|
};
|
|
45
|
-
/**
|
|
46
|
-
* #slot
|
|
47
|
-
*/
|
|
48
40
|
readonly disableGeneHeuristic: {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
41
|
+
type: "boolean";
|
|
42
|
+
} & {
|
|
43
|
+
defaultValue: boolean;
|
|
52
44
|
};
|
|
53
|
-
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
|
|
45
|
+
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined, true, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>, any>>;
|
|
54
46
|
export type BigBedAdapterConfig = Instance<typeof BigBedAdapter>;
|
|
55
47
|
export default BigBedAdapter;
|
|
@@ -1,14 +1,7 @@
|
|
|
1
|
-
import { ConfigurationSchema } from '@jbrowse/core/configuration';
|
|
1
|
+
import { ConfigurationSchema, expandUriShorthand, } from '@jbrowse/core/configuration';
|
|
2
|
+
import { densityAdapterConfigSchemaFields } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
2
3
|
export function normalizeSnapshot(snap) {
|
|
3
|
-
return snap
|
|
4
|
-
? {
|
|
5
|
-
...snap,
|
|
6
|
-
bigBedLocation: {
|
|
7
|
-
uri: snap.uri,
|
|
8
|
-
baseUri: snap.baseUri,
|
|
9
|
-
},
|
|
10
|
-
}
|
|
11
|
-
: snap;
|
|
4
|
+
return expandUriShorthand(snap, 'bigBedLocation');
|
|
12
5
|
}
|
|
13
6
|
/**
|
|
14
7
|
* #config BigBedAdapter
|
|
@@ -60,6 +53,7 @@ const BigBedAdapter = ConfigurationSchema('BigBedAdapter', {
|
|
|
60
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)',
|
|
61
54
|
defaultValue: false,
|
|
62
55
|
},
|
|
56
|
+
...densityAdapterConfigSchemaFields,
|
|
63
57
|
}, {
|
|
64
58
|
explicitlyTyped: true,
|
|
65
59
|
/**
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { BigBed } from '@gmod/bbi';
|
|
2
|
+
import Trix from '@gmod/trix';
|
|
3
|
+
import BaseResult from '@jbrowse/core/TextSearch/BaseResults';
|
|
4
|
+
import { BaseAdapter } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
5
|
+
import type { BigBedTextSearchAdapterConfig } from './configSchema.ts';
|
|
6
|
+
import type PluginManager from '@jbrowse/core/PluginManager';
|
|
7
|
+
import type { BaseTextSearchAdapter, BaseTextSearchArgs } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
8
|
+
import type { getSubAdapterType } from '@jbrowse/core/data_adapters/dataAdapterCache';
|
|
9
|
+
interface Hit {
|
|
10
|
+
label: string;
|
|
11
|
+
refName: string;
|
|
12
|
+
start: number;
|
|
13
|
+
end: number;
|
|
14
|
+
}
|
|
15
|
+
export declare function mergeTranscripts(hits: Hit[]): Hit[];
|
|
16
|
+
export default class BigBedTextSearchAdapter extends BaseAdapter<BigBedTextSearchAdapterConfig> implements BaseTextSearchAdapter {
|
|
17
|
+
bigbed: BigBed;
|
|
18
|
+
trix?: Trix;
|
|
19
|
+
constructor(config: BigBedTextSearchAdapterConfig, getSubAdapter?: getSubAdapterType, pluginManager?: PluginManager);
|
|
20
|
+
names(query: string, exactOnly: boolean, signal?: AbortSignal): Promise<{
|
|
21
|
+
exact: string[];
|
|
22
|
+
prefixed: (readonly [string, string])[];
|
|
23
|
+
}>;
|
|
24
|
+
lookUp(name: string, word: string, signal?: AbortSignal): Promise<Hit[]>;
|
|
25
|
+
searchIndex({ queryString, searchType, signal }: BaseTextSearchArgs): Promise<BaseResult[]>;
|
|
26
|
+
}
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { BigBed } from '@gmod/bbi';
|
|
2
|
+
import Trix from '@gmod/trix';
|
|
3
|
+
import BaseResult from '@jbrowse/core/TextSearch/BaseResults';
|
|
4
|
+
import { BaseAdapter } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
5
|
+
import { checkAbortSignal } from '@jbrowse/core/util/aborting';
|
|
6
|
+
import { openLocation } from '@jbrowse/core/util/io';
|
|
7
|
+
// each name a query resolves costs a walk of the BigBed's B+ tree, so a query
|
|
8
|
+
// resolves every name its exact word carries up to one cap, and the words it
|
|
9
|
+
// only prefixes, each whole, while their names fit the other
|
|
10
|
+
const MAX_EXACT_NAMES = 50;
|
|
11
|
+
const MAX_PREFIX_NAMES = 50;
|
|
12
|
+
const MAX_TRIX_HITS = 500;
|
|
13
|
+
function isSet(location) {
|
|
14
|
+
return 'uri' in location
|
|
15
|
+
? !!location.uri
|
|
16
|
+
: 'localPath' in location
|
|
17
|
+
? !!location.localPath
|
|
18
|
+
: true;
|
|
19
|
+
}
|
|
20
|
+
// the column that matched is the name the hit goes by: a gene symbol for a
|
|
21
|
+
// search by symbol, the accession for a search by accession
|
|
22
|
+
function hitFor({ refName, start, end, rest = '', }, word) {
|
|
23
|
+
const fields = rest.split('\t');
|
|
24
|
+
const label = fields.find(f => f.toLowerCase() === word) ?? fields[0];
|
|
25
|
+
return refName && label ? { label, refName, start, end } : undefined;
|
|
26
|
+
}
|
|
27
|
+
// Transcripts sharing the name that matched and overlapping on one sequence
|
|
28
|
+
// are one gene, the rule BigBedAdapter draws them by, so a search for a gene
|
|
29
|
+
// lands on the gene rather than asking which of its transcripts
|
|
30
|
+
export function mergeTranscripts(hits) {
|
|
31
|
+
const merged = [];
|
|
32
|
+
const sorted = hits.toSorted((a, b) => a.label.localeCompare(b.label) ||
|
|
33
|
+
a.refName.localeCompare(b.refName) ||
|
|
34
|
+
a.start - b.start);
|
|
35
|
+
for (const hit of sorted) {
|
|
36
|
+
const last = merged.at(-1);
|
|
37
|
+
if (last?.label === hit.label &&
|
|
38
|
+
last.refName === hit.refName &&
|
|
39
|
+
hit.start <= last.end) {
|
|
40
|
+
last.end = Math.max(last.end, hit.end);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
merged.push({ ...hit });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return merged;
|
|
47
|
+
}
|
|
48
|
+
// A word is resolved whole or not at all, since a word missing some of its
|
|
49
|
+
// names would land on part of its gene
|
|
50
|
+
function prefixedNames(byWord, word) {
|
|
51
|
+
const pairs = [];
|
|
52
|
+
for (const [term, names] of byWord) {
|
|
53
|
+
if (term !== word && term.startsWith(word)) {
|
|
54
|
+
if (pairs.length + names.length > MAX_PREFIX_NAMES) {
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
pairs.push(...names.map(name => [term, name]));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return pairs;
|
|
61
|
+
}
|
|
62
|
+
export default class BigBedTextSearchAdapter extends BaseAdapter {
|
|
63
|
+
bigbed;
|
|
64
|
+
trix;
|
|
65
|
+
constructor(config, getSubAdapter, pluginManager) {
|
|
66
|
+
super(config, getSubAdapter, pluginManager);
|
|
67
|
+
this.bigbed = new BigBed({
|
|
68
|
+
filehandle: openLocation(this.getConf('bigBedLocation'), pluginManager),
|
|
69
|
+
});
|
|
70
|
+
const ix = this.getConf('ixFilePath');
|
|
71
|
+
const ixx = this.getConf('ixxFilePath');
|
|
72
|
+
if (isSet(ix) && isSet(ixx)) {
|
|
73
|
+
this.trix = new Trix(openLocation(ixx, pluginManager), openLocation(ix, pluginManager), MAX_TRIX_HITS);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// The names to look up: the query as spelled, which the extra index answers
|
|
77
|
+
// however the trix split it into words, then the names the trix finds for
|
|
78
|
+
// its word. GenArk's trix drops an accession's version, so a versioned query
|
|
79
|
+
// asks for the bare word and keeps the names spelling the query
|
|
80
|
+
async names(query, exactOnly, signal) {
|
|
81
|
+
const word = query.toLowerCase();
|
|
82
|
+
if (!this.trix) {
|
|
83
|
+
return { exact: [query], prefixed: [] };
|
|
84
|
+
}
|
|
85
|
+
const trixWord = word.replace(/\.\d+$/, '');
|
|
86
|
+
const byWord = new Map();
|
|
87
|
+
for (const [term, name] of await this.trix.search(trixWord, { signal })) {
|
|
88
|
+
const names = byWord.get(term);
|
|
89
|
+
if (names) {
|
|
90
|
+
names.push(name);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
byWord.set(term, [name]);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const exact = trixWord === word
|
|
97
|
+
? (byWord.get(word) ?? [])
|
|
98
|
+
: (byWord.get(trixWord) ?? []).filter(n => n.toLowerCase() === word);
|
|
99
|
+
return {
|
|
100
|
+
exact: [...new Set([query, ...exact])].slice(0, MAX_EXACT_NAMES),
|
|
101
|
+
prefixed: exactOnly ? [] : prefixedNames(byWord, word),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
async lookUp(name, word, signal) {
|
|
105
|
+
return (await this.bigbed.searchExtraIndex(name, { signal }))
|
|
106
|
+
.map(f => hitFor(f, word))
|
|
107
|
+
.filter(h => h !== undefined);
|
|
108
|
+
}
|
|
109
|
+
async searchIndex({ queryString, searchType, signal }) {
|
|
110
|
+
const query = queryString.trim();
|
|
111
|
+
const word = query.toLowerCase();
|
|
112
|
+
const { exact, prefixed } = await this.names(query, searchType === 'exact', signal);
|
|
113
|
+
const [exactHits, prefixHits] = await Promise.all([
|
|
114
|
+
Promise.all(exact.map(name => this.lookUp(name, word, signal))),
|
|
115
|
+
Promise.all(prefixed.map(([term, name]) => this.lookUp(name, term, signal))),
|
|
116
|
+
]);
|
|
117
|
+
checkAbortSignal(signal);
|
|
118
|
+
const results = (hits, exact) => mergeTranscripts(hits).map(({ label, refName, start, end }) => new BaseResult({
|
|
119
|
+
label,
|
|
120
|
+
locString: `${refName}:${start + 1}..${end}`,
|
|
121
|
+
exact,
|
|
122
|
+
}));
|
|
123
|
+
return [
|
|
124
|
+
...results(exactHits.flat(), true),
|
|
125
|
+
...results(prefixHits.flat(), false),
|
|
126
|
+
];
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { Instance } from '@jbrowse/mobx-state-tree';
|
|
2
|
+
/**
|
|
3
|
+
* #config BigBedTextSearchAdapter
|
|
4
|
+
* #trackType TextSearchAdapter
|
|
5
|
+
*
|
|
6
|
+
* Finds features by the names a BigBed was built to look up, its
|
|
7
|
+
* `bedToBigBed -extraIndex` columns, which a UCSC hub declares with
|
|
8
|
+
* `searchIndex`. The hub's `searchTrix` index, when given, adds prefix and
|
|
9
|
+
* case-insensitive matching. A UCSC track hub connection configures one for
|
|
10
|
+
* its first gene track declaring a `searchIndex`, GenArk's `ncbiRefSeq`.
|
|
11
|
+
*
|
|
12
|
+
* #example
|
|
13
|
+
* ```js
|
|
14
|
+
* {
|
|
15
|
+
* type: 'BigBedTextSearchAdapter',
|
|
16
|
+
* bigBedLocation: { uri: 'bbi/ncbiRefSeq.bb' },
|
|
17
|
+
* ixFilePath: { uri: 'ixIxx/ncbiRefSeq.ix' },
|
|
18
|
+
* ixxFilePath: { uri: 'ixIxx/ncbiRefSeq.ixx' },
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
declare const BigBedTextSearchAdapter: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
|
|
23
|
+
type: {
|
|
24
|
+
type: "string";
|
|
25
|
+
} & {
|
|
26
|
+
defaultValue: string;
|
|
27
|
+
};
|
|
28
|
+
readonly bigBedLocation: {
|
|
29
|
+
type: "fileLocation";
|
|
30
|
+
} & {
|
|
31
|
+
defaultValue: unknown;
|
|
32
|
+
};
|
|
33
|
+
readonly ixFilePath: {
|
|
34
|
+
type: "fileLocation";
|
|
35
|
+
} & {
|
|
36
|
+
defaultValue: unknown;
|
|
37
|
+
};
|
|
38
|
+
readonly ixxFilePath: {
|
|
39
|
+
type: "fileLocation";
|
|
40
|
+
} & {
|
|
41
|
+
defaultValue: unknown;
|
|
42
|
+
};
|
|
43
|
+
readonly assemblyNames: {
|
|
44
|
+
type: "stringArray";
|
|
45
|
+
} & {
|
|
46
|
+
defaultValue: unknown;
|
|
47
|
+
};
|
|
48
|
+
}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined, true, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>, any>>;
|
|
49
|
+
export interface BigBedTextSearchAdapterConfig extends Instance<typeof BigBedTextSearchAdapter> {
|
|
50
|
+
}
|
|
51
|
+
export default BigBedTextSearchAdapter;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { ConfigurationSchema } from '@jbrowse/core/configuration';
|
|
2
|
+
/**
|
|
3
|
+
* #config BigBedTextSearchAdapter
|
|
4
|
+
* #trackType TextSearchAdapter
|
|
5
|
+
*
|
|
6
|
+
* Finds features by the names a BigBed was built to look up, its
|
|
7
|
+
* `bedToBigBed -extraIndex` columns, which a UCSC hub declares with
|
|
8
|
+
* `searchIndex`. The hub's `searchTrix` index, when given, adds prefix and
|
|
9
|
+
* case-insensitive matching. A UCSC track hub connection configures one for
|
|
10
|
+
* its first gene track declaring a `searchIndex`, GenArk's `ncbiRefSeq`.
|
|
11
|
+
*
|
|
12
|
+
* #example
|
|
13
|
+
* ```js
|
|
14
|
+
* {
|
|
15
|
+
* type: 'BigBedTextSearchAdapter',
|
|
16
|
+
* bigBedLocation: { uri: 'bbi/ncbiRefSeq.bb' },
|
|
17
|
+
* ixFilePath: { uri: 'ixIxx/ncbiRefSeq.ix' },
|
|
18
|
+
* ixxFilePath: { uri: 'ixIxx/ncbiRefSeq.ixx' },
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
const BigBedTextSearchAdapter = ConfigurationSchema('BigBedTextSearchAdapter', {
|
|
23
|
+
/**
|
|
24
|
+
* #slot
|
|
25
|
+
* the BigBed whose extra indexes resolve a name to its features
|
|
26
|
+
*/
|
|
27
|
+
bigBedLocation: {
|
|
28
|
+
type: 'fileLocation',
|
|
29
|
+
defaultValue: { uri: '/path/to/my.bb', locationType: 'UriLocation' },
|
|
30
|
+
},
|
|
31
|
+
/**
|
|
32
|
+
* #slot
|
|
33
|
+
* a UCSC `searchTrix` `.ix`, whose records are the names the extra
|
|
34
|
+
* indexes hold. Unset, a search matches a name exactly as typed
|
|
35
|
+
*/
|
|
36
|
+
ixFilePath: {
|
|
37
|
+
type: 'fileLocation',
|
|
38
|
+
defaultValue: { uri: '', locationType: 'UriLocation' },
|
|
39
|
+
},
|
|
40
|
+
/**
|
|
41
|
+
* #slot
|
|
42
|
+
* the `.ixx` beside `ixFilePath`
|
|
43
|
+
*/
|
|
44
|
+
ixxFilePath: {
|
|
45
|
+
type: 'fileLocation',
|
|
46
|
+
defaultValue: { uri: '', locationType: 'UriLocation' },
|
|
47
|
+
},
|
|
48
|
+
/**
|
|
49
|
+
* #slot
|
|
50
|
+
*/
|
|
51
|
+
assemblyNames: {
|
|
52
|
+
type: 'stringArray',
|
|
53
|
+
defaultValue: [],
|
|
54
|
+
description: 'List of assemblies covered by text search adapter',
|
|
55
|
+
},
|
|
56
|
+
}, { explicitlyTyped: true });
|
|
57
|
+
export default BigBedTextSearchAdapter;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import TextSearchAdapterType from '@jbrowse/core/pluggableElementTypes/TextSearchAdapterType';
|
|
2
|
+
import configSchema from './configSchema.js';
|
|
3
|
+
export default function BigBedTextSearchAdapterF(pluginManager) {
|
|
4
|
+
pluginManager.addTextSearchAdapterType(() => new TextSearchAdapterType({
|
|
5
|
+
name: 'BigBedTextSearchAdapter',
|
|
6
|
+
displayName: 'BigBed text search adapter',
|
|
7
|
+
description: 'Searches a BigBed by its extra-indexed names',
|
|
8
|
+
configSchema,
|
|
9
|
+
getAdapterClass: () => import('./BigBedTextSearchAdapter.js').then(r => r.default),
|
|
10
|
+
}));
|
|
11
|
+
}
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
2
2
|
import type { StarFusionAdapterConfig } from './configSchema.ts';
|
|
3
3
|
import type { BaseOptions } from '@jbrowse/core/data_adapters/BaseAdapter';
|
|
4
|
-
import type { Feature,
|
|
4
|
+
import type { Feature, Region } from '@jbrowse/core/util';
|
|
5
5
|
export default class StarFusionAdapter extends BaseFeatureDataAdapter<StarFusionAdapterConfig> {
|
|
6
6
|
private loadData;
|
|
7
|
-
protected intervalTrees: Record<string, Promise<IntervalTree<Feature> | undefined> | undefined>;
|
|
8
7
|
static capabilities: string[];
|
|
9
8
|
private loadDataP;
|
|
10
9
|
getRefNames(opts?: BaseOptions): Promise<string[]>;
|
|
11
10
|
private featureFromLine;
|
|
12
11
|
private loadFeatureTreeP;
|
|
13
|
-
private
|
|
12
|
+
private treeFeatures;
|
|
14
13
|
getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
|
|
15
14
|
}
|