Skip to content

Commit fe3bd1c

Browse files
committed
Update imports
1 parent 2f0faa6 commit fe3bd1c

File tree

4 files changed

+142
-91
lines changed

4 files changed

+142
-91
lines changed

jbrowse/package-lock.json

Lines changed: 28 additions & 50 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

jbrowse/package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"dependencies": {
1717
"@gmod/vcf": "^6.0.8",
1818
"@jbrowse/core": "^3.2.0",
19+
"@jbrowse/product-core": "^3.2.0",
1920
"@jbrowse/plugin-linear-genome-view": "^3.2.0",
2021
"@jbrowse/plugin-svg": "^3.2.0",
2122
"@jbrowse/plugin-variants": "^3.2.0",
@@ -34,9 +35,9 @@
3435
"jspdf-autotable": "^5.0.2",
3536
"node-polyfill-webpack-plugin": "4.1.0",
3637
"path-browserify": "^1.0.1",
37-
"react": "^18.0.0",
38+
"react": "^18.3.0",
3839
"react-data-grid": "7.0.0-beta.46",
39-
"react-dom": "^18.0.0",
40+
"react-dom": "^18.3.0",
4041
"react-google-charts": "^5.2.1",
4142
"react-select": "^5.10.1",
4243
"regenerator-runtime": "^0.14.1",
@@ -50,8 +51,8 @@
5051
"@types/jexl": "^2.3.4",
5152
"@types/jquery": "^3.5.32",
5253
"@types/node": "^20.14.11",
53-
"@types/react": "^18.0.0",
54-
"@types/react-dom": "^18.0.0",
54+
"@types/react": "^18.3.0",
55+
"@types/react-dom": "^18.3.0",
5556
"rimraf": "^6.0.1",
5657
"typescript": "^5.1.6"
5758
}

jbrowse/src/client/JBrowse/Browser/plugins/ExtendedVariantPlugin/ExtendedVariantAdapter/ExtendedVariantAdapter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export default class extends VcfTabixAdapter {
2727
observer.next(v)
2828
})
2929
observer.complete()
30-
}, opts.signal)
30+
}, opts.stopToken)
3131
}
3232

3333
private async getFeaturesAsArray(query: NoAssemblyRegion, opts: BaseOptions = {}) {

jbrowse/src/client/JBrowse/Browser/plugins/ExtendedVariantPlugin/ExtendedVariantAdapter/VcfTabixAdapter.ts

Lines changed: 108 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,158 @@
1+
import { TabixIndexedFile } from '@gmod/tabix'
2+
import VcfParser from '@gmod/vcf'
3+
import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter'
14
import {
2-
BaseFeatureDataAdapter,
3-
BaseOptions,
4-
} from '@jbrowse/core/data_adapters/BaseAdapter'
5-
import { NoAssemblyRegion } from '@jbrowse/core/util/types'
5+
fetchAndMaybeUnzipText,
6+
updateStatus,
7+
} from '@jbrowse/core/util'
68
import { openLocation } from '@jbrowse/core/util/io'
79
import { ObservableCreate } from '@jbrowse/core/util/rxjs'
8-
import { Feature } from '@jbrowse/core/util'
9-
import { TabixIndexedFile } from '@gmod/tabix'
10-
import VcfParser from '@gmod/vcf'
10+
11+
import type { BaseOptions } from '@jbrowse/core/data_adapters/BaseAdapter'
12+
import type { Feature } from '@jbrowse/core/util'
13+
import type { NoAssemblyRegion } from '@jbrowse/core/util/types'
1114
import { VcfFeature } from '@jbrowse/plugin-variants';
1215

