diff --git a/dev/annotation/annotation.html b/dev/annotation/annotation.html
index b98c2fce6..edf78c37d 100644
--- a/dev/annotation/annotation.html
+++ b/dev/annotation/annotation.html
@@ -37,6 +37,14 @@
Annotation tracks
"supportsWholeGenome": true,
"name": "Bed - No Index"
},
+ {
+ "type": "annotation",
+ "format": "bigBed",
+ "url": "../../genes.bb",
+ "indexed": false,
+ "supportsWholeGenome": true,
+ "name": "Bed - No Index"
+ },
{
"type": "annotation",
"format": "bed",
diff --git a/dev/twobit/twobit.html b/dev/twobit/twobit.html
index f87f2a2fa..b7568e751 100644
--- a/dev/twobit/twobit.html
+++ b/dev/twobit/twobit.html
@@ -18,7 +18,7 @@
reference: {
id: "GCF_016699485.2",
format: "2bit",
- twobitURL: "https://hgdownload.gi.ucsc.edu/hubs//GCA/011/100/615/GCA_011100615.1/GCA_011100615.1.2bit",
+ twoBitURL: "https://hgdownload.gi.ucsc.edu/hubs//GCA/011/100/615/GCA_011100615.1/GCA_011100615.1.2bit",
aliasBbURL: "https://hgdownload.gi.ucsc.edu/hubs//GCA/011/100/615/GCA_011100615.1/GCA_011100615.1.chromAlias.bb",
nameSet: "ucsc",
wholeGenomeView: false
diff --git a/dev/twobit/twobit_aliasBB.html b/dev/twobit/twobit_aliasBB.html
new file mode 100644
index 000000000..ca25a799a
--- /dev/null
+++ b/dev/twobit/twobit_aliasBB.html
@@ -0,0 +1,52 @@
+
+
+
+ twobit
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/twobit/twobit_basic.html b/dev/twobit/twobit_basic.html
new file mode 100644
index 000000000..909d16e65
--- /dev/null
+++ b/dev/twobit/twobit_basic.html
@@ -0,0 +1,50 @@
+
+
+
+ twobit
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/twobit/twobit_chromSizes.html b/dev/twobit/twobit_chromSizes.html
index 7e5280fc3..6962b8e4c 100644
--- a/dev/twobit/twobit_chromSizes.html
+++ b/dev/twobit/twobit_chromSizes.html
@@ -18,7 +18,7 @@
reference: {
id: "GCF_016699485.2",
format: "2bit",
- twobitURL: "https://hgdownload.gi.ucsc.edu/hubs//GCA/011/100/615/GCA_011100615.1/GCA_011100615.1.2bit",
+ twoBitURL: "https://hgdownload.gi.ucsc.edu/hubs//GCA/011/100/615/GCA_011100615.1/GCA_011100615.1.2bit",
chromeSizes: "https://hgdownload.gi.ucsc.edu/hubs//GCA/011/100/615/GCA_011100615.1/GCA_011100615.1.chrom.sizes.txt",
wholeGenomeView: false
}
diff --git a/dev/twobit/twobit_t2t.html b/dev/twobit/twobit_t2t.html
index a999a4acb..078bd9bd3 100644
--- a/dev/twobit/twobit_t2t.html
+++ b/dev/twobit/twobit_t2t.html
@@ -14,60 +14,69 @@
const config =
{
- locus: "myc",
+ //locus: "myc",
+ locus:"CP068269.2:35,726,976-35,734,192",
+ showChromosomeWidget: false,
reference: {
- "id": "chm13v2.0",
- "name": "Human (T2T CHM13-v2.0)",
- "fastaURL": "https://s3.amazonaws.com/igv.org.genomes/chm13v2.0/chm13v2.0.fa",
- "indexURL": "https://s3.amazonaws.com/igv.org.genomes/chm13v2.0/chm13v2.0.fa.fai",
- "cytobandURL": "https://s3.amazonaws.com/igv.org.genomes/chm13v2.0/CHM13_v2.0.cytoBandMapped.bed",
- "aliasURL": "https://s3.amazonaws.com/igv.org.genomes/chm13v2.0/GCA_009914755.4.chromAlias.txt",
- twobitURL: "https://hgdownload.soe.ucsc.edu/hubs/GCA/009/914/755/GCA_009914755.4/GCA_009914755.4.2bit",
+ wholeGenomeView: false,
+ id: "chm13v2.0",
+ name: "Human (T2T CHM13-v2.0)",
+ twoBitURL: "https://hgdownload.soe.ucsc.edu/hubs/GCA/009/914/755/GCA_009914755.4/GCA_009914755.4.2bit",
cytobandBbURL: "https://hgdownload.soe.ucsc.edu/hubs/GCA/009/914/755/GCA_009914755.4/bbi/GCA_009914755.4_T2T-CHM13v2.0.cytoBandMapped/cytoBandMapped.bb",
- aliasBbURL: "https://hgdownload.soe.ucsc.edu/hubs/GCA/009/914/755/GCA_009914755.4/GCA_009914755.4.chromAlias.bb",
+ chromAliasBbURL: "https://hgdownload.soe.ucsc.edu/hubs/GCA/009/914/755/GCA_009914755.4/GCA_009914755.4.chromAlias.bb",
nameSet: "ucsc",
- "tracks": [
+ tracks: [
+ // {
+ // "id": "catLiftOffGenesV1",
+ // "name": "CAT/Liftoff Genes",
+ // "format": "bigbed",
+ // "description": " CAT + Liftoff Gene Annotations",
+ // "url": "https://hgdownload.soe.ucsc.edu/hubs/GCA/009/914/755/GCA_009914755.4/bbi/GCA_009914755.4_T2T-CHM13v2.0.catLiftOffGenesV1/catLiftOffGenesV1.bb",
+ // "displayMode": "EXPANDED",
+ // "height": 200,
+ // "visibilityWindow": -1,
+ // "supportsWholeGenome": false
+ // },
+ //
+ // // Include a hg38 bigwig track -- test chromosome aliasing
+ // {
+ // "url": "https://www.encodeproject.org/files/ENCFF754TJH/@@download/ENCFF754TJH.bigWig",
+ // "name": "Encode bigwig",
+ // },
+
+ // plain wig track
+ {
+ url: "../../test/data/hubs/ENCFF754TJH.wig",
+ name: "Encode wig"
+ },
+
+ // plain bed track
{
- "id": "catLiftOffGenesV1",
- "name": "CAT/Liftoff Genes",
- "format": "bigbed",
- "description": " CAT + Liftoff Gene Annotations",
- "url": "https://hgdownload.soe.ucsc.edu/hubs/GCA/009/914/755/GCA_009914755.4/bbi/GCA_009914755.4_T2T-CHM13v2.0.catLiftOffGenesV1/catLiftOffGenesV1.bb",
- "displayMode": "EXPANDED",
- "height": 200,
- "visibilityWindow": -1,
- "supportsWholeGenome": false,
- "order": 1000000
+ url: "../../test/data/hubs/catLiftOff.bed",
+ name: "plain bed"
},
+
+ // indexed bed track
{
- "id": "augustus",
- "name": "Augustus",
- "format": "bigbed",
- "description": " Augustus Gene Predictions",
- "url": "https://hgdownload.soe.ucsc.edu/hubs/GCA/009/914/755/GCA_009914755.4/bbi/GCA_009914755.4_T2T-CHM13v2.0.augustus.bb",
- "displayMode": "EXPANDED",
- "color": "180,0,0",
- "height": 200,
- "visibilityWindow": -1,
- "supportsWholeGenome": false,
- "order": 1000001
+ url: "../../test/data/hubs/catLiftOff.bed.gz",
+ indexUrl: "../../test/data/hubs/catLiftOff.bed.gz.tbi",
+ name: "indexed bed"
},
+
+ //bam
{
- "name": "Genes",
- "format": "bed",
- "url": "https://s3.amazonaws.com/igv.org.genomes/chm13v2.0/chm13v2.0_geneLocations.short.bed.gz",
- "hidden" : true,
- "searchable": true
+ type: "alignment",
+ url: "https://1000genomes.s3.amazonaws.com/phase3/data/NA19625/exome_alignment/NA19625.mapped.ILLUMINA.bwa.ASW.exome.20120522.bam",
+ indexURL: "https://1000genomes.s3.amazonaws.com/phase3/data/NA19625/exome_alignment/NA19625.mapped.ILLUMINA.bwa.ASW.exome.20120522.bam.bai",
+ name: "NA12878n"
}
]
}
}
- igv.createBrowser(document.getElementById('igvDiv'), config)
- .then(browser => {
+ const browser = await igv.createBrowser(document.getElementById('igvDiv'), config)
- })
diff --git a/dev/twobit/twobithg38.html b/dev/twobit/twobithg38.html
index 5baaccb90..85ddca1f3 100644
--- a/dev/twobit/twobithg38.html
+++ b/dev/twobit/twobithg38.html
@@ -24,7 +24,7 @@
"cytobandURL": "http://hgdownload.cse.ucsc.edu/goldenPath/hg38/database/cytoBandIdeo.txt.gz",
"aliasURL": "https://s3.amazonaws.com/igv.broadinstitute.org/annotations/hg38/hg38_alias.tab",
"format": "2bit",
- "twobitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/hg38/bigZips/hg38.2bit",
+ "twoBitURL": "https://hgdownload.soe.ucsc.edu/goldenPath/hg38/bigZips/hg38.2bit",
"aliasBbURL": "https://hgdownload.soe.ucsc.edu/goldenPath/hg38/bigZips/hg38.chromAlias.bb",
"tracks": [
{
diff --git a/dev/ucsc/hub.html b/dev/ucsc/hub.html
index 2f9dd8a65..5cc243574 100644
--- a/dev/ucsc/hub.html
+++ b/dev/ucsc/hub.html
@@ -35,7 +35,7 @@
const hubOptions = {
- url: "https://hgdownload.soe.ucsc.edu/hubs/GCA/009/914/755/GCA_009914755.4/hub.txt",
+ url: "https://hgdownload.soe.ucsc.edu/hubs/GCA/018/471/515/GCA_018471515.1/hub.txt",
includeTracks: "all"
}
@@ -45,6 +45,7 @@
const igvConfig = {
locus: hub.getDefaultPosition(),
+ showChromosomeWidget: false,
reference: ref
}
diff --git a/dev/ucsc/slowHub.html b/dev/ucsc/slowHub.html
index 5857a5530..a74d865d8 100644
--- a/dev/ucsc/slowHub.html
+++ b/dev/ucsc/slowHub.html
@@ -22,21 +22,16 @@
const hub = await Hub.loadHub(hubOptions)
- const ref = hub.getGenomeConfig()
const igvConfig = {
+ showChromosomeWidget: false,
locus: hub.getDefaultPosition(),
- reference: ref
+ reference: hub.getGenomeConfig()
}
- const browser = await igv.createBrowser(document.getElementById('igvDiv'), igvConfig)
+ //igvConfig.reference.chromAliasBbURL = undefined // TODO <- chromAliasBB is slowish
- const selector = document.getElementById("select")
- selector.addEventListener("change", () => document.getElementById("hub-input").value = selector.value)
- document.getElementById("load-genome").addEventListener("click", () =>
- browser.loadGenome({url: document.getElementById("hub-input").value}))
- document.getElementById("load-session").addEventListener("click", () =>
- browser.loadSession({url: document.getElementById("hub-input").value}))
+ const browser = await igv.createBrowser(document.getElementById('igvDiv'), igvConfig)
diff --git a/dev/wig/bigWigs.html b/dev/wig/bigWigs.html
index 6a372da20..18f8c05b2 100644
--- a/dev/wig/bigWigs.html
+++ b/dev/wig/bigWigs.html
@@ -29,17 +29,17 @@
"Bar": 999.999
}
},
- {
- "url": "https://www.encodeproject.org/files/ENCFF754TJH/@@download/ENCFF754TJH.bigWig",
- "graphType": "points",
- "pointSize": 3,
- "name": "Encode bigwig points"
- },
- {
- "url": "https://www.encodeproject.org/files/ENCFF754TJH/@@download/ENCFF754TJH.bigWig",
- "graphType": "line",
- "name": "Encode bigwig line"
- },
+ // {
+ // "url": "https://www.encodeproject.org/files/ENCFF754TJH/@@download/ENCFF754TJH.bigWig",
+ // "graphType": "points",
+ // "pointSize": 3,
+ // "name": "Encode bigwig points"
+ // },
+ // {
+ // "url": "https://www.encodeproject.org/files/ENCFF754TJH/@@download/ENCFF754TJH.bigWig",
+ // "graphType": "line",
+ // "name": "Encode bigwig line"
+ // },
{
"url": "https://s3-us-west-2.amazonaws.com/ilmn.igv-test/test2.bigWig",
color: 'rgb(0,0,255)',
diff --git a/js/bam/bamReader.js b/js/bam/bamReader.js
index 071e1682b..a7be50b96 100644
--- a/js/bam/bamReader.js
+++ b/js/bam/bamReader.js
@@ -1,29 +1,3 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2016-2017 The Regents of the University of California
- * Author: Jim Robinson
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
import {loadIndex} from "./indexFactory.js"
import AlignmentContainer from "./alignmentContainer.js"
import BamUtils from "./bamUtils.js"
@@ -39,6 +13,8 @@ import BGZBlockLoader from "./bgzBlockLoader.js"
*/
class BamReader {
+ chrAliasTable = new Map()
+
constructor(config, genome) {
this.config = config
this.genome = genome
@@ -51,9 +27,7 @@ class BamReader {
async readAlignments(chr, bpStart, bpEnd) {
- const chrToIndex = await this.getChrIndex()
- const queryChr = this.chrAliasTable.hasOwnProperty(chr) ? this.chrAliasTable[chr] : chr
- const chrId = chrToIndex[queryChr]
+ const chrId = await this.#getChrIdx(chr)
const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.config)
if (chrId === undefined) {
@@ -70,7 +44,7 @@ class BamReader {
for (let c of chunks) {
const ba = await this._blockLoader.getData(c.minv, c.maxv)
- const done = BamUtils.decodeBamRecords(ba, c.minv.offset, alignmentContainer, this.indexToChr, chrId, bpStart, bpEnd, this.filter)
+ const done = BamUtils.decodeBamRecords(ba, c.minv.offset, alignmentContainer, this.header.chrNames, chrId, bpStart, bpEnd, this.filter)
if (done) {
break
}
@@ -80,6 +54,42 @@ class BamReader {
}
}
+ async #getChrIdx(chr) {
+
+ await this.getHeader()
+
+ if (this.chrAliasTable.has(chr)) {
+ chr = this.chrAliasTable.get(chr)
+ if (chr === undefined) {
+ return undefined
+ }
+ }
+
+ let chrIdx = this.header.chrToIndex[chr]
+
+ // Try alias
+ if (chrIdx === undefined) {
+ const aliasRecord = await this.genome.getAliasRecord(chr)
+ let alias
+ if (aliasRecord) {
+ const aliases = Object.keys(aliasRecord)
+ .filter(k => k !== "start" && k !== "end")
+ .map(k => aliasRecord[k])
+ .filter(a => this.header.chrToIndex[a])
+ if (aliases.length > 0) {
+ alias = aliases[0]
+ chrIdx = this.header.chrToIndex[aliases[0]]
+ }
+ }
+ this.chrAliasTable.set(chr, alias) // alias may be undefined => no alias exists. Setting prevents repeated attempts
+ }
+ return chrIdx
+ }
+
+ /**
+ *
+ * @returns {Promise<{magicNumer: number, size: number, chrNames: Array, chrToIndex: ({}|*), chrAliasTable: ({}|*)}>}
+ */
async getHeader() {
if (!this.header) {
const genome = this.genome
@@ -102,9 +112,8 @@ class BamReader {
}
async getIndex() {
- const genome = this.genome
if (!this.index) {
- this.index = await loadIndex(this.baiPath, this.config, genome)
+ this.index = await loadIndex(this.baiPath, this.config, this.genome)
}
return this.index
}
@@ -116,7 +125,7 @@ class BamReader {
const header = await this.getHeader()
this.chrToIndex = header.chrToIndex
this.indexToChr = header.chrNames
- this.chrAliasTable = header.chrAliasTable
+ this.chrNames = new Set(header.chrNames)
return this.chrToIndex
}
diff --git a/js/bam/bamReaderNonIndexed.js b/js/bam/bamReaderNonIndexed.js
index f210659e9..1819af123 100644
--- a/js/bam/bamReaderNonIndexed.js
+++ b/js/bam/bamReaderNonIndexed.js
@@ -37,6 +37,8 @@ import {buildOptions, isDataURL} from "../util/igvUtils.js"
*/
class BamReaderNonIndexed {
+ chrAliasTable = new Map()
+
constructor(config, genome) {
this.config = config
this.genome = genome
@@ -45,52 +47,75 @@ class BamReaderNonIndexed {
BamUtils.setReaderDefaults(this, config)
}
- // Return an alignment container
+ /**
+ *
+ * @param chr
+ * @param bpStart
+ * @param bpEnd
+ * @returns {Promise}
+ */
async readAlignments(chr, bpStart, bpEnd) {
- if (this.alignmentCache) {
- const header = this.header
- const queryChr = header.chrAliasTable.hasOwnProperty(chr) ? header.chrAliasTable[chr] : chr
- const qAlignments = this.alignmentCache.queryFeatures(queryChr, bpStart, bpEnd)
- const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.config)
- for (let a of qAlignments) {
- alignmentContainer.push(a)
- }
- alignmentContainer.finish()
- return alignmentContainer
-
- } else {
+ if (!this.alignmentCache) {
+ // For a non-indexed BAM file all alignments are read at once and cached.
+ let unc
if (this.isDataUri) {
const data = decodeDataURI(this.bamPath)
- const unc = BGZip.unbgzf(data.buffer)
- this.parseAlignments(unc)
- return this.fetchAlignments(chr, bpStart, bpEnd)
+ unc = BGZip.unbgzf(data.buffer)
} else {
const arrayBuffer = await igvxhr.loadArrayBuffer(this.bamPath, buildOptions(this.config))
- const unc = BGZip.unbgzf(arrayBuffer)
- this.parseAlignments(unc)
- return this.fetchAlignments(chr, bpStart, bpEnd)
+ unc = BGZip.unbgzf(arrayBuffer)
}
+ this.alignmentCache = this.#parseAlignments(unc)
}
+ const queryChr = await this.#getQueryChr(chr)
+ const qAlignments = this.alignmentCache.queryFeatures(queryChr, bpStart, bpEnd)
+ const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.config)
+ for (let a of qAlignments) {
+ alignmentContainer.push(a)
+ }
+ alignmentContainer.finish()
+ return alignmentContainer
}
- parseAlignments(data) {
+ #parseAlignments(data) {
const alignments = []
this.header = BamUtils.decodeBamHeader(data)
- BamUtils. decodeBamRecords(data, this.header.size, alignments, this.header.chrNames)
- this.alignmentCache = new FeatureCache(alignments, this.genome)
+ BamUtils.decodeBamRecords(data, this.header.size, alignments, this.header.chrNames)
+ return new FeatureCache(alignments, this.genome)
}
- fetchAlignments(chr, bpStart, bpEnd) {
- const queryChr = this.header.chrAliasTable.hasOwnProperty(chr) ? this.header.chrAliasTable[chr] : chr
- const features = this.alignmentCache.queryFeatures(queryChr, bpStart, bpEnd)
- const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.config)
- for (let feature of features) {
- alignmentContainer.push(feature)
+ async #getQueryChr(chr) {
+
+ const ownNames = new Set(this.header.chrNames)
+ if (ownNames.has(chr)) {
+ return chr
}
- alignmentContainer.finish()
- return alignmentContainer
+
+ if (this.chrAliasTable.has(chr)) {
+ return this.chrAliasTable.get(chr)
+ }
+
+ // Try alias
+
+ if (this.genome) {
+ const aliasRecord = await this.genome.getAliasRecord(chr)
+ let alias
+ if (aliasRecord) {
+ const aliases = Object.keys(aliasRecord)
+ .filter(k => k !== "start" && k !== "end")
+ .map(k => aliasRecord[k])
+ .filter(a => ownNames.has(a))
+ if (aliases.length > 0) {
+ alias = aliases[0]
+ }
+ }
+ this.chrAliasTable.set(chr, alias) // alias may be undefined => no alias exists. Setting prevents repeated attempts
+ return alias
+ }
+
+ return chr
}
}
diff --git a/js/bam/bamUtils.js b/js/bam/bamUtils.js
index b847a55cd..5f1faacd4 100644
--- a/js/bam/bamUtils.js
+++ b/js/bam/bamUtils.js
@@ -51,23 +51,11 @@ const MAXIMUM_SAMPLING_DEPTH = 10000
const BamUtils = {
- readHeader: function (url, options, genome) {
-
- return igvxhr.loadArrayBuffer(url, options)
-
- .then(function (compressedBuffer) {
-
- var header, unc, uncba
-
- unc = BGZip.unbgzf(compressedBuffer)
- uncba = unc
-
- header = BamUtils.decodeBamHeader(uncba, genome)
-
- return header
-
- })
+ readHeader: async function (url, options, genome) {
+ const compressedBuffer = await igvxhr.loadArrayBuffer(url, options)
+ const uncba = BGZip.unbgzf(compressedBuffer)
+ return BamUtils.decodeBamHeader(uncba, genome)
},
/**
@@ -97,7 +85,6 @@ const BamUtils = {
chrToIndex = {}
chrNames = []
- chrAliasTable = {}
for (i = 0; i < nRef; ++i) {
var lName = readInt(ba, p)
@@ -111,11 +98,6 @@ const BamUtils = {
chrToIndex[name] = i
chrNames[i] = name
- if (genome) {
- alias = genome.getChromosomeName(name)
- chrAliasTable[alias] = name
- }
-
p = p + 8 + lName
}
@@ -123,8 +105,7 @@ const BamUtils = {
magicNumber: magic,
size: p,
chrNames: chrNames,
- chrToIndex: chrToIndex,
- chrAliasTable: chrAliasTable
+ chrToIndex: chrToIndex
}
},
diff --git a/js/bigwig/bpTree.js b/js/bigwig/bpTree.js
index 50f3dcf04..0d996568d 100644
--- a/js/bigwig/bpTree.js
+++ b/js/bigwig/bpTree.js
@@ -10,6 +10,8 @@ import BinaryParser from "../binary.js"
*/
export default class BPTree {
+ nodeCache = new Map()
+
static async loadBpTree(path, startOffset) {
const bpTree = new BPTree(path, startOffset)
return bpTree.init()
@@ -37,52 +39,89 @@ export default class BPTree {
const {keySize, valSize} = this.header
- if (valSize !== 16) {
- throw Error(`Unexpected valSize: ${valSize}`)
+ if (!(valSize === 16 || valSize === 8)) {
+ throw Error(`Unexpected valSize ${valSize}`)
}
const readTreeNode = async (offset) => {
- let binaryParser = await this.#getParserFor(offset, 4)
- const type = binaryParser.getByte()
- const reserved = binaryParser.getByte()
- const count = binaryParser.getUShort()
+ if (this.nodeCache.has(offset)) {
+ return this.nodeCache.get(offset)
+ } else {
+
+ let binaryParser = await this.#getParserFor(offset, 4)
+ const type = binaryParser.getByte()
+ const reserved = binaryParser.getByte()
+ const count = binaryParser.getUShort()
+ const items = []
+
+ if (type === 1) {
+ // Leaf node
+ const size = count * (keySize + valSize)
+ binaryParser = await this.#getParserFor(offset + 4, size)
+ for (let i = 0; i < count; i++) {
+ const key = binaryParser.getFixedLengthString(keySize)
+ const offset = binaryParser.getLong()
+
+ let value
+ if (valSize === 16) {
+ const length = binaryParser.getInt()
+ binaryParser.getInt()
+ value = {offset, length}
+ } else {
+ value = {offset}
+ }
+ items.push({key, value})
+ }
+ } else {
+ // Non leaf node
+ const size = count * (keySize + 8)
+ binaryParser = await this.#getParserFor(offset + 4, size)
+
+ for (let i = 0; i < count; i++) {
+ const key = binaryParser.getFixedLengthString(keySize)
+ const offset = binaryParser.getLong()
+ items.push({key, offset})
+ }
+ }
+
+ const node = {type, count, items}
+ this.nodeCache.set(offset, node)
+ return node
+ }
+ }
+
+ const walkTreeNode = async (offset) => {
+
+ const node = await readTreeNode(offset)
- if (type === 1) {
+ if (node.type === 1) {
// Leaf node
- const size = count * (keySize + valSize)
- binaryParser = await this.#getParserFor(offset + 4, size)
- for (let i = 0; i < count; i++) {
- const key = binaryParser.getFixedLengthString(keySize)
- const offset = binaryParser.getLong()
- const length = binaryParser.getInt()
- const reserved = binaryParser.getInt()
- const value = {offset, length}
- if (term === key) return value
+ for (let item of node.items) {
+ if (term === item.key) {
+ return item.value
+ }
}
} else {
// Non leaf node
- const size = count * (keySize + 8)
- binaryParser = await this.#getParserFor(offset + 4, size)
// Read and discard the first key.
- const firstKey = binaryParser.getFixedLengthString(keySize)
- let childOffset = binaryParser.getLong()
+ let childOffset = node.items[0].offset
- for (let i = 1; i < count; i++) {
- const key = binaryParser.getFixedLengthString(keySize)
+ for (let i = 1; i < node.items.length; i++) {
+ const key = node.items[i].key
if (term.localeCompare(key) < 0) {
break
}
- childOffset = binaryParser.getLong()
+ childOffset = node.items[i].offset
}
- return readTreeNode(childOffset)
+ return walkTreeNode(childOffset)
}
}
// Kick things off
- return readTreeNode(this.header.nodeOffset)
+ return walkTreeNode(this.header.nodeOffset)
}
async #getParserFor(start, size) {
diff --git a/js/bigwig/bwReader.js b/js/bigwig/bwReader.js
index 594471e50..baa3b01b0 100644
--- a/js/bigwig/bwReader.js
+++ b/js/bigwig/bwReader.js
@@ -45,11 +45,13 @@ const BUFFER_SIZE = 512000 // buffer
class BWReader {
+ chrAliasTable = new Map()
+ rpTreeCache = new Map()
+
constructor(config, genome) {
this.path = config.url
this.format = config.format || "bigwig"
this.genome = genome
- this.rpTreeCache = {}
this.config = config
this.bufferSize = BUFFER_SIZE
this.loader = isDataURL(this.path) ?
@@ -74,9 +76,14 @@ class BWReader {
async readFeatures(chr1, bpStart, chr2, bpEnd, bpPerPixel, windowFunction = "mean") {
+ if (!bpStart) bpStart = 0
+ if (!bpEnd) bpEnd = Number.MAX_SAFE_INTEGER
+
await this.loadHeader()
- const chrIdx1 = this.chromTree.nameToId[chr1]
- const chrIdx2 = this.chromTree.nameToId[chr2]
+
+ let chrIdx1 = await this.#getIdForChr(chr1)
+ let chrIdx2 = await this.#getIdForChr(chr2)
+
if (chrIdx1 === undefined || chrIdx2 === undefined) {
return []
}
@@ -153,6 +160,42 @@ class BWReader {
}
}
+ /**
+ * Return the ID for the given chromosome name. If there is no direct match, search for a chromosome alias.
+ *
+ * @param chr
+ * @returns {Promise<*>}
+ */
+ async #getIdForChr(chr) {
+
+ if (this.chrAliasTable.has(chr)) {
+ chr = this.chrAliasTable.get(chr)
+ if (chr === undefined) {
+ return undefined
+ }
+ }
+
+ let chrIdx = this.chromTree.nameToId.get(chr)
+
+ // Try alias
+ if (chrIdx === undefined) {
+ const aliasRecord = await this.genome.getAliasRecord(chr)
+ let alias
+ if (aliasRecord) {
+ const aliases = Object.keys(aliasRecord)
+ .filter(k => k !== "start" && k !== "end")
+ .map(k => aliasRecord[k])
+ .filter(a => this.chromTree.nameToId.has(a))
+ if (aliases.length > 0) {
+ alias = aliases[0]
+ chrIdx = this.chromTree.nameToId.get(aliases[0])
+ }
+ }
+ this.chrAliasTable.set(chr, alias) // alias may be undefined => no alias exists. Setting prevents repeated attempts
+ }
+ return chrIdx
+ }
+
/**
* Potentially searchable if a bigbed source. Bigwig files are not searchable.
@@ -205,28 +248,23 @@ class BWReader {
async _searchForRegions(term) {
const searchTrees = await this.#getSearchTrees()
if (searchTrees) {
- // First try search term as entered. For now take the first one, we don't support multiple results
+
+ // Use a trix index if we have one to map entered term to indexed value in bb file
+ if (this._trix) {
+ const termLower = term.toLowerCase()
+ const trixResults = await this._trix.search(termLower)
+ if (trixResults && trixResults.has(termLower)) { // <= exact matches only for now
+ term = trixResults.get(termLower)[0]
+ }
+ }
+
+ // For now take the first match, we don't support multiple results
for (let bpTree of searchTrees) {
const result = await bpTree.search(term)
if (result) {
return result
}
}
-
- // If no term use a trix index if we have one to map entered term to indexed value in bb file
- if (this._trix) {
- term = term.toLowerCase()
- const trixResults = await this._trix.search(term)
- if (trixResults && trixResults.has(term)) { // <= exact matches only for now
- const term2 = trixResults.get(term)[0]
- for (let bpTree of searchTrees) {
- const result = await bpTree.search(term2)
- if (result) {
- return result
- }
- }
- }
- }
}
}
@@ -346,6 +384,7 @@ class BWReader {
if (header.chromTreeOffset > 0) {
binaryParser.position = header.chromTreeOffset - startOffset
this.chromTree = await ChromTree.parseTree(binaryParser, startOffset, this.genome)
+ this.chrNames = new Set(this.chromTree.idToName)
} else {
// TODO -- this is an error, not expected
throw "BigWig chromosome tree offset <= 0"
@@ -382,7 +421,7 @@ class BWReader {
const extensionSize = binaryParser.getUShort()
const extraIndexCount = binaryParser.getUShort()
const extraIndexListOffset = binaryParser.getLong()
- if(extraIndexCount === 0) return
+ if (extraIndexCount === 0) return
let sz = extraIndexCount * (2 + 2 + 8 + 4 + 10 * (2 + 2))
data = await this.loader.loadArrayBuffer(this.path, buildOptions(this.config, {
@@ -409,6 +448,10 @@ class BWReader {
for (let j = 0; j < fc; j++) {
const fieldId = binaryParser.getUShort()
+
+ //const field = this.autoSql.fields[fieldId]
+ //console.log(field)
+
reserved.push(binaryParser.getUShort())
}
}
@@ -418,13 +461,13 @@ class BWReader {
async loadRPTree(offset) {
- let rpTree = this.rpTreeCache[offset]
+ let rpTree = this.rpTreeCache.get(offset)
if (rpTree) {
return rpTree
} else {
rpTree = new RPTree(offset, this.config, this.littleEndian, this.loader)
await rpTree.load()
- this.rpTreeCache[offset] = rpTree
+ this.rpTreeCache.set(offset, rpTree)
return rpTree
}
}
@@ -447,10 +490,11 @@ class BWReader {
if (this.type === "bigwig") {
this.visibilityWindow = -1
} else {
- // bigbed
- let genomeSize = this.genome ? this.genome.getGenomeLength() : 3088286401
+ this.visibilityWindow = -1
+ // bigbed -- todo, we can't know genome length.
+ //let genomeSize = this.genome ? this.genome.getGenomeLength() : 3088286401
// Estimate window size to return ~ 1,000 features, assuming even distribution across the genome
- this.visibilityWindow = header.dataCount < 1000 ? -1 : 1000 * (genomeSize / header.dataCount)
+ //this.visibilityWindow = header.dataCount < 1000 ? -1 : 1000 * (genomeSize / header.dataCount)
}
}
diff --git a/js/bigwig/chromTree.js b/js/bigwig/chromTree.js
index 79a1e33b8..2bf7f05a4 100644
--- a/js/bigwig/chromTree.js
+++ b/js/bigwig/chromTree.js
@@ -27,7 +27,7 @@ export default class ChromTree {
const reserved = binaryParser.getLong()
const header = {magic, blockSize, keySize, valSize, itemCount, reserved}
- const nameToId = {}
+ const nameToId = new Map()
const idToName = []
const readTreeNode = (offset) => {
@@ -45,7 +45,7 @@ export default class ChromTree {
value = binaryParser.getInt()
const chromSize = binaryParser.getInt()
if (genome) key = genome.getChromosomeName(key) // Translate to canonical chr name
- nameToId[key] = value
+ nameToId.set(key, value)
idToName[value] = key
} else {
diff --git a/js/bigwig/trix.js b/js/bigwig/trix.js
index 1360bd656..8129bf4ef 100644
--- a/js/bigwig/trix.js
+++ b/js/bigwig/trix.js
@@ -8,6 +8,7 @@
import {igvxhr} from "../../node_modules/igv-utils/src/index.js"
+
// this is the number of hex characters to use for the address in ixixx, see
// https://github.com/GMOD/ixixx-js/blob/master/src/index.ts#L182
const ADDRESS_SIZE = 10
@@ -16,7 +17,7 @@ export default class Trix {
ixFile // URL to the ix file
ixxFile // URL to the ixx file
- ixBuffer // Buffer for the ix file contents -- we read it once, they aren't very large
+ bufferCache = new Map()
constructor(ixxFile, ixFile) {
this.ixFile = ixFile
@@ -50,6 +51,7 @@ export default class Trix {
const match = word.startsWith(searchWord)
if (match) {
matches.push(line)
+ console.log("match " + line)
}
// we are done scanning if we are lexicographically greater than the search string
if (word.slice(0, searchWord.length) > searchWord) {
@@ -65,6 +67,7 @@ export default class Trix {
const [term, ...parts] = m.split(' ')
results.set(term, parts.map(p => p.split(',')[0]))
}
+ console.log(results)
return results
}
}
@@ -94,10 +97,6 @@ export default class Trix {
async _getBuffer(searchWord, opts) {
- if (!this.ixBuffer) {
- this.ixBuffer = await igvxhr.loadString(this.ixFile)
- }
-
let start = 0
let end = 65536
const indexes = await this.getIndex(opts)
@@ -116,6 +115,13 @@ export default class Trix {
return undefined
}
- return this.ixBuffer.slice(start, start + len)
+ if(this.bufferCache.has(start)) {
+ return this.bufferCache.get(start)
+ } else {
+ const buffer = igvxhr.loadString(this.ixFile, {range: {start, size: len}})
+ this.bufferCache.set(start, buffer)
+ return buffer
+ }
+
}
}
diff --git a/js/browser.js b/js/browser.js
index 60fa217eb..637794097 100755
--- a/js/browser.js
+++ b/js/browser.js
@@ -54,6 +54,8 @@ import {translateSession} from "./hic/shoeboxUtils.js"
import Hub from "./ucsc/ucscHub.js"
import MultiTrackSelectButton from "./ui/multiTrackSelectButton.js"
import MenuUtils from "./ui/menuUtils.js"
+import Genome from "./genome/genome.js"
+import {setDefaults} from "./igv-create.js"
// css - $igv-scrollbar-outer-width: 14px;
const igv_scrollbar_outer_width = 14
@@ -81,8 +83,6 @@ class Browser {
this.root = DOMUtils.div({class: 'igv-container'})
parentDiv.appendChild(this.root)
-
-
// spinner
this.spinner = DOMUtils.div({class: 'igv-loading-spinner-container'})
this.root.appendChild(this.spinner)
@@ -234,10 +234,7 @@ class Browser {
// chromosome select widget
this.chromosomeSelectWidget = new ChromosomeSelectWidget(this, $genomicLocation.get(0))
- if (undefined === config.showChromosomeWidget) {
- config.showChromosomeWidget = true // Default to true
- }
- if (true === config.showChromosomeWidget) {
+ if (config.showChromosomeWidget !== false) {
this.chromosomeSelectWidget.show()
} else {
this.chromosomeSelectWidget.hide()
@@ -458,6 +455,9 @@ class Browser {
*/
async loadSession(options) {
+ // UCSC hub hack
+ const chromosomeSelectWidget = this.chromosomeSelectWidget
+
this.sampleInfo.initialize()
// TODO: deprecated
@@ -494,12 +494,17 @@ class Browser {
} else if (filename.endsWith("hub.txt")) {
const hub = await Hub.loadHub(options)
+ if(chromosomeSelectWidget) {
+ chromosomeSelectWidget.hide()
+ }
const genomeConfig = hub.getGenomeConfig(options.includeTracks)
const initialLocus = hub.getDefaultPosition()
- return {
+ const config = {
+ showChromosomeWidget: false,
locus: initialLocus,
reference: genomeConfig
}
+ return setDefaults(config)
} else if (filename.endsWith(".json")) {
return igvxhr.loadJson(urlOrFile)
} else {
@@ -519,6 +524,7 @@ class Browser {
// prepare to load a new session, discarding DOM and state
this.cleanHouseForSession()
+ this.config = session
// Check for juicebox session
if (session.browsers) {
@@ -557,7 +563,9 @@ class Browser {
console.warn("No genome or reference object specified")
return
}
- const genomeConfig = await GenomeUtils.expandReference(this.alert, genomeOrReference)
+ const genomeConfig = StringUtils.isString(genomeOrReference) ?
+ await GenomeUtils.expandReference(this.alert, genomeOrReference) :
+ genomeOrReference
await this.loadReference(genomeConfig, session.locus)
@@ -683,7 +691,7 @@ class Browser {
*/
async loadReference(genomeConfig, initialLocus) {
- const genome = await GenomeUtils.loadGenome(genomeConfig)
+ const genome = await Genome.loadGenome(genomeConfig)
const genomeChange = undefined === this.genome || (this.genome.id !== genome.id)
@@ -739,7 +747,9 @@ class Browser {
let genomeLabel = (genome.id && genome.id.length < 20 ? genome.id : `${genome.id.substring(0,8)}...${genome.id.substring(genome.id.length-8)}`)
this.$current_genome.text(genomeLabel)
this.$current_genome.attr('title', genome.description)
- this.chromosomeSelectWidget.update(genome)
+ if(this.config.showChromosomeWidget !== false) {
+ this.chromosomeSelectWidget.update(genome)
+ }
}
/**
@@ -756,7 +766,7 @@ class Browser {
const hub = await Hub.loadHub(idOrConfig)
genomeConfig = hub.getGenomeConfig("genes")
} else {
- genomeConfig = await GenomeUtils.expandReference(this.alert, idOrConfig)
+ genomeConfig = idOrConfig //await GenomeUtils.expandReference(this.alert, idOrConfig)
}
await this.loadReference(genomeConfig, undefined)
@@ -1454,8 +1464,11 @@ class Browser {
this.chromosomeSelectWidget.select.value = referenceFrameList.length === 1 ? this.referenceFrameList[0].chr : ''
+
+
const loc = this.referenceFrameList.map(rf => rf.getLocusString()).join(' ')
- //const loc = this.referenceFrameList.length === 1 ? this.referenceFrameList[0].getLocusString() : '';
+
+
this.$searchInput.val(loc)
this.fireEvent('locuschange', [this.referenceFrameList])
@@ -2282,16 +2295,5 @@ function toggleTrackLabels(trackViews, isVisible) {
}
}
-async function searchWebService(browser, locus, searchConfig) {
-
- let path = searchConfig.url.replace("$FEATURE$", locus.toUpperCase())
- if (path.indexOf("$GENOME$") > -1) {
- path = path.replace("$GENOME$", (browser.genome.id ? browser.genome.id : "hg19"))
- }
- const result = await igvxhr.loadString(path)
- return {result: result, locusSearchString: locus}
-}
-
-export {searchWebService}
export default Browser
diff --git a/js/cram/cramReader.js b/js/cram/cramReader.js
index 5abddeee1..9e9e7ad86 100644
--- a/js/cram/cramReader.js
+++ b/js/cram/cramReader.js
@@ -1,28 +1,3 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2018 The Regents of the University of California
- * Author: Jim Robinson
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
import gmodCRAM from "../vendor/cram-bundle.js"
import AlignmentContainer from "../bam/alignmentContainer.js"
@@ -46,6 +21,7 @@ const CRAM_MATE_MAPPED_FLAG = 0x2
*/
class CramReader {
+ chrAliasTable = new Map()
constructor(config, genome, browser) {
this.config = config
@@ -69,35 +45,26 @@ class CramReader {
BamUtils.setReaderDefaults(this, config)
- function seqFetch(seqID, start, end) {
-
+ async function seqFetch(seqID, start, end) {
const sequence = this.genome.sequence
const genome = this.genome
-
- return this.getHeader()
- .then(function (header) {
- const chr = genome.getChromosomeName(header.chrNames[seqID])
- return sequence.getSequence(chr, start - 1, end)
- })
+ const header = await this.getHeader()
+ const chr = genome.getChromosomeName(header.indexToChr[seqID])
+ return sequence.getSequence(chr, start - 1, end)
}
}
/**
- * Parse the sequence dictionary from the SAM header and build chr name tables. This function
- * is public so it can be unit tested.
- *
- * @returns {PromiseLike}
+ * Parse the sequence dictionary from the SAM header and build chr name tables.
*/
async getHeader() {
if (!this.header) {
- const genome = this.genome
const samHeader = await this.cramFile.getSamHeader()
const chrToIndex = {}
- const chrNames = []
- const chrAliasTable = {}
+ const indexToChr = []
const readGroups = []
for (let line of samHeader) {
@@ -105,12 +72,8 @@ class CramReader {
for (let d of line.data) {
if (d.tag === "SN") {
const seq = d.value
- chrToIndex[seq] = chrNames.length
- chrNames.push(seq)
- if (genome) {
- const alias = genome.getChromosomeName(seq)
- chrAliasTable[alias] = seq
- }
+ chrToIndex[seq] = indexToChr.length
+ indexToChr.push(seq)
break
}
}
@@ -120,10 +83,11 @@ class CramReader {
}
this.header = {
- chrNames: chrNames,
+ indexToChr: indexToChr,
chrToIndex: chrToIndex,
- chrAliasTable: chrAliasTable,
+ chrNames: new Set(header.chrToIndex),
readGroups: readGroups
+
}
}
@@ -132,7 +96,18 @@ class CramReader {
async readAlignments(chr, bpStart, bpEnd) {
- const browser = this.browser
+ if (!this.chrAliasTable.has(chr)) {
+ const chromosome = this.genome.getChromosome(chr)
+ if (chromosome) {
+ const aliases = chromosome.altNames
+ for (let a of aliases) {
+ if (this.chrNames.has(a)) {
+ this.chrAliasTable.set(chr, a)
+ }
+ }
+ }
+ }
+
const header = await this.getHeader()
const queryChr = header.chrAliasTable.hasOwnProperty(chr) ? header.chrAliasTable[chr] : chr
const chrIdx = header.chrToIndex[queryChr]
diff --git a/js/genome/bpt.js b/js/genome/bpt.js
new file mode 100644
index 000000000..e793f62f8
--- /dev/null
+++ b/js/genome/bpt.js
@@ -0,0 +1,195 @@
+/* bptFile - B+ Trees. These are a method of indexing data similar to binary trees, but
+ * with many children rather than just two at each node. They work well when stored on disk,
+ * since typically only two or three disk accesses are needed to locate any particular
+ * piece of data. This implementation is *just* for disk based storage. For memory
+ * use the rbTree instead. Currently the implementation is just useful for data warehouse
+ * type applications. That is it implements a function to create a b+ tree from bulk data
+ * (bptFileCreate) and a function to lookup a value given a key (bptFileFind) but not functions
+ * to add or delete individual items.
+ *
+ * The layout of the file on disk is:
+ * header
+ * root node
+ * (other nodes)
+ * In general when the tree is first built the higher level nodes are stored before the
+ * lower level nodes. It is possible if a b+ tree is dynamically updated for this to
+ * no longer be strictly true, but actually currently the b+ tree code here doesn't implement
+ * dynamic updates - it just creates a b+ tree from a sorted list.
+ *
+ * Each node can be one of two types - index or leaf. The index nodes contain pointers
+ * to child nodes. The leaf nodes contain the actual data.
+ *
+ * The layout of the file header is:
+ * 4 bytes - The value bptSig (0x78CA8C91)
+ * 4 bytes - Number of children per block (not byte size of block)
+ * 4 bytes - Number of significant bytes in key
+ * 4 bytes - Number of bytes in value
+ * - 8 bytes - Number of items in index
+ * 4 bytes - Always 0 for now
+ * 4 bytes - Always 0 for now
+ * The magic number may be byte-swapped, in which case all numbers in the file
+ * need to be byte-swapped.
+ *
+ * The nodes start with a header:
+ * 1 byte - 1 for leaf nodes, 0 for index nodes.
+ * 1 byte - Always 0 for now.
+ * 2 bytes - The number of children/items in node
+ * This is followed by count items. For the index nodes the items are
+ * key size bytes - always written most significant byte first
+ * 8 bytes - Offset of child node in index file.
+ * For leaf nodes the items are
+ * key size bytes - always written most significant byte first
+ * val sized bytes - the value associated with the key.
+ * Note in general the leaf nodes may not be the same size as the index nodes, though in
+ * the important case where the values are file offsets they will be.
+ */
+
+
+// static void twoBitSeekTo(struct twoBitFile *tbf, char *name)
+// /* Seek to start of named record. Abort if can't find it. */
+// {
+// if (tbf->bpt)
+// {
+// bits32 offset;
+// if (!bptFileFind(tbf->bpt, name, strlen(name), &offset, sizeof(offset)))
+// errAbort("%s is not in %s", name, tbf->bpt->fileName);
+// fseek(tbf->f, offset, SEEK_SET);
+// }
+// else
+// {
+// struct twoBitIndex *index = hashFindVal(tbf->hash, name);
+// if (index == NULL)
+// errAbort("%s is not in %s", name, tbf->fileName);
+// fseek(tbf->f, index->offset, SEEK_SET);
+// }
+// }
+
+// struct twoBitFile *twoBitOpenExternalBptIndex(char *twoBitName, char *bptName)
+// /* Open file, read in header, but not regular index. Instead use
+// * bpt index. Beware if you use this the indexList field will be NULL
+// * as will the hash. */
+// {
+// struct twoBitFile *tbf = twoBitOpenReadHeader(twoBitName);
+// tbf->bpt = bptFileOpen(bptName);
+// if (tbf->seqCount != tbf->bpt->itemCount)
+// errAbort("%s and %s don't have same number of sequences!", twoBitName, bptName);
+// return tbf;
+// }
+
+
+// static boolean rFind(struct bptFile *bpt, bits64 blockStart, void *key, void *val)
+// /* Find value corresponding to key. If found copy value to memory pointed to by val and return
+// * true. Otherwise return false. */
+// {
+// /* Seek to start of block. */
+// udcSeek(bpt->udc, blockStart);
+//
+// /* Read block header. */
+// UBYTE isLeaf;
+// UBYTE reserved;
+// bits16 i, childCount;
+// udcMustReadOne(bpt->udc, isLeaf);
+// udcMustReadOne(bpt->udc, reserved);
+// boolean isSwapped = bpt->isSwapped;
+// childCount = udcReadBits16(bpt->udc, isSwapped);
+//
+// UBYTE keyBuf[bpt->keySize]; /* Place to put a key, buffered on stack. */
+//
+// if (isLeaf)
+// {
+// for (i=0; iudc, keyBuf, bpt->keySize);
+// udcMustRead(bpt->udc, val, bpt->valSize);
+// if (memcmp(key, keyBuf, bpt->keySize) == 0)
+// return TRUE;
+// }
+// return FALSE;
+// }
+// else
+// {
+// /* Read and discard first key. */
+// udcMustRead(bpt->udc, keyBuf, bpt->keySize);
+//
+// /* Scan info for first file offset. */
+// bits64 fileOffset = udcReadBits64(bpt->udc, isSwapped);
+//
+// /* Loop through remainder. */
+// for (i=1; iudc, keyBuf, bpt->keySize);
+// if (memcmp(key, keyBuf, bpt->keySize) < 0)
+// break;
+// fileOffset = udcReadBits64(bpt->udc, isSwapped);
+// }
+// return rFind(bpt, fileOffset, key, val);
+// }
+// }
+
+// boolean bptFileFind(struct bptFile *bpt, void *key, int keySize, void *val, int valSize)
+// /* Find value associated with key. Return TRUE if it's found.
+// * Parameters:
+// * bpt - file handle returned by bptFileOpen
+// * key - pointer to key string, which needs to be bpt->keySize long
+// * val - pointer to where to put retrieved value
+// */
+// {
+// /* Check key size vs. file key size, and act appropriately. If need be copy key to a local
+// * buffer and zero-extend it. */
+// if (keySize > bpt->keySize)
+// return FALSE;
+// char keyBuf[keySize];
+// if (keySize != bpt->keySize)
+// {
+// memcpy(keyBuf, key, keySize);
+// memset(keyBuf+keySize, 0, bpt->keySize - keySize);
+// key = keyBuf;
+// }
+//
+// /* Make sure the valSize matches what's in file. */
+// if (valSize != bpt->valSize)
+// errAbort("Value size mismatch between bptFileFind (valSize=%d) and %s (valSize=%d)",
+// valSize, bpt->fileName, bpt->valSize);
+//
+// /* Call recursive finder. */
+// return rFind(bpt, bpt->rootOffset, key, val);
+// }
+
+
+// struct bptFile *bptFileAttach(char *fileName, struct udcFile *udc)
+// /* Open up index file on previously open file, with header at current file position. */
+// {
+// /* Open file and allocate structure to hold info from header etc. */
+// struct bptFile *bpt = needMem(sizeof(*bpt));
+// bpt->fileName = fileName;
+// bpt->udc = udc;
+//
+// /* Read magic number at head of file and use it to see if we are proper file type, and
+// * see if we are byte-swapped. */
+// bits32 magic;
+// boolean isSwapped = FALSE;
+// udcMustReadOne(udc, magic);
+// if (magic != bptSig)
+// {
+// magic = byteSwap32(magic);
+// isSwapped = bpt->isSwapped = TRUE;
+// if (magic != bptSig)
+// errAbort("%s is not a bpt b-plus tree index file", fileName);
+// }
+//
+// /* Read rest of defined bits of header, byte swapping as needed. */
+// bpt->blockSize = udcReadBits32(udc, isSwapped);
+// bpt->keySize = udcReadBits32(udc, isSwapped);
+// bpt->valSize = udcReadBits32(udc, isSwapped);
+// bpt->itemCount = udcReadBits64(udc, isSwapped);
+//
+// /* Skip over reserved bits of header. */
+// bits32 reserved32;
+// udcMustReadOne(udc, reserved32);
+// udcMustReadOne(udc, reserved32);
+//
+// /* Save position of root block of b+ tree. */
+// bpt->rootOffset = udcTell(udc);
+//
+// return bpt;
+// }
\ No newline at end of file
diff --git a/js/genome/cachedSequence.js b/js/genome/cachedSequence.js
index b39eb5b1d..b022bad29 100644
--- a/js/genome/cachedSequence.js
+++ b/js/genome/cachedSequence.js
@@ -10,6 +10,16 @@ class CachedSequence {
this.sequenceReader = sequenceReader
}
+ get hasChromosomes() {
+ return this.sequenceReader.hasChromosomes
+ }
+ get chromosomes() {
+ return this.sequenceReader.chromosomes
+ }
+ async getSequenceRecord(chr) {
+ return this.sequenceReader.getSequenceRecord(chr)
+ }
+
async getSequence(chr, start, end) {
const hasCachedSquence = this.interval && this.interval.contains(chr, start, end)
@@ -40,14 +50,13 @@ class CachedSequence {
return this.sequenceReader.init()
}
- get chromosomes() {
- return this.sequenceReader.chromosomes
- }
-
get chromosomeNames() {
return this.sequenceReader.chromosomeNames
}
+ getFirstChromosomeName() {
+ return typeof this.sequenceReader.getFirstChromosomeName === 'function' ? this.sequenceReader.getFirstChromosomeName() : undefined
+ }
}
export default CachedSequence
diff --git a/js/genome/chromAliasBB.js b/js/genome/chromAliasBB.js
new file mode 100644
index 000000000..d3ff4cce6
--- /dev/null
+++ b/js/genome/chromAliasBB.js
@@ -0,0 +1,67 @@
+/**
+ * Represenets a UCSC bigbed alias file
+ *
+ *
+ * @param aliasURL
+ * @param config
+ * @returns {Promise<*[]>}
+ */
+import {isNumber, buildOptions} from "../util/igvUtils.js"
+import {igvxhr, StringUtils} from "../../node_modules/igv-utils/src/index.js"
+import BWSource from "../bigwig/bwSource.js"
+import BWReader from "../bigwig/bwReader.js"
+
+class ChromAliasBB {
+
+ aliasRecordCache = new Map()
+
+ constructor(url, config, genome) {
+ config = config || {}
+ config.url = url
+ this.reader = new BWReader(config, genome)
+ }
+
+ /**
+ * Return the canonical chromosome name for the alias. If none found return the alias
+ *
+ * @param alias
+ * @returns {*}
+ */
+ getChromosomeName(alias) {
+ return this.aliasRecordCache.has(alias) ? this.aliasRecordCache.get(alias).chr : alias
+ }
+
+ /**
+ * Return an alternate chromosome name (alias). If not exists, return chr
+ * @param chr
+ * @param nameSet -- The name set, e.g. "ucsc"
+ * @returns {*|undefined}
+ */
+ getChromosomeAlias(chr, nameSet)
+ {
+ const aliasRecord = this.aliasRecordCache.get(chr)
+ return aliasRecord ? aliasRecord[nameSet] || chr : chr
+ }
+
+ /**
+ * Search for chromosome alias bed record. If found, catch results in the alias -> chr map
+ * @param alias
+ * @returns {Promise}
+ */
+ async search(alias) {
+ if (!this.aliasRecordCache.has(alias)) {
+ const aliasRecord = await this.reader.search(alias)
+ if (aliasRecord) {
+ for (let key of Object.keys(aliasRecord)) {
+ if ("start" !== key && "end" !== key) {
+ this.aliasRecordCache.set(aliasRecord[key], aliasRecord)
+ }
+ }
+ }
+ }
+ return this.aliasRecordCache.get(alias)
+ }
+
+}
+
+export default ChromAliasBB
diff --git a/js/genome/chromAliasFile.js b/js/genome/chromAliasFile.js
new file mode 100644
index 000000000..fdb7ef49b
--- /dev/null
+++ b/js/genome/chromAliasFile.js
@@ -0,0 +1,77 @@
+/**
+ * Represenets a UCSC tab-delimited Alias file
+ *
+ * example - header line is optional but reccomended, required to support altName setting for genome
+ * # refseq assembly genbank ncbi ucsc
+ * NC_048407.1 chr01 CM023106.1 1 chr1
+ *
+ * @param aliasURL
+ * @param config
+ * @returns {Promise<*[]>}
+ */
+import {isNumber, buildOptions} from "../util/igvUtils.js"
+import {igvxhr, StringUtils} from "../../node_modules/igv-utils/src/index.js"
+
+class ChromAliasFile {
+
+ aliasRecordCache = new Map()
+
+ constructor(aliasURL, config, genome) {
+ this.aliasURL = aliasURL
+ this.config = config
+ this.genome = genome
+ }
+
+ /**
+ * Return the canonical chromosome name for the alias. If none found return the alias
+ *
+ * @param alias
+ * @returns {*}
+ */
+ getChromosomeName(alias) {
+ return this.aliasRecordCache.has(alias) ? this.aliasRecordCache.get(alias).chr : alias
+ }
+
+
+ async loadAliases() {
+
+ const data = await igvxhr.loadString(this.aliasURL, buildOptions(this.config))
+ const lines = StringUtils.splitLines(data)
+ const firstLine = lines[0]
+ if (firstLine.startsWith("#")) {
+ this.headings = firstLine.split("\t").map(h => h.trim())
+ this.altNameSets = this.headings.slice(1)
+ }
+
+ const chromosomeNameSet = this.genome.chromosomes ?
+ new Set(this.genome.chromosomes.keys()) : new Set()
+
+ for (let line of lines) {
+ if (!line.startsWith("#") && line.length > 0) {
+ const tokens = line.split("\t")
+
+ let chr = tokens.find(t => chromosomeNameSet.has(t))
+ if(!chr) {
+ chr = tokens[0]
+ }
+
+ const aliasRecord = {chr}
+ for (let i = 0; i < tokens.length; i++) {
+ const key = this.headings ? this.headings[i] : i
+ aliasRecord[key] = tokens[i]
+ this.aliasRecordCache.set(tokens[i], aliasRecord)
+ }
+ }
+ }
+ }
+
+ async search(alias) {
+ if(this.aliasRecordCache.size === 0) {
+ await this.loadAliases()
+ }
+ return this.aliasRecordCache.get(alias)
+
+ }
+}
+
+export default ChromAliasFile
diff --git a/js/genome/chromSizes.js b/js/genome/chromSizes.js
index 320a9bf1d..e95b4df4d 100644
--- a/js/genome/chromSizes.js
+++ b/js/genome/chromSizes.js
@@ -1,29 +1,3 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2014 Broad Institute
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-// Indexed fasta files
import {BGZip, igvxhr, StringUtils} from "../../node_modules/igv-utils/src/index.js"
import Chromosome from "./chromosome.js"
import {isDataURL} from "../util/igvUtils.js"
@@ -48,6 +22,14 @@ class ChromSizes {
return this.loadAll()
}
+ get hasChromosomes() {
+ return true
+ }
+
+ getSequenceRecord(chr) {
+ return this.chromosomes.get(chr)
+ }
+
get chromosomeNames() {
if(!this.#chromosomeNames) {
this.#chromosomeNames = Array.from(this.chromosomes.keys())
diff --git a/js/genome/cytoband.js b/js/genome/cytoband.js
index 0ab9cd1b1..9eb008022 100644
--- a/js/genome/cytoband.js
+++ b/js/genome/cytoband.js
@@ -22,18 +22,18 @@ class Cytoband {
}
}
-async function loadCytobands(cytobandUrl, config) {
+async function loadCytobands(cytobandURL, config) {
let data
- if (isDataURL(cytobandUrl)) {
- const plain = BGZip.decodeDataURI(cytobandUrl)
+ if (isDataURL(cytobandURL)) {
+ const plain = BGZip.decodeDataURI(cytobandURL)
data = ""
const len = plain.length
for (let i = 0; i < len; i++) {
data += String.fromCharCode(plain[i])
}
} else {
- data = await igvxhr.loadString(cytobandUrl, buildOptions(config))
+ data = await igvxhr.loadString(cytobandURL, buildOptions(config))
}
const cytobands = {}
@@ -118,4 +118,4 @@ async function loadCytobandsBB(url, config) {
return {chromosomes, cytobands}
}
-export {Cytoband, loadCytobands, loadCytobandsBB}
+export {Cytoband}
diff --git a/js/genome/cytobandFile.js b/js/genome/cytobandFile.js
new file mode 100644
index 000000000..8bec39c34
--- /dev/null
+++ b/js/genome/cytobandFile.js
@@ -0,0 +1,77 @@
+import {buildOptions, isDataURL} from "../util/igvUtils.js"
+import {BGZip, igvxhr, StringUtils} from "../../node_modules/igv-utils/src/index.js"
+import {Cytoband} from "./cytoband.js"
+
+class CytobandFile {
+
+ cytobands = new Map()
+
+ constructor(url, config) {
+ this.url = url;
+ this.config = config;
+ }
+
+ async getCytobands(chr) {
+ if(this.cytobands.size === 0) {
+ await this.#loadCytobands()
+ }
+ return this.cytobands.get(chr)
+ }
+
+
+ /**
+ * Load a UCSC bigbed cytoband file. Features are in bed+4 format.
+ * {
+ * "chr": "chr1",
+ * "start": 0,
+ * "end": 1735965,
+ * "name": "p36.33",
+ * "gieStain": "gneg"
+ * }
+ * @returns {Promise<*[]>}
+ */
+ async #loadCytobands() {
+
+ let data
+ if (isDataURL(this.url)) {
+ const plain = BGZip.decodeDataURI(this.url)
+ data = ""
+ const len = plain.length
+ for (let i = 0; i < len; i++) {
+ data += String.fromCharCode(plain[i])
+ }
+ } else {
+ data = await igvxhr.loadString(this.url, buildOptions(this.config))
+ }
+
+ let lastChr
+ let bands = []
+ const lines = StringUtils.splitLines(data)
+ for (let line of lines) {
+
+ const tokens = line.split("\t")
+ const chrName = tokens[0] //genome.getChromosomeName(tokens[0]) // Note allowance for alias name, not sure why this is needed here
+ if (!lastChr) lastChr = chrName
+
+ if (chrName !== lastChr) {
+ this.cytobands.set(lastChr, bands)
+ bands = []
+ lastChr = chrName
+ }
+
+ if (tokens.length === 5) {
+ //10 0 3000000 p15.3 gneg
+ var start = parseInt(tokens[1])
+ var end = parseInt(tokens[2])
+ var name = tokens[3]
+ var stain = tokens[4]
+ bands.push(new Cytoband(start, end, name, stain))
+ }
+ }
+
+ }
+
+}
+
+export default CytobandFile
+
diff --git a/js/genome/cytobandFileBB.js b/js/genome/cytobandFileBB.js
new file mode 100644
index 000000000..6de6c5de1
--- /dev/null
+++ b/js/genome/cytobandFileBB.js
@@ -0,0 +1,32 @@
+import {Cytoband} from "./cytoband.js"
+import BWSource from "../bigwig/bwSource.js"
+
+class CytobandFileBB {
+
+ cytobandMap = new Map()
+
+ constructor(url, config, genome) {
+ config = config || {}
+ config.url = url
+ this.source = new BWSource(config, genome)
+ }
+
+ async getCytobands(chr) {
+
+ if (this.cytobandMap.has(chr)) {
+ return this.cytobandMap.get(chr)
+ } else {
+ let cytobands = await this.#readCytobands(chr)
+ if (!cytobands) cytobands = [] // Prevent loading again
+ this.cytobandMap.set(chr, cytobands)
+ return cytobands
+ }
+ }
+
+ async #readCytobands(chr) {
+ const features = await this.source.getFeatures({chr})
+ return features.map(f => new Cytoband(f.start, f.end, f.name, f.gieStain))
+ }
+}
+
+export default CytobandFileBB
\ No newline at end of file
diff --git a/js/genome/fasta.js b/js/genome/fasta.js
index 429bf9eae..4e4aa6b42 100644
--- a/js/genome/fasta.js
+++ b/js/genome/fasta.js
@@ -10,7 +10,7 @@ async function loadFasta(reference) {
let fasta
if ("chromsizes" === reference.format) {
fasta = new ChromSizes(reference.fastaURL)
- } else if ("2bit" === reference.format || reference.twobitURL) {
+ } else if ("2bit" === reference.format || reference.twoBitURL) {
fasta = new CachedSequence(new Twobit(reference))
} else if (isDataURL(reference.fastaURL) || reference.indexed === false) {
fasta = new NonIndexedFasta(reference)
diff --git a/js/genome/genome.js b/js/genome/genome.js
index b706897ce..4e2324a1d 100644
--- a/js/genome/genome.js
+++ b/js/genome/genome.js
@@ -1,6 +1,12 @@
import {StringUtils} from "../../node_modules/igv-utils/src/index.js"
-import {isNumber} from "../util/igvUtils.js"
import Chromosome from "./chromosome.js"
+import {loadFasta} from "./fasta.js"
+import ChromAliasBB from "./chromAliasBB.js"
+import ChromAliasFile from "./chromAliasFile.js"
+import CytobandFileBB from "./cytobandFileBB.js"
+import CytobandFile from "./cytobandFile.js"
+
+import {loadChromSizes} from "./chromSizes.js"
/**
* The Genome class represents an assembly and consists of the following elements
@@ -12,67 +18,73 @@ import Chromosome from "./chromosome.js"
class Genome {
- constructor(config, sequence, aliases, chromosomes, cytobands) {
+ static async loadGenome(options) {
+
+ const genome = new Genome(options)
+ await genome.init()
+ return genome
+ }
+ constructor(config) {
this.config = config
this.id = config.id || generateGenomeID(config)
this.name = config.name
- this.sequence = sequence
this.nameSet = config.nameSet
- this.chromosomes = chromosomes
- this.chromosomeNames = Array.from(this.chromosomes.keys())
+ }
- const firstChromosome = chromosomes.values().next().value
- if(firstChromosome.altNames) {
- this.altNameSets = Array.from(firstChromosome.altNames.keys())
- }
+ async init() {
- // Set chromosome order for WG view and chromosome pulldown. If chromosome order is not specified sort
- if (config.chromosomeOrder) {
- if (Array.isArray(config.chromosomeOrder)) {
- this.wgChromosomeNames = config.chromosomeOrder
- } else {
- this.wgChromosomeNames = config.chromosomeOrder.split(',').map(nm => nm.trim())
- }
+ const config = this.config
+
+ this.sequence = await loadFasta(config)
+
+ if (config.chromSizes) {
+ // a chromSizes file is neccessary for 2bit sequences for whole-genome view or chromosome pulldown
+ this.chromosomes = await loadChromSizes(config.chromSizes)
} else {
- this.wgChromosomeNames = trimSmallChromosomes(chromosomes)
+ this.chromosomes = this.sequence.chromosomes || new Map() // This might be undefined, depending on sequence type
}
- // Build the alias table and correct cytoband sequence names
- if(aliases) {
- this.chrAliasTable = createAliasTable(this.chromosomes, aliases)
- } else {
- this.chrAliasTable = {}
+ // For backward compatibility
+ if(this.chromosomes.size > 0) {
+ this.chromosomeNames = Array.from(this.chromosomes.keys())
}
- if (cytobands) {
- this.cytobands = {}
- for (let c of Object.keys(cytobands)) {
- const chrName = this.getChromosomeName(c)
- this.cytobands[chrName] = cytobands[c]
+
+ if (config.chromAliasBbURL) {
+ this.chromAlias = new ChromAliasBB(config.chromAliasBbURL, Object.assign({}, config), this)
+ } else if (config.aliasURL) {
+ this.chromAlias = new ChromAliasFile(config.aliasURL, Object.assign({}, config), this)
+ }
+
+ if (config.cytobandBbURL) {
+ this.cytobandSource = new CytobandFileBB(config.cytobandBbURL, Object.assign({}, config), this)
+ } else if(config.cytobandURL) {
+ this.cytobandSource = new CytobandFile(config.cytobandURL, Object.assign({}, config))
+ }
+
+ if (false !== config.wholeGenomeView && this.chromosomes.size > 0) {
+ // Set chromosome order for WG view and chromosome pulldown. If chromosome order is not specified sort
+ if (config.chromosomeOrder) {
+ if (Array.isArray(config.chromosomeOrder)) {
+ this.wgChromosomeNames = config.chromosomeOrder
+ } else {
+ this.wgChromosomeNames = config.chromosomeOrder.split(',').map(nm => nm.trim())
+ }
+ } else {
+ this.wgChromosomeNames = trimSmallChromosomes(this.chromosomes)
}
}
// Optionally create the psuedo chromosome "all" to support whole genome view
- this.wholeGenomeView = config.wholeGenomeView !== false && this.wgChromosomeNames && this.chromosomeNames.length > 1
+ this.wholeGenomeView = config.wholeGenomeView !== false && this.wgChromosomeNames && this.chromosomes.size > 1
if (this.wholeGenomeView) {
const l = this.wgChromosomeNames.reduce((accumulator, currentValue) => accumulator += this.chromosomes.get(currentValue).bpLength, 0)
this.chromosomes.set("all", new Chromosome("all", 0, l))
- //this.chromosomeNames.unshift("all")
}
}
- updateChromosomes(chromosomes) {
- for(let key of chromosomes.keys()) {
- this.chromosomes.set(key, chromosomes.get(key))
- }
- }
-
- updateAliases(aliases) {
- this.chrAliasTable = createAliasTable(this.chromosomes, aliases);
- }
-
get description() {
@@ -105,47 +117,65 @@ class Genome {
if (this.showWholeGenomeView() && this.chromosomes.has("all")) {
return "all"
} else {
- return this.chromosomeNames[0]
+ return this.sequence.getFirstChromosomeName()
}
}
- getChromosomeName(str) {
- const chr = str ? this.chrAliasTable[str.toLowerCase()] : str
- return chr ? chr : str
+ getChromosomeName(chr) {
+ return this.chromAlias ? this.chromAlias.getChromosomeName(chr) : chr
}
getChromosomeDisplayName(str) {
- const canonicalName = this.getChromosomeName(str)
- if (this.nameSet) {
- return this.chromosomes.has(canonicalName) ? this.chromosomes.get(canonicalName).getAltName("ucsc") : canonicalName
+ if (this.nameSet && this.chromAlias) {
+ return this.chromAlias.getChromosomeAlias(str, this.nameSet) || str
} else {
- return canonicalName
+ return str
}
}
getChromosome(chr) {
- chr = this.getChromosomeName(chr)
+ if (this.chromAlias) {
+ chr = this.chromAlias.getChromosomeName(chr)
+ }
return this.chromosomes.get(chr)
}
- getCytobands(chr) {
- const chrName = this.getChromosomeName(chr)
- return this.cytobands ? this.cytobands[chrName] : null
- }
-
- getLongestChromosome() {
+ async loadChromosome(chr) {
- var longestChr,
- chromosomes = this.chromosomes
- for (let key in chromosomes) {
- if (chromosomes.hasOwnProperty(key)) {
- var chr = chromosomes[key]
- if (longestChr === undefined || chr.bpLength > longestChr.bpLength) {
- longestChr = chr
+ if (!this.chromosomes.has(chr)) {
+ const sequenceRecord = await this.sequence.getSequenceRecord(chr)
+ if (sequenceRecord) {
+ const chromosome = new Chromosome(chr, 0, sequenceRecord.bpLength)
+ this.chromosomes.set(chr, chromosome)
+ } else {
+ // Try alias
+ if (this.chromAlias) {
+ const chromAliasRecord = await this.chromAlias.search(chr)
+ if (chromAliasRecord) {
+ const chromosome = new Chromosome(chromAliasRecord.chr, 0, sequenceRecord.bpLength)
+ this.chromosomes.set(chr, chromosome)
+ }
}
+
+ this.chromosomes.set(chr, undefined) // Prevents future attempts
}
- return longestChr
+ }
+
+ return this.chromosomes.get(chr)
+ }
+
+ async getAliasRecord(chr) {
+ if (this.chromAlias) {
+ return this.chromAlias.search(chr)
+ }
+ }
+
+
+ getCytobands(chr) {
+ if (this.cytobandSource) {
+ const chrName = this.getChromosomeName(chr)
+ return this.cytobandSource.getCytobands(chrName)
}
}
@@ -253,55 +283,6 @@ class Genome {
}
}
-function createAliasTable(chromosomes, aliases) {
-
- /**
- * Return the official chromosome name for the (possibly) alias. Deals with
- * 1 <-> chr1, chrM <-> MT, IV <-> chr4, etc.
- * @param str
- */
- const chrAliasTable = {}
-
- // The standard mappings
- chrAliasTable["all"] = "all"
- chromosomes.forEach(function (c) {
- const name = c.name
- if (name.startsWith("chr")) {
- chrAliasTable[name.substring(3)] = name
- } else if (isNumber(name)) {
- chrAliasTable["chr" + name] = name
- }
- if (name === "chrM") chrAliasTable["mt"] = "chrM"
- if (name === "MT") chrAliasTable["chrm"] = "MT"
- chrAliasTable[name.toLowerCase()] = name
- })
-
- // Custom mappings
- if (aliases) {
- for (let array of aliases) {
-
- // Find the official chr name
- let defName
- for (let i = 0; i < array.length; i++) {
- if (chromosomes.get(array[i])) {
- defName = array[i]
- break
- }
- }
-
- if (defName) {
- for (let alias of array) {
- if (alias !== defName) {
- chrAliasTable[alias.toLowerCase()] = defName
- chrAliasTable[alias] = defName // Should not be needed
- }
- }
- }
- }
- }
- return chrAliasTable
-}
-
/**
* Trim small sequences (chromosomes) and return the list of trimmed chromosome names.
* The results are used to construct the whole genome view and optionally chromosome pulldown
@@ -322,7 +303,7 @@ function trimSmallChromosomes(chromosomes) {
if (c.bpLength < runningAverage / 100) {
continue
}
- runningAverage = ((i-1) * runningAverage + c.bpLength) / i
+ runningAverage = ((i - 1) * runningAverage + c.bpLength) / i
wgChromosomeNames.push(c.name)
}
i++
diff --git a/js/genome/genomeUtils.js b/js/genome/genomeUtils.js
index c426dd529..12d35042a 100644
--- a/js/genome/genomeUtils.js
+++ b/js/genome/genomeUtils.js
@@ -1,65 +1,10 @@
-import Genome from "./genome.js"
-import {loadFasta} from "./fasta.js"
-import {loadCytobands, loadCytobandsBB} from "./cytoband.js"
-import {loadChromSizes} from "./chromSizes.js"
-import {buildOptions} from "../util/igvUtils.js"
import {igvxhr, StringUtils} from "../../node_modules/igv-utils/src/index.js"
-import BWReader from "../bigwig/bwReader.js"
-import Chromosome from "./chromosome.js"
const DEFAULT_GENOMES_URL = "https://igv.org/genomes/genomes.json"
const BACKUP_GENOMES_URL = "https://s3.amazonaws.com/igv.org.genomes/genomes.json"
const GenomeUtils = {
- loadGenome: async function (options) {
-
- const sequence = await loadFasta(options)
-
- let aliases
- let chromosomes
- let cytobands
-
-
- if (options.chromSizes) { // Order is important, try this first
- chromosomes = await loadChromSizes(options.chromSizes)
- } else {
- chromosomes = sequence.chromosomes
- }
-
-
- if (options.cytobandURL) {
- cytobands = await loadCytobands(options.cytobandURL, options)
- }
-
- if (options.aliasURL) {
- aliases = await loadAliases(options.aliasURL, options)
- }
-
-
- const genome = new Genome(options, sequence, aliases, chromosomes, cytobands)
-
- if (options.cytobandBbURL) {
-
- loadCytobandsBB(options.cytobandBbURL, options).then((cc) => {
- if (!chromosomes) {
- genome.updateChromosomes(cc.chromosomes)
- }
- genome.cytobands = cc.cytobands
- })
- }
- if (options.aliasBbURL) {
- loadAliasesBB(options.aliasBbURL, options)
- .then(abb => {
- genome.updateChromosomes(abb.chromosomes)
- genome.updateAliases(abb.aliases)
- })
- }
-
-
- return genome
- },
-
initializeGenomes: async function (config) {
if (!GenomeUtils.KNOWN_GENOMES) {
@@ -146,62 +91,6 @@ const GenomeUtils = {
}
}
-/**
- * Load a tab-delimited alias file
- * @param aliasURL
- * @param config
- * @returns {Promise<*[]>}
- */
-async function loadAliases(aliasURL, config) {
-
- const data = await igvxhr.loadString(aliasURL, buildOptions(config))
- const lines = StringUtils.splitLines(data)
- const aliases = []
- for (let line of lines) {
- if (!line.startsWith("#") && line.length > 0) aliases.push(line.split("\t"))
- }
- return aliases
-}
-/**
- * Load a UCSC bigbed alias file. Features are in bed+3 format.
- * {
- * "chr": "CM021939.1",
- * "start": 0,
- * "end": 223606306,
- * "genbank": "CM021939.1",
- * "assembly": "1",
- * "ensembl": "1",
- * "ncbi": "1",
- * "ucsc": "chr1"
- * }
- * @param url
- * @param config
- * @returns {Promise<*[]>}
- */
-async function loadAliasesBB(url, config) {
-
- const bbReader = new BWReader({url: url, format: "bigbed", wholeFile: true})
- const features = await bbReader.readWGFeatures()
- if (features.length === 0) return
-
- const keys = Object.keys(features[0]).filter(k => !(k === "start" || k === "end"))
-
-
- const aliases = []
- const chromosomes = new Map() // chromosome metadata object
- let order = 0
- for (let f of features) {
- aliases.push(keys.filter(k => f[k]).map(k => f[k]))
-
- const altNames = new Map()
- for (let k of keys.filter(k => k != "chr")) {
- altNames.set(k, f[k])
- }
- chromosomes.set(f["chr"], new Chromosome(f["chr"], order++, f["end"], altNames))
- }
-
- return {chromosomes, aliases}
-}
export default GenomeUtils
diff --git a/js/genome/indexedFasta.js b/js/genome/indexedFasta.js
index 087409d2c..e762fbcca 100644
--- a/js/genome/indexedFasta.js
+++ b/js/genome/indexedFasta.js
@@ -56,6 +56,13 @@ class FastaSequence {
this.config = config
}
+ get hasChromosomes() {
+ return true
+ }
+
+ getSequenceRecord(chr) {
+ return this.chromosomes.get(chr)
+ }
async init() {
return this.getIndex()
@@ -65,6 +72,11 @@ class FastaSequence {
if(!this.#chromosomeNames) {
this.#chromosomeNames = Array.from(this.chromosomes.keys())
}
+ return this.#chromosomeNames
+ }
+
+ getFirstChromosomeName() {
+ return this.chromosomeNames[0]
}
async getIndex() {
diff --git a/js/genome/nonIndexedFasta.js b/js/genome/nonIndexedFasta.js
index c33170720..a3045be33 100644
--- a/js/genome/nonIndexedFasta.js
+++ b/js/genome/nonIndexedFasta.js
@@ -1,29 +1,4 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2014 Broad Institute
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-// Indexed fasta files
+
import {BGZip, igvxhr, StringUtils} from "../../node_modules/igv-utils/src/index.js"
import Chromosome from "./chromosome.js"
import {buildOptions, isDataURL} from "../util/igvUtils.js"
@@ -59,10 +34,19 @@ class NonIndexedFasta {
return this.loadAll()
}
+ getSequenceRecord(chr) {
+ return this.chromosomes.get(chr)
+ }
+
get chromosomeNames() {
if(!this.#chromosomeNames) {
this.#chromosomeNames = Array.from(this.chromosomes.keys())
}
+ return this.#chromosomeNames
+ }
+
+ getFirstChromosomeName() {
+ return this.chromosomeNames[0]
}
async getSequence(chr, start, end) {
diff --git a/js/genome/twobit.js b/js/genome/twobit.js
index a189a0330..516265a26 100644
--- a/js/genome/twobit.js
+++ b/js/genome/twobit.js
@@ -6,6 +6,7 @@
import {igvxhr} from "../../node_modules/igv-utils/src/index.js"
import BinaryParser from "../binary.js"
+import BPTree from "../bigwig/bpTree.js"
const twoBit = ['T', 'C', 'A', 'G']
const byteTo4Bases = []
@@ -22,28 +23,40 @@ const maskedByteTo4Bases = byteTo4Bases.map(bases => bases.toLowerCase())
class TwobitSequence {
littleEndian
- index = new Map()
metaIndex = new Map()
+ bpt
constructor(config) {
- this.url = config.twobitURL || config.fastaURL
- }
+ this.url = config.twoBitURL || config.fastaURL
+ if(config.twoBitBptURL) {
+ this.bptURL = config.twoBitBptURL
+ }
+ }
async init() {
- await this._readIndex()
+ if(this.bptURL) {
+ this.index = await BPTree.loadBpTree(this.bptURL, 0)
+ } else {
+ const idx = await this._readIndex()
+ this.index = {
+ search: async (name) => {
+ return idx.has(name) ? {offset: idx.get(name)} : undefined
+ }
+ }
+ }
}
- get chromosomeNames() {
- return Array.from(this.index.keys())
+ get hasChromosomes() {
+ return false
}
async readSequence(seqName, regionStart, regionEnd) {
- if (this.index.size === 0) {
+ if (!this.index) {
await this.init()
}
- const record = await this._getSequenceMetaData(seqName)
+ const record = await this.getSequenceRecord(seqName)
if (!record) {
return null
}
@@ -108,6 +121,9 @@ class TwobitSequence {
}
async _readIndex() {
+
+ const index = new Map()
+
const loadRange = {start: 0, size: 64}
let arrayBuffer = await igvxhr.loadArrayBuffer(this.url, {range: loadRange})
let dataView = new DataView(arrayBuffer)
@@ -156,29 +172,14 @@ class TwobitSequence {
const name = binaryBuffer.getString(len)
const offset = binaryBuffer.getUInt()
ptr += len + 4
- this.index.set(name, offset)
+ index.set(name, offset)
estNameLength = Math.floor(estNameLength * (i / (i + 1)) + name.length / (i + 1))
}
+ return index
}
- /**
- * NOTE: this can be very slow for large # of sequences as each requires a seek. Its provided in case a 2bit
- * file is used without a corresponding chromSizes, chromAliases, or cytobad file. In other words last resort *
- * @returns {Promise<*>}
- */
- async getChromosomes() {
- if (!this.chromosomes) {
- await this.init()
- const seqNames = Array.from(this.index.keys())
- this.chromosomes = []
- for (let name of seqNames) {
- const metadata = await this._getSequenceMetaData(name)
- this.chromosomes.push({name, bpLength: metadata.dnaSize})
- }
- }
- return this.chromosomes
- }
+
/**
* Fetch the sequence metadata for the given seq name *
@@ -186,7 +187,7 @@ class TwobitSequence {
* @param seqName
* @returns {Promise}
*/
- async _getSequenceMetaData(seqName) {
+ async getSequenceRecord(seqName) {
if (!this.metaIndex.has(seqName)) {
@@ -194,10 +195,11 @@ class TwobitSequence {
throw Error("TwobitSequence object must be initialized before accessing sequence")
}
- let offset = this.index.get(seqName)
- if (!offset) {
+ let result = await this.index.search(seqName)
+ if (!result) {
return
}
+ let offset = result.offset
// Read size of dna data & # of "N" blocks
let size = 8
@@ -253,7 +255,8 @@ class TwobitSequence {
dnaSize,
nBlocks,
maskBlocks,
- packedPos
+ packedPos,
+ bpLength: dnaSize
}
this.metaIndex.set(seqName, meta)
diff --git a/js/ideogramTrack.js b/js/ideogramTrack.js
index 045b31c77..91a04dd4f 100644
--- a/js/ideogramTrack.js
+++ b/js/ideogramTrack.js
@@ -48,7 +48,7 @@ class IdeogramTrack {
return this.height
}
- draw({context, referenceFrame, pixelWidth, pixelHeight}) {
+ async draw({context, referenceFrame, pixelWidth, pixelHeight}) {
const chr = referenceFrame.chr
const chromosome = referenceFrame.genome.getChromosome(chr)
@@ -59,7 +59,7 @@ class IdeogramTrack {
const stainColors = []
- drawIdeogram({
+ await drawIdeogram({
ctx: context,
chr,
referenceFrame,
@@ -117,7 +117,7 @@ class IdeogramTrack {
}
}
-function drawIdeogram({ctx, chr, referenceFrame, genome, width, height, stainColors}) {
+async function drawIdeogram({ctx, chr, referenceFrame, genome, width, height, stainColors}) {
const shim = 1
const shim2 = 0.5 * shim
@@ -129,7 +129,7 @@ function drawIdeogram({ctx, chr, referenceFrame, genome, width, height, stainCol
IGVGraphics.fillRect(ctx, 0, 0, width, height, {fillStyle: IGVColor.greyScale(255)})
- const cytobands = genome.getCytobands(chr)
+ const cytobands = await genome.getCytobands(chr)
if (cytobands) {
const center = (ideogramTop + height / 2)
diff --git a/js/ideogramViewport.js b/js/ideogramViewport.js
index 55825e42e..67829624a 100644
--- a/js/ideogramViewport.js
+++ b/js/ideogramViewport.js
@@ -105,7 +105,7 @@ class IdeogramViewport extends TrackViewport {
this.draw({referenceFrame: this.referenceFrame})
}
- draw({referenceFrame}) {
+ async draw({referenceFrame}) {
IGVGraphics.configureHighDPICanvas(this.ideogram_ctx, this.$viewport.width(), this.$viewport.height())
diff --git a/js/igv-create.js b/js/igv-create.js
index 2ec4d058b..8fc77a907 100644
--- a/js/igv-create.js
+++ b/js/igv-create.js
@@ -199,6 +199,8 @@ function setDefaults(config) {
config.tracks = []
}
+ return config
+
}
@@ -282,4 +284,4 @@ async function createTrack(config, browser) {
return await Browser.prototype.createTrack.call(browser, config)
}
-export {createTrack, createBrowser, removeBrowser, removeAllBrowsers, getAllBrowsers, visibilityChange}
+export {createTrack, createBrowser, removeBrowser, removeAllBrowsers, getAllBrowsers, visibilityChange, setDefaults}
diff --git a/js/referenceFrame.js b/js/referenceFrame.js
index f20eee76f..7e3976d62 100755
--- a/js/referenceFrame.js
+++ b/js/referenceFrame.js
@@ -34,8 +34,8 @@ class ReferenceFrame {
constructor(genome, chr, start, end, bpPerPixel) {
this.genome = genome
- this.chr = chr
+ this.chr = chr // this.genome.getChromosomeName(chr)
this.start = start
// TODO WARNING THIS IS NOT UPDATED !!!
@@ -45,6 +45,10 @@ class ReferenceFrame {
this.id = DOMUtils.guid()
}
+ get locusSearchString() {
+ return `${this.chr}:${this.start+1}-${this.end}`
+ }
+
/**
* Extend this frame to accomodate the given locus. Used th CircularView methods to merge 2 frames.
* @param locus
@@ -125,9 +129,9 @@ class ReferenceFrame {
const centerBP = undefined === centerBPOrUndefined ? (this.start + this.toBP(viewportWidth / 2.0)) : centerBPOrUndefined
// save initial start and bpp
- const {start, bpPerPixel} = this.start
-
- const {bpLength} = this.getChromosome()
+ const initialStart = this.start
+ const initialBpPerPixel = this.bpPerPixel
+ const bpLength = this.getChromosome().bpLength
const bppThreshold = scaleFactor < 1.0 ? browser.minimumBases() / viewportWidth : bpLength / viewportWidth
// update bpp
@@ -144,7 +148,7 @@ class ReferenceFrame {
this.end = this.start + widthBP
- const viewChanged = start !== this.start || bpPerPixel !== this.bpPerPixel
+ const viewChanged = initialStart !== this.start || initialBpPerPixel !== this.bpPerPixel
if (viewChanged) {
await browser.updateViews(true)
}
@@ -229,7 +233,6 @@ function createReferenceFrameList(loci, genome, browserFlanking, minimumBases, v
locus.end,
(locus.end - locus.start) / viewportWidth)
- referenceFrame.locusSearchString = locus.locusSearchString
// GTEX hack
if (locus.gene || locus.snp) {
@@ -249,7 +252,6 @@ function adjustReferenceFrame(scaleFactor, referenceFrame, viewportWidth, alignm
referenceFrame.start = alignmentCC - (referenceFrame.bpPerPixel * (viewportWidth / 2))
referenceFrame.end = referenceFrame.start + (referenceFrame.bpPerPixel * viewportWidth)
- referenceFrame.locusSearchString = referenceFrame.getLocusString()
}
function createReferenceFrameWithAlignment(genome, chromosomeName, bpp, viewportWidth, alignmentStart, alignmentLength) {
diff --git a/js/search.js b/js/search.js
index 41f9c42ad..17aa068b7 100644
--- a/js/search.js
+++ b/js/search.js
@@ -33,59 +33,88 @@ async function search(browser, string) {
return
}
- if (string && string.trim().toLowerCase() === "all" || string === "*") {
- string = "all"
- }
-
const loci = string.split(' ')
let searchConfig = browser.searchConfig || DEFAULT_SEARCH_CONFIG
let list = []
- const searchLocus = async (locus) => {
- let locusObject = parseLocusString(browser, locus)
+ const searchForLocus = async (locus) => {
+
+ if (locus.trim().toLowerCase() === "all" || locus === "*") {
+ if (browser.genome.wholeGenomeView) {
+ const wgChr = browser.genome.getChromosome("all")
+ return {chr: "all", start: 0, end: wgChr.bpLength}
+ } else {
+ return undefined
+ }
+ }
+
+ let locusObject
+ let chromosome
+ if(locus.includes(":")) {
+ locusObject = parseLocusString(locus, browser.isSoftclipped())
+ chromosome = await browser.genome.loadChromosome(locusObject.chr)
+ }
+
+ if (!chromosome) {
+ locusObject = undefined
- if (!locusObject) {
+ // Not a locus string, search track annotations
const searchableTracks = browser.tracks.filter(t => t.searchable)
- for(let track of searchableTracks) {
+ for (let track of searchableTracks) {
const feature = await track.search(locus)
- if(feature) {
+ if (feature) {
locusObject = {
chr: feature.chr,
start: feature.start,
end: feature.end,
- gene: feature.name,
- locusSearchString: string
+ gene: feature.name
}
- break; // We don't support multiple feature hits yets
+ break
+ }
+ }
+
+ // If still not found try webservice, if enabled
+ if (!locusObject && (browser.config && false !== browser.config.search)) {
+ try {
+ locusObject = await searchWebService(browser, locus, searchConfig)
+ } catch (error) {
+ console.error(error)
+ throw Error("Search service currently unavailable.")
}
}
+
+ // Finally assume string is a chromosome name.
+ chromosome = await browser.genome.loadChromosome(locus)
+ if(chromosome) {
+ locusObject = {chr: chromosome.name}
+ }
}
- if (!locusObject && (browser.config && false !== browser.config.search)) {
- try {
- locusObject = await searchWebService(browser, locus, searchConfig)
- } catch (error) {
- console.error(error)
- throw Error("Search service currently unavailable.")
+ // Force load chromosome here (a side effect, but neccessary to do this in an async function so it's available)
+ if (locusObject) {
+ chromosome = chromosome || await browser.genome.loadChromosome(locusObject.chr)
+ locusObject.chr = chromosome.name // Replace possible alias with canonical name
+ if (locusObject.start === undefined && locusObject.end === undefined) {
+ locusObject.start = 0
+ locusObject.end = chromosome.bpLength
}
}
+
return locusObject
}
for (let locus of loci) {
- const locusObject = await searchLocus(locus)
+ const locusObject = await searchForLocus(locus)
if (locusObject) {
- locusObject.locusSearchString = locus
list.push(locusObject)
}
}
// If nothing is found, consider possibility that loci name itself has spaces
if (list.length === 0) {
- const locusObject = await searchLocus(string.replaceAll(' ', '+'))
+ const locusObject = await searchForLocus(string.replaceAll(' ', '+'))
if (locusObject) {
- locusObject.locusSearchString = string
list.push(locusObject)
}
}
@@ -93,14 +122,21 @@ async function search(browser, string) {
return 0 === list.length ? undefined : list
}
-function parseLocusString(browser, locus) {
+/**
+ * Parse a locus string of the form :-
+ *
+ * @param locus
+ * @param isSoftclipped
+ * @returns {{start: number, end: number, chr: *}|undefined|{start: number, chr: *}}
+ */
+function parseLocusString(locus, isSoftclipped = false) {
// Check for tab delimited locus string
const tabTokens = locus.split('\t')
- if (tabTokens.length >= 3) {
+ if (tabTokens.length > 2) {
// Possibly a tab-delimited locus
try {
- const chr = browser.genome.getChromosomeName(tabTokens[0])
+ const chr = tabTokens[0]// browser.genome.getChromosomeName(tabTokens[0])
const start = parseInt(tabTokens[1].replace(/,/g, ''), 10) - 1
const end = parseInt(tabTokens[2].replace(/,/g, ''), 10)
if (!isNaN(start) && !isNaN(end)) {
@@ -109,77 +145,61 @@ function parseLocusString(browser, locus) {
} catch (e) {
// Not a tab delimited locus, apparently, but not really an error as that was a guess
}
-
}
const a = locus.split(':')
- const chr = a[0]
- if ('all' === chr && browser.genome.getChromosome(chr)) {
- return {chr, start: 0, end: browser.genome.getChromosome(chr).bpLength}
-
- } else if (undefined === browser.genome.getChromosome(chr)) {
- return undefined
+ const locusObject = {chr: a[0]}
+ if (a.length > 1) {
+
+ let b = a[1].split('-')
+ if (b.length > 2) {
+ // Allow for negative coordinates, which is possible if showing alignment soft clips
+ if (a[1].startsWith('-')) {
+ const i = a[1].indexOf('-', 1)
+ if (i > 0) {
+ const t1 = a[1].substring(0, i)
+ const t2 = a[1].substring(i + 1)
+ b = [t1, t2]
+ }
+ } else {
+ return undefined
+ }
+ }
- } else {
- const queryChr = browser.genome.getChromosomeName(chr)
- const extent = {
- chr: queryChr,
- start: 0,
- end: browser.genome.getChromosome(chr).bpLength
+ let numeric
+ numeric = b[0].replace(/,/g, '')
+ if (isNaN(numeric)) {
+ return undefined
}
- if (a.length > 1) {
-
- let b = a[1].split('-')
- if (b.length > 2) {
- // Allow for negative coordinates, which is possible if showing alignment soft clips
- if (a[1].startsWith('-')) {
- const i = a[1].indexOf('-', 1)
- if (i > 0) {
- const t1 = a[1].substring(0, i)
- const t2 = a[1].substring(i + 1)
- b = [t1, t2]
- }
- } else {
- return undefined
- }
+ locusObject.start = parseInt(numeric, 10) - 1
+ locusObject.end = locusObject.start + 1
- }
+ if (1 === b.length) {
+ // Don't clamp coordinates if single coordinate is supplied.
+ locusObject.start -= 20
+ locusObject.end += 20
+ }
- let numeric
- numeric = b[0].replace(/,/g, '')
+ if (2 === b.length) {
+ numeric = b[1].replace(/,/g, '')
if (isNaN(numeric)) {
return undefined
+ } else {
+ locusObject.end = parseInt(numeric, 10)
}
- extent.start = parseInt(numeric, 10) - 1
- extent.end = extent.start + 1
-
- if (1 === b.length) {
- // Don't clamp coordinates if single coordinate is supplied.
- extent.start -= 20
- extent.end += 20
- }
-
- if (2 === b.length) {
- numeric = b[1].replace(/,/g, '')
- if (isNaN(numeric)) {
- return undefined
- } else {
- extent.end = parseInt(numeric, 10)
- }
-
- // Allow negative coordinates only if browser is softclipped, i.e. there is at least alignment track with softclipping on
- if (extent.start < 0 && !browser.isSoftclipped()) {
- const delta = -extent.start
- extent.start += delta
- extent.end += delta
- }
+ // Allow negative coordinates only if browser is softclipped, i.e. there is at least alignment track with softclipping on
+ if (locusObject.start < 0 && !isSoftclipped) {
+ const delta = -extent.start
+ locusObject.start += delta
+ locusObject.end += delta
}
}
-
- return extent
}
+
+ return locusObject
+
}
async function searchWebService(browser, locus, searchConfig) {
@@ -192,9 +212,6 @@ async function searchWebService(browser, locus, searchConfig) {
const result = await igvxhr.loadString(path, options)
const locusObject = processSearchResult(browser, result, searchConfig)
- if (locusObject) {
- locusObject.locusSearchString = locus
- }
return locusObject
}
@@ -238,13 +255,7 @@ function processSearchResult(browser, result, searchConfig) {
console.error("Search service results must include chromosome and start fields: " + result)
}
- const chrResult = result[chromosomeField]
- const chromosome = browser.genome.getChromosome(chrResult)
- if (!chromosome) {
- return undefined
- }
- const chr = chromosome.name
-
+ const chr = result[chromosomeField]
let start = result[startField] - coords
let end = result[endField]
if (undefined === end) {
diff --git a/js/trackViewport.js b/js/trackViewport.js
index 1724c9159..2e66835b1 100644
--- a/js/trackViewport.js
+++ b/js/trackViewport.js
@@ -178,7 +178,8 @@ class TrackViewport extends Viewport {
const chr = referenceFrame.chr
// Expand the requested range so we can pan a bit without reloading. But not beyond chromosome bounds
- const chrLength = this.browser.genome.getChromosome(chr).bpLength
+ const chromosome = this.browser.genome.getChromosome(chr)
+ const chrLength = chromosome ? chromosome.bpLength : Number.MAX_SAFE_INTEGER
const pixelWidth = this.$viewport.width()// * 3;
const bpWidth = pixelWidth * referenceFrame.bpPerPixel
const bpStart = Math.floor(Math.max(0, referenceFrame.start - bpWidth))
diff --git a/js/ucsc/ucscHub.js b/js/ucsc/ucscHub.js
index 7cbf6def6..5bef81623 100644
--- a/js/ucsc/ucscHub.js
+++ b/js/ucsc/ucscHub.js
@@ -1,4 +1,3 @@
-
/*
https://genomewiki.ucsc.edu/index.php/Assembly_Hubs
https://genome.ucsc.edu/goldenpath/help/hgTrackHubHelp.html
@@ -6,7 +5,7 @@
https://genome.ucsc.edu/goldenpath/help/trackDb/trackDbHub.html
*/
-import { igvxhr} from "../../node_modules/igv-utils/src/index.js"
+import {igvxhr} from "../../node_modules/igv-utils/src/index.js"
class Hub {
@@ -32,7 +31,8 @@ class Hub {
}
static supportedTypes = new Set(["bigBed", "bigWig", "bigGenePred"])
- static filterTracks = new Set(["cytoBandIdeo"])
+ static filterTracks = new Set(["cytoBandIdeo", "assembly", "gap", "gapOverlap", "allGaps",
+ "cpgIslandExtUnmasked", "windowMasker"])
constructor(url, stanzas, groups) {
@@ -83,13 +83,14 @@ class Hub {
getDefaultPosition() {
return this.genomeStanza.getProperty("defaultPos")
}
+
/* Example genome stanza
genome GCF_000186305.1
taxId 176946
groups groups.txt
description Burmese python
twoBitPath GCF_000186305.1.2bit
-twoBitBptUrl GCF_000186305.1.2bit.bpt
+twoBitBptURL GCF_000186305.1.2bit.bpt
chromSizes GCF_000186305.1.chrom.sizes.txt
chromAliasBb GCF_000186305.1.chromAlias.bb
organism Python_molurus_bivittatus-5.0.2 Sep. 2013
@@ -106,17 +107,29 @@ isPcr dynablat-01.soe.ucsc.edu 4040 dynamic GCF/000/186/305/GCF_000186305.1
const config = {
id: this.genomeStanza.getProperty("genome"),
name: this.genomeStanza.getProperty("scientificName") || this.genomeStanza.getProperty("organism") || this.genomeStanza.getProperty("description"),
- twobitURL: this.baseURL + this.genomeStanza.getProperty("twoBitPath"),
- aliasBbURL: this.baseURL + this.genomeStanza.getProperty("chromAliasBb"),
+ twoBitURL: this.baseURL + this.genomeStanza.getProperty("twoBitPath"),
nameSet: "ucsc",
- blat: this.genomeStanza.getProperty("blat")
+ wholeGenomeView: false
}
config.description = config.id
- if (this.genomeStanza.hasProperty("chromSizes")) {
- config.chromSizes = this.baseURL + this.genomeStanza.getProperty("chromSizes")
+ if (this.genomeStanza.hasProperty("blat")) {
+ config.blat = this.baseURL + this.genomeStanza.getProperty("blat")
+ }
+ if (this.genomeStanza.hasProperty("chromAliasBb")) {
+ config.chromAliasBbURL = this.baseURL + this.genomeStanza.getProperty("chromAliasBb")
}
+ if (this.genomeStanza.hasProperty("twoBitBptURL")) {
+ config.twoBitBptURL = this.baseURL + this.genomeStanza.getProperty("twoBitBptURL")
+ }
+ if (this.genomeStanza.hasProperty("twoBitBptUrl")) {
+ config.twoBitBptURL = this.baseURL + this.genomeStanza.getProperty("twoBitBptUrl")
+ }
+ // chromSizes can take a very long time to load, and is not useful with the default WGV = off
+ // if (this.genomeStanza.hasProperty("chromSizes")) {
+ // config.chromSizes = this.baseURL + this.genomeStanza.getProperty("chromSizes")
+ // }
if (this.genomeStanza.hasProperty("description")) {
config.description += `\n${this.genomeStanza.getProperty("description")}`
}
@@ -132,6 +145,15 @@ isPcr dynablat-01.soe.ucsc.edu 4040 dynamic GCF/000/186/305/GCF_000186305.1
}
// Search for cytoband
+ /*
+ track cytoBandIdeo
+ shortLabel Chromosome Band (Ideogram)
+ longLabel Ideogram for Orientation
+ group map
+ visibility dense
+ type bigBed 4 +
+ bigDataUrl bbi/GCA_004027145.1_DauMad_v1_BIUU.cytoBand.bb
+ */
const cytoStanza = this.trackStanzas.filter(t => "cytoBandIdeo" === t.name && t.getProperty("bigDataUrl"))
if (cytoStanza.length > 0) {
config.cytobandBbURL = this.baseURL + cytoStanza[0].getProperty("bigDataUrl")
@@ -184,6 +206,7 @@ isPcr dynablat-01.soe.ucsc.edu 4040 dynamic GCF/000/186/305/GCF_000186305.1
const format = t.format
const config = {
+ "id": t.getProperty("track"),
"name": t.getProperty("shortLabel"),
"format": format,
"url": this.baseURL + t.getProperty("bigDataUrl"),
@@ -234,11 +257,11 @@ isPcr dynablat-01.soe.ucsc.edu 4040 dynamic GCF/000/186/305/GCF_000186305.1
if (t.hasProperty("url")) {
config.infoURL = t.getProperty("url")
}
- if(t.hasProperty("searchIndex")) {
- config.searchIndex = t.getProperty("searchIndex")
+ if (t.hasProperty("searchIndex")) {
+ config.searchIndex = t.getProperty("searchIndex")
}
- if(t.hasProperty("searchTrix")) {
- config.searchTrix = this.baseURL + t.getProperty("searchTrix")
+ if (t.hasProperty("searchTrix")) {
+ config.searchTrix = this.baseURL + t.getProperty("searchTrix")
}
if (t.hasProperty("group")) {
@@ -345,8 +368,8 @@ async function loadStanzas(options) {
// Break - start a new node
startNewNode = true
} else {
-
const key = line.substring(indent, i)
+ if (key.startsWith("#")) continue
const value = line.substring(i + 1)
if (startNewNode) {
// Start a new node -- indent is currently ignored as igv.js does not support sub-tracks,
diff --git a/js/ui/chromosomeSelectWidget.js b/js/ui/chromosomeSelectWidget.js
index 751034ef4..d62573535 100644
--- a/js/ui/chromosomeSelectWidget.js
+++ b/js/ui/chromosomeSelectWidget.js
@@ -65,11 +65,7 @@ class ChromosomeSelectWidget {
// Add the "all" selector if whole genome view is supported
if (genome.showWholeGenomeView()) {
- const name = 'all'
- const option = document.createElement('option')
- option.setAttribute('value', name)
- option.innerText = genome.getChromosomeDisplayName(name)
- this.select.appendChild(option)
+ list.unshift("all")
}
if (list.length < 1000) {
diff --git a/test/data/genomes/GCF_000002655.1.chromAlias.bb b/test/data/genomes/GCF_000002655.1.chromAlias.bb
new file mode 100644
index 000000000..9c21ef476
Binary files /dev/null and b/test/data/genomes/GCF_000002655.1.chromAlias.bb differ
diff --git a/test/data/genomes/GCF_000002655.1.chromAlias.txt b/test/data/genomes/GCF_000002655.1.chromAlias.txt
new file mode 100644
index 000000000..f04d5686a
--- /dev/null
+++ b/test/data/genomes/GCF_000002655.1.chromAlias.txt
@@ -0,0 +1,9 @@
+# refseq assembly genbank ncbi ucsc
+NC_007194.1 1 CM000169.1 1 chr1
+NC_007195.1 2 CM000170.1 2 chr2
+NC_007196.1 3 CM000171.1 3 chr3
+NC_007197.1 4 CM000172.1 4 chr4
+NC_007198.1 5 CM000173.1 5 chr5
+NC_007199.1 6 CM000174.1 6 chr6
+NC_007200.1 7 CM000175.1 7 chr7
+NC_007201.1 8 CM000176.1 8 chr8
diff --git a/test/data/genomes/hub.txt b/test/data/genomes/hub.txt
new file mode 100644
index 000000000..676408fbe
--- /dev/null
+++ b/test/data/genomes/hub.txt
@@ -0,0 +1,309 @@
+hub GCF_000002655.1 genome assembly
+shortLabel ascomycetes A.fumigatus Af293
+longLabel ascomycetes A.fumigatus Af293/Aspergillus fumigatus Af293/GCF_000002655.1_ASM265v1 genome assembly
+useOneFile on
+email hclawson@ucsc.edu
+descriptionUrl html/GCF_000002655.1_ASM265v1.description.html
+
+genome GCF_000002655.1
+taxId 330879
+groups groups.txt
+description ascomycetes A.fumigatus Af293
+twoBitPath GCF_000002655.1.2bit
+twoBitBptURL GCF_000002655.1.2bit.bpt
+chromSizes GCF_000002655.1.chrom.sizes.txt
+chromAliasBb GCF_000002655.1.chromAlias.bb
+chromAuthority ucsc
+organism ASM265v1 Jun. 2005
+defaultPos NC_007194.1:1639659-1649659
+scientificName Aspergillus fumigatus Af293
+htmlPath html/GCF_000002655.1_ASM265v1.description.html
+blat dynablat-01.soe.ucsc.edu 4040 dynamic GCF/000/002/655/GCF_000002655.1
+transBlat dynablat-01.soe.ucsc.edu 4040 dynamic GCF/000/002/655/GCF_000002655.1
+isPcr dynablat-01.soe.ucsc.edu 4040 dynamic GCF/000/002/655/GCF_000002655.1
+
+track assembly
+longLabel Assembly
+shortLabel Assembly
+visibility pack
+colorByStrand 150,100,30 230,170,40
+color 150,100,30
+altColor 230,170,40
+bigDataUrl bbi/GCF_000002655.1_ASM265v1.assembly.bb
+type bigBed 6
+html html/GCF_000002655.1_ASM265v1.assembly
+searchIndex name
+searchTrix ixIxx/GCF_000002655.1_ASM265v1.assembly.ix
+url https://www.ncbi.nlm.nih.gov/nuccore/$$
+urlLabel NCBI Nucleotide database:
+group map
+
+track gap
+longLabel AGP gap
+shortLabel Gap (AGP defined)
+visibility dense
+color 0,0,0
+bigDataUrl bbi/GCF_000002655.1_ASM265v1.gap.bb
+type bigBed 4
+group map
+html html/GCF_000002655.1_ASM265v1.gap
+
+track cytoBandIdeo
+shortLabel Chromosome Band (Ideogram)
+longLabel Ideogram for Orientation
+group map
+visibility dense
+type bigBed 4 +
+bigDataUrl bbi/GCF_000002655.1_ASM265v1.cytoBand.bb
+
+track gc5Base
+shortLabel GC Percent
+longLabel GC Percent in 5-Base Windows
+group map
+visibility full
+autoScale Off
+maxHeightPixels 128:36:16
+graphTypeDefault Bar
+gridDefault OFF
+windowingFunction Mean
+color 0,0,0
+altColor 128,128,128
+viewLimits 30:70
+type bigWig 0 100
+bigDataUrl bbi/GCF_000002655.1_ASM265v1.gc5Base.bw
+html html/GCF_000002655.1_ASM265v1.gc5Base
+
+track tanDups
+shortLabel Tandem Dups
+longLabel Paired identical sequences
+compositeTrack on
+visibility hide
+type bigBed 12
+group map
+html html/GCF_000002655.1_ASM265v1.tanDups
+
+ track tandemDups
+ parent tanDups on
+ shortLabel Tandem Dups
+ longLabel Paired exactly identical sequence survey over entire genome assembly
+ bigDataUrl bbi/GCF_000002655.1_ASM265v1.tandemDups.bb
+ type bigBed 12
+
+track repeatMasker
+compositeTrack on
+shortLabel RepeatMasker
+longLabel Repeating Elements by RepeatMasker
+group varRep
+visibility dense
+type bigBed 6 +
+colorByStrand 50,50,150 150,50,50
+maxWindowToDraw 10000000
+spectrum on
+html html/GCF_000002655.1_ASM265v1.repeatMasker
+
+ track repeatMaskerLINE
+ parent repeatMasker
+ shortLabel LINE
+ longLabel LINE Repeating Elements by RepeatMasker
+ type bigBed 6 +
+ priority 2
+ bigDataUrl bbi/GCF_000002655.1_ASM265v1.rmsk.LINE.bb
+
+ track repeatMaskerLTR
+ parent repeatMasker
+ shortLabel LTR
+ longLabel LTR Repeating Elements by RepeatMasker
+ type bigBed 6 +
+ priority 3
+ bigDataUrl bbi/GCF_000002655.1_ASM265v1.rmsk.LTR.bb
+
+ track repeatMaskerDNA
+ parent repeatMasker
+ shortLabel DNA
+ longLabel DNA Repeating Elements by RepeatMasker
+ type bigBed 6 +
+ priority 4
+ bigDataUrl bbi/GCF_000002655.1_ASM265v1.rmsk.DNA.bb
+
+ track repeatMaskerSimple
+ parent repeatMasker
+ shortLabel Simple
+ longLabel Simple Repeating Elements by RepeatMasker
+ type bigBed 6 +
+ priority 5
+ bigDataUrl bbi/GCF_000002655.1_ASM265v1.rmsk.Simple.bb
+
+ track repeatMaskerLowComplexity
+ parent repeatMasker
+ shortLabel Low Complexity
+ longLabel Low Complexity Repeating Elements by RepeatMasker
+ type bigBed 6 +
+ priority 6
+ bigDataUrl bbi/GCF_000002655.1_ASM265v1.rmsk.Low_complexity.bb
+
+ track repeatMaskerRNA
+ parent repeatMasker
+ shortLabel RNA
+ longLabel RNA Repeating Elements by RepeatMasker
+ type bigBed 6 +
+ priority 8
+ bigDataUrl bbi/GCF_000002655.1_ASM265v1.rmsk.RNA.bb
+
+track simpleRepeat
+shortLabel Simple Repeats
+longLabel Simple Tandem Repeats by TRF
+group varRep
+visibility dense
+type bigBed 4 +
+bigDataUrl bbi/GCF_000002655.1_ASM265v1.simpleRepeat.bb
+html html/GCF_000002655.1_ASM265v1.simpleRepeat
+
+track refSeqComposite
+compositeTrack on
+shortLabel NCBI RefSeq
+longLabel RefSeq gene predictions from NCBI
+group genes
+visibility pack
+type bigBed
+dragAndDrop subTracks
+allButtonPair on
+dataVersion INSDC submitter (2020-03-07)
+html html/GCF_000002655.1_ASM265v1.refSeqComposite
+priority 2
+
+ track ncbiRefSeq
+ parent refSeqComposite on
+ color 12,12,120
+ altColor 120,12,12
+ shortLabel RefSeq All
+ type bigGenePred
+ labelFields name,geneName,geneName2
+ defaultLabelFields geneName2
+ searchIndex name
+ searchTrix ixIxx/GCF_000002655.1_ASM265v1.ncbiRefSeq.ix
+ bigDataUrl bbi/GCF_000002655.1_ASM265v1.ncbiRefSeq.bb
+ longLabel NCBI RefSeq genes, curated and predicted sets (NM_*, XM_*, NR_*, XR_*, NP_* or YP_*)
+ idXref ncbiRefSeqLink mrnaAcc name
+ baseColorUseCds given
+ baseColorDefault genomicCodons
+ priority 1
+
+ track ncbiRefSeqPredicted
+ color 12,12,120
+ parent refSeqComposite on
+ shortLabel RefSeq Predicted
+ longLabel NCBI RefSeq genes, predicted subset (XM_* or XR_*)
+ type bigGenePred
+ labelFields name,geneName,geneName2
+ defaultLabelFields geneName2
+ searchIndex name
+ searchTrix ixIxx/GCF_000002655.1_ASM265v1.ncbiRefSeqPredicted.ix
+ idXref ncbiRefSeqLink mrnaAcc name
+ bigDataUrl bbi/GCF_000002655.1_ASM265v1.ncbiRefSeqPredicted.bb
+ baseColorUseCds given
+ baseColorDefault genomicCodons
+ priority 3
+
+ track ncbiRefSeqOther
+ color 32,32,32
+ parent refSeqComposite on
+ shortLabel RefSeq Other
+ longLabel NCBI RefSeq other annotations (not NM_*, NR_*, XM_*, XR_*, NP_* or YP_*)
+ priority 4
+ searchIndex name
+ searchTrix ixIxx/GCF_000002655.1_ASM265v1.ncbiRefSeqOther.ix
+ bigDataUrl bbi/GCF_000002655.1_ASM265v1.ncbiRefSeqOther.bb
+ type bigBed 12 +
+ labelFields name
+ skipEmptyFields on
+ urls GeneID="https://www.ncbi.nlm.nih.gov/gene/$$" MIM="https://www.ncbi.nlm.nih.gov/omim/$$" HGNC="http://www.genenames.org/cgi-bin/gene_symbol_report?hgnc_id=$$" FlyBase="http://flybase.org/reports/$$" WormBase="http://www.wormbase.org/db/gene/gene?name=$$" RGD="https://rgd.mcw.edu/rgdweb/search/search.html?term=$$" SGD="https://www.yeastgenome.org/locus/$$" miRBase="http://www.mirbase.org/cgi-bin/mirna_entry.pl?acc=$$" ZFIN="https://zfin.org/$$" MGI="http://www.informatics.jax.org/marker/$$"
+
+ track ncbiRefSeqPsl
+ priority 5
+ parent refSeqComposite off
+ shortLabel RefSeq Alignments
+ longLabel RefSeq Alignments of RNAs
+ type bigPsl
+ searchIndex name
+ bigDataUrl bbi/GCF_000002655.1_ASM265v1.bigPsl.bb
+ indelDoubleInsert on
+ indelQueryInsert on
+ showDiffBasesAllScales .
+ showDiffBasesMaxZoom 10000.0
+ showCdsMaxZoom 10000.0
+ showCdsAllScales .
+ baseColorDefault diffCodons
+ pslSequence no
+ baseColorUseSequence lfExtra
+ baseColorUseCds table given
+ color 0,0,0
+
+track cpgIslands
+compositeTrack on
+shortLabel CpG Islands
+longLabel CpG Islands (Islands < 300 Bases are Light Green)
+group regulation
+visibility pack
+type bigBed 4 +
+html html/GCF_000002655.1_ASM265v1.cpgIslands
+
+ track cpgIslandExt
+ parent cpgIslands off
+ shortLabel CpG Islands
+ longLabel CpG Islands (Islands < 300 Bases are Light Green)
+ type bigBed 4 +
+ priority 1
+ bigDataUrl bbi/GCF_000002655.1_ASM265v1.cpgIslandExt.bb
+
+ track cpgIslandExtUnmasked
+ parent cpgIslands on
+ shortLabel Unmasked CpG
+ longLabel CpG Islands on All Sequence (Islands < 300 Bases are Light Green)
+ type bigBed 4 +
+ priority 2
+ bigDataUrl bbi/GCF_000002655.1_ASM265v1.cpgIslandExtUnmasked.bb
+
+track windowMasker
+shortLabel WM + SDust
+longLabel Genomic Intervals Masked by WindowMasker + SDust
+group varRep
+visibility dense
+type bigBed 3
+bigDataUrl bbi/GCF_000002655.1_ASM265v1.windowMasker.bb
+html html/GCF_000002655.1_ASM265v1.windowMasker
+
+track allGaps
+shortLabel All Gaps
+longLabel All gaps of unknown nucleotides (N's), including AGP annotated gaps
+group map
+visibility dense
+type bigBed 3
+bigDataUrl bbi/GCF_000002655.1_ASM265v1.allGaps.bb
+html html/GCF_000002655.1_ASM265v1.allGaps
+
+track augustus
+shortLabel Augustus
+longLabel Augustus Gene Predictions
+group genes
+visibility dense
+color 180,0,0
+type bigGenePred
+bigDataUrl bbi/GCF_000002655.1_ASM265v1.augustus.bb
+html html/GCF_000002655.1_ASM265v1.augustus
+
+track xenoRefGene
+shortLabel RefSeq mRNAs
+longLabel RefSeq mRNAs mapped to this assembly
+group rna
+visibility pack
+color 180,0,0
+type bigGenePred
+bigDataUrl bbi/GCF_000002655.1_ASM265v1.xenoRefGene.bb
+url https://www.ncbi.nlm.nih.gov/nuccore/$$
+urlLabel NCBI Nucleotide database:
+labelFields name,geneName,geneName2
+defaultLabelFields geneName
+searchIndex name
+searchTrix ixIxx/GCF_000002655.1_ASM265v1.xenoRefGene.ix
+html html/GCF_000002655.1_ASM265v1.xenoRefGene
+
diff --git a/test/data/hubs/ENCFF754TJH.wig b/test/data/hubs/ENCFF754TJH.wig
new file mode 100644
index 000000000..970736df9
--- /dev/null
+++ b/test/data/hubs/ENCFF754TJH.wig
@@ -0,0 +1,2621 @@
+#bedGraph section chr9:35696794-35728096
+chr9 35726969 35726977 8.62197
+chr9 35726977 35726986 7.45196
+chr9 35726986 35726989 7.51607
+chr9 35726989 35726992 6.45094
+chr9 35726992 35727002 7.51607
+chr9 35727002 35727006 8.62197
+chr9 35727006 35727015 9.76519
+chr9 35727015 35727021 8.62197
+chr9 35727021 35727025 9.76519
+chr9 35727025 35727065 10.9428
+chr9 35727065 35727069 12.1523
+chr9 35727069 35727070 13.3915
+chr9 35727070 35727081 12.1523
+chr9 35727081 35727084 13.3915
+chr9 35727084 35727087 14.6585
+chr9 35727087 35727090 13.3915
+chr9 35727090 35727094 12.1523
+chr9 35727094 35727103 10.9428
+chr9 35727103 35727104 12.1523
+chr9 35727104 35727107 13.3915
+chr9 35727107 35727109 12.1523
+chr9 35727109 35727121 10.9428
+chr9 35727121 35727124 12.1523
+chr9 35727124 35727127 13.3915
+chr9 35727127 35727129 14.6585
+chr9 35727129 35727131 15.9518
+chr9 35727131 35727132 14.9609
+chr9 35727132 35727135 13.729
+chr9 35727135 35727140 14.9609
+chr9 35727140 35727142 16.2176
+chr9 35727142 35727143 14.9609
+chr9 35727143 35727146 16.2176
+chr9 35727146 35727147 14.9609
+chr9 35727147 35727150 16.2176
+chr9 35727150 35727151 17.4975
+chr9 35727151 35727161 18.7997
+chr9 35727161 35727162 17.4975
+chr9 35727162 35727163 18.7997
+chr9 35727163 35727165 20.1229
+chr9 35727165 35727167 18.7997
+chr9 35727167 35727173 20.1229
+chr9 35727173 35727175 13.1908
+chr9 35727175 35727178 14.214
+chr9 35727178 35727187 15.2572
+chr9 35727187 35727190 16.3196
+chr9 35727190 35727193 17.4004
+chr9 35727193 35727199 18.4987
+chr9 35727199 35727205 19.614
+chr9 35727205 35727212 18.4987
+chr9 35727212 35727214 19.614
+chr9 35727214 35727215 18.4987
+chr9 35727215 35727221 19.614
+chr9 35727221 35727222 18.4987
+chr9 35727222 35727224 20.7455
+chr9 35727224 35727229 19.614
+chr9 35727229 35727231 20.7455
+chr9 35727231 35727236 19.614
+chr9 35727236 35727239 20.7455
+chr9 35727239 35727240 21.8928
+chr9 35727240 35727243 23.0552
+chr9 35727243 35727244 21.8928
+chr9 35727244 35727246 20.7455
+chr9 35727246 35727250 23.0552
+chr9 35727250 35727261 24.2323
+chr9 35727261 35727262 23.0552
+chr9 35727262 35727264 24.2323
+chr9 35727264 35727266 23.0552
+chr9 35727266 35727267 24.2323
+chr9 35727267 35727271 23.0552
+chr9 35727271 35727274 31.3667
+chr9 35727274 35727275 32.8443
+chr9 35727275 35727280 31.3667
+chr9 35727280 35727283 29.9038
+chr9 35727283 35727287 28.456
+chr9 35727287 35727289 27.0241
+chr9 35727289 35727290 28.456
+chr9 35727290 35727295 27.0241
+chr9 35727295 35727299 28.456
+chr9 35727299 35727302 29.9038
+chr9 35727302 35727303 28.456
+chr9 35727303 35727307 27.0241
+chr9 35727307 35727311 25.6084
+chr9 35727311 35727313 28.456
+chr9 35727313 35727315 30.6236
+chr9 35727315 35727316 29.1087
+chr9 35727316 35727328 27.6103
+chr9 35727328 35727330 26.1288
+chr9 35727330 35727333 24.6649
+chr9 35727333 35727338 23.2195
+chr9 35727338 35727339 21.7934
+chr9 35727339 35727346 20.3874
+chr9 35727346 35727349 21.7934
+chr9 35727349 35727350 20.3874
+chr9 35727350 35727352 21.7934
+chr9 35727352 35727354 20.3874
+chr9 35727354 35727355 21.7934
+chr9 35727355 35727357 20.3874
+chr9 35727357 35727362 21.7934
+chr9 35727362 35727365 20.3874
+chr9 35727365 35727371 18.7997
+chr9 35727371 35727374 20.1229
+chr9 35727374 35727376 21.4662
+chr9 35727376 35727380 20.1229
+chr9 35727380 35727384 18.7997
+chr9 35727384 35727386 20.1229
+chr9 35727386 35727390 18.7997
+chr9 35727390 35727393 17.4975
+chr9 35727393 35727394 18.7997
+chr9 35727394 35727398 20.1229
+chr9 35727398 35727399 22.8288
+chr9 35727399 35727402 24.2098
+chr9 35727402 35727403 22.8288
+chr9 35727403 35727404 24.2098
+chr9 35727404 35727407 25.6084
+chr9 35727407 35727412 27.0241
+chr9 35727412 35727413 28.456
+chr9 35727413 35727415 27.0241
+chr9 35727415 35727416 19.614
+chr9 35727416 35727425 20.7455
+chr9 35727425 35727431 23.0552
+chr9 35727431 35727439 21.8928
+chr9 35727439 35727442 20.7455
+chr9 35727442 35727443 21.8928
+chr9 35727443 35727450 23.0552
+chr9 35727450 35727452 24.2323
+chr9 35727452 35727453 26.6286
+chr9 35727453 35727457 27.8468
+chr9 35727457 35727458 29.0781
+chr9 35727458 35727469 27.8468
+chr9 35727469 35727476 29.0781
+chr9 35727476 35727479 30.3218
+chr9 35727479 35727485 31.5778
+chr9 35727485 35727486 32.8456
+chr9 35727486 35727491 31.5778
+chr9 35727491 35727501 32.8456
+chr9 35727501 35727503 31.5778
+chr9 35727503 35727505 32.8456
+chr9 35727505 35727511 43.5622
+chr9 35727511 35727514 41.9937
+chr9 35727514 35727518 40.437
+chr9 35727518 35727519 41.9937
+chr9 35727519 35727531 43.5622
+chr9 35727531 35727533 45.1423
+chr9 35727533 35727536 43.5622
+chr9 35727536 35727537 46.7337
+chr9 35727537 35727538 45.1423
+chr9 35727538 35727541 43.5622
+chr9 35727541 35727543 45.1423
+chr9 35727543 35727546 43.5622
+chr9 35727546 35727547 41.9937
+chr9 35727547 35727548 40.437
+chr9 35727548 35727553 41.9937
+chr9 35727553 35727555 43.5622
+chr9 35727555 35727564 46.2963
+chr9 35727564 35727565 47.9521
+chr9 35727565 35727576 46.2963
+chr9 35727576 35727578 47.9521
+chr9 35727578 35727579 49.6192
+chr9 35727579 35727580 51.2972
+chr9 35727580 35727582 52.9859
+chr9 35727582 35727583 51.2972
+chr9 35727583 35727585 47.9521
+chr9 35727585 35727588 49.6192
+chr9 35727588 35727589 51.2972
+chr9 35727589 35727591 52.9859
+chr9 35727591 35727592 51.2972
+chr9 35727592 35727593 47.9521
+chr9 35727593 35727595 46.2963
+chr9 35727595 35727596 47.9521
+chr9 35727596 35727599 46.2963
+chr9 35727599 35727601 47.9521
+chr9 35727601 35727603 46.7337
+chr9 35727603 35727607 48.336
+chr9 35727607 35727612 49.9491
+chr9 35727612 35727617 51.5726
+chr9 35727617 35727620 54.85
+chr9 35727620 35727621 56.5035
+chr9 35727621 35727624 58.1665
+chr9 35727624 35727627 59.8388
+chr9 35727627 35727628 61.5202
+chr9 35727628 35727632 63.2106
+chr9 35727632 35727633 64.9098
+chr9 35727633 35727635 63.2106
+chr9 35727635 35727637 64.9098
+chr9 35727637 35727638 63.2106
+chr9 35727638 35727639 64.9098
+chr9 35727639 35727640 66.6175
+chr9 35727640 35727643 68.3337
+chr9 35727643 35727645 66.6175
+chr9 35727645 35727646 68.3337
+chr9 35727646 35727648 70.0582
+chr9 35727648 35727654 71.7907
+chr9 35727654 35727657 73.5313
+chr9 35727657 35727658 75.2796
+chr9 35727658 35727661 73.5313
+chr9 35727661 35727662 75.2796
+chr9 35727662 35727664 77.0356
+chr9 35727664 35727668 75.2796
+chr9 35727668 35727669 77.0356
+chr9 35727669 35727671 78.7992
+chr9 35727671 35727672 77.0356
+chr9 35727672 35727674 80.5702
+chr9 35727674 35727675 78.7992
+chr9 35727675 35727676 80.5702
+chr9 35727676 35727687 77.0356
+chr9 35727687 35727693 78.7992
+chr9 35727693 35727695 77.0356
+chr9 35727695 35727697 75.2796
+chr9 35727697 35727704 77.0356
+chr9 35727704 35727708 75.2796
+chr9 35727708 35727714 77.0356
+chr9 35727714 35727716 80.5702
+chr9 35727716 35727718 78.7992
+chr9 35727718 35727726 77.0356
+chr9 35727726 35727730 78.7992
+chr9 35727730 35727731 82.3485
+chr9 35727731 35727732 80.5702
+chr9 35727732 35727736 82.3485
+chr9 35727736 35727738 84.134
+chr9 35727738 35727739 85.9265
+chr9 35727739 35727740 84.134
+chr9 35727740 35727741 85.9265
+chr9 35727741 35727754 89.6805
+chr9 35727754 35727755 91.5414
+chr9 35727755 35727756 93.4091
+chr9 35727756 35727757 91.5414
+chr9 35727757 35727759 89.6805
+chr9 35727759 35727760 87.8265
+chr9 35727760 35727762 84.1399
+chr9 35727762 35727763 85.9796
+chr9 35727763 35727765 87.8265
+chr9 35727765 35727766 85.9796
+chr9 35727766 35727769 87.8265
+chr9 35727769 35727770 87.4079
+chr9 35727770 35727771 89.2549
+chr9 35727771 35727772 87.4079
+chr9 35727772 35727775 85.5679
+chr9 35727775 35727777 87.4079
+chr9 35727777 35727778 89.2549
+chr9 35727778 35727780 87.4079
+chr9 35727780 35727781 85.5679
+chr9 35727781 35727787 89.2549
+chr9 35727787 35727788 87.4079
+chr9 35727788 35727789 85.5679
+chr9 35727789 35727792 87.4079
+chr9 35727792 35727801 85.5679
+chr9 35727801 35727802 83.7352
+chr9 35727802 35727803 81.9097
+chr9 35727803 35727806 85.5679
+chr9 35727806 35727808 89.2549
+chr9 35727808 35727810 87.4079
+chr9 35727810 35727812 89.2549
+chr9 35727812 35727813 87.4079
+chr9 35727813 35727816 89.2549
+chr9 35727816 35727817 88.8361
+chr9 35727817 35727818 90.6832
+chr9 35727818 35727822 88.8361
+chr9 35727822 35727823 92.5372
+chr9 35727823 35727824 94.3978
+chr9 35727824 35727825 96.2651
+chr9 35727825 35727827 98.1389
+chr9 35727827 35727831 96.2651
+chr9 35727831 35727832 98.1389
+chr9 35727832 35727834 96.2651
+chr9 35727834 35727836 98.1389
+chr9 35727836 35727837 100.019
+chr9 35727837 35727839 101.906
+chr9 35727839 35727843 103.799
+chr9 35727843 35727844 105.698
+chr9 35727844 35727846 107.603
+chr9 35727846 35727847 109.514
+chr9 35727847 35727854 111.431
+chr9 35727854 35727855 107.603
+chr9 35727855 35727858 105.698
+chr9 35727858 35727860 107.603
+chr9 35727860 35727862 106.178
+chr9 35727862 35727863 108.09
+chr9 35727863 35727865 111.932
+chr9 35727865 35727866 110.008
+chr9 35727866 35727867 108.09
+chr9 35727867 35727868 110.008
+chr9 35727868 35727869 108.09
+chr9 35727869 35727870 106.178
+chr9 35727870 35727874 104.272
+chr9 35727874 35727875 106.178
+chr9 35727875 35727884 104.272
+chr9 35727884 35727887 100.508
+chr9 35727887 35727891 98.6628
+chr9 35727891 35727892 96.8238
+chr9 35727892 35727895 94.9912
+chr9 35727895 35727898 93.165
+chr9 35727898 35727899 94.9912
+chr9 35727899 35727901 96.8238
+chr9 35727901 35727902 94.9912
+chr9 35727902 35727906 93.165
+chr9 35727906 35727907 94.9912
+chr9 35727907 35727909 93.165
+chr9 35727909 35727910 91.3453
+chr9 35727910 35727915 89.5323
+chr9 35727915 35727916 85.9265
+chr9 35727916 35727918 87.726
+chr9 35727918 35727919 91.3453
+chr9 35727919 35727920 89.5323
+chr9 35727920 35727921 91.3453
+chr9 35727921 35727924 87.726
+chr9 35727924 35727926 85.9265
+chr9 35727926 35727929 87.726
+chr9 35727929 35727932 85.9265
+chr9 35727932 35727938 87.726
+chr9 35727938 35727939 89.5323
+chr9 35727939 35727940 87.726
+chr9 35727940 35727942 89.5323
+chr9 35727942 35727943 91.3453
+chr9 35727943 35727946 89.5323
+chr9 35727946 35727947 87.726
+chr9 35727947 35727948 89.5323
+chr9 35727948 35727949 93.165
+chr9 35727949 35727950 89.5323
+chr9 35727950 35727954 85.9265
+chr9 35727954 35727955 84.134
+chr9 35727955 35727957 85.9265
+chr9 35727957 35727959 84.134
+chr9 35727959 35727961 85.9265
+chr9 35727961 35727962 84.134
+chr9 35727962 35727963 82.3485
+chr9 35727963 35727964 80.5702
+chr9 35727964 35727965 78.7992
+chr9 35727965 35727967 77.0356
+chr9 35727967 35727968 78.7992
+chr9 35727968 35727971 77.0356
+chr9 35727971 35727972 78.7992
+chr9 35727972 35727973 80.5702
+chr9 35727973 35727974 82.3485
+chr9 35727974 35727976 80.5702
+chr9 35727976 35727977 78.7992
+chr9 35727977 35727980 77.0356
+chr9 35727980 35727982 73.5313
+chr9 35727982 35727983 75.2796
+chr9 35727983 35727985 73.5313
+chr9 35727985 35727987 71.7907
+chr9 35727987 35727991 70.0582
+chr9 35727991 35727992 68.3337
+chr9 35727992 35727996 70.0582
+chr9 35727996 35728003 71.7907
+chr9 35728003 35728005 70.0582
+chr9 35728005 35728007 71.7907
+chr9 35728007 35728010 70.0582
+chr9 35728010 35728012 68.3337
+chr9 35728012 35728014 70.0582
+chr9 35728014 35728015 68.3337
+chr9 35728015 35728016 70.0582
+chr9 35728016 35728017 71.7907
+chr9 35728017 35728020 70.0582
+chr9 35728020 35728023 68.3337
+chr9 35728023 35728024 66.6175
+chr9 35728024 35728027 71.4733
+chr9 35728027 35728032 73.2592
+chr9 35728032 35728033 76.8551
+chr9 35728033 35728034 80.4824
+chr9 35728034 35728035 78.6649
+chr9 35728035 35728038 80.4824
+chr9 35728038 35728040 78.6649
+chr9 35728040 35728041 80.4824
+chr9 35728041 35728042 82.3074
+chr9 35728042 35728045 84.1399
+chr9 35728045 35728046 82.3074
+chr9 35728046 35728049 80.4824
+chr9 35728049 35728053 84.1399
+chr9 35728053 35728054 85.9796
+chr9 35728054 35728072 89.6805
+chr9 35728072 35728073 91.5414
+chr9 35728073 35728074 93.4091
+chr9 35728074 35728075 95.2836
+chr9 35728075 35728078 97.1647
+chr9 35728078 35728080 96.7113
+chr9 35728080 35728081 98.592
+chr9 35728081 35728082 100.479
+chr9 35728082 35728083 98.592
+chr9 35728083 35728086 96.7113
+chr9 35728086 35728087 94.8372
+chr9 35728087 35728088 91.1088
+chr9 35728088 35728090 89.2549
+chr9 35728090 35728091 91.1088
+chr9 35728091 35728092 92.9696
+chr9 35728092 35728094 91.1088
+chr9 35728094 35728095 92.9696
+chr9 35728095 35728096 91.1088
+#bedGraph section chr9:35728096-35730652
+chr9 35728096 35728097 92.9696
+chr9 35728097 35728102 96.7113
+chr9 35728102 35728108 94.8372
+chr9 35728108 35728109 96.7113
+chr9 35728109 35728110 94.8372
+chr9 35728110 35728111 96.7113
+chr9 35728111 35728112 92.9696
+chr9 35728112 35728113 91.1088
+chr9 35728113 35728114 89.2549
+chr9 35728114 35728115 91.1088
+chr9 35728115 35728116 92.9696
+chr9 35728116 35728117 94.8372
+chr9 35728117 35728119 96.7113
+chr9 35728119 35728120 98.592
+chr9 35728120 35728125 102.373
+chr9 35728125 35728135 104.272
+chr9 35728135 35728137 106.178
+chr9 35728137 35728138 108.09
+chr9 35728138 35728139 106.178
+chr9 35728139 35728140 108.09
+chr9 35728140 35728144 111.932
+chr9 35728144 35728145 113.861
+chr9 35728145 35728147 111.932
+chr9 35728147 35728150 113.861
+chr9 35728150 35728151 115.797
+chr9 35728151 35728152 117.738
+chr9 35728152 35728153 115.797
+chr9 35728153 35728154 117.738
+chr9 35728154 35728156 119.685
+chr9 35728156 35728159 112.363
+chr9 35728159 35728162 114.259
+chr9 35728162 35728163 112.363
+chr9 35728163 35728164 114.259
+chr9 35728164 35728165 112.363
+chr9 35728165 35728168 114.259
+chr9 35728168 35728169 112.363
+chr9 35728169 35728170 114.259
+chr9 35728170 35728171 112.363
+chr9 35728171 35728172 115.797
+chr9 35728172 35728173 113.861
+chr9 35728173 35728178 111.932
+chr9 35728178 35728180 111.431
+chr9 35728180 35728181 109.514
+chr9 35728181 35728182 107.603
+chr9 35728182 35728184 105.698
+chr9 35728184 35728188 103.799
+chr9 35728188 35728189 105.698
+chr9 35728189 35728194 103.799
+chr9 35728194 35728196 101.906
+chr9 35728196 35728198 100.019
+chr9 35728198 35728212 96.2651
+chr9 35728212 35728214 92.5372
+chr9 35728214 35728215 88.8361
+chr9 35728215 35728218 88.4273
+chr9 35728218 35728219 86.5939
+chr9 35728219 35728220 84.7675
+chr9 35728220 35728221 81.1363
+chr9 35728221 35728222 79.3317
+chr9 35728222 35728223 82.9482
+chr9 35728223 35728228 84.7675
+chr9 35728228 35728229 86.5939
+chr9 35728229 35728230 84.7675
+chr9 35728230 35728231 82.9482
+chr9 35728231 35728232 81.1363
+chr9 35728232 35728235 82.9482
+chr9 35728235 35728236 84.7675
+chr9 35728236 35728237 82.9482
+chr9 35728237 35728239 79.3317
+chr9 35728239 35728241 77.5348
+chr9 35728241 35728250 79.3317
+chr9 35728250 35728253 77.5348
+chr9 35728253 35728254 79.3317
+chr9 35728254 35728255 77.5348
+chr9 35728255 35728256 75.7455
+chr9 35728256 35728257 73.964
+chr9 35728257 35728259 72.1905
+chr9 35728259 35728260 68.668
+chr9 35728260 35728263 65.1792
+chr9 35728263 35728265 63.6317
+chr9 35728265 35728266 61.9326
+chr9 35728266 35728267 60.2424
+chr9 35728267 35728271 58.5613
+chr9 35728271 35728273 60.2424
+chr9 35728273 35728274 58.5613
+chr9 35728274 35728276 56.8895
+chr9 35728276 35728277 55.2273
+chr9 35728277 35728279 53.5749
+chr9 35728279 35728280 51.9324
+chr9 35728280 35728282 50.3001
+chr9 35728282 35728284 48.6783
+chr9 35728284 35728287 45.467
+chr9 35728287 35728291 43.8782
+chr9 35728291 35728293 42.3009
+chr9 35728293 35728298 39.1822
+chr9 35728298 35728300 40.7354
+chr9 35728300 35728301 42.3009
+chr9 35728301 35728303 40.7354
+chr9 35728303 35728305 39.1822
+chr9 35728305 35728315 37.6416
+chr9 35728315 35728316 36.1139
+chr9 35728316 35728317 37.6416
+chr9 35728317 35728319 36.1139
+chr9 35728319 35728320 34.5996
+chr9 35728320 35728322 36.1139
+chr9 35728322 35728324 37.3607
+chr9 35728324 35728325 38.8926
+chr9 35728325 35728326 40.437
+chr9 35728326 35728328 38.8926
+chr9 35728328 35728330 37.3607
+chr9 35728330 35728332 35.8418
+chr9 35728332 35728340 37.3607
+chr9 35728340 35728345 27.8468
+chr9 35728345 35728346 26.6286
+chr9 35728346 35728348 25.4236
+chr9 35728348 35728349 26.6286
+chr9 35728349 35728357 27.8468
+chr9 35728357 35728362 29.0781
+chr9 35728362 35728363 27.8468
+chr9 35728363 35728364 26.6286
+chr9 35728364 35728372 27.8468
+chr9 35728372 35728373 26.6286
+chr9 35728373 35728375 27.8468
+chr9 35728375 35728382 25.4236
+chr9 35728382 35728387 24.2323
+chr9 35728387 35728392 23.0552
+chr9 35728392 35728393 24.2323
+chr9 35728393 35728396 23.0552
+chr9 35728396 35728398 24.2323
+chr9 35728398 35728399 26.6286
+chr9 35728399 35728401 27.8468
+chr9 35728401 35728402 29.0781
+chr9 35728402 35728405 30.3218
+chr9 35728405 35728406 31.5778
+chr9 35728406 35728409 32.8456
+chr9 35728409 35728411 34.125
+chr9 35728411 35728413 32.8456
+chr9 35728413 35728416 34.125
+chr9 35728416 35728420 35.4156
+chr9 35728420 35728423 34.125
+chr9 35728423 35728424 32.8456
+chr9 35728424 35728425 34.125
+chr9 35728425 35728427 36.7172
+chr9 35728427 35728431 38.0294
+chr9 35728431 35728432 39.3521
+chr9 35728432 35728433 40.6851
+chr9 35728433 35728438 42.0279
+chr9 35728438 35728439 40.6851
+chr9 35728439 35728440 39.3521
+chr9 35728440 35728441 40.6851
+chr9 35728441 35728442 42.0279
+chr9 35728442 35728447 43.3806
+chr9 35728447 35728448 46.1142
+chr9 35728448 35728453 48.8843
+chr9 35728453 35728454 50.2826
+chr9 35728454 35728457 51.6894
+chr9 35728457 35728458 53.1047
+chr9 35728458 35728461 54.5283
+chr9 35728461 35728462 55.96
+chr9 35728462 35728465 70.0582
+chr9 35728465 35728466 68.3337
+chr9 35728466 35728473 70.0582
+chr9 35728473 35728475 68.3337
+chr9 35728475 35728478 66.6175
+chr9 35728478 35728479 68.3337
+chr9 35728479 35728480 54.5283
+chr9 35728480 35728483 70.0582
+chr9 35728483 35728486 71.7907
+chr9 35728486 35728487 73.5313
+chr9 35728487 35728489 75.2796
+chr9 35728489 35728492 73.5313
+chr9 35728492 35728494 71.7907
+chr9 35728494 35728498 73.5313
+chr9 35728498 35728499 75.2796
+chr9 35728499 35728507 77.0356
+chr9 35728507 35728510 78.7992
+chr9 35728510 35728513 80.5702
+chr9 35728513 35728516 78.7992
+chr9 35728516 35728522 80.5702
+chr9 35728522 35728524 82.3485
+chr9 35728524 35728526 84.134
+chr9 35728526 35728536 85.9265
+chr9 35728536 35728538 87.726
+chr9 35728538 35728543 85.9265
+chr9 35728543 35728547 84.134
+chr9 35728547 35728548 85.9265
+chr9 35728548 35728550 84.134
+chr9 35728550 35728551 85.9265
+chr9 35728551 35728560 67.6883
+chr9 35728560 35728561 69.1869
+chr9 35728561 35728562 70.6922
+chr9 35728562 35728564 72.2043
+chr9 35728564 35728565 70.6922
+chr9 35728565 35728566 67.6883
+chr9 35728566 35728567 69.1869
+chr9 35728567 35728571 67.6883
+chr9 35728571 35728572 66.1967
+chr9 35728572 35728574 64.7122
+chr9 35728574 35728575 63.2349
+chr9 35728575 35728577 61.7648
+chr9 35728577 35728580 64.7122
+chr9 35728580 35728586 61.7648
+chr9 35728586 35728587 50.6919
+chr9 35728587 35728588 49.4127
+chr9 35728588 35728589 46.8775
+chr9 35728589 35728592 48.1412
+chr9 35728592 35728594 46.8775
+chr9 35728594 35728597 48.1412
+chr9 35728597 35728600 46.8775
+chr9 35728600 35728604 45.6218
+chr9 35728604 35728605 44.3741
+chr9 35728605 35728606 45.6218
+chr9 35728606 35728607 44.3741
+chr9 35728607 35728611 45.6218
+chr9 35728611 35728612 46.8775
+chr9 35728612 35728615 45.6218
+chr9 35728615 35728616 46.8775
+chr9 35728616 35728617 48.1412
+chr9 35728617 35728619 46.8775
+chr9 35728619 35728621 54.5283
+chr9 35728621 35728623 55.96
+chr9 35728623 35728624 54.5283
+chr9 35728624 35728625 55.96
+chr9 35728625 35728628 57.3996
+chr9 35728628 35728629 55.96
+chr9 35728629 35728630 57.3996
+chr9 35728630 35728631 58.847
+chr9 35728631 35728635 60.3021
+chr9 35728635 35728636 61.7648
+chr9 35728636 35728639 60.3021
+chr9 35728639 35728640 58.847
+chr9 35728640 35728642 60.3021
+chr9 35728642 35728644 58.847
+chr9 35728644 35728648 60.3021
+chr9 35728648 35728649 58.847
+chr9 35728649 35728650 60.3021
+chr9 35728650 35728653 58.847
+chr9 35728653 35728654 60.3021
+chr9 35728654 35728657 58.847
+chr9 35728657 35728662 60.3021
+chr9 35728662 35728664 61.7648
+chr9 35728664 35728671 60.3021
+chr9 35728671 35728672 61.7648
+chr9 35728672 35728675 60.3021
+chr9 35728675 35728676 61.7648
+chr9 35728676 35728677 60.3021
+chr9 35728677 35728678 61.7648
+chr9 35728678 35728679 63.2349
+chr9 35728679 35728680 64.7122
+chr9 35728680 35728681 63.2349
+chr9 35728681 35728682 64.7122
+chr9 35728682 35728686 63.2349
+chr9 35728686 35728689 61.7648
+chr9 35728689 35728691 60.3021
+chr9 35728691 35728693 75.2796
+chr9 35728693 35728694 58.847
+chr9 35728694 35728695 60.3021
+chr9 35728695 35728696 58.847
+chr9 35728696 35728697 60.3021
+chr9 35728697 35728702 61.7648
+chr9 35728702 35728706 63.2349
+chr9 35728706 35728707 61.7648
+chr9 35728707 35728709 63.2349
+chr9 35728709 35728710 64.7122
+chr9 35728710 35728711 66.1967
+chr9 35728711 35728713 67.6883
+chr9 35728713 35728716 66.1967
+chr9 35728716 35728717 67.6883
+chr9 35728717 35728719 66.1967
+chr9 35728719 35728726 67.6883
+chr9 35728726 35728729 82.9255
+chr9 35728729 35728731 81.1822
+chr9 35728731 35728733 79.4459
+chr9 35728733 35728734 77.7168
+chr9 35728734 35728736 75.9951
+chr9 35728736 35728739 74.2807
+chr9 35728739 35728743 75.9951
+chr9 35728743 35728744 77.7168
+chr9 35728744 35728746 81.1822
+chr9 35728746 35728758 82.9255
+chr9 35728758 35728759 81.1822
+chr9 35728759 35728765 82.9255
+chr9 35728765 35728766 81.1822
+chr9 35728766 35728767 79.4459
+chr9 35728767 35728768 77.7168
+chr9 35728768 35728769 81.1822
+chr9 35728769 35728770 79.4459
+chr9 35728770 35728771 77.7168
+chr9 35728771 35728772 75.9951
+chr9 35728772 35728774 74.2807
+chr9 35728774 35728776 72.5739
+chr9 35728776 35728783 74.2807
+chr9 35728783 35728785 75.9951
+chr9 35728785 35728788 74.2807
+chr9 35728788 35728790 75.9951
+chr9 35728790 35728791 77.7168
+chr9 35728791 35728792 81.1822
+chr9 35728792 35728793 82.9255
+chr9 35728793 35728794 81.1822
+chr9 35728794 35728801 82.9255
+chr9 35728801 35728802 81.1822
+chr9 35728802 35728805 76.4363
+chr9 35728805 35728812 78.1214
+chr9 35728812 35728815 79.8135
+chr9 35728815 35728819 78.1214
+chr9 35728819 35728821 74.7583
+chr9 35728821 35728832 71.4245
+chr9 35728832 35728833 69.7688
+chr9 35728833 35728834 71.4245
+chr9 35728834 35728836 69.7688
+chr9 35728836 35728837 66.4806
+chr9 35728837 35728842 64.8484
+chr9 35728842 35728850 61.6085
+chr9 35728850 35728854 60.001
+chr9 35728854 35728857 61.6085
+chr9 35728857 35728858 60.001
+chr9 35728858 35728859 61.6085
+chr9 35728859 35728861 60.001
+chr9 35728861 35728863 61.6085
+chr9 35728863 35728866 63.2243
+chr9 35728866 35728873 64.8484
+chr9 35728873 35728879 66.4806
+chr9 35728879 35728880 64.8484
+chr9 35728880 35728884 66.4806
+chr9 35728884 35728885 64.8484
+chr9 35728885 35728886 63.2243
+chr9 35728886 35728888 60.001
+chr9 35728888 35728892 58.4022
+chr9 35728892 35728894 60.8494
+chr9 35728894 35728896 59.2082
+chr9 35728896 35728898 57.5759
+chr9 35728898 35728899 59.2082
+chr9 35728899 35728901 55.9528
+chr9 35728901 35728904 54.3391
+chr9 35728904 35728908 52.7348
+chr9 35728908 35728910 49.5558
+chr9 35728910 35728914 51.9324
+chr9 35728914 35728915 53.5749
+chr9 35728915 35728916 51.9324
+chr9 35728916 35728917 50.3001
+chr9 35728917 35728919 49.9491
+chr9 35728919 35728921 48.336
+chr9 35728921 35728922 46.7337
+chr9 35728922 35728923 48.336
+chr9 35728923 35728924 46.7337
+chr9 35728924 35728926 45.1423
+chr9 35728926 35728929 43.5622
+chr9 35728929 35728931 41.9937
+chr9 35728931 35728932 38.8926
+chr9 35728932 35728934 37.3607
+chr9 35728934 35728936 35.8418
+chr9 35728936 35728937 34.3362
+chr9 35728937 35728939 32.8443
+chr9 35728939 35728942 34.3362
+chr9 35728942 35728945 32.8443
+chr9 35728945 35728949 31.3667
+chr9 35728949 35728950 29.9038
+chr9 35728950 35728951 31.3667
+chr9 35728951 35728952 29.9038
+chr9 35728952 35728953 28.456
+chr9 35728953 35728957 27.0241
+chr9 35728957 35728958 25.6084
+chr9 35728958 35728960 24.2098
+chr9 35728960 35728967 25.6084
+chr9 35728967 35728971 24.2098
+chr9 35728971 35728973 25.6084
+chr9 35728973 35728979 24.2098
+chr9 35728979 35728980 22.8288
+chr9 35728980 35728987 21.4662
+chr9 35728987 35728991 20.1229
+chr9 35728991 35728994 18.7997
+chr9 35728994 35728996 17.4975
+chr9 35728996 35728998 16.2176
+chr9 35728998 35729001 14.9609
+chr9 35729001 35729002 12.5232
+chr9 35729002 35729003 13.729
+chr9 35729003 35729009 12.5232
+chr9 35729009 35729011 11.3451
+chr9 35729011 35729014 10.1968
+chr9 35729014 35729015 9.08031
+chr9 35729015 35729018 10.1968
+chr9 35729018 35729020 9.08031
+chr9 35729020 35729021 7.99814
+chr9 35729021 35729022 6.9532
+chr9 35729022 35729023 7.99814
+chr9 35729023 35729038 6.9532
+chr9 35729038 35729045 5.94894
+chr9 35729045 35729057 6.9532
+chr9 35729057 35729062 7.45196
+chr9 35729062 35729079 6.39373
+chr9 35729079 35729084 5.38041
+chr9 35729084 35729090 6.39373
+chr9 35729090 35729095 5.38041
+chr9 35729095 35729125 6.39373
+chr9 35729125 35729128 8.55095
+chr9 35729128 35729130 7.99814
+chr9 35729130 35729132 9.08031
+chr9 35729132 35729141 10.1968
+chr9 35729141 35729145 11.3451
+chr9 35729145 35729147 12.5232
+chr9 35729147 35729149 13.729
+chr9 35729149 35729170 14.9609
+chr9 35729170 35729171 16.2176
+chr9 35729171 35729175 17.4975
+chr9 35729175 35729177 18.7997
+chr9 35729177 35729179 20.1229
+chr9 35729179 35729182 21.4662
+chr9 35729182 35729183 22.8288
+chr9 35729183 35729184 24.2098
+chr9 35729184 35729188 25.6084
+chr9 35729188 35729192 27.0241
+chr9 35729192 35729194 28.456
+chr9 35729194 35729199 27.0241
+chr9 35729199 35729201 28.456
+chr9 35729201 35729202 29.9038
+chr9 35729202 35729204 31.3667
+chr9 35729204 35729205 32.8443
+chr9 35729205 35729209 34.3362
+chr9 35729209 35729211 35.8418
+chr9 35729211 35729213 37.3607
+chr9 35729213 35729214 40.437
+chr9 35729214 35729216 41.9937
+chr9 35729216 35729219 43.5622
+chr9 35729219 35729226 45.1423
+chr9 35729226 35729228 48.336
+chr9 35729228 35729232 49.9491
+chr9 35729232 35729236 38.0294
+chr9 35729236 35729238 39.3521
+chr9 35729238 35729243 40.6851
+chr9 35729243 35729245 42.0279
+chr9 35729245 35729247 43.3806
+chr9 35729247 35729248 44.7427
+chr9 35729248 35729250 46.1142
+chr9 35729250 35729253 47.4948
+chr9 35729253 35729256 48.8843
+chr9 35729256 35729257 50.2826
+chr9 35729257 35729258 51.6894
+chr9 35729258 35729260 54.5283
+chr9 35729260 35729261 55.96
+chr9 35729261 35729263 57.3996
+chr9 35729263 35729265 58.847
+chr9 35729265 35729268 55.96
+chr9 35729268 35729270 73.5313
+chr9 35729270 35729272 71.7907
+chr9 35729272 35729273 70.0582
+chr9 35729273 35729274 71.7907
+chr9 35729274 35729275 73.5313
+chr9 35729275 35729278 75.2796
+chr9 35729278 35729281 77.0356
+chr9 35729281 35729282 75.2796
+chr9 35729282 35729287 73.5313
+chr9 35729287 35729289 71.7907
+chr9 35729289 35729290 70.0582
+chr9 35729290 35729293 71.7907
+chr9 35729293 35729294 70.0582
+chr9 35729294 35729296 71.7907
+chr9 35729296 35729300 70.0582
+chr9 35729300 35729302 73.5313
+chr9 35729302 35729303 75.2796
+chr9 35729303 35729307 77.0356
+chr9 35729307 35729308 78.7992
+chr9 35729308 35729309 80.5702
+chr9 35729309 35729311 82.3485
+chr9 35729311 35729316 80.5702
+chr9 35729316 35729317 82.3485
+chr9 35729317 35729321 84.134
+chr9 35729321 35729323 85.9265
+chr9 35729323 35729324 84.134
+chr9 35729324 35729326 82.3485
+chr9 35729326 35729334 85.9265
+chr9 35729334 35729336 87.726
+chr9 35729336 35729341 89.5323
+chr9 35729341 35729343 91.3453
+chr9 35729343 35729348 93.165
+chr9 35729348 35729349 96.8238
+chr9 35729349 35729350 94.9912
+chr9 35729350 35729353 96.8238
+chr9 35729353 35729356 93.165
+chr9 35729356 35729357 91.3453
+chr9 35729357 35729358 93.165
+chr9 35729358 35729359 91.3453
+chr9 35729359 35729364 89.5323
+chr9 35729364 35729366 87.726
+chr9 35729366 35729372 85.9265
+chr9 35729372 35729373 90.6832
+chr9 35729373 35729378 88.8361
+chr9 35729378 35729379 86.9959
+chr9 35729379 35729380 88.8361
+chr9 35729380 35729381 90.6832
+chr9 35729381 35729383 92.5372
+chr9 35729383 35729384 90.6832
+chr9 35729384 35729387 88.8361
+chr9 35729387 35729390 85.1628
+chr9 35729390 35729391 83.3369
+chr9 35729391 35729393 81.5183
+chr9 35729393 35729394 83.3369
+chr9 35729394 35729398 81.5183
+chr9 35729398 35729400 79.7071
+chr9 35729400 35729404 80.0916
+chr9 35729404 35729406 81.9097
+chr9 35729406 35729408 83.7352
+chr9 35729408 35729409 85.5679
+chr9 35729409 35729411 87.4079
+chr9 35729411 35729413 89.2549
+chr9 35729413 35729414 87.4079
+chr9 35729414 35729415 85.5679
+chr9 35729415 35729416 83.7352
+chr9 35729416 35729418 85.5679
+chr9 35729418 35729419 81.9097
+chr9 35729419 35729421 83.7352
+chr9 35729421 35729424 85.5679
+chr9 35729424 35729425 89.2549
+chr9 35729425 35729428 87.4079
+chr9 35729428 35729430 89.2549
+chr9 35729430 35729431 87.4079
+chr9 35729431 35729440 89.2549
+chr9 35729440 35729442 87.4079
+chr9 35729442 35729443 85.5679
+chr9 35729443 35729445 83.7352
+chr9 35729445 35729446 81.9097
+chr9 35729446 35729448 80.0916
+chr9 35729448 35729449 78.2811
+chr9 35729449 35729450 76.4783
+chr9 35729450 35729451 74.6833
+chr9 35729451 35729456 76.4783
+chr9 35729456 35729457 74.6833
+chr9 35729457 35729458 72.8962
+chr9 35729458 35729459 71.1173
+chr9 35729459 35729462 69.3466
+chr9 35729462 35729464 67.5844
+chr9 35729464 35729465 69.3466
+chr9 35729465 35729466 67.5844
+chr9 35729466 35729468 65.8308
+chr9 35729468 35729469 64.0859
+chr9 35729469 35729472 65.8308
+chr9 35729472 35729473 64.0859
+chr9 35729473 35729474 65.8308
+chr9 35729474 35729476 64.0859
+chr9 35729476 35729481 62.35
+chr9 35729481 35729483 58.9057
+chr9 35729483 35729484 57.1978
+chr9 35729484 35729486 53.8115
+chr9 35729486 35729487 55.4996
+chr9 35729487 35729488 57.1978
+chr9 35729488 35729490 55.4996
+chr9 35729490 35729491 53.8115
+chr9 35729491 35729495 52.1335
+chr9 35729495 35729497 53.8115
+chr9 35729497 35729500 52.1335
+chr9 35729500 35729502 53.8115
+chr9 35729502 35729503 55.4996
+chr9 35729503 35729504 57.1978
+chr9 35729504 35729508 58.9057
+chr9 35729508 35729509 60.6232
+chr9 35729509 35729510 64.0859
+chr9 35729510 35729511 62.35
+chr9 35729511 35729515 64.0859
+chr9 35729515 35729516 62.35
+chr9 35729516 35729517 60.6232
+chr9 35729517 35729519 62.35
+chr9 35729519 35729521 60.6232
+chr9 35729521 35729522 58.9057
+chr9 35729522 35729523 60.6232
+chr9 35729523 35729524 62.35
+chr9 35729524 35729525 64.0859
+chr9 35729525 35729528 65.8308
+chr9 35729528 35729530 64.0859
+chr9 35729530 35729533 66.1659
+chr9 35729533 35729535 64.4141
+chr9 35729535 35729536 66.1659
+chr9 35729536 35729537 64.4141
+chr9 35729537 35729540 62.6712
+chr9 35729540 35729541 60.9374
+chr9 35729541 35729543 59.213
+chr9 35729543 35729544 57.4981
+chr9 35729544 35729546 55.793
+chr9 35729546 35729548 56.0913
+chr9 35729548 35729554 52.697
+chr9 35729554 35729557 54.389
+chr9 35729557 35729558 56.0913
+chr9 35729558 35729559 57.8035
+chr9 35729559 35729561 56.0913
+chr9 35729561 35729562 54.389
+chr9 35729562 35729564 56.0913
+chr9 35729564 35729565 52.697
+chr9 35729565 35729566 54.389
+chr9 35729566 35729571 52.697
+chr9 35729571 35729572 51.0155
+chr9 35729572 35729575 52.697
+chr9 35729575 35729584 50.3001
+chr9 35729584 35729587 51.9324
+chr9 35729587 35729589 53.5749
+chr9 35729589 35729590 55.2273
+chr9 35729590 35729592 56.8895
+chr9 35729592 35729593 58.5613
+chr9 35729593 35729601 60.2424
+chr9 35729601 35729602 58.5613
+chr9 35729602 35729604 60.2424
+chr9 35729604 35729605 58.5613
+chr9 35729605 35729606 56.8895
+chr9 35729606 35729607 58.5613
+chr9 35729607 35729609 60.2424
+chr9 35729609 35729611 58.5613
+chr9 35729611 35729612 60.2424
+chr9 35729612 35729618 61.9326
+chr9 35729618 35729619 63.6317
+chr9 35729619 35729622 61.9326
+chr9 35729622 35729623 60.2424
+chr9 35729623 35729625 61.9326
+chr9 35729625 35729627 60.2424
+chr9 35729627 35729628 58.5613
+chr9 35729628 35729629 56.8895
+chr9 35729629 35729632 58.5613
+chr9 35729632 35729633 56.8895
+chr9 35729633 35729634 58.5613
+chr9 35729634 35729635 60.2424
+chr9 35729635 35729636 58.5613
+chr9 35729636 35729638 60.2424
+chr9 35729638 35729640 63.6317
+chr9 35729640 35729642 61.9326
+chr9 35729642 35729643 57.5759
+chr9 35729643 35729645 55.9528
+chr9 35729645 35729646 59.2082
+chr9 35729646 35729651 57.5759
+chr9 35729651 35729652 59.2082
+chr9 35729652 35729657 57.5759
+chr9 35729657 35729662 59.2082
+chr9 35729662 35729665 57.5759
+chr9 35729665 35729667 59.2082
+chr9 35729667 35729669 60.8494
+chr9 35729669 35729671 48.8843
+chr9 35729671 35729672 47.4948
+chr9 35729672 35729677 48.8843
+chr9 35729677 35729678 50.2826
+chr9 35729678 35729682 48.8843
+chr9 35729682 35729685 50.2826
+chr9 35729685 35729687 51.6894
+chr9 35729687 35729689 53.1047
+chr9 35729689 35729690 54.5283
+chr9 35729690 35729692 53.1047
+chr9 35729692 35729693 51.6894
+chr9 35729693 35729694 54.5283
+chr9 35729694 35729695 53.1047
+chr9 35729695 35729696 54.5283
+chr9 35729696 35729700 53.1047
+chr9 35729700 35729703 54.5283
+chr9 35729703 35729709 55.96
+chr9 35729709 35729710 57.3996
+chr9 35729710 35729712 60.3021
+chr9 35729712 35729713 58.847
+chr9 35729713 35729718 60.3021
+chr9 35729718 35729722 61.7648
+chr9 35729722 35729723 64.7122
+chr9 35729723 35729727 66.1967
+chr9 35729727 35729730 64.7122
+chr9 35729730 35729732 63.2349
+chr9 35729732 35729735 60.3021
+chr9 35729735 35729737 58.847
+chr9 35729737 35729739 60.3021
+chr9 35729739 35729742 61.7648
+chr9 35729742 35729745 60.3021
+chr9 35729745 35729746 61.7648
+chr9 35729746 35729755 60.3021
+chr9 35729755 35729762 61.7648
+chr9 35729762 35729764 63.2349
+chr9 35729764 35729767 64.7122
+chr9 35729767 35729768 66.1967
+chr9 35729768 35729774 67.6883
+chr9 35729774 35729775 66.1967
+chr9 35729775 35729776 67.6883
+chr9 35729776 35729777 66.1967
+chr9 35729777 35729778 67.6883
+chr9 35729778 35729782 64.7122
+chr9 35729782 35729784 66.1967
+chr9 35729784 35729785 64.7122
+chr9 35729785 35729788 63.2349
+chr9 35729788 35729789 64.7122
+chr9 35729789 35729791 61.7648
+chr9 35729791 35729793 60.3021
+chr9 35729793 35729795 63.2349
+chr9 35729795 35729797 64.7122
+chr9 35729797 35729799 63.2349
+chr9 35729799 35729800 61.7648
+chr9 35729800 35729801 60.3021
+chr9 35729801 35729802 61.7648
+chr9 35729802 35729803 80.5702
+chr9 35729803 35729805 78.7992
+chr9 35729805 35729807 77.0356
+chr9 35729807 35729809 72.5739
+chr9 35729809 35729812 70.8747
+chr9 35729812 35729815 69.1834
+chr9 35729815 35729817 67.5001
+chr9 35729817 35729818 65.8249
+chr9 35729818 35729822 67.5001
+chr9 35729822 35729825 65.8249
+chr9 35729825 35729826 64.1579
+chr9 35729826 35729827 62.4993
+chr9 35729827 35729830 60.8494
+chr9 35729830 35729833 62.4993
+chr9 35729833 35729834 60.8494
+chr9 35729834 35729837 64.1579
+chr9 35729837 35729840 62.4993
+chr9 35729840 35729843 60.8494
+chr9 35729843 35729845 57.5759
+chr9 35729845 35729849 55.9528
+chr9 35729849 35729850 54.3391
+chr9 35729850 35729852 52.7348
+chr9 35729852 35729853 54.3391
+chr9 35729853 35729854 51.1403
+chr9 35729854 35729856 49.5558
+chr9 35729856 35729857 47.9815
+chr9 35729857 35729858 49.5558
+chr9 35729858 35729862 47.9815
+chr9 35729862 35729864 44.8645
+chr9 35729864 35729865 43.3223
+chr9 35729865 35729868 44.8645
+chr9 35729868 35729871 46.4176
+chr9 35729871 35729872 44.8645
+chr9 35729872 35729874 46.4176
+chr9 35729874 35729877 47.9815
+chr9 35729877 35729883 46.4176
+chr9 35729883 35729890 47.9815
+chr9 35729890 35729891 49.5558
+chr9 35729891 35729894 47.9815
+chr9 35729894 35729895 46.4176
+chr9 35729895 35729898 44.8645
+chr9 35729898 35729901 43.3223
+chr9 35729901 35729902 44.8645
+chr9 35729902 35729903 43.3223
+chr9 35729903 35729906 41.7914
+chr9 35729906 35729907 40.272
+chr9 35729907 35729909 38.7646
+chr9 35729909 35729912 35.7866
+chr9 35729912 35729914 37.2693
+chr9 35729914 35729915 38.7646
+chr9 35729915 35729922 37.2693
+chr9 35729922 35729927 35.7866
+chr9 35729927 35729928 34.3169
+chr9 35729928 35729931 32.8605
+chr9 35729931 35729933 31.4178
+chr9 35729933 35729938 29.9893
+chr9 35729938 35729939 31.4178
+chr9 35729939 35729940 32.8605
+chr9 35729940 35729941 34.3169
+chr9 35729941 35729942 32.8605
+chr9 35729942 35729944 31.4178
+chr9 35729944 35729946 29.9893
+chr9 35729946 35729948 31.4178
+chr9 35729948 35729949 32.8605
+chr9 35729949 35729955 34.3169
+chr9 35729955 35729958 35.7866
+chr9 35729958 35729959 34.3169
+chr9 35729959 35729961 35.7866
+chr9 35729961 35729963 27.8468
+chr9 35729963 35729968 30.3218
+chr9 35729968 35729970 31.5778
+chr9 35729970 35729972 30.3218
+chr9 35729972 35729973 31.5778
+chr9 35729973 35729974 30.3218
+chr9 35729974 35729982 27.8468
+chr9 35729982 35729985 29.0781
+chr9 35729985 35729986 30.3218
+chr9 35729986 35729992 31.5778
+chr9 35729992 35729993 30.3218
+chr9 35729993 35729994 31.5778
+chr9 35729994 35729997 32.8456
+chr9 35729997 35729998 31.5778
+chr9 35729998 35730005 32.8456
+chr9 35730005 35730007 26.7526
+chr9 35730007 35730008 27.8562
+chr9 35730008 35730012 26.7526
+chr9 35730012 35730016 31.5778
+chr9 35730016 35730018 32.8456
+chr9 35730018 35730019 31.5778
+chr9 35730019 35730023 30.3218
+chr9 35730023 35730025 29.0781
+chr9 35730025 35730026 30.3218
+chr9 35730026 35730029 29.0781
+chr9 35730029 35730030 30.3218
+chr9 35730030 35730031 29.0781
+chr9 35730031 35730032 30.3218
+chr9 35730032 35730034 31.5778
+chr9 35730034 35730039 32.8456
+chr9 35730039 35730040 34.125
+chr9 35730040 35730041 35.4156
+chr9 35730041 35730043 34.125
+chr9 35730043 35730044 35.4156
+chr9 35730044 35730046 36.7172
+chr9 35730046 35730049 38.0294
+chr9 35730049 35730051 39.3521
+chr9 35730051 35730052 40.6851
+chr9 35730052 35730053 39.3521
+chr9 35730053 35730056 40.6851
+chr9 35730056 35730058 42.0279
+chr9 35730058 35730072 43.3806
+chr9 35730072 35730078 35.8811
+chr9 35730078 35730083 34.7044
+chr9 35730083 35730088 35.8811
+chr9 35730088 35730089 34.7044
+chr9 35730089 35730090 33.5373
+chr9 35730090 35730091 34.7044
+chr9 35730091 35730093 35.8811
+chr9 35730093 35730094 38.263
+chr9 35730094 35730095 39.4677
+chr9 35730095 35730096 38.263
+chr9 35730096 35730100 39.4677
+chr9 35730100 35730101 40.6814
+chr9 35730101 35730103 48.8843
+chr9 35730103 35730105 47.4948
+chr9 35730105 35730107 48.8843
+chr9 35730107 35730108 50.2826
+chr9 35730108 35730114 48.8843
+chr9 35730114 35730118 50.2826
+chr9 35730118 35730119 48.8843
+chr9 35730119 35730120 50.2826
+chr9 35730120 35730122 51.6894
+chr9 35730122 35730130 50.2826
+chr9 35730130 35730131 51.6894
+chr9 35730131 35730133 53.1047
+chr9 35730133 35730134 51.6894
+chr9 35730134 35730138 50.2826
+chr9 35730138 35730143 48.8843
+chr9 35730143 35730145 47.4948
+chr9 35730145 35730147 57.5759
+chr9 35730147 35730149 55.9528
+chr9 35730149 35730153 57.5759
+chr9 35730153 35730154 59.2082
+chr9 35730154 35730156 57.5759
+chr9 35730156 35730158 55.9528
+chr9 35730158 35730160 57.5759
+chr9 35730160 35730163 59.2082
+chr9 35730163 35730165 60.8494
+chr9 35730165 35730167 59.2082
+chr9 35730167 35730169 60.8494
+chr9 35730169 35730171 59.2082
+chr9 35730171 35730173 57.5759
+chr9 35730173 35730174 55.9528
+chr9 35730174 35730175 54.3391
+chr9 35730175 35730176 55.9528
+chr9 35730176 35730177 57.5759
+chr9 35730177 35730179 55.9528
+chr9 35730179 35730183 57.5759
+chr9 35730183 35730186 55.9528
+chr9 35730186 35730189 54.3391
+chr9 35730189 35730190 52.0964
+chr9 35730190 35730192 53.6591
+chr9 35730192 35730193 55.231
+chr9 35730193 35730196 53.6591
+chr9 35730196 35730203 52.0964
+chr9 35730203 35730206 53.6591
+chr9 35730206 35730207 55.231
+chr9 35730207 35730209 56.8122
+chr9 35730209 35730211 58.4022
+chr9 35730211 35730212 60.001
+chr9 35730212 35730213 61.6085
+chr9 35730213 35730216 63.2243
+chr9 35730216 35730220 64.8484
+chr9 35730220 35730221 63.2243
+chr9 35730221 35730224 64.8484
+chr9 35730224 35730225 66.4806
+chr9 35730225 35730231 68.1208
+chr9 35730231 35730232 66.4806
+chr9 35730232 35730233 69.1834
+chr9 35730233 35730237 67.5001
+chr9 35730237 35730238 55.96
+chr9 35730238 35730239 57.3996
+chr9 35730239 35730240 55.96
+chr9 35730240 35730241 54.5283
+chr9 35730241 35730242 55.96
+chr9 35730242 35730245 54.5283
+chr9 35730245 35730246 53.1047
+chr9 35730246 35730247 51.6894
+chr9 35730247 35730250 50.2826
+chr9 35730250 35730251 51.6894
+chr9 35730251 35730253 53.1047
+chr9 35730253 35730254 51.6894
+chr9 35730254 35730255 50.2826
+chr9 35730255 35730257 51.6894
+chr9 35730257 35730260 50.2826
+chr9 35730260 35730266 48.8843
+chr9 35730266 35730269 47.4948
+chr9 35730269 35730270 48.8843
+chr9 35730270 35730271 47.4948
+chr9 35730271 35730273 46.1142
+chr9 35730273 35730275 47.4948
+chr9 35730275 35730280 48.8843
+chr9 35730280 35730281 50.2826
+chr9 35730281 35730286 51.6894
+chr9 35730286 35730291 54.5283
+chr9 35730291 35730292 55.96
+chr9 35730292 35730293 57.3996
+chr9 35730293 35730294 55.96
+chr9 35730294 35730300 57.3996
+chr9 35730300 35730303 55.96
+chr9 35730303 35730306 54.5283
+chr9 35730306 35730307 55.96
+chr9 35730307 35730310 54.5283
+chr9 35730310 35730311 55.96
+chr9 35730311 35730312 57.3996
+chr9 35730312 35730313 55.96
+chr9 35730313 35730315 57.3996
+chr9 35730315 35730319 55.96
+chr9 35730319 35730320 54.5283
+chr9 35730320 35730322 53.1047
+chr9 35730322 35730324 54.5283
+chr9 35730324 35730325 53.1047
+chr9 35730325 35730327 54.5283
+chr9 35730327 35730328 53.1047
+chr9 35730328 35730329 51.6894
+chr9 35730329 35730330 50.2826
+chr9 35730330 35730332 48.8843
+chr9 35730332 35730335 47.4948
+chr9 35730335 35730339 48.8843
+chr9 35730339 35730340 47.4948
+chr9 35730340 35730343 48.8843
+chr9 35730343 35730344 47.4948
+chr9 35730344 35730346 48.8843
+chr9 35730346 35730347 47.4948
+chr9 35730347 35730349 48.8843
+chr9 35730349 35730352 47.4948
+chr9 35730352 35730353 46.1142
+chr9 35730353 35730354 44.7427
+chr9 35730354 35730355 47.4948
+chr9 35730355 35730356 46.1142
+chr9 35730356 35730361 43.3806
+chr9 35730361 35730364 42.0279
+chr9 35730364 35730365 40.6851
+chr9 35730365 35730370 39.3521
+chr9 35730370 35730375 38.0294
+chr9 35730375 35730376 36.7172
+chr9 35730376 35730386 44.8645
+chr9 35730386 35730388 46.4176
+chr9 35730388 35730392 47.9815
+chr9 35730392 35730395 46.4176
+chr9 35730395 35730399 44.8645
+chr9 35730399 35730402 43.3223
+chr9 35730402 35730404 44.8645
+chr9 35730404 35730408 46.4176
+chr9 35730408 35730415 47.9815
+chr9 35730415 35730416 46.4176
+chr9 35730416 35730417 44.8645
+chr9 35730417 35730418 46.4176
+chr9 35730418 35730420 47.9815
+chr9 35730420 35730421 46.4176
+chr9 35730421 35730424 44.8645
+chr9 35730424 35730426 46.4176
+chr9 35730426 35730427 43.3223
+chr9 35730427 35730429 44.8645
+chr9 35730429 35730432 43.3223
+chr9 35730432 35730438 41.7914
+chr9 35730438 35730442 40.272
+chr9 35730442 35730446 42.3009
+chr9 35730446 35730448 40.7354
+chr9 35730448 35730450 39.1822
+chr9 35730450 35730452 37.6416
+chr9 35730452 35730453 39.1822
+chr9 35730453 35730458 37.6416
+chr9 35730458 35730466 39.1822
+chr9 35730466 35730467 40.7354
+chr9 35730467 35730468 42.3009
+chr9 35730468 35730475 43.8782
+chr9 35730475 35730478 42.3009
+chr9 35730478 35730480 40.7354
+chr9 35730480 35730481 39.1822
+chr9 35730481 35730482 40.7354
+chr9 35730482 35730484 42.3009
+chr9 35730484 35730487 40.7354
+chr9 35730487 35730490 37.6416
+chr9 35730490 35730491 36.1139
+chr9 35730491 35730492 34.5996
+chr9 35730492 35730493 36.1139
+chr9 35730493 35730494 37.6416
+chr9 35730494 35730495 34.5996
+chr9 35730495 35730498 36.1139
+chr9 35730498 35730501 37.6416
+chr9 35730501 35730502 39.1822
+chr9 35730502 35730511 37.6416
+chr9 35730511 35730512 39.1822
+chr9 35730512 35730513 40.7354
+chr9 35730513 35730517 39.1822
+chr9 35730517 35730519 37.6416
+chr9 35730519 35730521 39.1822
+chr9 35730521 35730525 37.6416
+chr9 35730525 35730526 39.1822
+chr9 35730526 35730530 37.6416
+chr9 35730530 35730531 36.1139
+chr9 35730531 35730539 38.1976
+chr9 35730539 35730542 39.7922
+chr9 35730542 35730544 38.1976
+chr9 35730544 35730549 36.6163
+chr9 35730549 35730551 35.0488
+chr9 35730551 35730558 33.4956
+chr9 35730558 35730560 31.957
+chr9 35730560 35730571 33.4956
+chr9 35730571 35730572 31.957
+chr9 35730572 35730575 33.4956
+chr9 35730575 35730582 33.9098
+chr9 35730582 35730584 35.4777
+chr9 35730584 35730590 33.9098
+chr9 35730590 35730591 35.4777
+chr9 35730591 35730595 33.9098
+chr9 35730595 35730596 35.4777
+chr9 35730596 35730598 36.6163
+chr9 35730598 35730599 35.0488
+chr9 35730599 35730601 36.6163
+chr9 35730601 35730602 38.1976
+chr9 35730602 35730604 36.6163
+chr9 35730604 35730605 38.1976
+chr9 35730605 35730611 36.6163
+chr9 35730611 35730613 38.1976
+chr9 35730613 35730616 39.7922
+chr9 35730616 35730619 38.1976
+chr9 35730619 35730622 35.8418
+chr9 35730622 35730627 34.3362
+chr9 35730627 35730629 35.8418
+chr9 35730629 35730633 37.3607
+chr9 35730633 35730635 35.8418
+chr9 35730635 35730641 37.3607
+chr9 35730641 35730644 35.8418
+chr9 35730644 35730645 34.3362
+chr9 35730645 35730647 35.8418
+chr9 35730647 35730648 37.3607
+chr9 35730648 35730650 35.8418
+chr9 35730650 35730651 37.3607
+chr9 35730651 35730652 35.8418
+#bedGraph section chr9:35730652-35733148
+chr9 35730652 35730655 34.3362
+chr9 35730655 35730658 35.8418
+chr9 35730658 35730659 34.3362
+chr9 35730659 35730660 32.8443
+chr9 35730660 35730663 34.3362
+chr9 35730663 35730665 35.8418
+chr9 35730665 35730666 34.3362
+chr9 35730666 35730671 35.8418
+chr9 35730671 35730672 34.3362
+chr9 35730672 35730673 35.8418
+chr9 35730673 35730679 37.3607
+chr9 35730679 35730680 35.8418
+chr9 35730680 35730685 37.3607
+chr9 35730685 35730687 38.8926
+chr9 35730687 35730693 40.437
+chr9 35730693 35730694 41.9937
+chr9 35730694 35730695 43.5622
+chr9 35730695 35730699 45.1423
+chr9 35730699 35730701 46.7337
+chr9 35730701 35730702 48.336
+chr9 35730702 35730707 46.7337
+chr9 35730707 35730709 45.1423
+chr9 35730709 35730712 46.7337
+chr9 35730712 35730713 45.1423
+chr9 35730713 35730714 43.5622
+chr9 35730714 35730715 45.1423
+chr9 35730715 35730719 46.7337
+chr9 35730719 35730721 48.336
+chr9 35730721 35730722 49.9491
+chr9 35730722 35730724 48.336
+chr9 35730724 35730731 49.9491
+chr9 35730731 35730732 51.5726
+chr9 35730732 35730735 53.2063
+chr9 35730735 35730736 51.5726
+chr9 35730736 35730741 49.9491
+chr9 35730741 35730742 48.336
+chr9 35730742 35730747 49.9491
+chr9 35730747 35730748 48.336
+chr9 35730748 35730751 45.1423
+chr9 35730751 35730759 43.5622
+chr9 35730759 35730768 45.7804
+chr9 35730768 35730769 47.4219
+chr9 35730769 35730771 45.7804
+chr9 35730771 35730772 47.4219
+chr9 35730772 35730774 45.7804
+chr9 35730774 35730775 49.0747
+chr9 35730775 35730780 45.7804
+chr9 35730780 35730785 43.5622
+chr9 35730785 35730790 41.9937
+chr9 35730790 35730792 40.437
+chr9 35730792 35730796 41.9937
+chr9 35730796 35730797 43.5622
+chr9 35730797 35730798 45.1423
+chr9 35730798 35730799 46.7337
+chr9 35730799 35730800 48.336
+chr9 35730800 35730801 46.7337
+chr9 35730801 35730802 48.336
+chr9 35730802 35730805 49.9491
+chr9 35730805 35730810 51.5726
+chr9 35730810 35730812 53.2063
+chr9 35730812 35730813 51.5726
+chr9 35730813 35730815 49.9491
+chr9 35730815 35730819 51.5726
+chr9 35730819 35730821 53.2063
+chr9 35730821 35730822 54.85
+chr9 35730822 35730826 53.2063
+chr9 35730826 35730828 54.85
+chr9 35730828 35730830 53.2063
+chr9 35730830 35730831 54.85
+chr9 35730831 35730835 56.5035
+chr9 35730835 35730838 53.2063
+chr9 35730838 35730840 54.85
+chr9 35730840 35730841 53.2063
+chr9 35730841 35730843 51.5726
+chr9 35730843 35730846 54.85
+chr9 35730846 35730847 56.5035
+chr9 35730847 35730849 58.1665
+chr9 35730849 35730852 56.5035
+chr9 35730852 35730854 58.1665
+chr9 35730854 35730856 56.5035
+chr9 35730856 35730857 58.1665
+chr9 35730857 35730858 59.8388
+chr9 35730858 35730859 61.5202
+chr9 35730859 35730861 59.8388
+chr9 35730861 35730863 58.1665
+chr9 35730863 35730864 59.8388
+chr9 35730864 35730868 56.5035
+chr9 35730868 35730869 58.1665
+chr9 35730869 35730870 59.8388
+chr9 35730870 35730871 58.1665
+chr9 35730871 35730873 56.5035
+chr9 35730873 35730879 58.1665
+chr9 35730879 35730881 59.8388
+chr9 35730881 35730883 61.5202
+chr9 35730883 35730885 59.8388
+chr9 35730885 35730887 61.5202
+chr9 35730887 35730890 63.2106
+chr9 35730890 35730893 64.9098
+chr9 35730893 35730895 66.6175
+chr9 35730895 35730900 64.9098
+chr9 35730900 35730901 66.6175
+chr9 35730901 35730902 68.3337
+chr9 35730902 35730903 70.0582
+chr9 35730903 35730905 68.3337
+chr9 35730905 35730907 70.0582
+chr9 35730907 35730911 71.7907
+chr9 35730911 35730920 70.0582
+chr9 35730920 35730924 73.2592
+chr9 35730924 35730928 75.0532
+chr9 35730928 35730929 76.8551
+chr9 35730929 35730931 78.6649
+chr9 35730931 35730932 80.4824
+chr9 35730932 35730934 78.6649
+chr9 35730934 35730935 80.4824
+chr9 35730935 35730937 78.6649
+chr9 35730937 35730938 76.8551
+chr9 35730938 35730939 75.0532
+chr9 35730939 35730942 73.2592
+chr9 35730942 35730944 69.6957
+chr9 35730944 35730945 71.4733
+chr9 35730945 35730946 73.2592
+chr9 35730946 35730947 71.4733
+chr9 35730947 35730953 73.2592
+chr9 35730953 35730954 75.0532
+chr9 35730954 35730955 76.8551
+chr9 35730955 35730956 75.0532
+chr9 35730956 35730959 78.6649
+chr9 35730959 35730960 76.8551
+chr9 35730960 35730961 75.0532
+chr9 35730961 35730962 73.2592
+chr9 35730962 35730963 75.0532
+chr9 35730963 35730964 76.8551
+chr9 35730964 35730966 78.6649
+chr9 35730966 35730967 76.8551
+chr9 35730967 35730968 75.0532
+chr9 35730968 35730969 78.6649
+chr9 35730969 35730970 80.4824
+chr9 35730970 35730971 78.6649
+chr9 35730971 35730975 80.4824
+chr9 35730975 35730976 82.3074
+chr9 35730976 35730977 84.1399
+chr9 35730977 35730983 85.9796
+chr9 35730983 35730986 84.1399
+chr9 35730986 35730987 82.3074
+chr9 35730987 35730991 80.4824
+chr9 35730991 35730992 84.1399
+chr9 35730992 35730995 82.3074
+chr9 35730995 35730996 84.1399
+chr9 35730996 35730997 82.3074
+chr9 35730997 35731008 80.4824
+chr9 35731008 35731009 78.6649
+chr9 35731009 35731012 76.8551
+chr9 35731012 35731013 75.0532
+chr9 35731013 35731019 73.2592
+chr9 35731019 35731021 71.4733
+chr9 35731021 35731022 69.6957
+chr9 35731022 35731023 67.9265
+chr9 35731023 35731026 67.5844
+chr9 35731026 35731029 63.2106
+chr9 35731029 35731032 61.5202
+chr9 35731032 35731033 63.2106
+chr9 35731033 35731035 61.5202
+chr9 35731035 35731041 63.2106
+chr9 35731041 35731042 61.5202
+chr9 35731042 35731045 59.8388
+chr9 35731045 35731047 56.5035
+chr9 35731047 35731048 54.85
+chr9 35731048 35731049 53.2063
+chr9 35731049 35731054 54.85
+chr9 35731054 35731055 53.2063
+chr9 35731055 35731060 51.5726
+chr9 35731060 35731063 53.2063
+chr9 35731063 35731064 54.85
+chr9 35731064 35731067 53.2063
+chr9 35731067 35731069 51.5726
+chr9 35731069 35731070 49.9491
+chr9 35731070 35731071 51.5726
+chr9 35731071 35731072 49.9491
+chr9 35731072 35731074 51.5726
+chr9 35731074 35731075 49.9491
+chr9 35731075 35731077 51.5726
+chr9 35731077 35731080 49.9491
+chr9 35731080 35731082 51.5726
+chr9 35731082 35731083 53.2063
+chr9 35731083 35731084 51.5726
+chr9 35731084 35731087 49.9491
+chr9 35731087 35731090 46.7337
+chr9 35731090 35731093 45.1423
+chr9 35731093 35731096 43.5622
+chr9 35731096 35731101 41.9937
+chr9 35731101 35731103 43.5622
+chr9 35731103 35731104 41.9937
+chr9 35731104 35731108 40.437
+chr9 35731108 35731112 37.3607
+chr9 35731112 35731114 35.8418
+chr9 35731114 35731115 34.3362
+chr9 35731115 35731116 32.8443
+chr9 35731116 35731118 31.3667
+chr9 35731118 35731121 29.9038
+chr9 35731121 35731131 31.3667
+chr9 35731131 35731135 29.9038
+chr9 35731135 35731136 28.456
+chr9 35731136 35731140 27.0241
+chr9 35731140 35731141 28.456
+chr9 35731141 35731154 31.3667
+chr9 35731154 35731159 32.8443
+chr9 35731159 35731160 34.3362
+chr9 35731160 35731161 35.8418
+chr9 35731161 35731166 37.3607
+chr9 35731166 35731176 38.8892
+chr9 35731176 35731178 37.3227
+chr9 35731178 35731181 38.8892
+chr9 35731181 35731183 40.4687
+chr9 35731183 35731186 42.0607
+chr9 35731186 35731187 43.665
+chr9 35731187 35731192 45.0396
+chr9 35731192 35731198 46.6606
+chr9 35731198 35731199 48.2929
+chr9 35731199 35731200 49.9362
+chr9 35731200 35731202 48.2929
+chr9 35731202 35731203 49.9362
+chr9 35731203 35731208 48.2929
+chr9 35731208 35731209 46.6606
+chr9 35731209 35731210 48.2929
+chr9 35731210 35731212 46.6606
+chr9 35731212 35731214 45.0396
+chr9 35731214 35731216 46.6606
+chr9 35731216 35731218 45.0396
+chr9 35731218 35731222 46.6606
+chr9 35731222 35731229 45.0396
+chr9 35731229 35731230 46.6606
+chr9 35731230 35731232 48.2929
+chr9 35731232 35731236 49.9362
+chr9 35731236 35731239 48.2929
+chr9 35731239 35731244 51.5902
+chr9 35731244 35731248 53.2546
+chr9 35731248 35731249 53.2063
+chr9 35731249 35731250 54.85
+chr9 35731250 35731251 56.5035
+chr9 35731251 35731253 54.85
+chr9 35731253 35731256 53.2063
+chr9 35731256 35731259 54.85
+chr9 35731259 35731267 56.5035
+chr9 35731267 35731269 54.85
+chr9 35731269 35731275 56.5035
+chr9 35731275 35731276 58.1665
+chr9 35731276 35731277 61.5202
+chr9 35731277 35731280 63.2106
+chr9 35731280 35731281 61.5202
+chr9 35731281 35731282 59.8388
+chr9 35731282 35731283 58.1665
+chr9 35731283 35731284 59.8388
+chr9 35731284 35731286 61.5202
+chr9 35731286 35731287 63.2106
+chr9 35731287 35731288 64.9098
+chr9 35731288 35731289 63.2106
+chr9 35731289 35731294 64.9098
+chr9 35731294 35731300 63.2106
+chr9 35731300 35731301 61.5202
+chr9 35731301 35731302 59.8388
+chr9 35731302 35731305 58.1665
+chr9 35731305 35731308 56.5035
+chr9 35731308 35731310 58.1665
+chr9 35731310 35731315 59.8388
+chr9 35731315 35731316 58.1665
+chr9 35731316 35731318 59.8388
+chr9 35731318 35731319 58.1665
+chr9 35731319 35731320 59.8388
+chr9 35731320 35731327 58.1665
+chr9 35731327 35731332 56.5035
+chr9 35731332 35731334 54.85
+chr9 35731334 35731336 56.5035
+chr9 35731336 35731337 58.1665
+chr9 35731337 35731338 59.8388
+chr9 35731338 35731340 58.1665
+chr9 35731340 35731341 61.5202
+chr9 35731341 35731343 59.8388
+chr9 35731343 35731344 61.5202
+chr9 35731344 35731348 63.2106
+chr9 35731348 35731351 64.9098
+chr9 35731351 35731352 66.6175
+chr9 35731352 35731353 68.3337
+chr9 35731353 35731354 70.0582
+chr9 35731354 35731355 68.3337
+chr9 35731355 35731358 66.6175
+chr9 35731358 35731359 64.9098
+chr9 35731359 35731360 68.3337
+chr9 35731360 35731364 66.6175
+chr9 35731364 35731366 68.3337
+chr9 35731366 35731370 70.0582
+chr9 35731370 35731372 68.3337
+chr9 35731372 35731373 66.6175
+chr9 35731373 35731374 68.3337
+chr9 35731374 35731379 70.0582
+chr9 35731379 35731385 66.6175
+chr9 35731385 35731386 64.9098
+chr9 35731386 35731387 66.6175
+chr9 35731387 35731388 68.3337
+chr9 35731388 35731389 68.3352
+chr9 35731389 35731391 64.8597
+chr9 35731391 35731392 66.5931
+chr9 35731392 35731393 70.0857
+chr9 35731393 35731396 71.8444
+chr9 35731396 35731397 70.0857
+chr9 35731397 35731399 71.8444
+chr9 35731399 35731401 68.3352
+chr9 35731401 35731402 66.5931
+chr9 35731402 35731403 68.3352
+chr9 35731403 35731404 70.0857
+chr9 35731404 35731405 71.8444
+chr9 35731405 35731407 73.6113
+chr9 35731407 35731408 75.3861
+chr9 35731408 35731409 77.1688
+chr9 35731409 35731410 75.3861
+chr9 35731410 35731411 77.1688
+chr9 35731411 35731415 75.7455
+chr9 35731415 35731416 73.964
+chr9 35731416 35731420 72.1905
+chr9 35731420 35731423 73.964
+chr9 35731423 35731425 72.1905
+chr9 35731425 35731426 73.964
+chr9 35731426 35731427 72.1905
+chr9 35731427 35731429 70.4251
+chr9 35731429 35731431 68.668
+chr9 35731431 35731432 70.4251
+chr9 35731432 35731435 72.1905
+chr9 35731435 35731437 70.4251
+chr9 35731437 35731440 72.1905
+chr9 35731440 35731442 73.964
+chr9 35731442 35731443 75.7455
+chr9 35731443 35731445 77.5348
+chr9 35731445 35731450 79.3317
+chr9 35731450 35731454 77.5348
+chr9 35731454 35731460 79.3317
+chr9 35731460 35731461 81.1363
+chr9 35731461 35731462 82.9482
+chr9 35731462 35731463 84.7675
+chr9 35731463 35731464 82.9482
+chr9 35731464 35731465 84.7675
+chr9 35731465 35731466 86.5939
+chr9 35731466 35731467 84.6603
+chr9 35731467 35731470 86.4616
+chr9 35731470 35731472 88.2698
+chr9 35731472 35731474 90.0849
+chr9 35731474 35731475 88.2698
+chr9 35731475 35731476 90.0849
+chr9 35731476 35731477 88.2698
+chr9 35731477 35731478 84.6757
+chr9 35731478 35731480 86.4328
+chr9 35731480 35731481 82.9255
+chr9 35731481 35731486 86.4328
+chr9 35731486 35731490 89.9671
+chr9 35731490 35731492 91.7441
+chr9 35731492 35731493 89.9671
+chr9 35731493 35731494 91.7441
+chr9 35731494 35731495 93.5275
+chr9 35731495 35731496 95.3172
+chr9 35731496 35731499 97.1132
+chr9 35731499 35731500 95.3172
+chr9 35731500 35731505 97.1132
+chr9 35731505 35731507 98.9153
+chr9 35731507 35731508 100.724
+chr9 35731508 35731510 97.1132
+chr9 35731510 35731511 98.9153
+chr9 35731511 35731512 102.538
+chr9 35731512 35731513 104.358
+chr9 35731513 35731514 102.538
+chr9 35731514 35731519 100.724
+chr9 35731519 35731520 102.538
+chr9 35731520 35731521 104.358
+chr9 35731521 35731522 102.538
+chr9 35731522 35731524 100.724
+chr9 35731524 35731525 98.9153
+chr9 35731525 35731529 100.724
+chr9 35731529 35731531 102.538
+chr9 35731531 35731532 100.724
+chr9 35731532 35731544 97.1132
+chr9 35731544 35731545 93.5275
+chr9 35731545 35731546 91.7441
+chr9 35731546 35731548 89.9671
+chr9 35731548 35731549 88.1966
+chr9 35731549 35731552 73.723
+chr9 35731552 35731554 75.2483
+chr9 35731554 35731559 73.723
+chr9 35731559 35731560 75.2483
+chr9 35731560 35731569 73.723
+chr9 35731569 35731571 75.2483
+chr9 35731571 35731572 73.723
+chr9 35731572 35731575 75.2483
+chr9 35731575 35731577 76.7799
+chr9 35731577 35731580 75.2483
+chr9 35731580 35731581 73.723
+chr9 35731581 35731583 76.7799
+chr9 35731583 35731586 75.2483
+chr9 35731586 35731589 76.7799
+chr9 35731589 35731590 78.3179
+chr9 35731590 35731591 79.8622
+chr9 35731591 35731595 78.3179
+chr9 35731595 35731596 76.7799
+chr9 35731596 35731598 78.3179
+chr9 35731598 35731600 76.7799
+chr9 35731600 35731601 73.723
+chr9 35731601 35731603 72.2043
+chr9 35731603 35731605 73.723
+chr9 35731605 35731606 72.2043
+chr9 35731606 35731612 70.6922
+chr9 35731612 35731613 69.1869
+chr9 35731613 35731614 70.6922
+chr9 35731614 35731620 69.1869
+chr9 35731620 35731621 70.6922
+chr9 35731621 35731622 69.1869
+chr9 35731622 35731626 67.6883
+chr9 35731626 35731627 66.1967
+chr9 35731627 35731628 64.7122
+chr9 35731628 35731629 63.2349
+chr9 35731629 35731630 78.7992
+chr9 35731630 35731631 80.5702
+chr9 35731631 35731633 82.3485
+chr9 35731633 35731635 78.7992
+chr9 35731635 35731636 80.5702
+chr9 35731636 35731639 78.7992
+chr9 35731639 35731640 80.5702
+chr9 35731640 35731643 78.7992
+chr9 35731643 35731644 82.3485
+chr9 35731644 35731645 80.5702
+chr9 35731645 35731649 77.0356
+chr9 35731649 35731650 78.7992
+chr9 35731650 35731659 77.0356
+chr9 35731659 35731661 78.7992
+chr9 35731661 35731662 80.5702
+chr9 35731662 35731665 82.3485
+chr9 35731665 35731666 64.7122
+chr9 35731666 35731667 66.1967
+chr9 35731667 35731668 64.7122
+chr9 35731668 35731669 66.1967
+chr9 35731669 35731672 64.7122
+chr9 35731672 35731678 67.6883
+chr9 35731678 35731681 69.1869
+chr9 35731681 35731682 70.6922
+chr9 35731682 35731684 72.2043
+chr9 35731684 35731685 73.723
+chr9 35731685 35731686 62.5291
+chr9 35731686 35731687 63.8784
+chr9 35731687 35731689 65.234
+chr9 35731689 35731690 73.723
+chr9 35731690 35731693 76.7799
+chr9 35731693 35731697 78.3179
+chr9 35731697 35731698 79.8622
+chr9 35731698 35731700 76.7799
+chr9 35731700 35731703 78.3179
+chr9 35731703 35731704 79.8622
+chr9 35731704 35731705 82.969
+chr9 35731705 35731706 81.4126
+chr9 35731706 35731708 84.5315
+chr9 35731708 35731717 86.0998
+chr9 35731717 35731718 87.674
+chr9 35731718 35731719 89.254
+chr9 35731719 35731720 87.674
+chr9 35731720 35731721 89.254
+chr9 35731721 35731724 87.674
+chr9 35731724 35731725 89.254
+chr9 35731725 35731726 87.674
+chr9 35731726 35731729 86.0998
+chr9 35731729 35731730 87.674
+chr9 35731730 35731731 86.0998
+chr9 35731731 35731733 89.254
+chr9 35731733 35731736 90.8396
+chr9 35731736 35731737 89.254
+chr9 35731737 35731738 90.8396
+chr9 35731738 35731741 92.4308
+chr9 35731741 35731744 94.0275
+chr9 35731744 35731745 95.6297
+chr9 35731745 35731746 97.2373
+chr9 35731746 35731749 98.8502
+chr9 35731749 35731752 97.2373
+chr9 35731752 35731753 98.8502
+chr9 35731753 35731756 97.2373
+chr9 35731756 35731759 98.8502
+chr9 35731759 35731761 100.468
+chr9 35731761 35731762 98.8502
+chr9 35731762 35731763 100.468
+chr9 35731763 35731765 102.092
+chr9 35731765 35731766 103.72
+chr9 35731766 35731768 105.354
+chr9 35731768 35731770 108.636
+chr9 35731770 35731771 105.354
+chr9 35731771 35731772 103.72
+chr9 35731772 35731776 105.354
+chr9 35731776 35731779 106.992
+chr9 35731779 35731780 105.354
+chr9 35731780 35731781 108.636
+chr9 35731781 35731782 110.284
+chr9 35731782 35731785 111.938
+chr9 35731785 35731788 113.596
+chr9 35731788 35731789 115.259
+chr9 35731789 35731794 113.596
+chr9 35731794 35731795 111.938
+chr9 35731795 35731796 113.596
+chr9 35731796 35731797 115.259
+chr9 35731797 35731798 116.926
+chr9 35731798 35731799 118.598
+chr9 35731799 35731800 115.259
+chr9 35731800 35731802 113.596
+chr9 35731802 35731804 115.259
+chr9 35731804 35731805 118.598
+chr9 35731805 35731809 146.468
+chr9 35731809 35731811 150.428
+chr9 35731811 35731812 152.415
+chr9 35731812 35731814 150.428
+chr9 35731814 35731816 152.415
+chr9 35731816 35731818 154.406
+chr9 35731818 35731819 152.415
+chr9 35731819 35731824 154.406
+chr9 35731824 35731825 156.402
+chr9 35731825 35731826 159.766
+chr9 35731826 35731828 157.736
+chr9 35731828 35731829 161.153
+chr9 35731829 35731830 163.185
+chr9 35731830 35731834 161.153
+chr9 35731834 35731835 165.221
+chr9 35731835 35731836 167.262
+chr9 35731836 35731837 171.356
+chr9 35731837 35731839 169.307
+chr9 35731839 35731840 167.262
+chr9 35731840 35731843 165.221
+chr9 35731843 35731844 163.185
+chr9 35731844 35731846 159.125
+chr9 35731846 35731847 157.101
+chr9 35731847 35731849 159.125
+chr9 35731849 35731851 161.153
+chr9 35731851 35731854 165.221
+chr9 35731854 35731855 167.262
+chr9 35731855 35731856 169.307
+chr9 35731856 35731858 173.409
+chr9 35731858 35731859 171.356
+chr9 35731859 35731860 173.409
+chr9 35731860 35731863 171.356
+chr9 35731863 35731865 173.409
+chr9 35731865 35731867 175.466
+chr9 35731867 35731869 177.527
+chr9 35731869 35731870 175.466
+chr9 35731870 35731871 177.527
+chr9 35731871 35731872 175.466
+chr9 35731872 35731874 179.593
+chr9 35731874 35731881 181.662
+chr9 35731881 35731884 179.593
+chr9 35731884 35731885 177.527
+chr9 35731885 35731886 175.466
+chr9 35731886 35731891 173.409
+chr9 35731891 35731892 175.466
+chr9 35731892 35731893 173.409
+chr9 35731893 35731894 175.466
+chr9 35731894 35731895 177.527
+chr9 35731895 35731896 175.466
+chr9 35731896 35731900 170.492
+chr9 35731900 35731901 168.466
+chr9 35731901 35731905 170.492
+chr9 35731905 35731906 168.466
+chr9 35731906 35731907 166.445
+chr9 35731907 35731909 133.849
+chr9 35731909 35731910 135.565
+chr9 35731910 35731912 137.286
+chr9 35731912 35731913 135.565
+chr9 35731913 35731914 137.286
+chr9 35731914 35731919 133.849
+chr9 35731919 35731920 135.565
+chr9 35731920 35731922 132.137
+chr9 35731922 35731923 130.43
+chr9 35731923 35731924 132.137
+chr9 35731924 35731925 130.43
+chr9 35731925 35731926 128.726
+chr9 35731926 35731927 127.027
+chr9 35731927 35731933 125.333
+chr9 35731933 35731934 127.027
+chr9 35731934 35731936 128.726
+chr9 35731936 35731938 130.43
+chr9 35731938 35731939 128.726
+chr9 35731939 35731940 130.43
+chr9 35731940 35731942 132.137
+chr9 35731942 35731943 130.43
+chr9 35731943 35731944 128.726
+chr9 35731944 35731946 125.333
+chr9 35731946 35731949 123.642
+chr9 35731949 35731951 121.957
+chr9 35731951 35731952 120.275
+chr9 35731952 35731954 118.598
+chr9 35731954 35731956 116.926
+chr9 35731956 35731959 115.259
+chr9 35731959 35731960 113.596
+chr9 35731960 35731961 111.938
+chr9 35731961 35731963 110.284
+chr9 35731963 35731964 106.992
+chr9 35731964 35731965 105.354
+chr9 35731965 35731967 103.72
+chr9 35731967 35731968 102.092
+chr9 35731968 35731970 98.8502
+chr9 35731970 35731971 97.2373
+chr9 35731971 35731972 95.6297
+chr9 35731972 35731973 94.0275
+chr9 35731973 35731974 92.4308
+chr9 35731974 35731975 90.8396
+chr9 35731975 35731976 87.674
+chr9 35731976 35731981 86.0998
+chr9 35731981 35731985 84.5315
+chr9 35731985 35731986 86.0998
+chr9 35731986 35731987 84.5315
+chr9 35731987 35731988 81.4126
+chr9 35731988 35731989 79.8622
+chr9 35731989 35731990 78.3179
+chr9 35731990 35731991 76.7799
+chr9 35731991 35731993 73.723
+chr9 35731993 35731994 72.2043
+chr9 35731994 35731995 69.1869
+chr9 35731995 35731996 67.6883
+chr9 35731996 35731997 66.1967
+chr9 35731997 35732001 63.2349
+chr9 35732001 35732002 61.7648
+chr9 35732002 35732003 60.3021
+chr9 35732003 35732004 58.847
+chr9 35732004 35732005 57.3996
+chr9 35732005 35732006 55.96
+chr9 35732006 35732007 57.3996
+chr9 35732007 35732008 55.96
+chr9 35732008 35732010 54.5283
+chr9 35732010 35732011 53.1047
+chr9 35732011 35732012 51.6894
+chr9 35732012 35732014 48.8843
+chr9 35732014 35732016 46.1142
+chr9 35732016 35732018 44.7427
+chr9 35732018 35732022 43.3806
+chr9 35732022 35732023 42.0279
+chr9 35732023 35732024 40.6851
+chr9 35732024 35732025 39.3521
+chr9 35732025 35732026 40.6851
+chr9 35732026 35732029 39.3521
+chr9 35732029 35732034 38.0294
+chr9 35732034 35732036 36.7172
+chr9 35732036 35732037 48.336
+chr9 35732037 35732038 46.7337
+chr9 35732038 35732039 45.1423
+chr9 35732039 35732042 43.5622
+chr9 35732042 35732043 41.9937
+chr9 35732043 35732045 40.437
+chr9 35732045 35732046 38.8926
+chr9 35732046 35732047 37.3607
+chr9 35732047 35732048 37.6416
+chr9 35732048 35732049 36.1139
+chr9 35732049 35732050 34.5996
+chr9 35732050 35732053 33.099
+chr9 35732053 35732055 31.6126
+chr9 35732055 35732056 30.1409
+chr9 35732056 35732058 28.6844
+chr9 35732058 35732059 27.2437
+chr9 35732059 35732063 25.9699
+chr9 35732063 35732069 23.1603
+chr9 35732069 35732071 21.7827
+chr9 35732071 35732073 20.4244
+chr9 35732073 35732074 19.0862
+chr9 35732074 35732075 17.7691
+chr9 35732075 35732076 16.4741
+chr9 35732076 35732077 15.2025
+chr9 35732077 35732079 13.9556
+chr9 35732079 35732080 12.7348
+chr9 35732080 35732087 10.3785
+chr9 35732087 35732088 9.24709
+chr9 35732088 35732089 8.15
+chr9 35732089 35732090 7.09016
+chr9 35732090 35732093 6.07102
+chr9 35732093 35732095 8.15
+chr9 35732095 35732097 7.09016
+chr9 35732097 35732108 6.07102
+chr9 35732108 35732119 7.09016
+chr9 35732119 35732142 9.24709
+chr9 35732142 35732146 10.3785
+chr9 35732146 35732149 9.24709
+chr9 35732149 35732153 9.17755
+chr9 35732153 35732164 10.3028
+chr9 35732164 35732165 11.4598
+chr9 35732165 35732172 10.3028
+chr9 35732172 35732178 9.17755
+chr9 35732178 35732181 8.08668
+chr9 35732181 35732210 7.03305
+chr9 35732210 35732225 8.08668
+chr9 35732225 35732233 6.05104
+chr9 35732233 35732235 5.14595
+chr9 35732235 35732255 5.55229
+chr9 35732255 35732259 6.02011
+chr9 35732259 35732265 4.13368
+chr9 35732265 35732269 3.27149
+chr9 35732269 35732279 2.97456
+chr9 35732279 35732293 2.23271
+chr9 35732293 35732298 1.56475
+chr9 35732298 35732304 0.98447
+chr9 35732304 35732316 0.51106
+chr9 35732316 35732325 0.44498
+chr9 35732325 35732346 0.87362
+chr9 35732346 35732350 1.40663
+chr9 35732350 35732373 0.87362
+chr9 35732373 35732401 0.44498
+chr9 35732401 35732404 0.87362
+chr9 35732404 35732424 1.40663
+chr9 35732424 35732441 2.02601
+chr9 35732441 35732465 2.71852
+chr9 35732465 35732466 2.02601
+chr9 35732466 35732474 2.23271
+chr9 35732474 35732477 2.97456
+chr9 35732477 35732479 3.22618
+chr9 35732479 35732483 4.07979
+chr9 35732483 35732486 4.98946
+chr9 35732486 35732487 4.07979
+chr9 35732487 35732496 4.98946
+chr9 35732496 35732531 5.94894
+chr9 35732531 35732536 6.02011
+chr9 35732536 35732539 8.08668
+chr9 35732539 35732540 9.17755
+chr9 35732540 35732553 10.3028
+chr9 35732553 35732554 11.4598
+chr9 35732554 35732555 12.5232
+chr9 35732555 35732557 13.729
+chr9 35732557 35732561 14.9609
+chr9 35732561 35732564 16.2176
+chr9 35732564 35732569 14.9609
+chr9 35732569 35732570 16.2176
+chr9 35732570 35732575 17.4975
+chr9 35732575 35732577 20.1229
+chr9 35732577 35732578 21.4662
+chr9 35732578 35732579 20.4329
+chr9 35732579 35732580 16.3196
+chr9 35732580 35732581 17.4004
+chr9 35732581 35732588 18.4987
+chr9 35732588 35732590 19.614
+chr9 35732590 35732593 20.7455
+chr9 35732593 35732595 23.0552
+chr9 35732595 35732596 25.4236
+chr9 35732596 35732599 27.8468
+chr9 35732599 35732600 29.0781
+chr9 35732600 35732602 30.3218
+chr9 35732602 35732606 31.5778
+chr9 35732606 35732608 32.8456
+chr9 35732608 35732609 34.125
+chr9 35732609 35732610 35.4156
+chr9 35732610 35732612 38.0294
+chr9 35732612 35732613 40.6851
+chr9 35732613 35732619 42.0279
+chr9 35732619 35732620 40.6851
+chr9 35732620 35732621 42.0279
+chr9 35732621 35732625 43.3806
+chr9 35732625 35732628 44.7427
+chr9 35732628 35732629 47.4948
+chr9 35732629 35732631 48.8843
+chr9 35732631 35732632 50.2826
+chr9 35732632 35732633 51.6894
+chr9 35732633 35732636 53.1047
+chr9 35732636 35732637 51.6894
+chr9 35732637 35732638 53.1047
+chr9 35732638 35732639 54.5283
+chr9 35732639 35732640 57.3996
+chr9 35732640 35732641 58.847
+chr9 35732641 35732644 60.3021
+chr9 35732644 35732646 61.7648
+chr9 35732646 35732647 63.2349
+chr9 35732647 35732648 64.7122
+chr9 35732648 35732652 67.6883
+chr9 35732652 35732654 69.1869
+chr9 35732654 35732655 70.6922
+chr9 35732655 35732656 53.4922
+chr9 35732656 35732659 54.7101
+chr9 35732659 35732661 55.9345
+chr9 35732661 35732662 58.4025
+chr9 35732662 35732664 59.6459
+chr9 35732664 35732665 62.1511
+chr9 35732665 35732667 63.4127
+chr9 35732667 35732668 64.6802
+chr9 35732668 35732669 65.9535
+chr9 35732669 35732670 67.2326
+chr9 35732670 35732671 68.5173
+chr9 35732671 35732676 69.8076
+chr9 35732676 35732677 67.2326
+chr9 35732677 35732678 68.5173
+chr9 35732678 35732679 69.8076
+chr9 35732679 35732680 68.5173
+chr9 35732680 35732682 67.2326
+chr9 35732682 35732683 68.5173
+chr9 35732683 35732684 67.2326
+chr9 35732684 35732685 68.5173
+chr9 35732685 35732690 69.8076
+chr9 35732690 35732692 71.1034
+chr9 35732692 35732694 73.7114
+chr9 35732694 35732697 83.4034
+chr9 35732697 35732699 81.9718
+chr9 35732699 35732701 72.4048
+chr9 35732701 35732702 71.1034
+chr9 35732702 35732705 73.7114
+chr9 35732705 35732706 75.0235
+chr9 35732706 35732707 76.3408
+chr9 35732707 35732710 77.6632
+chr9 35732710 35732711 76.3408
+chr9 35732711 35732712 77.6632
+chr9 35732712 35732713 78.9908
+chr9 35732713 35732715 77.6632
+chr9 35732715 35732719 75.0235
+chr9 35732719 35732721 84.8403
+chr9 35732721 35732723 81.9718
+chr9 35732723 35732731 84.8403
+chr9 35732731 35732732 86.2824
+chr9 35732732 35732733 87.7298
+chr9 35732733 35732736 86.2824
+chr9 35732736 35732738 84.8403
+chr9 35732738 35732740 87.7298
+chr9 35732740 35732741 89.1823
+chr9 35732741 35732743 90.6398
+chr9 35732743 35732745 92.1024
+chr9 35732745 35732746 93.5699
+chr9 35732746 35732747 81.6612
+chr9 35732747 35732750 83.0038
+chr9 35732750 35732751 81.6612
+chr9 35732751 35732755 83.0038
+chr9 35732755 35732756 84.3514
+chr9 35732756 35732759 85.7038
+chr9 35732759 35732761 87.061
+chr9 35732761 35732765 88.4229
+chr9 35732765 35732767 87.061
+chr9 35732767 35732768 88.4229
+chr9 35732768 35732769 87.061
+chr9 35732769 35732771 88.4229
+chr9 35732771 35732778 89.7895
+chr9 35732778 35732779 87.061
+chr9 35732779 35732783 85.7038
+chr9 35732783 35732784 87.061
+chr9 35732784 35732789 85.7038
+chr9 35732789 35732792 87.061
+chr9 35732792 35732793 85.7038
+chr9 35732793 35732795 88.4229
+chr9 35732795 35732796 115.259
+chr9 35732796 35732797 113.596
+chr9 35732797 35732800 115.259
+chr9 35732800 35732801 116.926
+chr9 35732801 35732802 113.596
+chr9 35732802 35732806 111.938
+chr9 35732806 35732807 113.596
+chr9 35732807 35732810 111.938
+chr9 35732810 35732811 110.284
+chr9 35732811 35732812 111.938
+chr9 35732812 35732815 113.596
+chr9 35732815 35732817 116.926
+chr9 35732817 35732819 118.598
+chr9 35732819 35732820 120.275
+chr9 35732820 35732821 121.957
+chr9 35732821 35732822 123.642
+chr9 35732822 35732823 121.957
+chr9 35732823 35732824 123.642
+chr9 35732824 35732826 121.957
+chr9 35732826 35732827 120.275
+chr9 35732827 35732829 121.957
+chr9 35732829 35732831 123.642
+chr9 35732831 35732832 125.333
+chr9 35732832 35732833 121.957
+chr9 35732833 35732835 120.275
+chr9 35732835 35732839 121.957
+chr9 35732839 35732840 132.656
+chr9 35732840 35732843 134.455
+chr9 35732843 35732848 136.259
+chr9 35732848 35732851 138.067
+chr9 35732851 35732854 136.259
+chr9 35732854 35732855 138.067
+chr9 35732855 35732858 141.696
+chr9 35732858 35732860 143.518
+chr9 35732860 35732861 145.343
+chr9 35732861 35732862 149.006
+chr9 35732862 35732864 150.844
+chr9 35732864 35732865 152.686
+chr9 35732865 35732866 154.532
+chr9 35732866 35732867 152.686
+chr9 35732867 35732868 156.382
+chr9 35732868 35732869 154.532
+chr9 35732869 35732870 156.382
+chr9 35732870 35732872 158.236
+chr9 35732872 35732873 156.382
+chr9 35732873 35732874 154.532
+chr9 35732874 35732875 152.686
+chr9 35732875 35732878 150.844
+chr9 35732878 35732879 149.006
+chr9 35732879 35732880 147.173
+chr9 35732880 35732882 145.343
+chr9 35732882 35732890 143.518
+chr9 35732890 35732891 141.696
+chr9 35732891 35732892 139.88
+chr9 35732892 35732894 136.259
+chr9 35732894 35732895 134.455
+chr9 35732895 35732896 132.656
+chr9 35732896 35732897 130.861
+chr9 35732897 35732899 132.656
+chr9 35732899 35732900 134.455
+chr9 35732900 35732901 132.656
+chr9 35732901 35732902 130.861
+chr9 35732902 35732905 132.656
+chr9 35732905 35732906 134.455
+chr9 35732906 35732907 136.259
+chr9 35732907 35732908 134.455
+chr9 35732908 35732909 132.656
+chr9 35732909 35732910 130.861
+chr9 35732910 35732912 129.071
+chr9 35732912 35732914 127.285
+chr9 35732914 35732916 129.071
+chr9 35732916 35732918 132.656
+chr9 35732918 35732919 134.455
+chr9 35732919 35732920 136.259
+chr9 35732920 35732921 134.455
+chr9 35732921 35732922 132.656
+chr9 35732922 35732923 136.259
+chr9 35732923 35732925 134.455
+chr9 35732925 35732926 136.259
+chr9 35732926 35732929 134.455
+chr9 35732929 35732931 130.861
+chr9 35732931 35732932 129.071
+chr9 35732932 35732933 130.861
+chr9 35732933 35732935 129.071
+chr9 35732935 35732936 127.285
+chr9 35732936 35732937 129.071
+chr9 35732937 35732940 127.285
+chr9 35732940 35732944 125.504
+chr9 35732944 35732945 123.728
+chr9 35732945 35732948 121.956
+chr9 35732948 35732949 120.189
+chr9 35732949 35732951 118.427
+chr9 35732951 35732953 114.918
+chr9 35732953 35732954 118.427
+chr9 35732954 35732955 121.956
+chr9 35732955 35732956 118.427
+chr9 35732956 35732957 120.189
+chr9 35732957 35732958 116.67
+chr9 35732958 35732961 114.918
+chr9 35732961 35732963 114.846
+chr9 35732963 35732964 113.068
+chr9 35732964 35732965 114.846
+chr9 35732965 35732967 116.63
+chr9 35732967 35732969 114.846
+chr9 35732969 35732970 113.068
+chr9 35732970 35732974 111.295
+chr9 35732974 35732975 113.068
+chr9 35732975 35732976 111.295
+chr9 35732976 35732977 113.068
+chr9 35732977 35732979 116.63
+chr9 35732979 35732980 118.418
+chr9 35732980 35732982 116.63
+chr9 35732982 35732984 113.068
+chr9 35732984 35732988 111.295
+chr9 35732988 35732989 109.527
+chr9 35732989 35732990 107.765
+chr9 35732990 35732991 109.527
+chr9 35732991 35732995 111.295
+chr9 35732995 35732997 107.765
+chr9 35732997 35732998 106.008
+chr9 35732998 35733001 104.256
+chr9 35733001 35733002 100.77
+chr9 35733002 35733003 99.0349
+chr9 35733003 35733004 97.3058
+chr9 35733004 35733005 95.5826
+chr9 35733005 35733006 93.8653
+chr9 35733006 35733007 95.5826
+chr9 35733007 35733009 93.8653
+chr9 35733009 35733011 92.154
+chr9 35733011 35733014 90.4487
+chr9 35733014 35733016 92.154
+chr9 35733016 35733030 90.4487
+chr9 35733030 35733031 92.154
+chr9 35733031 35733033 90.4487
+chr9 35733033 35733035 92.154
+chr9 35733035 35733036 95.5826
+chr9 35733036 35733037 93.8653
+chr9 35733037 35733039 92.154
+chr9 35733039 35733044 90.4487
+chr9 35733044 35733045 92.154
+chr9 35733045 35733048 90.4487
+chr9 35733048 35733050 92.154
+chr9 35733050 35733052 93.8653
+chr9 35733052 35733056 95.5826
+chr9 35733056 35733057 92.154
+chr9 35733057 35733062 90.4487
+chr9 35733062 35733063 87.0568
+chr9 35733063 35733064 88.7496
+chr9 35733064 35733065 90.4487
+chr9 35733065 35733066 88.7496
+chr9 35733066 35733068 90.4487
+chr9 35733068 35733070 88.7496
+chr9 35733070 35733076 90.4487
+chr9 35733076 35733078 88.7496
+chr9 35733078 35733079 87.0568
+chr9 35733079 35733082 85.3703
+chr9 35733082 35733083 87.0568
+chr9 35733083 35733084 85.3703
+chr9 35733084 35733087 83.6902
+chr9 35733087 35733088 85.3703
+chr9 35733088 35733092 87.0568
+chr9 35733092 35733093 83.6902
+chr9 35733093 35733094 82.0166
+chr9 35733094 35733096 78.6895
+chr9 35733096 35733097 77.0361
+chr9 35733097 35733099 78.6895
+chr9 35733099 35733105 77.0361
+chr9 35733105 35733107 73.7504
+chr9 35733107 35733108 75.3897
+chr9 35733108 35733113 67.6883
+chr9 35733113 35733114 66.1967
+chr9 35733114 35733116 63.2349
+chr9 35733116 35733117 61.7648
+chr9 35733117 35733118 60.3021
+chr9 35733118 35733119 58.847
+chr9 35733119 35733120 57.3996
+chr9 35733120 35733121 58.847
+chr9 35733121 35733125 60.3021
+chr9 35733125 35733126 58.847
+chr9 35733126 35733127 57.3996
+chr9 35733127 35733128 58.847
+chr9 35733128 35733130 57.3996
+chr9 35733130 35733133 55.96
+chr9 35733133 35733137 54.5283
+chr9 35733137 35733138 55.96
+chr9 35733138 35733139 57.3996
+chr9 35733139 35733140 55.96
+chr9 35733140 35733142 54.5283
+chr9 35733142 35733145 55.96
+chr9 35733145 35733147 46.8775
+chr9 35733147 35733148 45.6218
+#bedGraph section chr9:35733148-35747728
+chr9 35733148 35733150 55.96
+chr9 35733150 35733155 54.5283
+chr9 35733155 35733156 55.96
+chr9 35733156 35733158 54.5283
+chr9 35733158 35733159 55.96
+chr9 35733159 35733166 54.5283
+chr9 35733166 35733167 53.1047
+chr9 35733167 35733168 51.6894
+chr9 35733168 35733170 50.2826
+chr9 35733170 35733171 51.6894
+chr9 35733171 35733172 53.1047
+chr9 35733172 35733175 54.5283
+chr9 35733175 35733179 51.6894
+chr9 35733179 35733181 53.1047
+chr9 35733181 35733182 51.6894
+chr9 35733182 35733183 50.2826
+chr9 35733183 35733188 48.8843
+chr9 35733188 35733189 47.4948
+chr9 35733189 35733190 46.1142
+chr9 35733190 35733191 44.7427
+chr9 35733191 35733194 43.3806
+chr9 35733194 35733195 42.0279
+chr9 35733195 35733196 40.6851
+chr9 35733196 35733200 42.0279
+chr9 35733200 35733202 40.6851
+chr9 35733202 35733203 42.0279
+chr9 35733203 35733204 40.6851
+chr9 35733204 35733205 39.3521
+chr9 35733205 35733212 38.0294
+chr9 35733212 35733213 36.7172
+chr9 35733213 35733216 35.4156
+chr9 35733216 35733219 36.7172
+chr9 35733219 35733225 38.0294
+chr9 35733225 35733227 39.3521
+chr9 35733227 35733237 38.0294
+chr9 35733237 35733238 36.7172
+chr9 35733238 35733245 38.0294
+chr9 35733245 35733247 39.3521
+chr9 35733247 35733248 38.0294
+chr9 35733248 35733251 47.9815
+chr9 35733251 35733254 49.5558
+chr9 35733254 35733258 51.1403
+chr9 35733258 35733261 40.6851
+chr9 35733261 35733262 38.0294
+chr9 35733262 35733268 40.6851
+chr9 35733268 35733269 42.0279
+chr9 35733269 35733271 43.3806
+chr9 35733271 35733273 42.0279
+chr9 35733273 35733276 43.3806
+chr9 35733276 35733277 44.7427
+chr9 35733277 35733278 43.3806
+chr9 35733278 35733279 42.0279
+chr9 35733279 35733281 40.6851
+chr9 35733281 35733282 42.0279
+chr9 35733282 35733283 40.6851
+chr9 35733283 35733285 39.3521
+chr9 35733285 35733295 49.5694
+chr9 35733295 35733298 47.9658
+chr9 35733298 35733300 46.373
+chr9 35733300 35733303 44.7911
+chr9 35733303 35733304 43.2204
+chr9 35733304 35733305 44.7911
+chr9 35733305 35733307 43.2204
+chr9 35733307 35733310 44.7911
+chr9 35733310 35733311 43.2204
+chr9 35733311 35733312 44.7911
+chr9 35733312 35733324 43.2204
+chr9 35733324 35733325 41.6614
+chr9 35733325 35733326 40.1142
+chr9 35733326 35733330 38.5792
+chr9 35733330 35733334 40.1142
+chr9 35733334 35733337 41.6614
+chr9 35733337 35733342 43.2204
+chr9 35733342 35733344 41.6614
+chr9 35733344 35733346 43.2204
+chr9 35733346 35733348 41.6614
+chr9 35733348 35733350 43.2204
+chr9 35733350 35733352 41.6614
+chr9 35733352 35733354 43.2204
+chr9 35733354 35733355 44.7911
+chr9 35733355 35733356 47.9658
+chr9 35733356 35733359 46.373
+chr9 35733359 35733360 44.7911
+chr9 35733360 35733362 46.373
+chr9 35733362 35733364 44.7911
+chr9 35733364 35733366 43.2204
+chr9 35733366 35733368 41.6614
+chr9 35733368 35733385 43.2204
+chr9 35733385 35733387 41.6614
+chr9 35733387 35733389 43.2204
+chr9 35733389 35733390 41.6614
+chr9 35733390 35733391 40.1142
+chr9 35733391 35733392 38.5792
+chr9 35733392 35733394 38.7774
+chr9 35733394 35733400 37.249
+chr9 35733400 35733402 35.7335
+chr9 35733402 35733406 32.7431
+chr9 35733406 35733407 34.2314
+chr9 35733407 35733408 32.7431
+chr9 35733408 35733410 31.2689
+chr9 35733410 35733414 31.4395
+chr9 35733414 35733415 29.974
+chr9 35733415 35733421 31.4395
+chr9 35733421 35733422 29.974
+chr9 35733422 35733426 31.4395
+chr9 35733426 35733431 29.974
+chr9 35733431 35733433 28.5236
+chr9 35733433 35733434 27.0891
+chr9 35733434 35733436 26.9367
+chr9 35733436 35733444 28.3652
+chr9 35733444 35733447 26.9367
+chr9 35733447 35733450 25.5246
+chr9 35733450 35733451 24.1294
+chr9 35733451 35733456 21.3928
+chr9 35733456 35733472 20.053
+chr9 35733472 35733474 18.7332
+chr9 35733474 35733476 17.4346
+chr9 35733476 35733478 16.1581
+chr9 35733478 35733488 14.9049
+chr9 35733488 35733492 13.6765
+chr9 35733492 35733493 12.4741
+chr9 35733493 35733494 11.2996
+chr9 35733494 35733495 10.1547
+chr9 35733495 35733500 9.04166
+chr9 35733500 35733502 7.96295
+chr9 35733502 35733508 9.04166
+chr9 35733508 35733513 7.96295
+chr9 35733513 35733519 9.04166
+chr9 35733519 35733522 7.96295
+chr9 35733522 35733527 6.92148
+chr9 35733527 35733542 5.92066
+chr9 35733542 35733546 6.92148
+chr9 35733546 35733549 5.92066
+chr9 35733549 35733555 5.94894
+chr9 35733555 35733556 4.98946
+chr9 35733556 35733571 4.07979
+chr9 35733571 35733576 2.34351
+chr9 35733576 35733581 1.78082
+chr9 35733581 35733585 2.34351
+chr9 35733585 35733617 3.6244
+chr9 35733617 35733642 2.95987
+chr9 35733642 35733646 2.34351
+chr9 35733646 35733653 2.95987
+chr9 35733653 35733658 2.34351
+chr9 35733658 35733660 1.78082
+chr9 35733660 35733682 2.34351
+chr9 35733682 35733684 1.78082
+chr9 35733684 35733687 3.2082
+chr9 35733687 35733692 4.05839
+chr9 35733692 35733701 4.96463
+chr9 35733701 35733702 5.92066
+chr9 35733702 35733707 4.96463
+chr9 35733707 35733721 5.92066
+chr9 35733721 35733724 4.96463
+chr9 35733724 35733725 5.92066
+chr9 35733725 35733734 4.96463
+chr9 35733734 35733739 5.92066
+chr9 35733739 35733741 6.92148
+chr9 35733741 35733745 5.92066
+chr9 35733745 35733762 5.87208
+chr9 35733762 35733763 6.86696
+chr9 35733763 35733786 6.92148
+chr9 35733786 35733788 5.92066
+chr9 35733788 35733827 6.92148
+chr9 35733827 35733830 5.92066
+chr9 35733830 35733832 6.92148
+chr9 35733832 35733834 5.92066
+chr9 35733834 35733841 6.92148
+chr9 35733841 35733865 5.92066
+chr9 35733865 35733869 4.96463
+chr9 35733869 35733874 5.92066
+chr9 35733874 35733875 4.96463
+chr9 35733875 35733879 4.05839
+chr9 35733879 35733902 3.2082
+chr9 35733902 35733940 2.42202
+chr9 35733940 35733957 1.71033
+chr9 35733957 35733970 1.69102
+chr9 35733970 35733974 1.07366
+chr9 35733974 35733987 0.56487
+chr9 35733987 35733993 0.57318
+chr9 35733993 35734140 0.19719
+chr9 35734140 35734198 0.19372
diff --git a/test/data/hubs/catLiftOff.bed b/test/data/hubs/catLiftOff.bed
new file mode 100644
index 000000000..794a43de7
--- /dev/null
+++ b/test/data/hubs/catLiftOff.bed
@@ -0,0 +1,5 @@
+chr9 35717602 35752875 TLN1-201 0 - 35718445 35746352 76,85,212 57 969,129,183,63,126,125,106,108,186,117,126,184,167,147,120,102,150,171,102,133,182,141,162,144,123,90,94,140,198,120,209,103,129,135,114,117,129,167,295,168,99,209,109,114,181,77,102,156,105,61,128,143,153,130,98,163,121 0,1096,1375,1669,1860,2084,2408,3026,3243,6616,6831,7047,7388,7725,8606,8805,9017,9251,9505,9823,10127,10403,10786,11396,13616,13852,14044,14310,14650,15060,15890,16251,17008,17294,17629,17815,18114,19445,20201,20674,21867,22129,22574,22795,23094,23488,23867,24703,25174,25916,27007,27247,27627,27885,28279,28620,35152 TLN1 cmpl cmpl 0,0,0,0,0,1,0,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,2,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1,0,0,2,0,0,0,0,2,0,1,1,0,1,0,-1 CHM13_T0216333 protein_coding CHM13_G0055742 protein_coding ENSG00000137076.21 ENST00000314888.10 ENST00000314888.10-0 N/A nan nan N/A N/A nan 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 1,2,2,2,2,1,1,1,1,2,2,2,2,1,2,2,2,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,1 ortholog transMap True True True False
+chr9 35717993 35753211 CHM13_T0216334 0 - 35753211 35753211 76,85,212 53 578,129,183,63,126,125,106,108,186,117,126,184,167,147,120,102,150,171,102,133,182,141,162,144,123,90,94,140,198,120,209,103,129,135,114,117,129,167,295,168,99,167,57,156,105,61,128,143,153,130,98,163,457 0,705,984,1278,1469,1693,2017,2635,2852,6225,6440,6656,6997,7334,8215,8414,8626,8860,9114,9432,9736,10012,10395,11005,13225,13461,13653,13919,14259,14669,15499,15860,16617,16903,17238,17424,17723,19054,19810,20283,21476,21738,23521,24312,24783,25525,26616,26856,27236,27494,27888,28229,34761 MSTRG.5603 none none -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 CHM13_T0216334 protein_coding CHM13_G0055742 protein_coding ENSG00000137076.21 N/A exRef-MSTRG.5603.2 N/A N/A N/A N/A N/A N/A 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,0 1,2,2,2,2,1,1,1,1,2,2,2,2,1,2,2,2,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,2,2,2,2,2,1 putative_novel_isoform exRef N/A N/A N/A False
+chr9 35724217 35728532 TLN1-203 0 - 35728532 35728532 85,212,76 6 118,126,184,167,114,105 0,216,432,773,1110,4210 TLN1 none none -1,-1,-1,-1,-1,-1 CHM13_T0216336 processed_transcript CHM13_G0055742 protein_coding ENSG00000137076.21 ENST00000464379.5 ENST00000464379.5-0 N/A nan nan N/A N/A nan 1,1,1,1,1,1 2,2,2,2,1 ortholog transMap True True True False
+chr9 35728013 35728625 TLN1-208 0 - 35728625 35728625 85,212,76 2 133,237 0,375 TLN1 none none -1,-1 CHM13_T0216340 processed_transcript CHM13_G0055742 protein_coding ENSG00000137076.21 ENST00000495712.1 ENST00000495712.1-0 N/A nan nan N/A N/A nan 1,1 2 ortholog transMap True True True False
+chr9 35731333 35731399 MIR6852-201 0 - 35731399 35731399 85,212,76 1 66 0 MIR6852 none none -1 CHM13_T0216341 miRNA CHM13_G0055743 miRNA ENSG00000284195.1 ENST00000621699.1 ENST00000621699.1-0 N/A nan nan N/A N/A nan 1 nan ortholog transMap True True True False
diff --git a/test/data/hubs/catLiftOff.bed.gz b/test/data/hubs/catLiftOff.bed.gz
new file mode 100644
index 000000000..86441cd59
Binary files /dev/null and b/test/data/hubs/catLiftOff.bed.gz differ
diff --git a/test/data/hubs/catLiftOff.bed.gz.tbi b/test/data/hubs/catLiftOff.bed.gz.tbi
new file mode 100644
index 000000000..f6737da70
Binary files /dev/null and b/test/data/hubs/catLiftOff.bed.gz.tbi differ
diff --git a/test/data/hubs/groups.txt b/test/data/hubs/groups.txt
new file mode 100644
index 000000000..aff9f47f7
--- /dev/null
+++ b/test/data/hubs/groups.txt
@@ -0,0 +1,39 @@
+name user
+label Custom Tracks
+priority 1
+defaultIsClosed 1
+
+name map
+label Mapping and Sequencing
+priority 2
+defaultIsClosed 0
+
+name genes
+label Genes and Gene Predictions
+priority 3
+defaultIsClosed 0
+
+name rna
+label mRNA and EST
+priority 4
+defaultIsClosed 0
+
+name regulation
+label Expression and Regulation
+priority 5
+defaultIsClosed 0
+
+name compGeno
+label Comparative Genomics
+priority 6
+defaultIsClosed 0
+
+name varRep
+label Variation and Repeats
+priority 7
+defaultIsClosed 0
+
+name x
+label Experimental Tracks
+priority 10
+defaultIsClosed 1
diff --git a/test/data/hubs/hub.txt b/test/data/hubs/hub.txt
new file mode 100644
index 000000000..7944f7e6c
--- /dev/null
+++ b/test/data/hubs/hub.txt
@@ -0,0 +1,281 @@
+hub GCF_000186305.1 genome assembly
+shortLabel Burmese python
+longLabel Burmese python/Python bivittatus/GCF_000186305.1_Python_molurus_bivittatus-5.0.2 genome assembly
+useOneFile on
+email hclawson@ucsc.edu
+descriptionUrl html/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.description.html
+
+genome GCF_000186305.1
+taxId 176946
+groups groups.txt
+description Burmese python
+twoBitPath GCF_000186305.1.2bit
+twoBitBptURL GCF_000186305.1.2bit.bpt
+chromSizes GCF_000186305.1.chrom.sizes.txt
+chromAliasBb GCF_000186305.1.chromAlias.bb
+organism Python_molurus_bivittatus-5.0.2 Sep. 2013
+defaultPos NW_006532014.1:484194-494194
+scientificName Python bivittatus
+htmlPath html/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.description.html
+blat dynablat-01.soe.ucsc.edu 4040 dynamic GCF/000/186/305/GCF_000186305.1
+transBlat dynablat-01.soe.ucsc.edu 4040 dynamic GCF/000/186/305/GCF_000186305.1
+isPcr dynablat-01.soe.ucsc.edu 4040 dynamic GCF/000/186/305/GCF_000186305.1
+
+track assembly
+longLabel Assembly
+shortLabel Assembly
+visibility pack
+colorByStrand 150,100,30 230,170,40
+color 150,100,30
+altColor 230,170,40
+bigDataUrl bbi/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.assembly.bb
+type bigBed 6
+html html/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.assembly
+searchIndex name
+searchTrix ixIxx/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.assembly.ix
+url https://www.ncbi.nlm.nih.gov/nuccore/$$
+urlLabel NCBI Nucleotide database:
+group map
+
+track gap
+longLabel AGP gap
+shortLabel Gap (AGP defined)
+visibility dense
+color 0,0,0
+bigDataUrl bbi/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.gap.bb
+type bigBed 4
+group map
+html html/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.gap
+
+track cytoBandIdeo
+shortLabel Chromosome Band (Ideogram)
+longLabel Ideogram for Orientation
+group map
+visibility dense
+type bigBed 4 +
+bigDataUrl bbi/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.cytoBand.bb
+
+track gc5Base
+shortLabel GC Percent
+longLabel GC Percent in 5-Base Windows
+group map
+visibility full
+autoScale Off
+maxHeightPixels 128:36:16
+graphTypeDefault Bar
+gridDefault OFF
+windowingFunction Mean
+color 0,0,0
+altColor 128,128,128
+viewLimits 30:70
+type bigWig 0 100
+bigDataUrl bbi/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.gc5Base.bw
+html html/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.gc5Base
+
+track tanDups
+shortLabel Tandem Dups
+longLabel Paired identical sequences
+compositeTrack on
+visibility hide
+type bigBed 12
+group map
+html html/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.tanDups
+
+ track gapOverlap
+ parent tanDups on
+ shortLabel Gap Overlaps
+ longLabel Paired exactly identical sequence on each side of a gap
+ bigDataUrl bbi/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.gapOverlap.bb
+ type bigBed 12
+
+ track tandemDups
+ parent tanDups on
+ shortLabel Tandem Dups
+ longLabel Paired exactly identical sequence survey over entire genome assembly
+ bigDataUrl bbi/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.tandemDups.bb
+ type bigBed 12
+
+track repeatMasker
+shortLabel RepeatMasker
+longLabel RepeatMasker Repetitive Elements
+type bigRmsk 9 +
+visibility pack
+group varRep
+bigDataUrl bbi/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.rmsk.bb
+maxWindowToDraw 5000000
+html html/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.repeatMasker
+
+track simpleRepeat
+shortLabel Simple Repeats
+longLabel Simple Tandem Repeats by TRF
+group varRep
+visibility dense
+type bigBed 4 +
+bigDataUrl bbi/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.simpleRepeat.bb
+html html/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.simpleRepeat
+
+track refSeqComposite
+compositeTrack on
+shortLabel NCBI RefSeq
+longLabel RefSeq gene predictions from NCBI
+group genes
+visibility pack
+type bigBed
+dragAndDrop subTracks
+allButtonPair on
+dataVersion NCBI Python bivittatus Annotation Release 102 (2022-11-07)
+html html/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.refSeqComposite
+priority 2
+
+ track ncbiRefSeq
+ parent refSeqComposite on
+ color 12,12,120
+ altColor 120,12,12
+ shortLabel RefSeq All
+ type bigGenePred
+ labelFields name,geneName,geneName2
+ defaultLabelFields geneName2
+ searchIndex name
+ searchTrix ixIxx/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.ncbiRefSeq.ix
+ bigDataUrl bbi/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.ncbiRefSeq.bb
+ longLabel NCBI RefSeq genes, curated and predicted sets (NM_*, XM_*, NR_*, XR_*, NP_* or YP_*)
+ idXref ncbiRefSeqLink mrnaAcc name
+ baseColorUseCds given
+ baseColorDefault genomicCodons
+ priority 1
+
+ track ncbiRefSeqCurated
+ color 12,12,120
+ parent refSeqComposite on
+ shortLabel RefSeq Curated
+ longLabel NCBI RefSeq genes, curated subset (NM_*, NR_*, NP_* or YP_*)
+ type bigGenePred
+ labelFields name,geneName,geneName2
+ defaultLabelFields geneName2
+ searchIndex name
+ searchTrix ixIxx/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.ncbiRefSeqCurated.ix
+ idXref ncbiRefSeqLink mrnaAcc name
+ bigDataUrl bbi/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.ncbiRefSeqCurated.bb
+ baseColorUseCds given
+ baseColorDefault genomicCodons
+ priority 2
+
+ track ncbiRefSeqPredicted
+ color 12,12,120
+ parent refSeqComposite on
+ shortLabel RefSeq Predicted
+ longLabel NCBI RefSeq genes, predicted subset (XM_* or XR_*)
+ type bigGenePred
+ labelFields name,geneName,geneName2
+ defaultLabelFields geneName2
+ searchIndex name
+ searchTrix ixIxx/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.ncbiRefSeqPredicted.ix
+ idXref ncbiRefSeqLink mrnaAcc name
+ bigDataUrl bbi/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.ncbiRefSeqPredicted.bb
+ baseColorUseCds given
+ baseColorDefault genomicCodons
+ priority 3
+
+ track ncbiRefSeqOther
+ color 32,32,32
+ parent refSeqComposite on
+ shortLabel RefSeq Other
+ longLabel NCBI RefSeq other annotations (not NM_*, NR_*, XM_*, XR_*, NP_* or YP_*)
+ priority 4
+ searchIndex name
+ searchTrix ixIxx/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.ncbiRefSeqOther.ix
+ bigDataUrl bbi/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.ncbiRefSeqOther.bb
+ type bigBed 12 +
+ labelFields name
+ skipEmptyFields on
+ urls GeneID="https://www.ncbi.nlm.nih.gov/gene/$$" MIM="https://www.ncbi.nlm.nih.gov/omim/$$" HGNC="http://www.genenames.org/cgi-bin/gene_symbol_report?hgnc_id=$$" FlyBase="http://flybase.org/reports/$$" WormBase="http://www.wormbase.org/db/gene/gene?name=$$" RGD="https://rgd.mcw.edu/rgdweb/search/search.html?term=$$" SGD="https://www.yeastgenome.org/locus/$$" miRBase="http://www.mirbase.org/cgi-bin/mirna_entry.pl?acc=$$" ZFIN="https://zfin.org/$$" MGI="http://www.informatics.jax.org/marker/$$"
+
+ track ncbiRefSeqPsl
+ priority 5
+ parent refSeqComposite off
+ shortLabel RefSeq Alignments
+ longLabel RefSeq Alignments of RNAs
+ type bigPsl
+ searchIndex name
+ bigDataUrl bbi/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.bigPsl.bb
+ indelDoubleInsert on
+ indelQueryInsert on
+ showDiffBasesAllScales .
+ showDiffBasesMaxZoom 10000.0
+ showCdsMaxZoom 10000.0
+ showCdsAllScales .
+ baseColorDefault diffCodons
+ pslSequence no
+ baseColorUseSequence lfExtra
+ baseColorUseCds table given
+ color 0,0,0
+
+track cpgIslands
+compositeTrack on
+shortLabel CpG Islands
+longLabel CpG Islands (Islands < 300 Bases are Light Green)
+group regulation
+visibility pack
+type bigBed 4 +
+html html/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.cpgIslands
+
+ track cpgIslandExt
+ parent cpgIslands off
+ shortLabel CpG Islands
+ longLabel CpG Islands (Islands < 300 Bases are Light Green)
+ type bigBed 4 +
+ priority 1
+ bigDataUrl bbi/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.cpgIslandExt.bb
+
+ track cpgIslandExtUnmasked
+ parent cpgIslands on
+ shortLabel Unmasked CpG
+ longLabel CpG Islands on All Sequence (Islands < 300 Bases are Light Green)
+ type bigBed 4 +
+ priority 2
+ bigDataUrl bbi/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.cpgIslandExtUnmasked.bb
+
+track windowMasker
+shortLabel WM + SDust
+longLabel Genomic Intervals Masked by WindowMasker + SDust
+group varRep
+visibility dense
+type bigBed 3
+bigDataUrl bbi/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.windowMasker.bb
+html html/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.windowMasker
+
+track allGaps
+shortLabel All Gaps
+longLabel All gaps of unknown nucleotides (N's), including AGP annotated gaps
+group map
+visibility dense
+type bigBed 3
+bigDataUrl bbi/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.allGaps.bb
+html html/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.allGaps
+
+track augustus
+shortLabel Augustus
+longLabel Augustus Gene Predictions
+group genes
+visibility dense
+color 180,0,0
+type bigGenePred
+bigDataUrl bbi/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.augustus.bb
+html html/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.augustus
+
+track xenoRefGene
+shortLabel RefSeq mRNAs
+longLabel RefSeq mRNAs mapped to this assembly
+group rna
+visibility pack
+color 180,0,0
+type bigGenePred
+bigDataUrl bbi/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.xenoRefGene.bb
+url https://www.ncbi.nlm.nih.gov/nuccore/$$
+urlLabel NCBI Nucleotide database:
+labelFields name,geneName,geneName2
+defaultLabelFields geneName
+searchIndex name
+searchTrix ixIxx/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.xenoRefGene.ix
+html html/GCF_000186305.1_Python_molurus_bivittatus-5.0.2.xenoRefGene
+
diff --git a/test/data/twobit/GCA_004363605.1.2bit.bpt b/test/data/twobit/GCA_004363605.1.2bit.bpt
new file mode 100644
index 000000000..ec06fad36
Binary files /dev/null and b/test/data/twobit/GCA_004363605.1.2bit.bpt differ
diff --git a/test/data/twobit/GCF_000002655.1.2bit b/test/data/twobit/GCF_000002655.1.2bit
new file mode 100644
index 000000000..a522a4cd6
Binary files /dev/null and b/test/data/twobit/GCF_000002655.1.2bit differ
diff --git a/test/data/twobit/GCF_000002655.1.2bit.bpt b/test/data/twobit/GCF_000002655.1.2bit.bpt
new file mode 100644
index 000000000..efffb7e74
Binary files /dev/null and b/test/data/twobit/GCF_000002655.1.2bit.bpt differ
diff --git a/test/testHtsgetReader.js b/test/old/testHtsgetReader.js
similarity index 94%
rename from test/testHtsgetReader.js
rename to test/old/testHtsgetReader.js
index 48ae94422..428fdd70e 100644
--- a/test/testHtsgetReader.js
+++ b/test/old/testHtsgetReader.js
@@ -1,8 +1,8 @@
-import "./utils/mockObjects.js"
+import "../utils/mockObjects.js"
import {assert} from 'chai'
-import HtsgetBamReader from "../js/htsget/htsgetBamReader.js"
-import HtsgetVariantReader from "../js/htsget/htsgetVariantReader.js"
-import Browser from "../js/browser.js"
+import HtsgetBamReader from "../../js/htsget/htsgetBamReader.js"
+import HtsgetVariantReader from "../../js/htsget/htsgetVariantReader.js"
+import Browser from "../../js/browser.js"
// Mock genome with "1,2,3..." name convention
diff --git a/test/testAlignmentUtils.js b/test/testAlignmentUtils.js
index aef5a04df..0015d7405 100755
--- a/test/testAlignmentUtils.js
+++ b/test/testAlignmentUtils.js
@@ -8,46 +8,53 @@ suite("testAlignmentUtils", function () {
test("Alignment packing", async function () {
this.timeout(10000)
- const chr = 'chr22'
- const start = 24375132
- const end = 24385311
- const bamReader = new BamReaderNonIndexed({
- type: 'bam',
- url: 'test/data/bam/gstt1_sample.bam',
- indexed: false
- })
+ await _testPacking('chr22')
+ await _testPacking('22') // Test aliasing
- const alignmentContainer = await bamReader.readAlignments(chr, start, end)
- const rows = packAlignmentRows(alignmentContainer.alignments, start, end, false)
+ async function _testPacking(chr) {
+ const start = 24375132
+ const end = 24385311
- let count = 0
- for (let r of rows) count += r.alignments.length
+ const bamReader = new BamReaderNonIndexed({
+ type: 'bam',
+ url: 'test/data/bam/gstt1_sample.bam',
+ indexed: false
+ })
- // All alignments are packed
- assert.equal(alignmentContainer.alignments.length, count)
+ const alignmentContainer = await bamReader.readAlignments(chr, start, end)
- // No duplicates
- const seen = new Set()
- for (let r of rows) {
- for (let a of r.alignments) {
- if (seen.has(a)) {
- assert.fail(a, undefined, 'Alignment seen twice')
+ const rows = packAlignmentRows(alignmentContainer.alignments, start, end, false)
+
+ let count = 0
+ for (let r of rows) count += r.alignments.length
+
+ // All alignments are packed
+ assert.equal(alignmentContainer.alignments.length, count)
+
+ // No duplicates
+ const seen = new Set()
+ for (let r of rows) {
+ for (let a of r.alignments) {
+ if (seen.has(a)) {
+ assert.fail(a, undefined, 'Alignment seen twice')
+ }
+ seen.add(a)
}
- seen.add(a)
}
- }
- // No alignment overlaps
- for (let r of rows) {
- let lastEnd = -1
- for (let a of r.alignments) {
- assert.isAtLeast(a.start, lastEnd, 'Alignment start is < last end')
- lastEnd = a.end
+ // No alignment overlaps
+ for (let r of rows) {
+ let lastEnd = -1
+ for (let a of r.alignments) {
+ assert.isAtLeast(a.start, lastEnd, 'Alignment start is < last end')
+ lastEnd = a.end
+ }
}
}
+
})
diff --git a/test/testBAM.js b/test/testBAM.js
index f0e440e0c..4895e4f07 100755
--- a/test/testBAM.js
+++ b/test/testBAM.js
@@ -2,6 +2,10 @@ import "./utils/mockObjects.js"
import BamReader from "../js/bam/bamReader.js"
import {assert} from 'chai'
import BamReaderNonIndexed from "../js/bam/bamReaderNonIndexed.js"
+import {createGenome} from "./utils/Genome.js"
+
+
+const genome = createGenome()
suite("testBAM", function () {
@@ -12,10 +16,11 @@ suite("testBAM", function () {
const end = 155160000
const bamReader = new BamReader({
- type: 'bam',
- url: 'test/data/bam/na12889.bam',
- indexURL: 'test/data/bam/na12889.bam.csi'
- })
+ type: 'bam',
+ url: 'test/data/bam/na12889.bam',
+ indexURL: 'test/data/bam/na12889.bam.csi'
+ },
+ genome)
const alignmentContainer = await bamReader.readAlignments(chr, start, end)
validate(assert, alignmentContainer)
@@ -23,17 +28,20 @@ suite("testBAM", function () {
test("BAM alignments - non indexed", async function () {
- const chr = 'chr1'
const start = 155140000
const end = 155160000
const bamReader = new BamReaderNonIndexed({
- type: 'bam',
- url: 'test/data/bam/na12889.bam',
- indexed: false
- })
+ type: 'bam',
+ url: 'test/data/bam/na12889.bam',
+ indexed: false
+ },
+ genome)
- const alignmentContainer = await bamReader.readAlignments(chr, start, end)
+ let alignmentContainer = await bamReader.readAlignments("chr1", start, end)
+ validate(assert, alignmentContainer)
+
+ alignmentContainer = await bamReader.readAlignments("1", start, end)
validate(assert, alignmentContainer)
})
diff --git a/test/testBED.js b/test/testBED.js
index fdbcb0020..500307b28 100644
--- a/test/testBED.js
+++ b/test/testBED.js
@@ -5,7 +5,7 @@ import {assert} from 'chai'
import {createGenome} from "./utils/Genome.js"
const genome = createGenome()
-import GenomeUtils from "../js/genome/genomeUtils.js"
+import Genome from "../js/genome/genome.js"
suite("testBed", function () {
@@ -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 GenomeUtils.loadGenome({
+ const genome = await Genome.loadGenome({
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/testChromAlias.js b/test/testChromAlias.js
new file mode 100644
index 000000000..d14bde29b
--- /dev/null
+++ b/test/testChromAlias.js
@@ -0,0 +1,58 @@
+import "./utils/mockObjects.js"
+import ChromAliasFile from "../js/genome/chromAliasFile.js"
+import BWReader from "../js/bigwig/bwReader.js"
+import {assert} from "chai"
+
+
+suite("chromAlias", function () {
+
+ const genome = {
+ chromosomes: new Map([
+ ["NC_007194.1", {name: "NC_007194.1", bpLength: 1}],
+ ])
+ }
+
+ /**
+ * Test a UCSC style chrom alias flat file
+ *
+ * # refseq assembly genbank ncbi ucsc
+ * NC_007194.1 1 CM000169.1 1 chr1
+ * NC_007195.1 2 CM000170.1 2 chr2
+ * NC_007196.1 3 CM000171.1 3 chr3
+ * NC_007197.1 4 CM000172.1 4 chr4
+ * NC_007198.1 5 CM000173.1 5 chr5
+ * NC_007199.1 6 CM000174.1 6 chr6
+ * NC_007200.1 7 CM000175.1 7 chr7
+ * NC_007201.1 8 CM000176.1 8 chr8
+ */
+ test("test chromAlias.txt", async function () {
+
+ const url = "test/data/genomes/GCF_000002655.1.chromAlias.txt"
+
+ const chromAlias = new ChromAliasFile(url, {}, genome)
+ const chromAliasRecord = await chromAlias.search("1")
+ assert.equal(chromAliasRecord.chr, "NC_007194.1")
+ assert.equal(chromAliasRecord.genbank, "CM000169.1")
+ assert.equal(chromAliasRecord.ncbi, "1")
+ assert.equal(chromAliasRecord.ucsc, "chr1")
+ })
+
+ test("test chromalias bb extra index search", async function () {
+ this.timeout(200000)
+ const config = {
+ url: "test/data/genomes/GCF_000002655.1.chromAlias.bb",
+ format: "bigbed"
+ }
+
+ const bbReader = new BWReader(config)
+
+ // There are 5 extra indexes, 1 for each alias
+ const ncbiName = "3"
+ const f1 = await bbReader.search(ncbiName)
+ assert.equal(ncbiName, f1.ncbi)
+
+ const ucscName = "chr2"
+ const f2 = await bbReader.search(ucscName)
+ assert.equal(ucscName, f2.ucsc)
+ })
+})
diff --git a/test/testCytobands.js b/test/testCytobands.js
new file mode 100644
index 000000000..ecbe2fe6e
--- /dev/null
+++ b/test/testCytobands.js
@@ -0,0 +1,42 @@
+import "./utils/mockObjects.js"
+import {assert} from 'chai'
+import CytobandFileBB from "../js/genome/cytobandFileBB.js"
+
+
+suite("test cytobands", function () {
+
+
+ /**
+ * test parsing a cytoband BB file
+ * Example feature
+ * {
+ * "chr": "chr1",
+ * "start": 0,
+ * "end": 1735965,
+ * "name": "p36.33",
+ * "gieStain": "gneg"
+ * }
+ */
+ test("test cytoband bigbed", async function () {
+
+ const url = "test/data/bb/cytoBandMapped.bb"
+ const src = new CytobandFileBB(url)
+
+ const cytobands = await src.getCytobands("chr1")
+ const last = cytobands[cytobands.length-1];
+ assert.equal(248387328, last.end)
+
+ })
+
+ test("test cytoband bigbed remote", async function () {
+
+ const url = "https://hgdownload.soe.ucsc.edu/hubs/GCA/009/914/755/GCA_009914755.4/bbi/GCA_009914755.4_T2T-CHM13v2.0.cytoBandMapped/cytoBandMapped.bb"
+ const src = new CytobandFileBB(url)
+
+ const cytobands = await src.getCytobands("chr1") // "CP068269.2
+ const last = cytobands[cytobands.length-1];
+ assert.equal(248387328, last.end)
+
+ })
+ //CP068269.2
+})
diff --git a/test/testGenome.js b/test/testGenome.js
index 74affb027..70b1970fd 100644
--- a/test/testGenome.js
+++ b/test/testGenome.js
@@ -1,7 +1,8 @@
import "./utils/mockObjects.js"
-import GenomeUtils from "../js/genome/genomeUtils.js"
+import Genome from "../js/genome/genome.js"
import {assert} from 'chai'
-import {loadCytobandsBB} from "../js/genome/cytoband.js"
+import CytobandFileBB from "../js/genome/cytobandFileBB.js"
+
suite("testGenome", function () {
@@ -13,36 +14,32 @@ suite("testGenome", function () {
id: "hg19",
fastaURL: "https://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/1kg_v37/human_g1k_v37_decoy.fasta",
cytobandURL: "https://s3.amazonaws.com/igv.broadinstitute.org/genomes/seq/b37/b37_cytoband.txt",
- wholeGenomeView: false
+ wholeGenomeView: true
}
- const genome = await GenomeUtils.loadGenome(reference)
+ const genome = await Genome.loadGenome(reference)
assert.ok(genome)
assert.equal(86, genome.chromosomeNames.length)
assert.equal(genome.getCumulativeOffset("2"), 249250621)
})
- /**
- * test parsing a cytoband BB file from the T2T hub
- * Example feature
- * {
- * "chr": "chr1",
- * "start": 0,
- * "end": 1735965,
- * "name": "p36.33",
- * "gieStain": "gneg"
- * }
- */
- test("test cytoband bigbed", async function () {
-
- const url = "test/data/bb/cytoBandMapped.bb"
- const {cytobands, chromosomes} = await loadCytobandsBB(url, {})
-
- assert.equal(23, Object.keys(cytobands).length)
- assert.equal(23, chromosomes.size)
- const chr1 = chromosomes.get("chr1")
- assert.equal(248387328, chr1.bpLength)
+ test("2bit genome with chromSizes", async function() {
+
+ this.timeout(400000)
+
+ const reference = {
+ id: "GCF_016699485.2",
+ format: "2bit",
+ twoBitURL: "https://hgdownload.gi.ucsc.edu/hubs//GCA/011/100/615/GCA_011100615.1/GCA_011100615.1.2bit",
+ 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)
+ assert.ok(genome.chromosomes.size > 0)
+ assert.ok(genome.chromosomeNames.length > 0)
})
+
+
})
diff --git a/test/testGenomeUtils.js b/test/testGenomeUtils.js
index 2e0e5e939..9e3e1884f 100644
--- a/test/testGenomeUtils.js
+++ b/test/testGenomeUtils.js
@@ -118,22 +118,4 @@ suite("testGenomeUtils", function () {
})
- test("2bit genome", async function() {
-
- this.timeout(400000)
-
- const reference = {
- id: "GCF_016699485.2",
- format: "2bit",
- twobitURL: "https://hgdownload.gi.ucsc.edu/hubs//GCA/011/100/615/GCA_011100615.1/GCA_011100615.1.2bit",
- chromSizes: "https://hgdownload.gi.ucsc.edu/hubs//GCA/011/100/615/GCA_011100615.1/GCA_011100615.1.chrom.sizes.txt"
- }
-
-
- const genome = await GenomeUtils.loadGenome(reference)
-
- assert.ok(genome)
-
- })
-
})
\ No newline at end of file
diff --git a/test/testSearch.js b/test/testSearch.js
index 53289dda5..227ca728f 100644
--- a/test/testSearch.js
+++ b/test/testSearch.js
@@ -39,32 +39,25 @@ suite("testSearch", function () {
snpField: "snp"
},
+ isSoftclipped: () => false
+
}
test("locus strings", function () {
const s1 = "chr1:100-200"
- const locus1 = parseLocusString(browser, s1)
+ const locus1 = parseLocusString(s1)
assert.equal(locus1.chr, "chr1")
assert.equal(locus1.start, 99)
assert.equal(locus1.end, 200)
- // Chr name alias
- const s2 = "1:100-200"
- const locus2 = parseLocusString(browser, s2)
- assert.equal(locus2.chr, "chr1")
- assert.equal(locus2.start, 99)
- assert.equal(locus2.end, 200)
// Single base
const s3 = "1:100"
- const locus3 = parseLocusString(browser, s3)
- assert.equal(locus3.chr, "chr1")
+ const locus3 = parseLocusString(s3)
+ assert.equal(locus3.chr, "1")
assert.equal(locus3.start, 79)
assert.equal(locus3.end, 120)
- const s4 = "egfr"
- const locus4 = parseLocusString(browser, s4)
- assert.equal(locus4, undefined)
})
test("webservice", async function () {
@@ -77,7 +70,6 @@ suite("testSearch", function () {
assert.equal(locus.chr, "chr8")
assert.equal(locus.start, 127735432)
assert.equal(locus.end, 127742951)
- assert.equal(locus.locusSearchString, gene)
})
test("search (main function)", async function () {
@@ -94,19 +86,16 @@ suite("testSearch", function () {
assert.equal(locus1.chr, "chr1")
assert.equal(locus1.start, 99)
assert.equal(locus1.end, 200)
- assert.equal(locus1.locusSearchString, s1)
const locus2 = results[1]
assert.equal(locus2.chr, "chr8")
assert.equal(locus2.start, 127735432)
assert.equal(locus2.end, 127742951)
- assert.equal(locus2.locusSearchString, s2)
const locus3 = results[2]
assert.equal(locus3.chr, "chr1")
assert.equal(locus3.start, 155185822)
assert.equal(locus3.end, 155192915)
- assert.equal(locus3.locusSearchString, s3)
})
test("search name with spaces from bed file", async function () {
@@ -123,8 +112,9 @@ suite("testSearch", function () {
const mockBrowser = {
genome: {
+ loadChromosome: async (chr) => chr,
getChromosomeName: (chr) => chr,
- getChromosome: (chr) => undefined
+ getChromosome: (chr) => {return {name: chr, bpLenght: 0}}
},
tracks: [{
featureSource: featureSource,
diff --git a/test/testSeg.js b/test/testSeg.js
index 3f930130e..f4f3f88d1 100644
--- a/test/testSeg.js
+++ b/test/testSeg.js
@@ -1,6 +1,6 @@
import "./utils/mockObjects.js"
import FeatureSource from "../js/feature/featureSource.js"
-import GenomeUtils from "../js/genome/genomeUtils.js"
+import Genome from "../js/genome/genome.js"
import {assert} from 'chai'
import {createGenome} from "./utils/Genome.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 GenomeUtils.loadGenome(reference)
+ const genome = await Genome.loadGenome(reference)
const url = "https://www.dropbox.com/s/h1rotg4xgn1bq8a/segmented_data_080520.seg.gz?dl=0"
const featureSource = FeatureSource({
format: 'seg',
diff --git a/test/testTwobit.js b/test/testTwobit.js
index 7840f9b5d..8d4848856 100644
--- a/test/testTwobit.js
+++ b/test/testTwobit.js
@@ -1,6 +1,7 @@
import "./utils/mockObjects.js"
import {assert} from 'chai'
import TwobitSequence from "../js/genome/twobit.js"
+import BPTree from "../js/bigwig/bpTree.js"
suite("testTwobit", function () {
@@ -15,7 +16,7 @@ suite("testTwobit", function () {
const start = 5
const end = 100
const seqString = await twobit.readSequence("chr1", start, end)
- // assert.equal(seqString.length, end - start)
+ // assert.equal(seqString.length, end - start)
assert.equal(seqString, expectedSequence.substring(start, end))
})
@@ -47,18 +48,23 @@ suite("testTwobit", function () {
assert.equal(expectedSeq, seq)
})
+ test("twobit metadata", async function () {
+ const url = "test/data/twobit/GCF_000002655.1.2bit"
+ const twobit = new TwobitSequence({twoBitURL: url})
+ await twobit.init()
+ const sequenceRecord = await twobit.getSequenceRecord("NC_007196.1")
+ assert.deepEqual(sequenceRecord.dnaSize, 4079167)
+ })
test("twobit blocks", async function () {
this.timeout(200000)
const url = "https://hgdownload.soe.ucsc.edu/goldenPath/hg38/bigZips/hg38.2bit"
- const twobit = new TwobitSequence({fastaURL: url})
+ const twobit = new TwobitSequence({twoBitURL: url})
await twobit.init()
- await twobit._getSequenceMetaData("chr1")
-
- const meta = twobit.metaIndex.get("chr1")
+ const meta = await twobit.getSequenceRecord("chr1")
assert.equal(248956422, meta.dnaSize)
let lastBlockEnd = -1
@@ -76,5 +82,34 @@ suite("testTwobit", function () {
}
})
+ test("twobit .bpt index", async function () {
+
+ const url = "test/data/twobit/GCA_004363605.1.2bit.bpt"
+ const bpTree = await BPTree.loadBpTree(url, 0)
+ assert.ok(bpTree)
+
+ const result = await bpTree.search("RJWJ011179649.1")
+ assert.ok(result)
+
+
+ })
+
+ test("twobit w bpt", async function () {
+
+ const expectedSequence = "GCAGGTATCCAAAGCCAGAGGCCTGGTGCTACACGACTGG"
+
+ const url = "test/data/twobit/GCF_000002655.1.2bit"
+ const bptUrl = "test/data/twobit/GCF_000002655.1.2bit.bpt"
+ const twobit = new TwobitSequence({twoBitURL: url, twoBitBptURL: bptUrl})
+ const chr = "NC_007194.1"
+ const start = 1644639
+ const end = 1644679
+ const seqString = await twobit.readSequence(chr, start, end)
+ assert.equal(seqString, expectedSequence)
+
+
+
+ })
+
})
\ No newline at end of file
diff --git a/test/testUCSC.js b/test/testUCSC.js
index 545ad591c..e29e76be5 100644
--- a/test/testUCSC.js
+++ b/test/testUCSC.js
@@ -14,22 +14,21 @@ suite("ucsc utilities", function () {
this.timeout(200000)
- const hub = await Hub.loadHub({url: "https://hgdownload.soe.ucsc.edu/hubs/GCF/000/186/305/GCF_000186305.1/hub.txt"})
+ const hub = await Hub.loadHub({url: "test/data/hubs/hub.txt"})
assert.ok(hub.hub)
assert.ok(hub.genomeStanza)
assert.equal(22, hub.trackStanzas.length)
const genomeConfig = hub.getGenomeConfig()
- //const genome = await GenomeUtils.loadGenome(genomeConfig)
+ //const genome = await Genome.loadGenome(genomeConfig)
assert.ok(genomeConfig)
assert.equal("GCF_000186305.1", genomeConfig.id)
assert.equal("Python bivittatus", genomeConfig.name)
- assert.ok(genomeConfig.twobitURL)
- assert.ok(genomeConfig.aliasBbURL)
+ assert.ok(genomeConfig.twoBitBptURL)
+ assert.ok(genomeConfig.twoBitURL)
+ assert.ok(genomeConfig.chromAliasBbURL)
assert.ok(genomeConfig.cytobandBbURL)
-
-
})
test("trix", async function () {
@@ -68,5 +67,9 @@ suite("ucsc utilities", function () {
assert.equal(f2.name2.toLowerCase(), name2.toLowerCase())
})
+
+
+
+
})
diff --git a/test/utils/Genome.js b/test/utils/Genome.js
index e53d33bbe..4996f5927 100644
--- a/test/utils/Genome.js
+++ b/test/utils/Genome.js
@@ -39,6 +39,10 @@ function createGenome() {
chr.startsWith("chr") ? chr : "chr" + chr
},
+ loadChromosome: async function (chr) {
+ return this.getChromosome(chr)
+ },
+
getChromosome: function (chr) {
const name = this.getChromosomeName(chr)
@@ -46,43 +50,21 @@ function createGenome() {
return bpLength ? {name, bpLength} : undefined
},
- wgChromosomeNames: Object.keys(sizes),
+ getAliasRecord : async function(chr) {
+ const chromosome = this.getChromosome(chr)
- featureDB: new Map(),
+ return {
+ chr: chromosome.name,
+ start: 0,
+ end: chromosome.bpLength,
+ ncbi: chromosome.name.substring(3)
+ }
- addFeaturesToDB: function (featureList, config) {
+ },
- const insertFeature = (name, feature) => {
- const current = this.featureDB.get(name)
- if (current) {
- feature = (feature.end - feature.start) > (current.end - current.start) ? feature : current
- }
- this.featureDB.set(name, feature)
- }
+ wgChromosomeNames: Object.keys(sizes),
- for (let feature of featureList) {
- if (feature.name) {
- insertFeature(feature.name.toUpperCase(), feature)
- }
- if (feature.gene && feature.gene.name) {
- insertFeature(feature.gene.name.toUpperCase(), feature)
- }
-
- if (config.searchableFields) {
- for (let f of config.searchableFields) {
- const value = feature.getAttributeValue(f)
- if (value) {
- if (value.indexOf(" ") > 0) {
- insertFeature(value.replaceAll(" ", "+").toUpperCase(), feature)
- } else {
- insertFeature(value.toUpperCase(), feature)
- }
- }
- }
- }
- }
- }
}
}