package evoker;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/** Write BED-Files */
public class BEDFileWriter {
private BufferedOutputStream out; // the output stream
private byte buffer = 0;
private byte placesLeftInBuffer = 4;
/**
* Write to a specified file
* @param file to write to
* @throws FileNotFoundException
* @throws IOException
*/
public BEDFileWriter(File file) throws FileNotFoundException, IOException {
assert file != null;
out = new BufferedOutputStream(new FileOutputStream(file));
writeHeader();
}
/**
* Writes bytes to the file
* @param i
* @throws IOException
*/
public void write(byte[] i) throws IOException {
out.write(i);
}
/**
* Writes an array of genotypes (internal notation!) to the file
* @param genotypes
*/
public void writeGenotypes(int[] genotypes) throws IOException {
for (int geno : genotypes) {
writeGenotype(geno);
}
}
/**
* Writes the magic numbers to the file
* @throws IOException
*/
private void writeHeader() throws IOException {
out.write(Integer.parseInt("01101100", 2));
out.write(Integer.parseInt("00011011", 2));
out.write(Integer.parseInt("00000001", 2));
}
/**
* Writes single genotype to file
*
* 00 Homozygote "1"/"1" -> internal notation: 0
* 01 Heterozygote -> internal notation: 2
* 11 Homozygote "2"/"2" -> internal notation: 3
* 10 Missing genotype -> internal notation: 1
*/
public void writeGenotype(int type) throws IOException {
buffer = (byte) (buffer >>> 2);
switch (type) {
case 0:
break;
case 1:
buffer = (byte) (buffer | 0x40);
break;
case 2:
buffer = (byte) (buffer | 0x80);
break;
case 3:
buffer = (byte) (buffer | 0xc0);
break;
}
placesLeftInBuffer--;
if (placesLeftInBuffer == 0) {
clearBuffer();
placesLeftInBuffer = 4;
}
}
/**
* Pads the buffer with zeros and flushes it
*
* @throws IOException
*/
private void clearBuffer() throws IOException {
}
/**
* Pads the buffer with zeros and flushes it
* @throws IOException
*/
public void flush() throws IOException {
clearBuffer();
}
/**
* Closes the file (flushes it beforehand)
* @throws IOException
*/
public void close() throws IOException {
out.flush();
out.close();
}
}