@jbrowse/plugin-gff3 2.6.1 → 2.6.2

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.
Files changed (48) hide show
  1. package/dist/Gff3Adapter/Gff3Adapter.js +0 -1
  2. package/dist/Gff3Adapter/configSchema.js +0 -1
  3. package/dist/Gff3Adapter/index.js +0 -1
  4. package/dist/Gff3TabixAdapter/Gff3TabixAdapter.js +0 -1
  5. package/dist/Gff3TabixAdapter/configSchema.js +0 -1
  6. package/dist/Gff3TabixAdapter/index.js +0 -1
  7. package/dist/GuessGff3/index.js +0 -1
  8. package/dist/index.js +0 -1
  9. package/esm/Gff3Adapter/Gff3Adapter.js +0 -1
  10. package/esm/Gff3Adapter/configSchema.js +0 -1
  11. package/esm/Gff3Adapter/index.js +0 -1
  12. package/esm/Gff3TabixAdapter/Gff3TabixAdapter.js +0 -1
  13. package/esm/Gff3TabixAdapter/configSchema.js +0 -1
  14. package/esm/Gff3TabixAdapter/index.js +0 -1
  15. package/esm/GuessGff3/index.js +0 -1
  16. package/esm/index.js +0 -1
  17. package/package.json +3 -4
  18. package/dist/Gff3Adapter/Gff3Adapter.js.map +0 -1
  19. package/dist/Gff3Adapter/configSchema.js.map +0 -1
  20. package/dist/Gff3Adapter/index.js.map +0 -1
  21. package/dist/Gff3TabixAdapter/Gff3TabixAdapter.js.map +0 -1
  22. package/dist/Gff3TabixAdapter/configSchema.js.map +0 -1
  23. package/dist/Gff3TabixAdapter/index.js.map +0 -1
  24. package/dist/GuessGff3/index.js.map +0 -1
  25. package/dist/index.js.map +0 -1
  26. package/esm/Gff3Adapter/Gff3Adapter.js.map +0 -1
  27. package/esm/Gff3Adapter/configSchema.js.map +0 -1
  28. package/esm/Gff3Adapter/index.js.map +0 -1
  29. package/esm/Gff3TabixAdapter/Gff3TabixAdapter.js.map +0 -1
  30. package/esm/Gff3TabixAdapter/configSchema.js.map +0 -1
  31. package/esm/Gff3TabixAdapter/index.js.map +0 -1
  32. package/esm/GuessGff3/index.js.map +0 -1
  33. package/esm/index.js.map +0 -1
  34. package/src/Gff3Adapter/Gff3Adapter.test.ts +0 -31
  35. package/src/Gff3Adapter/Gff3Adapter.ts +0 -166
  36. package/src/Gff3Adapter/__snapshots__/Gff3Adapter.test.ts.snap +0 -57
  37. package/src/Gff3Adapter/configSchema.ts +0 -23
  38. package/src/Gff3Adapter/index.ts +0 -15
  39. package/src/Gff3TabixAdapter/Gff3TabixAdapter.test.ts +0 -37
  40. package/src/Gff3TabixAdapter/Gff3TabixAdapter.ts +0 -260
  41. package/src/Gff3TabixAdapter/__snapshots__/Gff3TabixAdapter.test.ts.snap +0 -57
  42. package/src/Gff3TabixAdapter/configSchema.ts +0 -56
  43. package/src/Gff3TabixAdapter/index.ts +0 -16
  44. package/src/GuessGff3/index.ts +0 -63
  45. package/src/index.ts +0 -16
  46. package/src/test_data/volvox.sort.gff3 +0 -246
  47. package/src/test_data/volvox.sort.gff3.gz +0 -0
  48. package/src/test_data/volvox.sort.gff3.gz.tbi +0 -0
