Skip to content

Commit

Permalink
Modified VariantContextWriterBuilder to automatically set output type… (
Browse files Browse the repository at this point in the history
#495)

Modified VariantContextWriterBuilder to automatically set output type to VCF_STREAM when the output file exists but is not a symlink, regular file or directory.
  • Loading branch information
tfenne committed Jun 1, 2016
1 parent bf5782d commit b723300
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ public VariantContextWriterBuilder setReferenceDictionary(final SAMSequenceDicti
public VariantContextWriterBuilder setOutputFile(final File outFile) {
this.outFile = outFile;
this.outStream = null;
determineOutputTypeFromFilename();
this.outType = determineOutputTypeFromFile(outFile);
return this;
}

Expand All @@ -169,10 +169,7 @@ public VariantContextWriterBuilder setOutputFile(final File outFile) {
* @return this <code>VariantContextWriterBuilder</code>
*/
public VariantContextWriterBuilder setOutputFile(final String outFile) {
this.outFile = new File(outFile);
this.outStream = null;
determineOutputTypeFromFilename();
return this;
return setOutputFile(new File(outFile));
}

/**
Expand Down Expand Up @@ -465,28 +462,43 @@ else if (STREAM_TYPES.contains(this.outType))
return writer;
}

private void determineOutputTypeFromFilename() {
if (isBCF(this.outFile)) {
this.outType = OutputType.BCF;
} else if (isCompressedVCF(this.outFile)) {
this.outType = OutputType.BLOCK_COMPRESSED_VCF;
} else if (isVCF(this.outFile)) {
this.outType = OutputType.VCF;
/**
* Attempts to determine the type of file/data to write based on the File path being
* written to. Will attempt to determine using the logical filename; if that fails it will
* attempt to resolve any symlinks and try again. If that fails, and the output file exists
* but is neither a file or directory then VCF_STREAM is returned.
*/
protected static OutputType determineOutputTypeFromFile(final File f) {
if (isBCF(f)) {
return OutputType.BCF;
} else if (isCompressedVCF(f)) {
return OutputType.BLOCK_COMPRESSED_VCF;
} else if (isVCF(f)) {
return OutputType.VCF;
}
else {
this.outType = OutputType.UNSPECIFIED;
// See if we have a special file (device, named pipe, etc.)
final File canonical = new File(IOUtil.getFullCanonicalPath(f));
if (!canonical.equals(f)) {
return determineOutputTypeFromFile(canonical);
}
else if (f.exists() && !f.isFile() && !f.isDirectory()) {
return OutputType.VCF_STREAM;
} else {
return OutputType.UNSPECIFIED;
}
}
}

private boolean isVCF(final File outFile) {
private static boolean isVCF(final File outFile) {
return outFile != null && outFile.getName().endsWith(".vcf");
}

private boolean isBCF(final File outFile) {
private static boolean isBCF(final File outFile) {
return outFile != null && outFile.getName().endsWith(".bcf");
}

private boolean isCompressedVCF(final File outFile) {
private static boolean isCompressedVCF(final File outFile) {
if (outFile == null)
return false;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,19 @@
import htsjdk.samtools.Defaults;
import htsjdk.samtools.SAMSequenceDictionary;
import htsjdk.samtools.util.BlockCompressedOutputStream;
import htsjdk.samtools.util.RuntimeIOException;
import htsjdk.tribble.AbstractFeatureReader;
import htsjdk.tribble.Tribble;
import htsjdk.tribble.util.TabixUtils;
import htsjdk.variant.VariantBaseTest;
import htsjdk.variant.variantcontext.writer.Options;
import htsjdk.variant.variantcontext.writer.VariantContextWriterBuilder.OutputType;
import org.testng.Assert;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Test;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

Expand Down Expand Up @@ -122,6 +121,29 @@ public void testSetOutputFile() throws IOException {
Assert.assertTrue(writer instanceof BCF2Writer, "testSetOutputFile BCF File");
}

@Test
public void testDetermineOutputType() {
Assert.assertEquals(OutputType.VCF, VariantContextWriterBuilder.determineOutputTypeFromFile(this.vcf));
Assert.assertEquals(OutputType.BCF, VariantContextWriterBuilder.determineOutputTypeFromFile(this.bcf));
Assert.assertEquals(OutputType.VCF_STREAM, VariantContextWriterBuilder.determineOutputTypeFromFile(new File("/dev/stdout")));
for (final File f: this.blockCompressedVCFs) {
Assert.assertEquals(OutputType.BLOCK_COMPRESSED_VCF, VariantContextWriterBuilder.determineOutputTypeFromFile(f));
}

// Test symlinking
try {
final Path link = Files.createTempFile("foo.", ".tmp");
Files.deleteIfExists(link);
Files.createSymbolicLink(link, this.vcf.toPath());
link.toFile().deleteOnExit();
Assert.assertEquals(OutputType.VCF, VariantContextWriterBuilder.determineOutputTypeFromFile(link.toFile()));
link.toFile().delete();
}
catch (final IOException ioe) {
throw new RuntimeIOException(ioe);
}
}

@Test
public void testSetOutputFileType() {
final VariantContextWriterBuilder builder = new VariantContextWriterBuilder()
Expand Down Expand Up @@ -374,4 +396,4 @@ public void testModifyOption() {
Assert.assertFalse(builder.isOptionSet(option)); // has been unset
}
}
}
}

0 comments on commit b723300

Please sign in to comment.