/* Copyright 2013 University of North Carolina at Chapel Hill. All rights reserved. */
package abra;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* Handles alignment for contigs and short reads.
*
* @author Lisle E. Mose (lmose at unc dot edu)
*/
public class Aligner {
private String reference;
private int numThreads;
public Aligner(String reference, int numThreads) {
this.reference = reference;
this.numThreads = numThreads;
}
public void align(String input, String outputSam, boolean isGapExtensionFavored) throws IOException, InterruptedException {
String cmd = "bwa mem -t " + numThreads + " " + reference + " " + input + " > " + outputSam;
runCommand(cmd);
}
private void runCommand(String cmd) throws IOException, InterruptedException {
runCommand(cmd, null);
}
private void runCommand(String cmd, StdoutHandler stdoutHandler) throws IOException, InterruptedException {
System.err.println("Running: [" + cmd + "]");
long s = System.currentTimeMillis();
String[] cmds = {
"bash",
"-c",
cmd
};
Process proc = Runtime.getRuntime().exec(cmds);
Thread stdout = null;
if (stdoutHandler != null) {
stdoutHandler.process(proc);
} else {
stdout = new Thread(new CommandOutputConsumer(proc, proc.getInputStream()));
stdout.start();
}
Thread stderr = new Thread(new CommandOutputConsumer(proc, proc.getErrorStream()));
stderr.start();
int ret = proc.waitFor();
if (stdoutHandler != null) {
stdoutHandler.postProcess();
} else {
stdout.join();
}
stderr.join();
long e = System.currentTimeMillis();
System.err.println("BWA time: " + (e-s)/1000 + " seconds.");
if (ret != 0) {
throw new RuntimeException("BWA exited with non-zero return code : [" + ret + "] for command: [" + cmd + "]");
}
}
public void shortAlign(String input, String outputSam, StdoutHandler stdoutHandler, boolean isBamInput) throws IOException, InterruptedException {
// Throttle back the number of threads to accomodate the stdout processing.
int threads = Math.max(numThreads-2, 1);
String bamFlag = isBamInput ? " -b " : " ";
// String map = "bwa aln " + reference + " " + input + " -b -t " + threads + " -o 0 | bwa samse " + reference + " - " + input + " -n 1000";
String map = "bwa aln " + reference + " " + input + bamFlag + "-t " + threads + " -o 0 | bwa samse " + reference + " - " + input + " -n 1000";
// Redirect stdout to file if no stdout consumer provided.
if (stdoutHandler == null) {
map += " > " + outputSam;
}
runCommand(map, stdoutHandler);
}
public void index() throws IOException, InterruptedException {
if (shouldUseSmallIndex()) {
runCommand("bwa index " + reference);
} else {
runCommand("bwa index -a bwtsw " + reference);
}
}
private boolean shouldUseSmallIndex() throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(reference));
try {
int lines = 0;
String line = reader.readLine();
while (line != null) {
lines++;
line = reader.readLine();
if (lines >= 1000000) {
return false;
}
}
} finally {
reader.close();
}
return true;
}
static class CommandOutputConsumer implements Runnable {
private Process proc;
private InputStream stream;
CommandOutputConsumer(Process proc, InputStream stream) {
this.proc = proc;
this.stream = stream;
}
@Override
public void run() {
InputStreamReader isr = new InputStreamReader(stream);
BufferedReader br = new BufferedReader(isr);
String line = null;
try {
while ( (line = br.readLine()) != null) {
System.err.println(line);
}
br.close();
isr.close();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
System.err.println("Stream thread done.");
}
}
public static void main(String[] args) throws Exception {
Aligner a = new Aligner("/datastore/nextgenout2/share/labs/UNCseq/lmose2/mapzilla/bwamem/ref/hg19.fa", 8);
a.align(args[0], args[1], true);
}
}