@@ -1,260 +0,0 @@
1
- /* eslint-disable no-underscore-dangle */
2
- import {
3
- BaseFeatureDataAdapter,
4
- BaseOptions,
5
- } from '@jbrowse/core/data_adapters/BaseAdapter'
6
- import { doesIntersect2 } from '@jbrowse/core/util/range'
7
- import { Region } from '@jbrowse/core/util/types'
8
- import { openLocation } from '@jbrowse/core/util/io'
9
- import { ObservableCreate } from '@jbrowse/core/util/rxjs'
10
- import SimpleFeature, { Feature } from '@jbrowse/core/util/simpleFeature'
11
- import { TabixIndexedFile } from '@gmod/tabix'
12
- import gff, { GFF3Feature, GFF3FeatureLineWithRefs } from '@gmod/gff'
13
- import { Observer } from 'rxjs'
14
- import {
15
- readConfObject,
16
- AnyConfigurationModel,
17
- } from '@jbrowse/core/configuration'
18
- import PluginManager from '@jbrowse/core/PluginManager'
19
- import { getSubAdapterType } from '@jbrowse/core/data_adapters/dataAdapterCache'
20
-
21
- interface LineFeature {
22
- start: number
23
- end: number
24
- lineHash: number
25
- fields: string[]
26
- }
27
-
28
- export default class extends BaseFeatureDataAdapter {
29
- protected gff: TabixIndexedFile
30
-
31
- protected dontRedispatch: string[]
32
-
33
- public constructor(
34
- config: AnyConfigurationModel,
35
- getSubAdapter?: getSubAdapterType,
36
- pluginManager?: PluginManager,
37
- ) {
38
- super(config, getSubAdapter, pluginManager)
39
- const gffGzLocation = readConfObject(config, 'gffGzLocation')
40
- const indexType = readConfObject(config, ['index', 'indexType'])
41
- const location = readConfObject(config, ['index', 'location'])
42
- const dontRedispatch = readConfObject(config, 'dontRedispatch')
43
-
44
- this.dontRedispatch = dontRedispatch || ['chromosome', 'contig', 'region']
45
- this.gff = new TabixIndexedFile({
46
- filehandle: openLocation(gffGzLocation, this.pluginManager),
47
- csiFilehandle:
48
- indexType === 'CSI'
49
- ? openLocation(location, this.pluginManager)
50
- : undefined,
51
- tbiFilehandle:
52
- indexType !== 'CSI'
53
- ? openLocation(location, this.pluginManager)
54
- : undefined,
55
- chunkCacheSize: 50 * 2 ** 20,
56
- renameRefSeqs: (n: string) => n,
57
- })
58
- }
59
-
60
- public async getRefNames(opts: BaseOptions = {}) {
61
- return this.gff.getReferenceSequenceNames(opts)
62
- }
63
-
64
- public async getHeader() {
65
- return this.gff.getHeader()
66
- }
67
-
68
- public getFeatures(query: Region, opts: BaseOptions = {}) {
69
- return ObservableCreate<Feature>(async observer => {
70
- const metadata = await this.gff.getMetadata()
71
- await this.getFeaturesHelper(query, opts, metadata, observer, true)
72
- }, opts.signal)
73
- }
74
-
75
- private async getFeaturesHelper(
76
- query: Region,
77
- opts: BaseOptions = {},
78
- metadata: { columnNumbers: { start: number; end: number } },
79
- observer: Observer<Feature>,
80
- allowRedispatch: boolean,
81
- originalQuery = query,
82
- ) {
83
- try {
84
- const lines: LineFeature[] = []
85
-
86
- await this.gff.getLines(
87
- query.refName,
88
- query.start,
89
- query.end,
90
- (line: string, fileOffset: number) => {
91
- lines.push(this.parseLine(metadata.columnNumbers, line, fileOffset))
92
- },
93
- )
94
- if (allowRedispatch && lines.length) {
95
- let minStart = Infinity
96
- let maxEnd = -Infinity
97
- lines.forEach(line => {
98
- const featureType = line.fields[2]
99
- // only expand redispatch range if feature is not a "dontRedispatch" type
100
- // skips large regions like chromosome,region
101
- if (!this.dontRedispatch.includes(featureType)) {
102
- const start = line.start - 1 // gff is 1-based
103
- if (start < minStart) {
104
- minStart = start
105
- }
106
- if (line.end > maxEnd) {
107
- maxEnd = line.end
108
- }
109
- }
110
- })
111
- if (maxEnd > query.end || minStart < query.start) {
112
- // make a new feature callback to only return top-level features
113
- // in the original query range
114
- await this.getFeaturesHelper(
115
- { ...query, start: minStart, end: maxEnd },
116
- opts,
117
- metadata,
118
- observer,
119
- false,
120
- query,
121
- )
122
- return
123
- }
124
- }
125
-
126
- const gff3 = lines
127
- .map((lineRecord: LineFeature) => {
128
- if (lineRecord.fields[8] && lineRecord.fields[8] !== '.') {
129
- if (!lineRecord.fields[8].includes('_lineHash')) {
130
- lineRecord.fields[8] += `;_lineHash=${lineRecord.lineHash}`
131
- }
132
- } else {
133
- lineRecord.fields[8] = `_lineHash=${lineRecord.lineHash}`
134
- }
135
- return lineRecord.fields.join('\t')
136
- })
137
- .join('\n')
138
-
139
- const features = gff.parseStringSync(gff3, {
140
- parseFeatures: true,
141
- parseComments: false,
142
- parseDirectives: false,
143
- parseSequences: false,
144
- disableDerivesFromReferences: true,
145
- })
146
-
147
- features.forEach(featureLocs =>
148
- this.formatFeatures(featureLocs).forEach(f => {
149
- if (
150
- doesIntersect2(
151
- f.get('start'),
152
- f.get('end'),
153
- originalQuery.start,
154
- originalQuery.end,
155
- )
156
- ) {
157
- observer.next(f)
158
- }
159
- }),
160
- )
161
- observer.complete()
162
- } catch (e) {
163
- observer.error(e)
164
- }
165
- }
166
-
167
- private parseLine(
168
- columnNumbers: { start: number; end: number },
169
- line: string,
170
- fileOffset: number,
171
- ) {
172
- const fields = line.split('\t')
173
-
174
- // note: index column numbers are 1-based
175
- return {
176
- start: +fields[columnNumbers.start - 1],
177
- end: +fields[columnNumbers.end - 1],
178
- lineHash: fileOffset,
179
- fields,
180
- }
181
- }
182
-
183
- private formatFeatures(featureLocs: GFF3Feature) {
184
- return featureLocs.map(
185
- featureLoc =>
186
- new SimpleFeature({
187
- data: this.featureData(featureLoc),
188
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
189
- id: `${this.id}-offset-${featureLoc.attributes!._lineHash![0]}`,
190
- }),
191
- )
192
- }
193
-
194
- private featureData(data: GFF3FeatureLineWithRefs) {
195
- const f: Record<string, unknown> = { ...data }
196
- ;(f.start as number) -= 1 // convert to interbase
197
- if (data.strand === '+') {
198
- f.strand = 1
199
- } else if (data.strand === '-') {
200
- f.strand = -1
201
- } else if (data.strand === '.') {
202
- f.strand = 0
203
- } else {
204
- f.strand = undefined
205
- }
206
- f.phase = Number(data.phase)
207
- f.refName = data.seq_id
208
- if (data.score === null) {
209
- delete f.score
210
- }
211
- if (data.phase === null) {
212
- delete f.score
213
- }
214
- const defaultFields = new Set([
215
- 'start',
216
- 'end',
217
- 'seq_id',
218
- 'score',
219
- 'type',
220
- 'source',
221
- 'phase',
222
- 'strand',
223
- ])
224
- const dataAttributes = data.attributes || {}
225
- for (const a of Object.keys(dataAttributes)) {
226
- let b = a.toLowerCase()
227
- if (defaultFields.has(b)) {
228
- // add "suffix" to tag name if it already exists
229
- // reproduces behavior of NCList
230
- b += '2'
231
- }
232
- if (dataAttributes[a] !== null) {
233
- let attr: string | string[] | undefined = dataAttributes[a]
234
- if (Array.isArray(attr) && attr.length === 1) {
235
- ;[attr] = attr
236
- }
237
- f[b] = attr
238
- }
239
- }
240
- f.refName = f.seq_id
241
-
242
- // the SimpleFeature constructor takes care of recursively inflating subfeatures
243
- if (data.child_features && data.child_features.length > 0) {
244
- f.subfeatures = data.child_features.flatMap(childLocs =>
245
- childLocs.map(childLoc => this.featureData(childLoc)),
246
- )
247
- }
248
-
249
- delete f.child_features
250
- delete f.data
251
- // delete f.derived_features
252
- delete f._linehash
253
- delete f.attributes
254
- delete f.seq_id
255
-
256
- return f
257
- }
258
-
259
- public freeResources(/* { region } */) {}
260
- }
@@ -1,57 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`adapter can fetch features from volvox.gff3 test getfeatures on gff plain text adapter 1`] = `
4
- [
5
- {
6
- "derived_features": [],
7
- "end": 6079,
8
- "name": "ctgB",
9
- "phase": 0,
10
- "refName": "ctgB",
11
- "source": "example",
12
- "start": 0,
13
- "strand": undefined,
14
- "type": "contig",
15
- "uniqueId": "test-offset-794328",
16
- },
17
- {
18
- "derived_features": [],
19
- "end": 1984,
20
- "name": "f07",
21
- "note": "This is an example",
22
- "phase": 0,
23
- "refName": "ctgB",
24
- "source": "example",
25
- "start": 1658,
26
- "strand": 1,
27
- "type": "remark",
28
- "uniqueId": "test-offset-794371",
29
- },
30
- {
31
- "derived_features": [],
32
- "end": 6130,
33
- "name": "f06",
34
- "note": "This is another example",
35
- "phase": 0,
36
- "refName": "ctgB",
37
- "source": "example",
38
- "start": 3013,
39
- "strand": 1,
40
- "type": "remark",
41
- "uniqueId": "test-offset-794440",
42
- },
43
- {
44
- "derived_features": [],
45
- "end": 5968,
46
- "name": "f05",
47
- "note": "ああ、この機能は、世界中を旅しています!",
48
- "phase": 0,
49
- "refName": "ctgB",
50
- "source": "example",
51
- "start": 4714,
52
- "strand": -1,
53
- "type": "remark",
54
- "uniqueId": "test-offset-794514",
55
- },
56
- ]
57
- `;
@@ -1,56 +0,0 @@
1
- import { types } from 'mobx-state-tree'
2
- import { ConfigurationSchema } from '@jbrowse/core/configuration'
3
-
4
- /**
5
- * #config Gff3TabixAdapter
6
- * #category adapter
7
- */
8
- function x() {} // eslint-disable-line @typescript-eslint/no-unused-vars
9
-
10
- const Gff3TabixAdapter = ConfigurationSchema(
11
- 'Gff3TabixAdapter',
12
- {
13
- /**
14
- * #slot
15
- */
16
- gffGzLocation: {
17
- type: 'fileLocation',
18
- defaultValue: { uri: '/path/to/my.gff.gz', locationType: 'UriLocation' },
19
- },
20
-
21
- index: ConfigurationSchema('Gff3TabixIndex', {
22
- /**
23
- * #slot index.indexType
24
- */
25
- indexType: {
26
- model: types.enumeration('IndexType', ['TBI', 'CSI']),
27
- type: 'stringEnum',
28
- defaultValue: 'TBI',
29
- },
30
- /**
31
- * #slot index.indexType
32
- */
33
- location: {
34
- type: 'fileLocation',
35
- defaultValue: {
36
- uri: '/path/to/my.gff.gz.tbi',
37
- locationType: 'UriLocation',
38
- },
39
- },
40
- }),
41
- /**
42
- * #slot
43
- * the Gff3TabixAdapter has to "redispatch" if it fetches a region and
44
- * features it finds inside that region extend outside the region we requested.
45
- * you can disable this for certain feature types to avoid fetching e.g. the
46
- * entire chromosome
47
- */
48
- dontRedispatch: {
49
- type: 'stringArray',
50
- defaultValue: ['chromosome', 'region'],
51
- },
52
- },
53
- { explicitlyTyped: true },
54
- )
55
-
56
- export default Gff3TabixAdapter
@@ -1,16 +0,0 @@
1
- import { AdapterType } from '@jbrowse/core/pluggableElementTypes'
2
- import PluginManager from '@jbrowse/core/PluginManager'
3
- import configSchema from './configSchema'
4
-
5
- export default (pluginManager: PluginManager) => {
6
- pluginManager.addAdapterType(
7
- () =>
8
- new AdapterType({
9
- name: 'Gff3TabixAdapter',
10
- displayName: 'GFF3 tabix adapter',
11
- configSchema,
12
- getAdapterClass: () =>
13
- import('./Gff3TabixAdapter').then(r => r.default),
14
- }),
15
- )
16
- }
@@ -1,63 +0,0 @@
1
- import PluginManager from '@jbrowse/core/PluginManager'
2
- import { FileLocation } from '@jbrowse/core/util/types'
3
- import {
4
- makeIndex,
5
- makeIndexType,
6
- getFileName,
7
- AdapterGuesser,
8
- } from '@jbrowse/core/util/tracks'
9
-
10
- export default (pluginManager: PluginManager) => {
11
- pluginManager.addToExtensionPoint(
12
- 'Core-guessAdapterForLocation',
13
- (adapterGuesser: AdapterGuesser) => {
14
- return (
15
- file: FileLocation,
16
- index?: FileLocation,
17
- adapterHint?: string,
18
- ) => {
19
- const regexGuess = /\.gff3?\.b?gz$/i
20
- const adapterName = 'Gff3TabixAdapter'
21
- const fileName = getFileName(file)
22
- const indexName = index && getFileName(index)
23
- if (regexGuess.test(fileName) || adapterHint === adapterName) {
24
- return {
25
- type: adapterName,
26
- bamLocation: file,
27
- gffGzLocation: file,
28
- index: {
29
- location: index || makeIndex(file, '.tbi'),
30
- indexType: makeIndexType(indexName, 'CSI', 'TBI'),
31
- },
32
- }
33
- }
34
- return adapterGuesser(file, index, adapterHint)
35
- }
36
- },
37
- )
38
-
39
- pluginManager.addToExtensionPoint(
40
- 'Core-guessAdapterForLocation',
41
- (adapterGuesser: AdapterGuesser) => {
42
- return (
43
- file: FileLocation,
44
- index?: FileLocation,
45
- adapterHint?: string,
46
- ) => {
47
- const regexGuess = /\.gff3?$/i
48
- const adapterName = 'Gff3Adapter'
49
- const fileName = getFileName(file)
50
- const obj = {
51
- type: adapterName,
52
- gffLocation: file,
53
- }
54
- if (regexGuess.test(fileName) && !adapterHint) {
55
- return obj
56
- } else if (adapterHint === adapterName) {
57
- return obj
58
- }
59
- return adapterGuesser(file, index, adapterHint)
60
- }
61
- },
62
- )
63
- }
package/src/index.ts DELETED
@@ -1,16 +0,0 @@
1
- import PluginManager from '@jbrowse/core/PluginManager'
2
- import Plugin from '@jbrowse/core/Plugin'
3
-
4
- import Gff3TabixAdapterF from './Gff3TabixAdapter'
5
- import Gff3AdapterF from './Gff3Adapter'
6
- import GuessGff3F from './GuessGff3'
7
-
8
- export default class extends Plugin {
9
- name = 'GFF3Plugin'
10
-
11
- install(pluginManager: PluginManager) {
12
- Gff3TabixAdapterF(pluginManager)
13
- Gff3AdapterF(pluginManager)
14
- GuessGff3F(pluginManager)
15
- }
16
- }