package net.sf.cram;
import htsjdk.samtools.SAMFileHeader.SortOrder;
import htsjdk.samtools.SAMFileWriter;
import htsjdk.samtools.SAMFileWriterFactory;
import htsjdk.samtools.SAMRecordIterator;
import htsjdk.samtools.SamInputResource;
import htsjdk.samtools.SamReader;
import htsjdk.samtools.SamReaderFactory;
import htsjdk.samtools.ValidationStringency;
import htsjdk.samtools.util.Log;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import net.sf.cram.CramTools.LevelConverter;
import net.sf.cram.CramTools.ValidationStringencyConverter;
import net.sf.cram.ref.ReferenceSource;
import com.beust.jcommander.IStringConverter;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.beust.jcommander.converters.FileConverter;
public class Transcode {
private static Log log = Log.getInstance(Transcode.class);
public static void usage(JCommander jc) {
StringBuilder sb = new StringBuilder();
sb.append("\n");
jc.usage(sb);
System.out.println("Version " + Merge.class.getPackage().getImplementationVersion());
System.out.println(sb.toString());
}
public static void main(String[] args) throws IOException {
Params params = new Params();
JCommander jc = new JCommander(params);
jc.parse(args);
Log.setGlobalLogLevel(params.logLevel);
if (args.length == 0 || params.help) {
usage(jc);
System.exit(1);
}
if (params.reference == null) {
System.out.println("Reference file not found, will try downloading...");
}
ReferenceSource referenceSource = null;
if (params.reference != null) {
System.setProperty("reference", params.reference.getAbsolutePath());
referenceSource = new ReferenceSource(params.reference);
} else {
String prop = System.getProperty("reference");
if (prop != null) {
referenceSource = new ReferenceSource(new File(prop));
}
}
SamReaderFactory factory = SamReaderFactory.make().validationStringency(params.validationLevel);
SamInputResource r;
if ("file".equalsIgnoreCase(params.url.getProtocol()))
r = SamInputResource.of(params.url.getPath());
else
r = SamInputResource.of(params.url);
SamReader reader = factory.open(r);
SAMRecordIterator iterator = reader.iterator();
SAMFileWriterFactory writerFactory = new SAMFileWriterFactory();
SAMFileWriter writer = null;
OutputStream os = new BufferedOutputStream(new FileOutputStream(params.outputFile));
switch (params.outputFormat) {
case BAM:
writer = writerFactory.makeBAMWriter(reader.getFileHeader(),
reader.getFileHeader().getSortOrder() == SortOrder.coordinate, os);
break;
case CRAM:
writer = writerFactory.makeCRAMWriter(reader.getFileHeader(), os, params.reference);
break;
default:
System.out.println("Unknown output format: " + params.outputFormat);
System.exit(1);
}
while (iterator.hasNext()) {
writer.addAlignment(iterator.next());
}
writer.close();
reader.close();
}
public enum FORMAT {
UNKNOWN, BAM, CRAM;
}
public static class FormatConverter implements IStringConverter<FORMAT> {
@Override
public FORMAT convert(String f) {
if (FORMAT.BAM.name().equalsIgnoreCase(f))
return FORMAT.BAM;
if (FORMAT.CRAM.name().equalsIgnoreCase(f))
return FORMAT.CRAM;
return FORMAT.UNKNOWN;
}
}
public static class URLConverter implements IStringConverter<URL> {
@Override
public URL convert(String f) {
URL url;
try {
return new URL(f);
} catch (MalformedURLException e) {
File file = new File(f);
if (file.exists())
try {
return file.toURI().toURL();
} catch (MalformedURLException e1) {
throw new RuntimeException(e1);
}
throw new RuntimeException("Malformed URL: " + f);
}
}
}
@Parameters(commandDescription = "Tool to merge CRAM or BAM files. ")
static class Params {
@Parameter(names = { "-l", "--log-level" }, description = "Change log level: DEBUG, INFO, WARNING, ERROR.", converter = LevelConverter.class)
Log.LogLevel logLevel = Log.LogLevel.ERROR;
@Parameter(names = { "-v", "--validation-level" }, description = "Change validation stringency level: STRICT, LENIENT, SILENT.", converter = ValidationStringencyConverter.class)
ValidationStringency validationLevel = ValidationStringency.DEFAULT_STRINGENCY;
@Parameter(names = { "--reference-fasta-file", "-R" }, converter = FileConverter.class, description = "Path to the reference fasta file, it must be uncompressed and indexed (use 'samtools faidx' for example).")
File reference;
@Parameter(names = { "-h", "--help" }, description = "Print help and quit")
boolean help = false;
@Parameter(names = { "-i", "--input-format" }, converter = FormatConverter.class, description = "Input file format")
FORMAT inputFormat;
@Parameter(names = { "-o", "--output-format" }, converter = FormatConverter.class, description = "Output file format")
FORMAT outputFormat;
@Parameter(names = { "-I", "--input" }, converter = URLConverter.class, description = "Input URL")
URL url;
@Parameter(names = { "-O", "--output-file" }, converter = FileConverter.class, description = "Output file")
File outputFile;
}
}