diff --git a/src/main/java/org/broad/igv/bbfile/BBBlock.java b/src/main/java/org/broad/igv/bbfile/BBBlock.java deleted file mode 100644 index ec4a583112..0000000000 --- a/src/main/java/org/broad/igv/bbfile/BBBlock.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.broad.igv.bbfile; - -class BBBlock { - long offset; - long size; - - public BBBlock(long offset, long size) { - this.offset = offset; - this.size = size; - } -} diff --git a/src/main/java/org/broad/igv/bbfile/BBDataSource.java b/src/main/java/org/broad/igv/bbfile/BBDataSource.java index e958d1877e..ce5c3c4031 100644 --- a/src/main/java/org/broad/igv/bbfile/BBDataSource.java +++ b/src/main/java/org/broad/igv/bbfile/BBDataSource.java @@ -25,7 +25,6 @@ package org.broad.igv.bbfile; -import org.apache.commons.math3.stat.StatUtils; import org.broad.igv.Globals; import org.broad.igv.bbfile.codecs.BBCodec; import org.broad.igv.bbfile.codecs.BBCodecFactory; @@ -40,13 +39,12 @@ import org.broad.igv.ui.IGV; import org.broad.igv.util.collections.FloatArrayList; import org.broad.igv.util.collections.IntArrayList; -import htsjdk.tribble.Feature; import java.io.IOException; import java.util.*; /** - * A hybrid source, implements both DataSource and FeatureSource. Way of the future? + * A hybrid source, implements both DataSource and FeatureSource. * * @author jrobinso * @date Jun 19, 2011 @@ -56,7 +54,7 @@ public class BBDataSource extends AbstractDataSource implements FeatureSource { Collection availableWindowFunctions = Arrays.asList(WindowFunction.min, WindowFunction.mean, WindowFunction.max, WindowFunction.none); - BBFileReader2 reader; + BBFileReader reader; private BBZoomHeader [] levels; // Feature visibility window (for bigBed) @@ -74,7 +72,7 @@ public class BBDataSource extends AbstractDataSource implements FeatureSource { BBCodec bedCodec; - public BBDataSource(BBFileReader2 reader, Genome genome) throws IOException { + public BBDataSource(BBFileReader reader, Genome genome) throws IOException { super(genome); this.reader = reader; @@ -126,7 +124,7 @@ private void initMinMax() { dataMin = 0; double mean = summary.sumData / summary.basesCovered; double stdDev = Math.sqrt(summary.sumSquares / summary.basesCovered); - dataMax = Math.min(summary.maxVal, mean + 2 * stdDev); + dataMax = Math.min(summary.maxVal, mean + 3 * stdDev); } } @@ -172,7 +170,7 @@ private BBZoomHeader getZoomLevelForScale(double resolution) { if (levels == null) return null; final BBZoomHeader [] headers = levels; - for (int i = headers.length - 1; i >= 0; i--) { + for (int i = i = 0; i < headers.length; i++) { BBZoomHeader zlHeader = headers[i]; long reductionLevel = zlHeader.reductionLevel; if (reductionLevel < resolution) { @@ -301,7 +299,7 @@ private List getWholeGenomeScores() { ArrayList scores = new ArrayList(); wholeGenomeScores.put(windowFunction, scores); - BBZoomHeader lowestResHeader = this.getZoomLevelForScale(scale); + BBZoomHeader lowestResHeader = levels[0]; //this.getZoomLevelForScale(scale); if (lowestResHeader == null) return null; Set wgChrNames = new HashSet<>(genome.getLongChromosomeNames()); diff --git a/src/main/java/org/broad/igv/bbfile/BBFileHeader.java b/src/main/java/org/broad/igv/bbfile/BBFileHeader.java old mode 100755 new mode 100644 index fa60f664ac..e65189cd33 --- a/src/main/java/org/broad/igv/bbfile/BBFileHeader.java +++ b/src/main/java/org/broad/igv/bbfile/BBFileHeader.java @@ -1,288 +1,39 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2007-2015 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. - */ +package org.broad.igv.bbfile; -/** - * Created by IntelliJ IDEA. - * User: martind - * Date: Nov 20, 2009 - * Time: 3:49:14 PM - * To change this template use File | Settings | File Templates. - */ +import org.broad.igv.logging.LogManager; +import org.broad.igv.logging.Logger; +import org.broad.igv.util.ByteBufferUnsigned; /** - * Container class defines the header information for BigBed and BigWig files + * BB File header -- supplemental table 5. Common header for BigWig and BigBed files. 64 bytes in size. */ -package org.broad.igv.bbfile; - - -import htsjdk.samtools.seekablestream.SeekableStream; -import org.broad.igv.logging.*; -import org.broad.igv.util.LittleEndianInputStream; - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; - -/* -* Container class for holding the BBFile header information, Table C . -**/ public class BBFileHeader { private static Logger log = LogManager.getLogger(BBFileHeader.class); - // defines bigBed/bigwig Header Format types - static public final int BBFILE_HEADER_SIZE = 64; - - static public final int BIGWIG_MAGIC_LTH = 0x888FFC26; // BigWig Magic Low to High - static public final int BIGWIG_MAGIC_HTL = 0x26FC8F66; // BigWig Magic High to Low - - static public final int BIGBED_MAGIC_LTH = 0x8789F2EB; // BigBed Magic Low to High - static public final int BIGBED_MAGIC_HTL = 0xEBF28987; // BigBed Magic High to Low - - // defines the bigBed/bigWig source file access - private String path; // bigBed file/pathname - private SeekableStream fis; // BBFile I/O stream handle - private long fileHeaderOffset; // file offset for file header - - private boolean isHeaderOK; // File header read correctly? - private boolean isLowToHigh; // flag indicates values represented low to high bytes - private boolean isBigBed; // flag indicates file is BigBed format - private boolean isBigWig; // flag indicates file is BigWig format; - - // BBFile Header items - Table C: - // mMagic number (4 bytes) indicates file type and byte order : - // 0x888FFC26 for bigWig, little endian if swapped - // 0x8789F2EB for bigBed, little endian if swapped - private int magic; // 4 byte mMagic Number - private int version; // 2 byte version ID; currently 3 - private int nZoomLevels; // 2 byte count of zoom sumary levels - private long chromTreeOffset; // 8 byte offset to mChromosome B+ Tree index - private long fullDataOffset; // 8 byte offset to unzoomed data dataCount - private long fullIndexOffset; // 8 byte offset to R+ Tree index of items - private int fieldCount; // 2 byte number of fields in bed. (0 for bigWig) - private int definedFieldCount; // 2 byte number of fields that are bed fields - private long autoSqlOffset; // 8 byte offset to 0 terminated string with .as spec - private long totalSummaryOffset; // 8 byte offset to file summary data block - private int uncompressBuffSize; // 4 byte maximum size for decompressed buffer - private long reserved; // 8 bytes reserved for future expansion. Currently 0 - - // constructor reads BBFile header from an input stream - public BBFileHeader(String path, SeekableStream fis, long fileOffset) { - - // save the path and seekable file handle - this.path = path; - this.fis = fis; - fileHeaderOffset = fileOffset; - - // read in BBFile header - isHeaderOK = readBBFileHeader(fileHeaderOffset); - } - - - public String getPath() { - return path; - } - - public boolean isHeaderOK() { - return isHeaderOK; - } - - public boolean isLowToHigh() { - return isLowToHigh; - } - - public boolean isBigBed() { - return isBigBed; - } - - public boolean isBigWig() { - return isBigWig; - } - - public int getFileHeaderSize() { - return BBFILE_HEADER_SIZE; - } - - // ************* return header items **************** - - public int getMagic() { - return magic; - } - - public int getVersion() { - return version; - } - - public int getZoomLevels() { - return nZoomLevels; - } - - public long getChromosomeTreeOffset() { - return chromTreeOffset; - } - - public long getFullDataOffset() { - return fullDataOffset; - } - - public long getFullIndexOffset() { - return fullIndexOffset; - } - - public int getFieldCount() { - return fieldCount; - } - - public int getDefinedFieldCount() { - return definedFieldCount; - } - - public long getAutoSqlOffset() { - return autoSqlOffset; - } - - public long getTotalSummaryOffset() { - return totalSummaryOffset; - } - - public int getUncompressBuffSize() { - return uncompressBuffSize; - } - - - public void print() { - - if (isHeaderOK) { - if (isBigWig()) - System.out.println("BigWig file " + path + ", file header at location " + fileHeaderOffset); - else if (isBigBed()) - System.out.println("BigBed file " + path + ", file header at location " + fileHeaderOffset); - } else { - System.out.println("BBFile " + path + " with bad magic = " + magic + - " from file header location " + fileHeaderOffset); - return; // bad read - remaining header items not interpreted - } - - - // header fields - System.out.println("BBFile header magic = " + magic); - System.out.println("Version = " + version); - System.out.println("Zoom Levels = " + nZoomLevels); - System.out.println("Chromosome Info B+ tree offset = " + chromTreeOffset); - System.out.println("Data Block offset = " + fullDataOffset); - System.out.println("Chromosome Data R+ tree offset = " + fullIndexOffset); - System.out.println("Bed fields count = " + fieldCount); - System.out.println("Bed defined fields count = " + definedFieldCount); - System.out.println("AutoSql Offset = " + autoSqlOffset); - System.out.println("Total Summary offset = " + totalSummaryOffset); - System.out.println("Maximum uncompressed buffer size = " + uncompressBuffSize); - System.out.println("m_reserved = " + reserved); - } - - /* - * Reads in BBFile header information. - * - * Returns: - * Success status flag is true for successfully read header, - * or is false for a read error. - **/ - private boolean readBBFileHeader(long fileOffset) { - - BBFileHeader bbHeader = null; - LittleEndianInputStream lbdis = null; - DataInputStream bdis = null; - - byte[] buffer = new byte[BBFILE_HEADER_SIZE]; - - - try { - // Read bigBed header into a buffer - fis.seek(fileOffset); - fis.readFully(buffer); - - // decode header - determine byte order from first 4 bytes - // first assume byte order is low to high - isLowToHigh = true; - lbdis = new LittleEndianInputStream(new ByteArrayInputStream(buffer)); - magic = lbdis.readInt(); - - // check for a valid bigBed or bigWig file - if (magic == BIGWIG_MAGIC_LTH) { - isBigWig = true; - } else if (magic == BIGBED_MAGIC_LTH) { - isBigBed = true; - } else { - bdis = new DataInputStream(new ByteArrayInputStream(buffer)); - magic = bdis.readInt(); - - // check for a valid bigBed or bigWig file - if (magic == BIGWIG_MAGIC_HTL) - isBigWig = true; - else if (magic == BIGBED_MAGIC_HTL) - isBigBed = true; - - else - return false; // can't identify BBFile type - - // success - set order high to low - isLowToHigh = false; - } - - // Get header information - if (isLowToHigh) { - version = lbdis.readUShort(); - nZoomLevels = lbdis.readUShort(); - chromTreeOffset = lbdis.readLong(); - fullDataOffset = lbdis.readLong(); - fullIndexOffset = lbdis.readLong(); - fieldCount = lbdis.readUShort(); - definedFieldCount = lbdis.readUShort(); - autoSqlOffset = lbdis.readLong(); - totalSummaryOffset = lbdis.readLong(); - uncompressBuffSize = lbdis.readInt(); - reserved = lbdis.readLong(); - } else { - version = (short) bdis.readUnsignedShort(); - nZoomLevels = (short) bdis.readUnsignedShort(); - chromTreeOffset = bdis.readLong(); - fullDataOffset = bdis.readLong(); - fullIndexOffset = bdis.readLong(); - fieldCount = (short) bdis.readUnsignedShort(); - definedFieldCount = (short) bdis.readUnsignedShort(); - autoSqlOffset = bdis.readLong(); - totalSummaryOffset = bdis.readLong(); - uncompressBuffSize = bdis.readInt(); - reserved = bdis.readLong(); - } - - } catch (IOException ex) { - throw new RuntimeException("Error reading file header for " + path, ex); - } - - // file header was read properly - return true; - } - -} // mEndBase of class BBFileHeader + int version; // 2 byte version ID; currently 3 + int nZoomLevels; // 2 byte count of zoom sumary levels + long chromTreeOffset; // 8 byte offset to mChromosome B+ Tree index + long fullDataOffset; // 8 byte offset to unzoomed data dataCount + long fullIndexOffset; // 8 byte offset to R+ Tree index of items + int fieldCount; // 2 byte number of fields in bed. (0 for bigWig) + int definedFieldCount; // 2 byte number of fields that are bed fields + long autoSqlOffset; // 8 byte offset to 0 terminated string with .as spec + long totalSummaryOffset; // 8 byte offset to file summary data block + int uncompressBuffSize; + long extensionOffset; + + public BBFileHeader(ByteBufferUnsigned bb) { + this.version = bb.getUShort(); + this.nZoomLevels = bb.getUShort(); + this.chromTreeOffset = bb.getLong(); + this.fullDataOffset = bb.getLong(); + this.fullIndexOffset = bb.getLong(); + this.fieldCount = bb.getUShort(); + this.definedFieldCount = bb.getUShort(); + this.autoSqlOffset = bb.getLong(); + this.totalSummaryOffset = bb.getLong(); + this.uncompressBuffSize = bb.getInt(); + this.extensionOffset = bb.getLong(); + } +} diff --git a/src/main/java/org/broad/igv/bbfile/BBFileHeader2.java b/src/main/java/org/broad/igv/bbfile/BBFileHeader2.java deleted file mode 100644 index 02cba6d3c4..0000000000 --- a/src/main/java/org/broad/igv/bbfile/BBFileHeader2.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.broad.igv.bbfile; - -import org.broad.igv.logging.LogManager; -import org.broad.igv.logging.Logger; -import org.broad.igv.util.ByteBufferUnsigned; - -/** - * BB File header -- supplemental table 5. Common header for BigWig and BigBed files. 64 bytes in size. - */ -public class BBFileHeader2 { - - private static Logger log = LogManager.getLogger(BBFileHeader2.class); - - int version; // 2 byte version ID; currently 3 - int nZoomLevels; // 2 byte count of zoom sumary levels - long chromTreeOffset; // 8 byte offset to mChromosome B+ Tree index - long fullDataOffset; // 8 byte offset to unzoomed data dataCount - long fullIndexOffset; // 8 byte offset to R+ Tree index of items - int fieldCount; // 2 byte number of fields in bed. (0 for bigWig) - int definedFieldCount; // 2 byte number of fields that are bed fields - long autoSqlOffset; // 8 byte offset to 0 terminated string with .as spec - long totalSummaryOffset; // 8 byte offset to file summary data block - int uncompressBuffSize; - long extensionOffset; - - public BBFileHeader2(ByteBufferUnsigned bb) { - this.version = bb.getUShort(); - this.nZoomLevels = bb.getUShort(); - this.chromTreeOffset = bb.getLong(); - this.fullDataOffset = bb.getLong(); - this.fullIndexOffset = bb.getLong(); - this.fieldCount = bb.getUShort(); - this.definedFieldCount = bb.getUShort(); - this.autoSqlOffset = bb.getLong(); - this.totalSummaryOffset = bb.getLong(); - this.uncompressBuffSize = bb.getInt(); - this.extensionOffset = bb.getLong(); - } -} diff --git a/src/main/java/org/broad/igv/bbfile/BBFileReader2.java b/src/main/java/org/broad/igv/bbfile/BBFileReader.java similarity index 88% rename from src/main/java/org/broad/igv/bbfile/BBFileReader2.java rename to src/main/java/org/broad/igv/bbfile/BBFileReader.java index d591ff8105..8a4ffce5d9 100644 --- a/src/main/java/org/broad/igv/bbfile/BBFileReader2.java +++ b/src/main/java/org/broad/igv/bbfile/BBFileReader.java @@ -12,12 +12,9 @@ import java.util.Iterator; import java.util.List; -public class BBFileReader2 { - - +public class BBFileReader { enum Type {BigWig, BigBed} - static public final int BBFILE_HEADER_SIZE = 64; static public final int BIGWIG_MAGIC_LTH = 0x888FFC26; // BigWig Magic Low to High static public final int BIGWIG_MAGIC_HTL = 0x26FC8F66; // BigWig Magic High to Low @@ -29,7 +26,7 @@ enum Type {BigWig, BigBed} String path; Type type; ByteOrder byteOrder = ByteOrder.LITTLE_ENDIAN; // until proven otherwise - BBFileHeader2 header; + BBFileHeader header; BBZoomHeader[] zoomHeaders; String autoSql; BBTotalSummary totalSummary; @@ -99,7 +96,16 @@ public List getZoomDataOverlapping(int zoomLevel, int startChromID, in float sumData = bb.getFloat(); float sumSquares = bb.getFloat(); - if((chromID > startChromID && chromID < endChromId) ||(chromEnd > start && chromStart < end)) { + boolean overlaps = false; + if(chromID == startChromID && chromID == endChromId) { + overlaps = chromEnd > start && chromStart < end; + } else if (chromID == startChromID) { + overlaps = chromEnd > end; + } else if (chromID == endChromId) { + overlaps = chromStart < start; + } + + if( overlaps) { zoomDataList.add(new ZoomData(chromID, chromStart, chromEnd, validCount, minValue, maxValue, sumData, sumSquares)); } } @@ -127,15 +133,25 @@ public List getBedDataOverlapping(int startChromID, int start, int endC while (bb.remaining() > 0) { int chromID = bb.getInt(); int chromStart = bb.getInt(); + int chromEnd = bb.getInt(); if((chromID > endChromId) || (chromID == endChromId && chromStart >= end)) { return bedDataList; } - int chromEnd = bb.getInt(); String rest = bb.getString(); - String chromName = this.chromTree.idToNameMap.get(chromID); - if((chromID > startChromID && chromID < endChromId) ||(chromEnd > start && chromStart < end)) { + + boolean overlaps = false; + if(chromID == startChromID && chromID == endChromId) { + overlaps = chromEnd > start && chromStart < end; + } else if (chromID == startChromID) { + overlaps = chromEnd > end; + } else if (chromID == endChromId) { + overlaps = chromStart < start; + } + + if(overlaps) { + String chromName = this.chromTree.idToNameMap.get(chromID); bedDataList.add(new BedData(chromName, chromStart, chromEnd, rest)); } } @@ -199,8 +215,16 @@ public List getWigItemsOverlapping(int startChromID, int start, int end return wigItemList; } - if (((chromID > startChromID && chromID < endChromId) ||(chromEnd > start && chromStart < end)) && - !Float.isNaN(value) && Float.isFinite(value)) { + boolean overlaps = false; + if(chromID == startChromID && chromID == endChromId) { + overlaps = chromEnd > start && chromStart < end; + } else if (chromID == startChromID) { + overlaps = chromEnd > end; + } else if (chromID == endChromId) { + overlaps = chromStart < start; + } + + if (overlaps) { wigItemList.add(new WigItem(chrName, chromStart, chromEnd, value)); } } @@ -238,9 +262,9 @@ public List getBuffersOverlapping(RTree rTree, int startChomID, int star } - public static BBFileReader2 getReaderFor(String path) { + public static BBFileReader getReaderFor(String path) { try { - BBFileReader2 reader = new BBFileReader2(path); + BBFileReader reader = new BBFileReader(path); reader.readBBFileHeader(); return reader; } catch (IOException e) { @@ -248,7 +272,7 @@ public static BBFileReader2 getReaderFor(String path) { } } - private BBFileReader2(String path) { + private BBFileReader(String path) { this.path = path; } @@ -286,7 +310,7 @@ private void readBBFileHeader() throws IOException { } // Read header (supplemental table 5) - this.header = new BBFileHeader2(bb); + this.header = new BBFileHeader(bb); // Rest of items up to unzoomed data. See supplemental table 4 long startOffset = BBFILE_HEADER_SIZE; @@ -393,6 +417,15 @@ public List findOverlappingBlocks(RTree fullIndexTree, int startChromID } + static class BBBlock { + long offset; + long size; + + public BBBlock(long offset, long size) { + this.offset = offset; + this.size = size; + } + } } diff --git a/src/main/java/org/broad/igv/bbfile/RTree.java b/src/main/java/org/broad/igv/bbfile/RTree.java index 20c4da1acb..3b11976877 100644 --- a/src/main/java/org/broad/igv/bbfile/RTree.java +++ b/src/main/java/org/broad/igv/bbfile/RTree.java @@ -54,7 +54,7 @@ List findItemsOverlapping(int startChromID, long startBase, int e private void _findItemsOverlapping(int startChromID, long startBase, int endChromId, long endBase, List items, RTreeNode node) throws IOException { - if(node.overlaps(startChromID, startBase, endChromId, endBase)) { + if (node.overlaps(startChromID, startBase, endChromId, endBase)) { for (RTreeNodeItem item : node.items) { if (item.overlaps(startChromID, startBase, endChromId, endBase)) { if (item.isLeaf) { @@ -93,69 +93,69 @@ RTreeNode readNode(long offset) throws IOException { return new RTreeNode(isLeaf, items); } } -} -class RTreeNode { - boolean isLeaf; - RTreeNodeItem[] items; - - int startChromID; - long startBase; - int endChromId; - long endBase; - - public RTreeNode(boolean isLeaf, RTreeNodeItem[] items) { - this.isLeaf = isLeaf; - this.items = items; - - RTreeNodeItem firstItem = items[0]; - startChromID = firstItem.startChromID; - endChromId = firstItem.endChromId; - startBase = firstItem.startBase; - endBase = firstItem.endBase; - - if(items.length > 1) { - for(int i=1; i< items.length; i++) { - RTreeNodeItem item = items[i]; - startChromID = Math.min(startChromID, item.startChromID); - startBase = Math.min(startBase, item.startBase); - endChromId = Math.max(endChromId, item.endChromId); - endBase = Math.max(endBase, item.endBase); - } + static class RTreeHeader { + + int blockSize; // number of children per block + long itemCount; // number of chromosomes/contigs in B+ tree + int startChromID; // ID of the first mChromosome in item + long startBase; // Position of first base in item + int endChromID; // ID of the first mChromosome in item + long endBase; // Position of first base in item + long endFileOffset; // file position marking mEndBase of data + int itemsPerSlot; // number of items per leaf + private long reserved; // Currently 0 + + RTreeHeader(ByteBufferUnsigned bb) { + int magic = bb.getInt(); + blockSize = bb.getInt(); + itemCount = bb.getLong(); + startChromID = bb.getInt(); + startBase = bb.getUInt(); + endChromID = bb.getInt(); + endBase = bb.getUInt(); + endFileOffset = bb.getLong(); + itemsPerSlot = bb.getInt(); + int reserved = bb.getInt(); } - } - boolean overlaps(int chrIdx1, long startBase, int chrIdx2, long endBase) { - return ((chrIdx2 > this.startChromID) || (chrIdx2 == this.startChromID && endBase >= this.startBase)) && - ((chrIdx1 < this.endChromId) || (chrIdx1 == this.endChromId && startBase <= this.endBase)); + static class RTreeNode { + boolean isLeaf; + RTreeNodeItem[] items; + + int startChromID; + long startBase; + int endChromId; + long endBase; + + public RTreeNode(boolean isLeaf, RTreeNodeItem[] items) { + this.isLeaf = isLeaf; + this.items = items; + + RTreeNodeItem firstItem = items[0]; + startChromID = firstItem.startChromID; + endChromId = firstItem.endChromId; + startBase = firstItem.startBase; + endBase = firstItem.endBase; + + if (items.length > 1) { + for (int i = 1; i < items.length; i++) { + RTreeNodeItem item = items[i]; + startChromID = Math.min(startChromID, item.startChromID); + startBase = Math.min(startBase, item.startBase); + endChromId = Math.max(endChromId, item.endChromId); + endBase = Math.max(endBase, item.endBase); + } + } + + } - } -} + boolean overlaps(int chrIdx1, long startBase, int chrIdx2, long endBase) { + return ((chrIdx2 > this.startChromID) || (chrIdx2 == this.startChromID && endBase >= this.startBase)) && + ((chrIdx1 < this.endChromId) || (chrIdx1 == this.endChromId && startBase <= this.endBase)); -class RTreeHeader { - - int blockSize; // number of children per block - long itemCount; // number of chromosomes/contigs in B+ tree - int startChromID; // ID of the first mChromosome in item - long startBase; // Position of first base in item - int endChromID; // ID of the first mChromosome in item - long endBase; // Position of first base in item - long endFileOffset; // file position marking mEndBase of data - int itemsPerSlot; // number of items per leaf - private long reserved; // Currently 0 - - RTreeHeader(ByteBufferUnsigned bb) { - int magic = bb.getInt(); - blockSize = bb.getInt(); - itemCount = bb.getLong(); - startChromID = bb.getInt(); - startBase = bb.getUInt(); - endChromID = bb.getInt(); - endBase = bb.getUInt(); - endFileOffset = bb.getLong(); - itemsPerSlot = bb.getInt(); - int reserved = bb.getInt(); + } } } diff --git a/src/main/java/org/broad/igv/methyl/BBMethylDataSource.java b/src/main/java/org/broad/igv/methyl/BBMethylDataSource.java index 5ad07f4bbf..8e4046d096 100644 --- a/src/main/java/org/broad/igv/methyl/BBMethylDataSource.java +++ b/src/main/java/org/broad/igv/methyl/BBMethylDataSource.java @@ -26,7 +26,7 @@ package org.broad.igv.methyl; import org.broad.igv.Globals; -import org.broad.igv.bbfile.BBFileReader2; +import org.broad.igv.bbfile.BBFileReader; import org.broad.igv.bbfile.BedData; import org.broad.igv.feature.Strand; import org.broad.igv.feature.genome.Genome; @@ -49,7 +49,7 @@ enum Type {ZILLER, USC} ; - BBFileReader2 reader; + BBFileReader reader; Type type; /** @@ -57,7 +57,7 @@ enum Type {ZILLER, USC} */ Map chrNameMap; - public BBMethylDataSource(BBFileReader2 reader, Type type, Genome genome) throws IOException { + public BBMethylDataSource(BBFileReader reader, Type type, Genome genome) throws IOException { this.reader = reader; this.type = type; init(genome); diff --git a/src/main/java/org/broad/igv/methyl/MethylTrack.java b/src/main/java/org/broad/igv/methyl/MethylTrack.java index 738961a0e4..bb7cb618d5 100644 --- a/src/main/java/org/broad/igv/methyl/MethylTrack.java +++ b/src/main/java/org/broad/igv/methyl/MethylTrack.java @@ -26,7 +26,7 @@ package org.broad.igv.methyl; import org.broad.igv.Globals; -import org.broad.igv.bbfile.BBFileReader2; +import org.broad.igv.bbfile.BBFileReader; import org.broad.igv.feature.genome.Genome; import org.broad.igv.renderer.DataRange; import org.broad.igv.renderer.GraphicUtils; @@ -35,7 +35,6 @@ import org.broad.igv.track.AbstractTrack; import org.broad.igv.track.RenderContext; import org.broad.igv.ui.panel.ReferenceFrame; -import org.broad.igv.util.LongRunningTask; import org.broad.igv.util.ResourceLocator; import java.awt.*; @@ -64,7 +63,7 @@ public class MethylTrack extends AbstractTrack { private int resolutionThreshold; private boolean loading = false; - public MethylTrack(ResourceLocator dataResourceLocator, BBFileReader2 reader, Genome genome) throws IOException { + public MethylTrack(ResourceLocator dataResourceLocator, BBFileReader reader, Genome genome) throws IOException { super(dataResourceLocator); setHeight(60); renderer = new PointsRenderer(); diff --git a/src/main/java/org/broad/igv/track/TrackLoader.java b/src/main/java/org/broad/igv/track/TrackLoader.java index 0871c08ccc..f70d82d9ed 100644 --- a/src/main/java/org/broad/igv/track/TrackLoader.java +++ b/src/main/java/org/broad/igv/track/TrackLoader.java @@ -28,7 +28,7 @@ import htsjdk.tribble.AsciiFeatureCodec; import htsjdk.tribble.Feature; import htsjdk.variant.vcf.VCFHeader; -import org.broad.igv.bbfile.BBFileReader2; +import org.broad.igv.bbfile.BBFileReader; import org.broad.igv.bedpe.BedPEParser; import org.broad.igv.bedpe.InteractionTrack; import org.broad.igv.bbfile.BBDataSource; @@ -60,7 +60,6 @@ import org.broad.igv.feature.tribble.TribbleIndexNotFoundException; import org.broad.igv.gwas.GWASData; import org.broad.igv.util.GoogleUtils; -import org.broad.igv.gwas.GWASFeature; import org.broad.igv.gwas.GWASParser; import org.broad.igv.gwas.GWASTrack; import org.broad.igv.htsget.HtsgetUtils; @@ -790,7 +789,7 @@ public void loadBWFile(ResourceLocator locator, List newTracks, Genome ge String trackId = locator.getPath(); String path = locator.getPath(); - BBFileReader2 reader = BBFileReader2.getReaderFor(path); + BBFileReader reader = BBFileReader.getReaderFor(path); BBDataSource bigwigSource = new BBDataSource(reader, genome); Track track = null; @@ -815,7 +814,7 @@ public void loadBWFile(ResourceLocator locator, List newTracks, Genome ge } - private void loadMethylTrack(ResourceLocator locator, BBFileReader2 reader, List newTracks, Genome genome) throws IOException { + private void loadMethylTrack(ResourceLocator locator, BBFileReader reader, List newTracks, Genome genome) throws IOException { MethylTrack track = new MethylTrack(locator, reader, genome); newTracks.add(track); diff --git a/src/test/java/org/broad/igv/bbfile/BBFileReader2Test.java b/src/test/java/org/broad/igv/bbfile/BBFileReaderTest.java similarity index 88% rename from src/test/java/org/broad/igv/bbfile/BBFileReader2Test.java rename to src/test/java/org/broad/igv/bbfile/BBFileReaderTest.java index 98a96a9539..536cdecebe 100644 --- a/src/test/java/org/broad/igv/bbfile/BBFileReader2Test.java +++ b/src/test/java/org/broad/igv/bbfile/BBFileReaderTest.java @@ -1,22 +1,20 @@ package org.broad.igv.bbfile; -import htsjdk.tribble.Feature; import org.broad.igv.util.TestUtils; import org.junit.Test; import java.io.IOException; -import java.util.Iterator; import java.util.List; import static org.junit.Assert.*; -public class BBFileReader2Test { +public class BBFileReaderTest { @Test public void testBedData() throws IOException { String path = "https://hgdownload.soe.ucsc.edu/hubs/GCA/009/914/755/GCA_009914755.4/bbi/GCA_009914755.4_T2T-CHM13v2.0.catLiftOffGenesV1/catLiftOffGenesV1.bb"; - BBFileReader2 reader = BBFileReader2.getReaderFor(path); + BBFileReader reader = BBFileReader.getReaderFor(path); List bedDataList = reader.getBedDataOverlapping(21, 26490012, 21, 42182827); assertTrue(bedDataList.size() > 0); } @@ -25,7 +23,7 @@ public void testBedData() throws IOException { public void testWigData() throws IOException { String path = "https://hgdownload.soe.ucsc.edu/hubs/GCA/009/914/755/GCA_009914755.4/bbi/GCA_009914755.4_T2T-CHM13v2.0.gc5Base.bw"; - BBFileReader2 reader = BBFileReader2.getReaderFor(path); + BBFileReader reader = BBFileReader.getReaderFor(path); List wigItemList = reader.getWigItemsOverlapping(21, 26490012, 21, (26490012 + 1)); assertEquals(1, wigItemList.size()); } @@ -34,7 +32,7 @@ public void testWigData() throws IOException { public void testZoomData() throws IOException { String path = "https://hgdownload.soe.ucsc.edu/hubs/GCA/009/914/755/GCA_009914755.4/bbi/GCA_009914755.4_T2T-CHM13v2.0.gc5Base.bw"; - BBFileReader2 reader = BBFileReader2.getReaderFor(path); + BBFileReader reader = BBFileReader.getReaderFor(path); List wigItemList = reader.getZoomDataOverlapping(1, 21, 26490012, 21, (26490012 + 1)); assertEquals(1, wigItemList.size()); } @@ -43,7 +41,7 @@ public void testZoomData() throws IOException { public void testBigBed() throws IOException { String path = TestUtils.DATA_DIR + "bb/chr21.refseq.bb"; - BBFileReader2 bbReader = BBFileReader2.getReaderFor(path); + BBFileReader bbReader = BBFileReader.getReaderFor(path); assertTrue(bbReader.isBigBedFile()); String chr = "chr21"; diff --git a/src/test/java/org/broad/igv/methyl/BBMethylDataSourceTest.java b/src/test/java/org/broad/igv/methyl/BBMethylDataSourceTest.java index 0a2d5490de..0e37daff6d 100644 --- a/src/test/java/org/broad/igv/methyl/BBMethylDataSourceTest.java +++ b/src/test/java/org/broad/igv/methyl/BBMethylDataSourceTest.java @@ -26,7 +26,7 @@ package org.broad.igv.methyl; import junit.framework.Assert; -import org.broad.igv.bbfile.BBFileReader2; +import org.broad.igv.bbfile.BBFileReader; import org.broad.igv.feature.Strand; import org.broad.igv.feature.genome.Genome; import org.broad.igv.util.TestUtils; @@ -70,7 +70,7 @@ public void testUscQuery() throws Exception { int start = 10001654; int end = 10001754; - BBFileReader2 reader = BBFileReader2.getReaderFor(testFile); + BBFileReader reader = BBFileReader.getReaderFor(testFile); MethylDataSource source = new BBMethylDataSource(reader, BBMethylDataSource.Type.USC, genome); Iterator iter = source.query(chr, start, end); @@ -99,7 +99,7 @@ public void testZillerQuery() throws Exception { int end = 27333475; Genome genome = null; - BBFileReader2 reader = BBFileReader2.getReaderFor(testFile); + BBFileReader reader = BBFileReader.getReaderFor(testFile); MethylDataSource source = new BBMethylDataSource(reader, BBMethylDataSource.Type.ZILLER, genome); Iterator iter = source.query(chr, start, end); @@ -122,7 +122,7 @@ public void testCacheQuery() throws Exception { int end = 27333475; Genome genome = null; - BBFileReader2 reader = BBFileReader2.getReaderFor(testFile); + BBFileReader reader = BBFileReader.getReaderFor(testFile); MethylDataSource source = new BBMethylDataSource(reader, BBMethylDataSource.Type.ZILLER, genome); Iterator iter = source.query(chr, start, end); List nonCachedScores = new ArrayList();