16+
function shorten2(name: string, max = 70) {
17+
return name.length > max ? `${name.slice(0, max)}...` : name
18+
}
19+
1320
export default class VcfTabixAdapter extends BaseFeatureDataAdapter {
1421
private configured?: Promise<{
1522
vcf: TabixIndexedFile
1623
parser: VcfParser
1724
}>
1825

19-
private async configurePre() {
20-
const pm = this.pluginManager
26+
private async configurePre(_opts?: BaseOptions) {
2127
const vcfGzLocation = this.getConf('vcfGzLocation')
2228
const location = this.getConf(['index', 'location'])
2329
const indexType = this.getConf(['index', 'indexType'])
2430

25-
const filehandle = openLocation(vcfGzLocation, pm)
31+
const filehandle = openLocation(vcfGzLocation, this.pluginManager)
2632
const isCSI = indexType === 'CSI'
2733
const vcf = new TabixIndexedFile({
2834
filehandle,
29-
csiFilehandle: isCSI ? openLocation(location, pm) : undefined,
30-
tbiFilehandle: !isCSI ? openLocation(location, pm) : undefined,
31-
chunkCacheSize: 50 * 2 ** 20
35+
csiFilehandle: isCSI
36+
? openLocation(location, this.pluginManager)
37+
: undefined,
38+
tbiFilehandle: !isCSI
39+
? openLocation(location, this.pluginManager)
40+
: undefined,
41+
chunkCacheSize: 50 * 2 ** 20,
3242
})
3343

34-
const header = await vcf.getHeader()
3544
return {
3645
vcf,
37-
parser: new VcfParser({ header }),
46+
parser: new VcfParser({
47+
header: await vcf.getHeader(),
48+
}),
3849
}
3950
}
4051

41-
protected async configure() {
52+
protected async configurePre2() {
4253
if (!this.configured) {
43-
this.configured = this.configurePre().catch(e => {
54+
this.configured = this.configurePre().catch((e: unknown) => {
4455
this.configured = undefined
4556
throw e
4657
})
4758
}
4859
return this.configured
4960
}
5061

62+
async configure(opts?: BaseOptions) {
63+
const { statusCallback = () => {} } = opts || {}
64+
return updateStatus('Downloading index', statusCallback, () =>
65+
this.configurePre2(),
66+
)
67+
}
5168
public async getRefNames(opts: BaseOptions = {}) {
52-
const { vcf } = await this.configure()
69+
const { vcf } = await this.configure(opts)
5370
return vcf.getReferenceSequenceNames(opts)
5471
}
5572

56-
async getHeader() {
57-
const { vcf } = await this.configure()
73+
async getHeader(opts?: BaseOptions) {
74+
const { vcf } = await this.configure(opts)
5875
return vcf.getHeader()
5976
}
6077

61-
async getMetadata() {
62-
const { parser } = await this.configure()
78+
async getMetadata(opts?: BaseOptions) {
79+
const { parser } = await this.configure(opts)
6380
return parser.getMetadata()
6481
}
6582

6683
public getFeatures(query: NoAssemblyRegion, opts: BaseOptions = {}) {
6784
return ObservableCreate<Feature>(async observer => {
6885
const { refName, start, end } = query
69-
const { vcf, parser } = await this.configure()
70-
await vcf.getLines(refName, start, end, {
71-
lineCallback: (line, fileOffset) => {
72-
observer.next(
73-
new VcfFeature({
74-
variant: parser.parseLine(line),
75-
parser,
76-
id: `${this.id}-vcf-${fileOffset}`,
77-
}),
78-
)
79-
},
80-
...opts,
81-
})
86+
const { statusCallback = () => {} } = opts
87+
const { vcf, parser } = await this.configure(opts)
88+
89+
await updateStatus('Downloading variants', statusCallback, () =>
90+
vcf.getLines(refName, start, end, {
91+
lineCallback: (line, fileOffset) => {
92+
observer.next(
93+
new VcfFeature({
94+
variant: parser.parseLine(line),
95+
parser,
96+
id: `${this.id}-vcf-${fileOffset}`,
97+
}),
98+
)
99+
},
100+
...opts,
101+
}),
102+
)
82103
observer.complete()
83-
}, opts.signal)
104+
}, opts.stopToken)
105+
}
106+
107+
async getSources() {
108+
const conf = this.getConf('samplesTsvLocation')
109+
if (conf.uri === '' || conf.uri === '/path/to/samples.tsv') {
110+
const { parser } = await this.configure()
111+
return parser.samples.map(name => ({
112+
name,
113+
}))
114+
} else {
115+
const txt = await fetchAndMaybeUnzipText(
116+
openLocation(conf, this.pluginManager),
117+
)
118+
const lines = txt.split(/\n|\r\n|\r/)
119+
const header = lines[0]!.split('\t')
120+
const { parser } = await this.configure()
121+
const metadataLines = lines
122+
.slice(1)
123+
.filter(f => !!f)
124+
.map(line => {
125+
const [name, ...rest] = line.split('\t')
126+
return {
127+
...Object.fromEntries(
128+
// force col 0 to be called name
129+
rest.map((c, idx) => [header[idx + 1]!, c] as const),
130+
),
131+
name: name!,
132+
}
133+
})
134+
const vcfSampleSet = new Set(parser.samples)
135+
const metadataSet = new Set(metadataLines.map(r => r.name))
136+
const metadataNotInVcfSamples = [...metadataSet].filter(
137+
f => !vcfSampleSet.has(f),
138+
)
139+
const vcfSamplesNotInMetadata = [...vcfSampleSet].filter(
140+
f => !metadataSet.has(f),
141+
)
142+
if (metadataNotInVcfSamples.length) {
143+
console.warn(
144+
`There are ${metadataNotInVcfSamples.length} samples in metadata file (${metadataLines.length} lines) not in VCF (${parser.samples.length} samples):`,
145+
shorten2(metadataNotInVcfSamples.join(',')),
146+
)
147+
}
148+
if (vcfSamplesNotInMetadata.length) {
149+
console.warn(
150+
`There are ${vcfSamplesNotInMetadata.length} samples in VCF file (${parser.samples.length} samples) not in metadata file (${metadataLines.length} lines):`,
151+
shorten2(vcfSamplesNotInMetadata.map(m => m).join(',')),
152+
)
153+
}
154+
return metadataLines.filter(f => vcfSampleSet.has(f.name))
155+
}
84156
}
85157

86158
public freeResources(/* { region } */): void {}

0 commit comments

Comments
 (0)