protected BAMIndexContent query( final int referenceSequence, final int startPos, final int endPos) { seek(4); final List<Chunk> metaDataChunks = new ArrayList<Chunk>(); final int sequenceCount = readInteger(); if (referenceSequence >= sequenceCount) { return null; } final BitSet regionBins = GenomicIndexUtil.regionToBins(startPos, endPos); if (regionBins == null) { return null; } skipToSequence(referenceSequence); final int binCount = readInteger(); boolean metaDataSeen = false; final Bin[] bins = new Bin[getMaxBinNumberForReference(referenceSequence) + 1]; for (int binNumber = 0; binNumber < binCount; binNumber++) { final int indexBin = readInteger(); final int nChunks = readInteger(); List<Chunk> chunks = null; // System.out.println("# bin[" + i + "] = " + indexBin + ", nChunks = " + nChunks); Chunk lastChunk = null; if (regionBins.get(indexBin)) { chunks = new ArrayList<Chunk>(nChunks); for (int ci = 0; ci < nChunks; ci++) { final long chunkBegin = readLong(); final long chunkEnd = readLong(); lastChunk = new Chunk(chunkBegin, chunkEnd); chunks.add(lastChunk); } } else if (indexBin == GenomicIndexUtil.MAX_BINS) { // meta data - build the bin so that the count of bins is correct; // but don't attach meta chunks to the bin, or normal queries will be off for (int ci = 0; ci < nChunks; ci++) { final long chunkBegin = readLong(); final long chunkEnd = readLong(); lastChunk = new Chunk(chunkBegin, chunkEnd); metaDataChunks.add(lastChunk); } metaDataSeen = true; continue; // don't create a Bin } else { skipBytes(16 * nChunks); chunks = Collections.emptyList(); } final Bin bin = new Bin(referenceSequence, indexBin); bin.setChunkList(chunks); bin.setLastChunk(lastChunk); bins[indexBin] = bin; } final int nLinearBins = readInteger(); final int regionLinearBinStart = LinearIndex.convertToLinearIndexOffset(startPos); final int regionLinearBinStop = endPos > 0 ? LinearIndex.convertToLinearIndexOffset(endPos) : nLinearBins - 1; final int actualStop = Math.min(regionLinearBinStop, nLinearBins - 1); long[] linearIndexEntries = new long[0]; if (regionLinearBinStart < nLinearBins) { linearIndexEntries = new long[actualStop - regionLinearBinStart + 1]; skipBytes(8 * regionLinearBinStart); for (int linearBin = regionLinearBinStart; linearBin <= actualStop; linearBin++) linearIndexEntries[linearBin - regionLinearBinStart] = readLong(); } final LinearIndex linearIndex = new LinearIndex(referenceSequence, regionLinearBinStart, linearIndexEntries); return new BAMIndexContent( referenceSequence, bins, binCount - (metaDataSeen ? 1 : 0), new BAMIndexMetaData(metaDataChunks), linearIndex); }