diff --git a/dev/ucsc/hub.html b/dev/ucsc/hub.html index 4465cc909..3229eab08 100644 --- a/dev/ucsc/hub.html +++ b/dev/ucsc/hub.html @@ -39,27 +39,27 @@ } const hub = await Hub.loadHub("https://hgdownload.soe.ucsc.edu/hubs/GCA/009/914/755/GCA_009914755.4/hub.txt", hubOptions) - const ref = hub.getGenomeConfig() const igvConfig = { - reference: ref + reference: hub.getGenomeConfig() } - // for(let tc of hub.getTrackConfigurations()) { - // for(let t of tc.tracks) { - // if(t.url.endsWith("undefined")) console.log(`${tc.label} ${t.name} ${t.url}`) - // } - // } - const browser = await igv.createBrowser(document.getElementById('igvDiv'), igvConfig) + browser.on('genomechange', (genome) => { + console.log(genome.getTrackConfigurations()) + }) + const selector = document.getElementById("select") selector.addEventListener("change", () => document.getElementById("hub-input").value = selector.value) document.getElementById("hub-input").value = "https://hgdownload.soe.ucsc.edu/hubs/GCA/009/914/755/GCA_009914755.4/hub.txt" - document.getElementById("load-genome").addEventListener("click", () => - browser.loadGenome({url: document.getElementById("hub-input").value})) + document.getElementById("load-genome").addEventListener("click", async () => { + await browser.loadGenome({url: document.getElementById("hub-input").value}) + console.log(browser.genome.getTrackConfigurations()) + }) + document.getElementById("load-session").addEventListener("click", () => browser.loadSession({url: document.getElementById("hub-input").value})) diff --git a/js/browser.js b/js/browser.js index df6497f78..163df77b0 100755 --- a/js/browser.js +++ b/js/browser.js @@ -682,7 +682,7 @@ class Browser { */ async loadReference(genomeConfig, initialLocus) { - const genome = await Genome.loadGenome(genomeConfig) + const genome = await Genome.createGenome(genomeConfig) const genomeChange = undefined === this.genome || (this.genome.id !== genome.id) @@ -702,6 +702,10 @@ class Browser { throw new Error(`Cannot set initial locus ${locus}`) } + if(genomeChange) { + this.fireEvent('genomechange', [genome]) + } + if (genomeChange && this.circularView) { this.circularView.setAssembly({ name: this.genome.id, diff --git a/js/genome/genome.js b/js/genome/genome.js index 17d283b4a..bdf1212c5 100644 --- a/js/genome/genome.js +++ b/js/genome/genome.js @@ -18,7 +18,7 @@ import {loadChromSizes} from "./chromSizes.js" class Genome { - static async loadGenome(options) { + static async createGenome(options) { const genome = new Genome(options) await genome.init() @@ -30,9 +30,9 @@ class Genome { this.id = config.id || generateGenomeID(config) this.name = config.name this.nameSet = config.nameSet - } + async init() { const config = this.config @@ -278,6 +278,10 @@ class Genome { const l = this.wgChromosomeNames.reduce((accumulator, currentValue) => accumulator += this.chromosomes.get(currentValue).bpLength, 0) this.chromosomes.set("all", new Chromosome("all", 0, l)) } + + getTrackConfigurations() { + return this.config.trackConfigurations + } } /** diff --git a/js/index.js b/js/index.js index e5c49dacb..891e82efa 100644 --- a/js/index.js +++ b/js/index.js @@ -12,6 +12,7 @@ import {igvxhr} from "../node_modules/igv-utils/src/index.js" import {registerTrackClass, registerTrackCreatorFunction} from "./trackFactory.js" import TrackBase from "./trackBase.js" import Hub from "./ucsc/ucscHub.js" +import Browser from "./browser.js" const setApiKey = igvxhr.setApiKey @@ -47,6 +48,7 @@ export default { registerTrackClass, registerTrackCreatorFunction, registerFileFormats, - Hub + Hub, + uncompressSession: Browser.uncompressSession } diff --git a/js/ucsc/ucscHub.js b/js/ucsc/ucscHub.js index 37bedde8d..41aa612ad 100644 --- a/js/ucsc/ucscHub.js +++ b/js/ucsc/ucscHub.js @@ -89,33 +89,6 @@ class Hub { return this.genomeStanza.getProperty("defaultPos") } - getTrackConfigurations() { - - // Organize track configs by group - const trackConfigMap = new Map() - for (let c of this.#getTracksConfigs()) { - const groupName = c.group || "other" - if (trackConfigMap.has(groupName)) { - trackConfigMap.get(groupName).push(c) - } else { - trackConfigMap.set(groupName, [c]) - } - } - - // Build group structure - const groupStanazMap = this.groupStanzas ? - new Map(this.groupStanzas.map(groupStanza => [groupStanza.getProperty("name"), groupStanza])) : - new Map() - - return Array.from(trackConfigMap.keys()).map(groupName => { - return { - label: groupStanazMap.has(groupName) ? groupStanazMap.get(groupName).getProperty("label") : groupName, - tracks: trackConfigMap.get(groupName) - } - }) - - } - /* Example genome stanza genome GCF_000186305.1 taxId 176946 @@ -205,11 +178,40 @@ isPcr dynablat-01.soe.ucsc.edu 4040 dynamic GCF/000/186/305/GCF_000186305.1 config.tracks = this.#getTracksConfigs(filter) } + config.trackConfigurations = this.#getGroupedTrackConfigurations() + return config } + #getGroupedTrackConfigurations() { + + // Organize track configs by group + const trackConfigMap = new Map() + for (let c of this.#getTracksConfigs()) { + const groupName = c.group || "other" + if (trackConfigMap.has(groupName)) { + trackConfigMap.get(groupName).push(c) + } else { + trackConfigMap.set(groupName, [c]) + } + } + + // Build group structure + const groupStanazMap = this.groupStanzas ? + new Map(this.groupStanzas.map(groupStanza => [groupStanza.getProperty("name"), groupStanza])) : + new Map() + + return Array.from(trackConfigMap.keys()).map(groupName => { + return { + label: groupStanazMap.has(groupName) ? groupStanazMap.get(groupName).getProperty("label") : groupName, + tracks: trackConfigMap.get(groupName) + } + }) + + } + /** - * Return collection of igv track config object, organized by "group* + * Return an array of igv track config objects that satisfy the filter */ #getTracksConfigs(filter) { return this.trackStanzas.filter(t => { diff --git a/test/testBED.js b/test/testBED.js index 500307b28..56e0b8216 100644 --- a/test/testBED.js +++ b/test/testBED.js @@ -325,7 +325,7 @@ suite("testBed", function () { this.timeout(20000) // Need an actual genome object for this test, not a mock object - const genome = await Genome.loadGenome({ + const genome = await Genome.createGenome({ id: "hg38", name: "Human (GRCh38/hg38)", fastaURL: "https://s3.dualstack.us-east-1.amazonaws.com/igv.broadinstitute.org/genomes/seq/hg38/hg38.fa", diff --git a/test/testGenome.js b/test/testGenome.js index 70b1970fd..c798eb3a1 100644 --- a/test/testGenome.js +++ b/test/testGenome.js @@ -17,7 +17,7 @@ suite("testGenome", function () { wholeGenomeView: true } - const genome = await Genome.loadGenome(reference) + const genome = await Genome.createGenome(reference) assert.ok(genome) assert.equal(86, genome.chromosomeNames.length) assert.equal(genome.getCumulativeOffset("2"), 249250621) @@ -35,7 +35,7 @@ suite("testGenome", function () { chromSizes: "https://hgdownload.gi.ucsc.edu/hubs//GCA/011/100/615/GCA_011100615.1/GCA_011100615.1.chrom.sizes.txt" } - const genome = await Genome.loadGenome(reference) + const genome = await Genome.createGenome(reference) assert.ok(genome.chromosomes.size > 0) assert.ok(genome.chromosomeNames.length > 0) diff --git a/test/testHubs.js b/test/testHubs.js index cc97682d1..0f0c688e3 100644 --- a/test/testHubs.js +++ b/test/testHubs.js @@ -10,7 +10,7 @@ import {isString} from "../node_modules/igv-utils/src/stringUtils.js" suite("hub.txt", function () { - test("genome", async function () { + test("genome config", async function () { const hub = await Hub.loadHub("test/data/hubs/hub.txt") assert.ok(hub.hub) @@ -27,20 +27,9 @@ suite("hub.txt", function () { assert.ok(genomeConfig.twoBitURL) assert.ok(genomeConfig.chromAliasBbURL) assert.ok(genomeConfig.cytobandBbURL) + assert.ok(genomeConfig.trackConfigurations.length > 0) }) - test("track configs", async function () { - - const hub = await Hub.loadHub("test/data/hubs/hub.txt") - assert.ok(hub.hub) - assert.ok(hub.genomeStanza) - assert.equal(22, hub.trackStanzas.length) - - const trackConfigs = hub.getTrackConfigurations() - - assert.ok(trackConfigs.length > 0) - - }) }) diff --git a/test/testSeg.js b/test/testSeg.js index f4f3f88d1..a5be03574 100644 --- a/test/testSeg.js +++ b/test/testSeg.js @@ -41,7 +41,7 @@ suite("testSeg", function () { cytobandURL: "https://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/b37/b37_cytoband.txt" } - const genome = await Genome.loadGenome(reference) + const genome = await Genome.createGenome(reference) const url = "https://www.dropbox.com/s/h1rotg4xgn1bq8a/segmented_data_080520.seg.gz?dl=0" const featureSource = FeatureSource({ format: 'seg',