Skip to content

Commit

Permalink
support whole genome view and chr dropdown under some conditions
Browse files Browse the repository at this point in the history
  • Loading branch information
jrobinso committed Sep 5, 2024
1 parent 64daf5a commit 86209f5
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 65 deletions.
3 changes: 2 additions & 1 deletion dev/ucsc/genome.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@

import igv from "../../js/index.js"

//https://hgdownload.soe.ucsc.edu/hubs/GCF/000/002/035/GCF_000002035.6/hub.txt
const igvConfig = {
genome: "GCA_000002305.1"
genome: "GCF_000002035.6"
}


Expand Down
62 changes: 14 additions & 48 deletions js/bigwig/bwReader.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,24 @@ class BWReader {
this.config = config
this.bufferSize = BUFFER_SIZE
this.loader = isDataURL(this.path) ?
new DataBuffer(this.path) : igvxhr
new DataBuffer(BGZip.decodeDataURI(this.path).buffer) :
igvxhr

if (config.searchTrix) {
this._trix = new Trix(`${config.searchTrix}x`, config.searchTrix)
}

}

/**
* Preload all the data for this bb file
* @returns {Promise<void>}
*/
async preload() {
const data = await igvxhr.loadArrayBuffer(this.path)
this.loader = new DataBuffer(data)
}

async readWGFeatures(bpPerPixel, windowFunction) {
await this.loadHeader()
const chrIdx1 = 0
Expand Down Expand Up @@ -393,7 +403,7 @@ class BWReader {
if (header.extensionOffset > 0) {
await this.loadExtendedHeader(header.extensionOffset)
}
return this.header
return this.header
}
}

