Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* The MIT License
*
* Copyright (c) 2012 The 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 picard.illumina.parser.readers;
import picard.PicardException;
import picard.util.UnsignedTypeUtil;
import java.io.File;
import java.nio.ByteBuffer;
/**
* The clocs file format is one of 3 Illumina formats(pos, locs, and clocs) that stores position data exclusively.
* clocs files store position data for successive clusters, compressed in bins as follows:
* Byte 0 : unused
* Byte 1-4 : unsigned int numBins
* The rest of the file consists of bins/blocks, where a bin consists of an integer
* indicating number of blocks, followed by that number of blocks and a block consists
* of an x-y coordinate pair. In otherwords:
*
* for each bin
* byte 1: Unsigned int numBlocks
* for each block:
* byte 1 : byte xRelativeCoordinate
* byte 2 : byte yRelativeCoordinate
*
* Actual x and y values are computed using the following algorithm
*
* xOffset = yOffset = 0
* imageWidth = 2048
* blockSize = 25
* maxXbins:Int = Math.Ceiling((double)ImageWidth/(double)blockSize)
* for each bin:
* for each location:
* x = convert.ToSingle(xRelativeCoordinate/10f + xoffset)
* y = convert.toSingle(yRelativeCoordinate/10f + yoffset)
* if (binIndex > 0 && ((binIndex + 1) % maxXbins == 0)) {
* xOffset = 0; yOffset += blockSize
* } else xOffset += blockSize
*/
public class ClocsFileReader extends AbstractIlluminaPositionFileReader {
private static final int HEADER_SIZE = 5;
private static final int IMAGE_WIDTH = 2048;
private static final int BLOCK_SIZE = 25;
private static final int NUM_BINS_IN_ROW = (int)Math.ceil((double) IMAGE_WIDTH / (double) BLOCK_SIZE);
/** Total number of bins */
private final long numBins;
/** An iterator through clocsFile's bytes */
private final BinaryFileIterator byteIterator;
//mutable vars
private float xOffset;
private float yOffset;
private long currentBin;
private int numClustersInBin; //MAX 255
private long currentClusterInBin;
public ClocsFileReader(final File clocsFile) {
super(clocsFile);
byteIterator = MMapBackedIteratorFactory.getByteIterator(HEADER_SIZE, clocsFile);
final ByteBuffer hbs = byteIterator.getHeaderBytes();
hbs.get(); //unusedByte
numBins = UnsignedTypeUtil.uIntToLong(hbs.getInt());
xOffset = 0;
yOffset = 0;
currentBin = 0;
startBlock();
checkAndAdvanceBin();
}
/**
* Grab the next set of offset values, decompress them.
* @return the position information of the next offset values
*/
@Override
protected PositionInfo unsafeNextInfo() {
final byte xByte = byteIterator.next();
final byte yByte = byteIterator.next();
final float xPos = UnsignedTypeUtil.uByteToInt(xByte)/10f + xOffset;
final float yPos = UnsignedTypeUtil.uByteToInt(yByte)/10f + yOffset;
++currentClusterInBin;
checkAndAdvanceBin();
return new PositionInfo(xPos, yPos, getLane(), getTile());
}
/** Compute offset for next bin and then increment the bin number and reset block information*/
private void checkAndAdvanceBin() {
while(currentClusterInBin >= numClustersInBin && currentBin < numBins) { //While rather than if statement to skip empty blocks
if ((currentBin + 1) % NUM_BINS_IN_ROW == 0) {
xOffset = 0;
yOffset += BLOCK_SIZE;
} else{
xOffset += BLOCK_SIZE;
}
currentBin += 1;
if(currentBin < numBins) {
startBlock();
}
}
}
/** Start the next block by reading it's numBlocks byte and setting the currentBlock index to 0 */
private void startBlock() {
numClustersInBin = UnsignedTypeUtil.uByteToInt(byteIterator.next());
currentClusterInBin = 0;
}
@Override
protected String makeExceptionMsg() {
return "ClocsFileReader(file=" + getFile().getName() + ", lane=" + getLane() + ", tile=" + getTile() +
", currentBin=" + currentBin + ", numBins=" + numBins + ", xOffset=" + xOffset + ", yOffset" + yOffset +
", currentBlock=" + currentClusterInBin + ", numBlocks=" + numClustersInBin;
}
@Override
public boolean hasNext() {
boolean valuesRemain = currentClusterInBin < numClustersInBin || currentBin < (numBins -1);
if(!valuesRemain && byteIterator.hasNext()) {
throw new PicardException("Read the number of expected bins( " + numBins + ") but still had more elements in file( " + byteIterator.getFile().getAbsolutePath() + ") ");
}
return valuesRemain;
}
public void close() {
}
}