package evoker; import java.util.ArrayList; import java.util.zip.GZIPInputStream; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.ByteOrder; public class BinaryFloatDataFile extends BinaryDataFile{ private int valuesPerEntry; BinaryFloatDataFile(String filename, int numInds, MarkerData md, String collection, int vals, String chromosome) throws IOException{ super(filename, numInds, md,collection, chromosome); this.valuesPerEntry = vals; bytesPerRecord = valuesPerEntry * 4 * numInds; checkFile(bntMagic); } BinaryFloatDataFile(String filename, int numInds, MarkerData md, String collection, int vals, boolean zipped, String chromosome) throws IOException{ super(filename, numInds, md,collection, chromosome); this.valuesPerEntry = vals; bytesPerRecord = valuesPerEntry * 4 * numInds; compressed = true; bntHeaderOffset = 8; // compressed file - do not use checkFile() // TODO: method for checking compressed files } BinaryFloatDataFile(String filename, RemoteBinaryFloatData rbfd) throws IOException{ super(filename,rbfd.numInds,rbfd.md,rbfd.collection, rbfd.chromosome); this.valuesPerEntry = rbfd.valuesPerEntry; bytesPerRecord = rbfd.bytesPerRecord; this.numSNPs = 1; checkFile(bntMagic); } public ArrayList<float[]> getRecord(String name){ //we subclass this so we can force the type of data in the ArrayList return super.getRecord(name); } ArrayList<float[]> getRecord(long snpIndex) throws IOException{ BufferedInputStream intIS; if (this.isCompressed()){ intIS = new BufferedInputStream(new GZIPInputStream(new FileInputStream(file),8192)); } else{ intIS = new BufferedInputStream(new FileInputStream(file),8192); } //skip to SNP of interest //sometimes the skip() method doesn't skip as far as you ask, so you have to keep flogging it //java sux. long remaining = (snpIndex * bytesPerRecord)+bntHeaderOffset; while ((remaining = remaining - intIS.skip(remaining)) > 0){ } //read raw snp data byte[] rawData = new byte[bytesPerRecord]; intIS.read(rawData, 0, bytesPerRecord); // close the input stream intIS.close(); ByteBuffer rawDataBuffer = ByteBuffer.wrap(rawData); rawDataBuffer.order(ByteOrder.LITTLE_ENDIAN); ArrayList<float[]> record = new ArrayList<float[]>(); for (int i = 0; i < numInds; i++){ float[] send = new float[valuesPerEntry]; for (int j = 0; j < valuesPerEntry; j++){ send[j] = rawDataBuffer.getFloat(); } record.add(send); } return record; } }