Expand Down Expand Up @@ -680,8 +690,8 @@ function decodeZoomData(data, chrIdx1, bpStart, chrIdx2, bpEnd, featureArray, ch

class DataBuffer {

constructor(dataURI) {
this.data = BGZip.decodeDataURI(dataURI).buffer
constructor(data) {
this.data = data
}

/**
Expand Down Expand Up @@ -710,49 +720,5 @@ class DataBuffer {
}
}

class WholeFileBuffer {

data

constructor(path) {
this.path = path
}

async loadFile() {
this.data = await igvxhr.loadArrayBuffer(this.path)
}

/**
* igvxhr interface
* @param ignore
* @param options
* @returns {any}
*/
async loadArrayBuffer(ignore, options) {
if (!this.data) {
await this.loadFile()
}
const range = options.range
return range ? this.data.slice(range.start, range.start + range.size) : this.data
}

/**
* BufferedReader interface
*
* @param requestedRange - byte rangeas {start, size}
* @param fulfill - function to receive result
* @param asUint8 - optional flag to return result as an UInt8Array
*/
async dataViewForRange(requestedRange, asUint8) {
if (!this.data) {
await this.loadFile()
}
const len = Math.min(this.data.byteLength - requestedRange.start, requestedRange.size)
return asUint8 ?
new Uint8Array(this.data, requestedRange.start, len) :
new DataView(this.data, requestedRange.start, len)
}

}

export default BWReader
2 changes: 1 addition & 1 deletion js/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -1579,7 +1579,7 @@ class Browser {
}

if (this.chromosomeSelectWidget) {
this.chromosomeSelectWidget.select.value = referenceFrameList.length === 1 ? this.referenceFrameList[0].chr : ''
this.chromosomeSelectWidget.setValue(referenceFrameList.length === 1 ? this.referenceFrameList[0].chr : '')
}

const loc = this.referenceFrameList.map(rf => rf.getLocusString()).join(' ')
Expand Down
7 changes: 7 additions & 0 deletions js/genome/chromAliasBB.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ class ChromAliasBB {
this.reader = new BWReader(config, genome)
}

async preload(chrNames) {
await this.reader.preload();
for(let nm of chrNames) {
await this.search(nm)
}
}

/**
* Return the cached canonical chromosome name for the alias. If none found return the alias.
*
Expand Down
3 changes: 3 additions & 0 deletions js/genome/chromAliasDefaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ class ChromAliasDefaults {
this.update(id, chromosomeNames)
}

async preload() {
// no-op
}

/**
* Return the canonical chromosome name for the alias. If none found return the alias
Expand Down
4 changes: 4 additions & 0 deletions js/genome/chromAliasFile.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ class ChromAliasFile {
this.genome = genome
}

async preload() {
return this.loadAliases();
}

/**
* Return the canonical chromosome name for the alias. If none found return the alias
*
Expand Down
24 changes: 13 additions & 11 deletions js/genome/genome.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,28 +57,28 @@ class Genome {

if (config.chromAliasBbURL) {
this.chromAlias = new ChromAliasBB(config.chromAliasBbURL, Object.assign({}, config), this)
if(!this.chromosomeNames) {
if (!this.chromosomeNames) {
this.chromosomeNames = await this.chromAlias.getChromosomeNames()
}
} else if (config.aliasURL) {
this.chromAlias = new ChromAliasFile(config.aliasURL, Object.assign({}, config), this)
} else if (this.chromosomeNames) {
this.chromAlias = new ChromAliasDefaults(this.id, this.chromosomeNames);
this.chromAlias = new ChromAliasDefaults(this.id, this.chromosomeNames)
}

if (config.cytobandBbURL) {
this.cytobandSource = new CytobandFileBB(config.cytobandBbURL, Object.assign({}, config), this)
if(!this.chromosomeNames) {
if (!this.chromosomeNames) {
this.chromosomeNames = await this.cytobandSource.getChromosomeNames()
}
} else if (config.cytobandURL) {
this.cytobandSource = new CytobandFile(config.cytobandURL, Object.assign({}, config))
if(!this.chromosomeNames) {
if (!this.chromosomeNames) {
this.chromosomeNames = await this.cytobandSource.getChromosomeNames()
}
if(this.chromosomes.size === 0) {
if (this.chromosomes.size === 0) {
const c = await this.cytobandSource.getChromosomes()
for(let chromosome of c) {
for (let chromosome of c) {
this.chromosomes.set(c.name, c)
}
}
Expand All @@ -96,6 +96,7 @@ class Genome {
} else {
this.#wgChromosomeNames = trimSmallChromosomes(this.chromosomes)
}
await this.chromAlias.preload(this.#wgChromosomeNames)
}

// Optionally create the psuedo chromosome "all" to support whole genome view
Expand Down Expand Up @@ -162,15 +163,15 @@ class Genome {
async loadChromosome(chr) {

if (this.chromAlias) {
const chromAliasRecord = await this.chromAlias.search(chr)
if(chromAliasRecord) {
const chromAliasRecord = await this.chromAlias.search(chr)
if (chromAliasRecord) {
chr = chromAliasRecord.chr
}
}

if (!this.chromosomes.has(chr)) {
let chromosome
const sequenceRecord = await this.sequence.getSequenceRecord(chr)
const sequenceRecord = await this.sequence.getSequenceRecord(chr)
if (sequenceRecord) {
chromosome = new Chromosome(chr, 0, sequenceRecord.bpLength)
}
Expand All @@ -180,6 +181,7 @@ class Genome {

return this.chromosomes.get(chr)
}

async getAliasRecord(chr) {
if (this.chromAlias) {
return this.chromAlias.search(chr)
Expand All @@ -199,7 +201,7 @@ class Genome {
}

get wgChromosomeNames() {
return this.#wgChromosomeNames ? this.#wgChromosomeNames.slice() : undefined
return this.#wgChromosomeNames ? this.#wgChromosomeNames.slice() : undefined
}

get showChromosomeWidget() {
Expand Down Expand Up @@ -303,7 +305,7 @@ class Genome {
* @param end
*/
getSequenceInterval(chr, start, end) {
if(typeof this.sequence.getSequenceInterval === 'function') {
if (typeof this.sequence.getSequenceInterval === 'function') {
return this.sequence.getSequenceInterval(chr, start, end)
} else {
return undefined
Expand Down
39 changes: 37 additions & 2 deletions js/ucsc/ucscHub.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ class Hub {
const groupsTxtURL = baseURL + genome.getProperty("groups")
groups = await loadStanzas(groupsTxtURL)
}

// If the genome has a chromSizes file, and it is not too large, set the chromSizesURL property. This will
// enable whole genome view and the chromosome pulldown
if (genome.hasProperty("chromSizes")) {
const chromSizesURL = baseURL + genome.getProperty("chromSizes")
const l = await getContentLength(chromSizesURL)
if (l !== null && Number.parseInt(l) < 1000000) {
genome.setProperty("chromSizesURL", chromSizesURL)
}
}
}

// TODO -- categorize extra "user" supplied and other tracks in some distinctive way before including them
Expand Down Expand Up @@ -126,8 +136,13 @@ isPcr dynablat-01.soe.ucsc.edu 4040 dynamic GCF/000/186/305/GCF_000186305.1
name: name,
twoBitURL: this.baseURL + this.genomeStanza.getProperty("twoBitPath"),
nameSet: "ucsc",
wholeGenomeView: false,
showChromosomeWidget: false
}

if (this.genomeStanza.hasProperty("chromSizesURL")) {
config.chromSizesURL = this.genomeStanza.getProperty("chromSizesURL")
} else {
config.wholeGenomeView = false
config.showChromosomeWidget = false
}

if (this.genomeStanza.hasProperty("defaultPos")) {
Expand Down Expand Up @@ -419,6 +434,26 @@ class Stanza {
}
}


/**
* Return the content length of the resource. If the content length cannot be determined return null;
* @param url
* @returns {Promise<number|string>}
*/
async function getContentLength(url) {
try {
const response = await fetch(url, {method: 'HEAD'})
const headers = response.headers
if (headers.has("content-length")) {
return headers.get("content-length")
} else {
return null
}
} catch (e) {
return null
}
}

/**
* Parse a UCSC file
* @param url
Expand Down
11 changes: 9 additions & 2 deletions js/ui/chromosomeSelectWidget.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class ChromosomeSelectWidget {
})

this.showAllChromosomes = browser.config.showAllChromosomes !== false // i.e. default to true

this.genome = browser.genome
}

show() {
Expand All @@ -58,10 +58,16 @@ class ChromosomeSelectWidget {
this.container.style.display = 'none'
}

setValue(chrName) {
this.select.value = this.genome.getChromosomeDisplayName(chrName)
}

update(genome) {

this.genome = genome

// Start with explicit chromosome name list
const list = genome.wgChromosomeNames || []
const list = genome.wgChromosomeNames.map(nm => genome.getChromosomeDisplayName(nm)) || []

if (this.showAllChromosomes && genome.chromosomeNames.length > 1) {
const exclude = new Set(list)
Expand All @@ -72,6 +78,7 @@ class ChromosomeSelectWidget {
break
}
if (!exclude.has(nm)) {
nm = genome.getChromosomeDisplayName(nm)
list.push(nm)
}
}
Expand Down

0 comments on commit 86209f5

Please sign in to comment.