package evoker; import java.io.*; import java.util.ArrayList; public class BedfileDataFile extends BinaryDataFile{ static String[] alleleMap = {"N","A","C","G","T"}; BedfileDataFile(String filename, int numInds, MarkerData md, String collection, String chromosome) throws IOException{ super(filename, numInds, md, collection, chromosome); bytesPerRecord = (int)Math.ceil(((double)numInds)/4); checkFile(bedMagic); } BedfileDataFile(String filename, RemoteBedfileData rbd) throws IOException{ super(filename, rbd.numInds, rbd.md, rbd.collection, rbd.chromosome); bytesPerRecord = (int)Math.ceil(((double)numInds)/4); numSNPs = 1; checkFile(bedMagic); } public ArrayList<Byte> getRecord(String name){ //we subclass this so we can force the type of data in the ArrayList return super.getRecord(name); } public ArrayList<Byte> getRecord(long snpIndex) throws IOException{ //have index, now load bed file BufferedInputStream bedIS = 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)+bedHeaderOffset; while ((remaining = remaining - bedIS.skip(remaining)) > 0){ } //read raw snp data byte[] rawSnpData = new byte[bytesPerRecord]; bedIS.read(rawSnpData, 0, bytesPerRecord); // close the input stream bedIS.close(); //convert into array of genotypes //genotype code is: //0 == homo 1 //1 == missing //2 == hetero //3 == homo 2 byte[] snpData = new byte[numInds+bedHeaderOffset]; int genoCount = 0; for (byte aRawSnpData : rawSnpData) { snpData[genoCount++] = (byte) ((aRawSnpData & (byte) 0x03) >>> 0); snpData[genoCount++] = (byte) ((aRawSnpData & (byte) 0x0c) >>> 2); snpData[genoCount++] = (byte) ((aRawSnpData & (byte) 0x30) >>> 4); snpData[genoCount++] = (byte) (((int)aRawSnpData & (int)0xc0) >>> 6); //note: may be up to 3 extra entries at end of snpData array -- don't use snpData.length! } ArrayList<Byte> genos = new ArrayList<Byte>(); for (int i = 0; i < numInds; i++){ genos.add(snpData[i]); } return genos; } }