Skip to content

Commit

Permalink
UpdateVcfSequenceDictionary handles stdout
Browse files Browse the repository at this point in the history
  • Loading branch information
ronlevine committed Feb 13, 2017
1 parent bce0086 commit f196cb1
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 8 deletions.
13 changes: 11 additions & 2 deletions src/main/java/picard/vcf/UpdateVcfSequenceDictionary.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,16 @@
import htsjdk.variant.variantcontext.writer.VariantContextWriterBuilder;
import htsjdk.variant.vcf.VCFFileReader;
import htsjdk.variant.vcf.VCFHeader;
import picard.PicardException;
import picard.cmdline.CommandLineProgram;
import picard.cmdline.CommandLineProgramProperties;
import picard.cmdline.Option;
import picard.cmdline.StandardOptionDefinitions;
import picard.cmdline.programgroups.VcfOrBcf;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

/**
* Takes a VCF file and a Sequence Dictionary (from a variety of file types) and updates the Sequence Dictionary in VCF.
Expand All @@ -56,7 +59,7 @@
programGroup = VcfOrBcf.class
)
public class UpdateVcfSequenceDictionary extends CommandLineProgram {
@Option(shortName = StandardOptionDefinitions.INPUT_SHORT_NAME, doc = "Input VCF")
@Option(shortName = StandardOptionDefinitions.INPUT_SHORT_NAME, doc = "Input VCF")
public File INPUT;

@Option(shortName = StandardOptionDefinitions.OUTPUT_SHORT_NAME, doc = "Output VCF to be written.")
Expand Down Expand Up @@ -89,7 +92,13 @@ protected int doWork() {
if (CREATE_INDEX)
builder.setOption(Options.INDEX_ON_THE_FLY);

final VariantContextWriter vcfWriter = builder.setOutputFile(OUTPUT).build();
try {
builder.setOutputStream(new FileOutputStream(OUTPUT));
} catch (final FileNotFoundException ex ) {
throw new PicardException("Could not open " + OUTPUT.getAbsolutePath() + ": " + ex.getMessage(), ex);
}

final VariantContextWriter vcfWriter = builder.build();
fileHeader.setSequenceDictionary(samSequenceDictionary);
vcfWriter.writeHeader(fileHeader);

Expand Down
47 changes: 41 additions & 6 deletions src/test/java/picard/vcf/UpdateVcfSequenceDictionaryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,37 +28,72 @@
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;
import org.testng.annotations.DataProvider;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;

/**
* @author George Grant
*/
public class UpdateVcfSequenceDictionaryTest {
private static final File TEST_DATA_PATH = new File("testdata/picard/vcf/");
private static final File OUTPUT_DATA_PATH = IOUtil.createTempDir("UpdateVcfSequenceDictionaryTest", null);
private static final File STD_OUT_FILE = new File(OUTPUT_DATA_PATH, "stdout.vcf");
private static final String STD_OUT_NAME = "/dev/stdout";

@AfterClass
public void teardown() {
IOUtil.deleteDirectoryTree(OUTPUT_DATA_PATH);
}

@Test
public void testUpdateVcfSequenceDictionary() {
final File input = new File(TEST_DATA_PATH, "vcfFormatTest.vcf");
@DataProvider(name = "OutputFiles")
public static Object[][] outputFies() {

return new Object[][] {
{OUTPUT_DATA_PATH + "updateVcfSequenceDictionaryTest-delete-me.vcf"},
{STD_OUT_NAME}
};
}

@Test(dataProvider = "OutputFiles")
public void testUpdateVcfSequenceDictionary(final String outputFileName) throws IOException, NoSuchFieldException, IllegalAccessException {
File input = new File(TEST_DATA_PATH, "vcfFormatTest.vcf");
// vcfFormatTest.bad_dict.vcf is a vcf with two (2) ##contig lines deleted
final File samSequenceDictionaryVcf = new File(TEST_DATA_PATH, "vcfFormatTest.bad_dict.vcf");
final File outputFile = new File(OUTPUT_DATA_PATH, "updateVcfSequenceDictionaryTest-delete-me.vcf");

File outputFile = new File(outputFileName);
outputFile.deleteOnExit();

final UpdateVcfSequenceDictionary updateVcfSequenceDictionary = new UpdateVcfSequenceDictionary();

if (outputFileName.equals(STD_OUT_NAME)) {

final FileOutputStream stream = new FileOutputStream(STD_OUT_FILE);

// Ugliness required to write to a stream given as a string on the commandline.
// Since the actual fd number is private inside FileDescriptor, needs reflection
// in order to pull it out.

final Field fdField = FileDescriptor.class.getDeclaredField("fd");
fdField.setAccessible(true);
updateVcfSequenceDictionary.OUTPUT = new File("/dev/fd/" + fdField.getInt(stream.getFD()));

} else {
final FileOutputStream stream = null;
updateVcfSequenceDictionary.OUTPUT = outputFile;
}
updateVcfSequenceDictionary.INPUT = input;
updateVcfSequenceDictionary.SEQUENCE_DICTIONARY = samSequenceDictionaryVcf;
updateVcfSequenceDictionary.OUTPUT = outputFile;

Assert.assertEquals(updateVcfSequenceDictionary.instanceMain(new String[0]), 0);

if (outputFileName.equals(STD_OUT_NAME)) {
outputFile = STD_OUT_FILE;
}

IOUtil.assertFilesEqual(samSequenceDictionaryVcf, outputFile);

// A little extra checking.
Expand Down

0 comments on commit f196cb1

Please sign in to comment.