From 31f7331385bca019bcdef12003091e9a6be52f46 Mon Sep 17 00:00:00 2001
From: Louis Bergelson
Date: Tue, 27 Nov 2018 16:10:28 -0500
Subject: [PATCH 1/3] literal copy of gatk3 version
---
.../fasta/FastaAlternateReferenceMaker.java | 250 ++++++++++++++++++
.../walkers/fasta/FastaReferenceMaker.java | 137 ++++++++++
2 files changed, 387 insertions(+)
create mode 100644 src/main/java/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker.java
create mode 100644 src/main/java/org/broadinstitute/hellbender/tools/walkers/fasta/FastaReferenceMaker.java
diff --git a/src/main/java/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker.java b/src/main/java/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker.java
new file mode 100644
index 00000000000..88f9a64455e
--- /dev/null
+++ b/src/main/java/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker.java
@@ -0,0 +1,250 @@
+/*
+ * Copyright 2012-2016 Broad Institute, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package org.broadinstitute.hellbender.tools.walkers.fasta;
+
+import org.broadinstitute.gatk.utils.commandline.Argument;
+import org.broadinstitute.gatk.utils.commandline.ArgumentCollection;
+import org.broadinstitute.gatk.utils.commandline.Input;
+import org.broadinstitute.gatk.utils.commandline.RodBinding;
+import org.broadinstitute.gatk.engine.CommandLineGATK;
+import org.broadinstitute.gatk.engine.arguments.StandardVariantContextInputArgumentCollection;
+import org.broadinstitute.gatk.utils.contexts.AlignmentContext;
+import org.broadinstitute.gatk.utils.contexts.ReferenceContext;
+import org.broadinstitute.gatk.utils.refdata.RefMetaDataTracker;
+import org.broadinstitute.gatk.engine.walkers.*;
+import org.broadinstitute.gatk.utils.BaseUtils;
+import org.broadinstitute.gatk.utils.GenomeLoc;
+import org.broadinstitute.gatk.engine.SampleUtils;
+import org.broadinstitute.gatk.utils.collections.Pair;
+import org.broadinstitute.gatk.utils.exceptions.UserException;
+import org.broadinstitute.gatk.utils.help.DocumentedGATKFeature;
+import org.broadinstitute.gatk.utils.help.HelpConstants;
+import htsjdk.variant.variantcontext.Allele;
+import htsjdk.variant.variantcontext.Genotype;
+import htsjdk.variant.variantcontext.VariantContext;
+import org.broadinstitute.gatk.utils.variant.GATKVCFConstants;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import java.util.Optional;
+
+
+/**
+ * Generate an alternative reference sequence over the specified interval
+ *
+ * Given a variant callset, this tool replaces the reference bases at variation sites with the bases supplied in the
+ * corresponding callset records. Additionally, it allows for one or more "snpmask" VCFs to set overlapping bases to 'N'.
+ *
+ * The output format can be partially controlled using the provided command-line arguments.
+ * Specify intervals with the usual -L argument to output only the reference bases within your intervals.
+ * Overlapping intervals are automatically merged; reference bases for each disjoint interval will be output as a
+ * separate fasta sequence (named numerically in order).
+ *
+ * Caveats
+ *
+ * - If there are multiple variants that start at a site, it chooses one of them randomly.
+ * - When there are overlapping indels (but with different start positions) only the first will be chosen.
+ * - This tool works only for SNPs and for simple indels (but not for things like complex substitutions).
+ *
+
+ * Input
+ *
+ * The reference, requested intervals, and any number of variant ROD files.
+ *
+ *
+ * Output
+ *
+ * A FASTA file representing the requested intervals.
+ *
+ *
+ * Usage example
+ *
+ * java -jar GenomeAnalysisTK.jar \
+ * -T FastaAlternateReferenceMaker \
+ * -R reference.fasta \
+ * -o output.fasta \
+ * -L input.intervals \
+ * -V input.vcf \
+ * [--snpmask mask.vcf]
+ *
+ *
+ */
+@DocumentedGATKFeature( groupName = HelpConstants.DOCS_CAT_REFUTILS, extraDocs = {CommandLineGATK.class} )
+@Reference(window=@Window(start=-1,stop=50))
+@Requires(value={DataSource.REFERENCE})
+public class FastaAlternateReferenceMaker extends FastaReferenceMaker {
+
+ /**
+ * Variants from this input file are used by this tool to construct an alternate reference.
+ */
+ @ArgumentCollection
+ protected StandardVariantContextInputArgumentCollection variantCollection = new StandardVariantContextInputArgumentCollection();
+
+ /**
+ * SNPs from this file are used as a mask (inserting N's in the sequence) when constructing the alternate reference
+ */
+ @Input(fullName="snpmask", shortName = "snpmask", doc="SNP mask VCF file", required=false)
+ protected RodBinding snpmask;
+
+ /**
+ * Gives priority to a SNP mask over an input VCF for a site. Only has an effect if the --snpmask argument is used.
+ */
+ @Argument(fullName="snpmaskPriority", shortName = "snpmaskPriority", doc="SNP mask priority", required=false)
+ protected Boolean snpmaskPriority = false;
+
+ /**
+ * This option will generate an error if the specified sample does not exist in the VCF.
+ * Non-diploid (or non-called) genotypes are ignored.
+ */
+ @Argument(fullName="use_IUPAC_sample", shortName="IUPAC", doc = "If specified, heterozygous SNP sites will be output using IUPAC ambiguity codes given the genotypes for this sample", required=false)
+ private String iupacSample = null;
+
+ private int deletionBasesRemaining = 0;
+
+ private static final String EMPTY_BASE = " ";
+
+ @Override
+ public void initialize() {
+ super.initialize();
+ if ( iupacSample != null ) {
+ final List rodName = Arrays.asList(variantCollection.variants.getName());
+ final Set samples = SampleUtils.getUniqueSamplesFromRods(getToolkit(), rodName);
+ if ( !samples.contains(iupacSample) )
+ throw new UserException.BadInput("the IUPAC sample specified is not present in the provided VCF file");
+ }
+ }
+
+ @Override
+ public Pair map(final RefMetaDataTracker tracker, final ReferenceContext ref, final AlignmentContext context) {
+
+ if (deletionBasesRemaining > 0) {
+ deletionBasesRemaining--;
+ return new Pair<>(context.getLocation(), "");
+ }
+
+ final String refBase = String.valueOf((char)ref.getBase());
+
+ // If we have a mask at this site, use it
+ if ( snpmaskPriority ){
+ final Pair mask = maskSnp(tracker, context);
+ if ( mask != null )
+ return mask;
+ }
+
+ // Check to see if we have a called snp
+ for ( final VariantContext vc : tracker.getValues(variantCollection.variants, ref.getLocus()) ) {
+ if ( vc.isFiltered() )
+ continue;
+
+ if ( vc.isSimpleDeletion()) {
+ deletionBasesRemaining = vc.getReference().length() - 1;
+ // delete the next n bases, not this one
+ return new Pair<>(context.getLocation(), refBase);
+ } else if ( vc.isSimpleInsertion() || vc.isSNP() ) {
+ // Get the first alt allele that is not a spanning deletion. If none present, use the empty allele
+ final Optional optionalAllele = getFirstNonSpanDelAltAllele(vc.getAlternateAlleles());
+ final Allele allele = optionalAllele.isPresent() ? optionalAllele.get() : Allele.create(EMPTY_BASE, false);
+ if ( vc.isSimpleInsertion() ) {
+ return new Pair<>(context.getLocation(), allele.toString());
+ } else {
+ final String base = (iupacSample != null) ? getIUPACbase(vc.getGenotype(iupacSample), refBase) : allele.toString();
+ return new Pair<>(context.getLocation(), base);
+ }
+ }
+ }
+
+ if ( !snpmaskPriority ){
+ final Pair mask = maskSnp(tracker, context);
+ if ( mask != null )
+ return mask;
+ }
+
+ // if we got here then we're just ref
+ return new Pair<>(context.getLocation(), refBase);
+ }
+
+ /**
+ * Get the first non spanning deletion (* or <*:DEL>) alt allele
+ * @param altAlleles the alternate alleles
+ * @return the first non spanning deletion allele or null
+ */
+ private Optional getFirstNonSpanDelAltAllele( final List altAlleles ) {
+ for (final Allele allele : altAlleles) {
+ if (!allele.equals(Allele.SPAN_DEL) && !allele.equals(GATKVCFConstants.SPANNING_DELETION_SYMBOLIC_ALLELE_DEPRECATED)) {
+ return Optional.of(allele);
+ }
+ }
+
+ return Optional.empty();
+ }
+
+ /**
+ * Mask a SNP (inserting N's in the sequence)
+ *
+ * @param tracker the Reference Metadata available at a particular site in the genome
+ * @param context the locus context data
+ * @return mask at the locus or null if no SNP at that locus
+ */
+ private Pair maskSnp(final RefMetaDataTracker tracker, final AlignmentContext context){
+ for (final VariantContext vc : tracker.getValues(snpmask)) {
+ if (vc.isSNP()) {
+ return new Pair<>(context.getLocation(), "N");
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the IUPAC encoding for the given genotype or the reference base if not possible
+ *
+ * @param genotype the genotype to encode
+ * @param ref the reference base
+ * @return non-null, non-empty String of bases
+ */
+ private String getIUPACbase(final Genotype genotype, final String ref) {
+ if ( genotype == null )
+ throw new IllegalStateException("The genotype is null for sample " + iupacSample);
+
+ // If have a spanning deletion, if both alleles are spanning deletions, use the empty allele. Otherwise, use the allele is not a
+ // spanning deletion.
+ if ( genotype.getAlleles().contains(Allele.SPAN_DEL) ) {
+ if ( genotype.isHomVar() ) {
+ return EMPTY_BASE;
+ } else {
+ return genotype.getAllele(0).equals(Allele.SPAN_DEL) ? genotype.getAllele(1).getBaseString() : genotype.getAllele(0).getBaseString();
+ }
+ }
+
+ if ( !genotype.isHet() )
+ return genotype.isHom() ? genotype.getAllele(0).getBaseString() : ref;
+
+ final byte allele1 = genotype.getAllele(0).getBases()[0];
+ final byte allele2 = genotype.getAllele(1).getBases()[0];
+ return new String(new byte[] {BaseUtils.basesToIUPAC(allele1, allele2)});
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/broadinstitute/hellbender/tools/walkers/fasta/FastaReferenceMaker.java b/src/main/java/org/broadinstitute/hellbender/tools/walkers/fasta/FastaReferenceMaker.java
new file mode 100644
index 00000000000..e04b631b7db
--- /dev/null
+++ b/src/main/java/org/broadinstitute/hellbender/tools/walkers/fasta/FastaReferenceMaker.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2012-2016 Broad Institute, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package org.broadinstitute.hellbender.tools.walkers.fasta;
+
+import org.broadinstitute.gatk.utils.commandline.Argument;
+import org.broadinstitute.gatk.utils.commandline.Output;
+import org.broadinstitute.gatk.engine.CommandLineGATK;
+import org.broadinstitute.gatk.utils.contexts.AlignmentContext;
+import org.broadinstitute.gatk.utils.contexts.ReferenceContext;
+import org.broadinstitute.gatk.utils.refdata.RefMetaDataTracker;
+import org.broadinstitute.gatk.engine.walkers.RefWalker;
+import org.broadinstitute.gatk.utils.GenomeLoc;
+import org.broadinstitute.gatk.utils.collections.Pair;
+import org.broadinstitute.gatk.utils.help.DocumentedGATKFeature;
+import org.broadinstitute.gatk.utils.help.HelpConstants;
+
+import java.io.PrintStream;
+
+/**
+ * Create a subset of a FASTA reference sequence
+ *
+ * This tool creates a new reference in FASTA format consisting of only those positions or intervals
+ * provided in the input data set. The output format can be partially controlled using the provided command-line
+ * arguments. Specify intervals with the usual -L argument to output only the reference bases within your intervals.
+ * Overlapping intervals are automatically merged; reference bases for each disjoint interval will be output as a
+ * separate fasta sequence (named numerically in order).
+ *
+ * Input
+ *
+ * The reference and requested intervals.
+ *
+ *
+ * Output
+ *
+ * A fasta file representing the requested intervals. Each interval has a description line starting with a greater-than (">") symbol followed by sequence data.
+ * The description begins with the contig name followed by the beginning position on the contig.
+ *
+ * For example, the fasta file for contig 1 and intervals 1:3-1:4 and 1:6-1:9
+ * >1 1:3
+ * AT
+ * >1 1:6
+ * GGGG
+ *
+ *
+ *
+ * Usage example
+ *
+ * java -jar GenomeAnalysisTK.jar \
+ * -T FastaReferenceMaker \
+ * -R reference.fasta \
+ * -o output.fasta \
+ * -L input.intervals
+ *
+ *
+ */
+@DocumentedGATKFeature( groupName = HelpConstants.DOCS_CAT_REFUTILS, extraDocs = {CommandLineGATK.class} )
+public class FastaReferenceMaker extends RefWalker, GenomeLoc> {
+
+ @Output PrintStream out;
+
+ @Argument(fullName="lineWidth", shortName="lw", doc="Maximum length of sequence to write per line", required=false)
+ public int fastaLineWidth=60;
+
+ /**
+ * Please note that when using this argument adjacent intervals will automatically be merged.
+ */
+ @Argument(fullName="rawOnelineSeq", shortName="raw", doc="Print sequences with no FASTA header lines, one line per interval (i.e. lineWidth = infinity)", required=false)
+ public boolean fastaRawSeqs=false;
+
+ protected FastaSequence fasta;
+
+ public void initialize() {
+ if (fastaRawSeqs) fastaLineWidth = Integer.MAX_VALUE;
+ fasta = new FastaSequence(out, fastaLineWidth, fastaRawSeqs);
+ }
+
+ public Pair map(RefMetaDataTracker rodData, ReferenceContext ref, AlignmentContext context) {
+ return new Pair(context.getLocation(), String.valueOf((char)ref.getBase()));
+ }
+
+ public GenomeLoc reduceInit() {
+ return null;
+ }
+
+ public GenomeLoc reduce(Pair value, GenomeLoc sum) {
+ if ( value == null )
+ return sum;
+
+ // if there is no interval to the left, then this is the first one
+ if ( sum == null ) {
+ sum = value.first;
+ fasta.setName(fasta.getName() + " " + sum.toString());
+ fasta.append(value.second);
+ }
+ // if the intervals are not contiguous, print out the leftmost one and start a new one
+ // (end of contig or new interval)
+ else if ( value.first.getStart() != sum.getStop() + 1 || ! value.first.getContig().equals(sum.getContig()) ) {
+ fasta.flush();
+ sum = value.first;
+ fasta.setName(fasta.getName() + " " + sum.toString());
+ fasta.append(value.second);
+ }
+ // otherwise, merge them
+ else {
+ sum = sum.setStop(sum, value.first.getStop());
+ fasta.append(value.second);
+ }
+ return sum;
+ }
+
+ public void onTraversalDone(GenomeLoc sum) {
+ fasta.flush();
+ }
+}
\ No newline at end of file
From 4e607874bee666e92c8800569f9b18df1b9723f4 Mon Sep 17 00:00:00 2001
From: Louis Bergelson
Date: Wed, 28 Nov 2018 13:17:54 -0500
Subject: [PATCH 2/3] Port FastaAlternateReferenceMaker
* new walker type ReferenceWalker
* changes to close behavior in FastaWriter and adding additional buffering
* new walkers:
CountBasesInReference
FastaReferenceMaker
FastaAlternateReferenceMaker
---
.../hellbender/engine/ReferenceContext.java | 3 +-
.../hellbender/engine/ReferenceWalker.java | 99 +++++
.../examples/ExampleReferenceWalker.java | 78 ++++
.../walkers/fasta/CountBasesInReference.java | 37 ++
.../fasta/FastaAlternateReferenceMaker.java | 380 +++++++++---------
.../walkers/fasta/FastaReferenceMaker.java | 181 +++++----
.../hellbender/utils/BaseUtils.java | 34 ++
.../hellbender/utils/SimpleInterval.java | 2 -
.../hellbender/utils/help/HelpConstants.java | 2 -
.../iterators/IntervalLocusIterator.java | 7 +-
.../utils/reference/FastaReferenceWriter.java | 28 +-
...ExampleReferenceWalkerIntegrationTest.java | 36 ++
.../GenomicsDBImportIntegrationTest.java | 26 +-
.../CountBasesInReferenceIntegrationTest.java | 38 ++
...lternateReferenceMakerIntegrationTest.java | 155 +++++++
.../FastaReferenceMakerIntegrationTest.java | 69 ++++
.../ReblockGVCFIntegrationTest.java | 4 +-
.../hellbender/utils/BaseUtilsUnitTest.java | 18 +
.../FastaReferenceWriterUnitTest.java | 97 +----
.../ExampleReferenceWalker/example.dict | 2 +
.../ExampleReferenceWalker/example.fasta | 6 +
.../ExampleReferenceWalker/example.fasta.fai | 1 +
.../ExampleReferenceWalker/example.vcf | 26 ++
.../ExampleReferenceWalker/example.vcf.idx | Bin 0 -> 307 bytes
.../ExampleReferenceWalker/veryspecific.bam | Bin 0 -> 637 bytes
.../veryspecific.bam.bai | Bin 0 -> 96 bytes
.../ExampleReferenceWalker/veryspecific.sam | 5 +
.../NA12878.WGS.b37.chr20.firstMB.vcf.gz | Bin 0 -> 23749 bytes
.../NA12878.WGS.b37.chr20.firstMB.vcf.gz.tbi | Bin 0 -> 570 bytes
.../NA12878.chr1_10mb_11mb.slx.indels.vcf | 5 +
.../NA12878.chr1_10mb_11mb.slx.indels.vcf.idx | Bin 0 -> 2211 bytes
...nate_reference_contiguous_diff_contig.dict | 3 +
...ate_reference_contiguous_diff_contig.fasta | 6 +
...reference_contiguous_diff_contig.fasta.fai | 2 +
...nate_reference_contiguous_same_contig.dict | 2 +
...ate_reference_contiguous_same_contig.fasta | 5 +
...reference_contiguous_same_contig.fasta.fai | 1 +
.../expected_no_mask.dict | 2 +
.../expected_no_mask.fasta | 3 +
.../expected_no_mask.fasta.fai | 1 +
.../expected_snp1.dict | 2 +
.../expected_snp1.fasta | 3 +
.../expected_snp1.fasta.fai | 1 +
.../expected_snp1_mask2.dict | 2 +
.../expected_snp1_mask2.fasta | 3 +
.../expected_snp1_mask2.fasta.fai | 1 +
.../expected_snp1_mask2_priority.dict | 2 +
.../expected_snp1_mask2_priority.fasta | 3 +
.../expected_snp1_mask2_priority.fasta.fai | 1 +
.../expected_snp2.dict | 2 +
.../expected_snp2.fasta | 3 +
.../expected_snp2.fasta.fai | 1 +
.../expected_snp2_mask1.dict | 2 +
.../expected_snp2_mask1.fasta | 3 +
.../expected_snp2_mask1.fasta.fai | 1 +
.../expected_snp2_mask1_priority.dict | 2 +
.../expected_snp2_mask1_priority.fasta | 3 +
.../expected_snp2_mask1_priority.fasta.fai | 1 +
.../expected_snp_mask.dict | 2 +
.../expected_snp_mask.fasta | 3 +
.../expected_snp_mask.fasta.fai | 1 +
.../expected_snpsAndIndels.dict | 2 +
.../expected_snpsAndIndels.fasta | 3 +
.../expected_snpsAndIndels.fasta.fai | 1 +
.../expected_snpsAndIndels_mask1.dict | 2 +
.../expected_snpsAndIndels_mask1.fasta | 3 +
.../expected_snpsAndIndels_mask1.fasta.fai | 1 +
...expected_snpsAndIndels_mask1_priority.dict | 2 +
...xpected_snpsAndIndels_mask1_priority.fasta | 3 +
...ted_snpsAndIndels_mask1_priority.fasta.fai | 1 +
.../expected_snpsAndIndels_mask2.fasta | 3 +
.../expected_snpsAndIndels_maskOverlaps.dict | 2 +
.../expected_snpsAndIndels_maskOverlaps.fasta | 3 +
...ected_snpsAndIndels_maskOverlaps.fasta.fai | 1 +
...d_snpsAndIndels_maskOverlaps_priority.dict | 2 +
..._snpsAndIndels_maskOverlaps_priority.fasta | 3 +
...sAndIndels_maskOverlaps_priority.fasta.fai | 1 +
.../expected_test_iupac.dict | 2 +
.../expected_test_iupac.fasta | 90 +++++
.../expected_test_iupac.fasta.fai | 1 +
.../iupac_sample_NA1.dict | 2 +
.../iupac_sample_NA1.fasta | 2 +
.../iupac_sample_NA1.fasta.fai | 1 +
.../iupac_sample_NA2.dict | 1 +
.../iupac_sample_NA2.fasta | 2 +
.../iupac_sample_NA2.fasta.fai | 1 +
.../iupac_sample_NA3.dict | 2 +
.../iupac_sample_NA3.fasta | 2 +
.../iupac_sample_NA3.fasta.fai | 1 +
.../overlapsIndelsMask.vcf | 164 ++++++++
.../overlapsIndelsMask.vcf.idx | Bin 0 -> 2104 bytes
.../FastaAlternateReferenceMaker/snps.vcf | 163 ++++++++
.../FastaAlternateReferenceMaker/snps.vcf.idx | Bin 0 -> 2159 bytes
.../FastaAlternateReferenceMaker/snps2.vcf | 163 ++++++++
.../snps2.vcf.idx | Bin 0 -> 2164 bytes
.../snpsAndIndels.vcf | 167 ++++++++
.../snpsAndIndels.vcf.idx | Bin 0 -> 2212 bytes
.../spanningDel.delOnly.starFirst.vcf | 116 ++++++
.../spanningDel.delOnly.starFirst.vcf.idx | Bin 0 -> 348 bytes
.../FastaReferenceMaker/reference_only.dict | 4 +
.../FastaReferenceMaker/reference_only.fasta | 28 ++
.../reference_only.fasta.fai | 3 +
...eference_only_contiguous_diff_contigs.dict | 3 +
...ference_only_contiguous_diff_contigs.fasta | 6 +
...nce_only_contiguous_diff_contigs.fasta.fai | 2 +
...reference_only_contiguous_same_contig.dict | 2 +
...eference_only_contiguous_same_contig.fasta | 5 +
...ence_only_contiguous_same_contig.fasta.fai | 1 +
.../testutils/ArgumentsBuilder.java | 9 +
.../hellbender/testutils/FastaTestUtils.java | 101 +++++
.../testutils/GenomicsDBTestUtils.java | 3 +-
111 files changed, 2090 insertions(+), 396 deletions(-)
create mode 100644 src/main/java/org/broadinstitute/hellbender/engine/ReferenceWalker.java
create mode 100644 src/main/java/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker.java
create mode 100644 src/main/java/org/broadinstitute/hellbender/tools/walkers/fasta/CountBasesInReference.java
create mode 100644 src/test/java/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalkerIntegrationTest.java
create mode 100644 src/test/java/org/broadinstitute/hellbender/tools/walkers/fasta/CountBasesInReferenceIntegrationTest.java
create mode 100644 src/test/java/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMakerIntegrationTest.java
create mode 100644 src/test/java/org/broadinstitute/hellbender/tools/walkers/fasta/FastaReferenceMakerIntegrationTest.java
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/example.dict
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/example.fasta
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/example.fasta.fai
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/example.vcf
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/example.vcf.idx
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/veryspecific.bam
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/veryspecific.bam.bai
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/veryspecific.sam
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/NA12878.WGS.b37.chr20.firstMB.vcf.gz
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/NA12878.WGS.b37.chr20.firstMB.vcf.gz.tbi
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/NA12878.chr1_10mb_11mb.slx.indels.vcf
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/NA12878.chr1_10mb_11mb.slx.indels.vcf.idx
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_diff_contig.dict
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_diff_contig.fasta
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_diff_contig.fasta.fai
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_same_contig.dict
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_same_contig.fasta
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_same_contig.fasta.fai
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_no_mask.dict
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_no_mask.fasta
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_no_mask.fasta.fai
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1.dict
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1.fasta
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1.fasta.fai
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1_mask2.dict
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1_mask2.fasta
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1_mask2.fasta.fai
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1_mask2_priority.dict
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1_mask2_priority.fasta
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1_mask2_priority.fasta.fai
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2.dict
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2.fasta
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2.fasta.fai
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2_mask1.dict
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2_mask1.fasta
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2_mask1.fasta.fai
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2_mask1_priority.dict
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2_mask1_priority.fasta
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2_mask1_priority.fasta.fai
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp_mask.dict
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp_mask.fasta
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp_mask.fasta.fai
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels.dict
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels.fasta
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels.fasta.fai
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask1.dict
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask1.fasta
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask1.fasta.fai
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask1_priority.dict
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask1_priority.fasta
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask1_priority.fasta.fai
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask2.fasta
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_maskOverlaps.dict
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_maskOverlaps.fasta
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_maskOverlaps.fasta.fai
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_maskOverlaps_priority.dict
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_maskOverlaps_priority.fasta
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_maskOverlaps_priority.fasta.fai
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_test_iupac.dict
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_test_iupac.fasta
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_test_iupac.fasta.fai
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA1.dict
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA1.fasta
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA1.fasta.fai
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA2.dict
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA2.fasta
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA2.fasta.fai
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA3.dict
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA3.fasta
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA3.fasta.fai
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/overlapsIndelsMask.vcf
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/overlapsIndelsMask.vcf.idx
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/snps.vcf
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/snps.vcf.idx
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/snps2.vcf
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/snps2.vcf.idx
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/snpsAndIndels.vcf
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/snpsAndIndels.vcf.idx
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/spanningDel.delOnly.starFirst.vcf
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/spanningDel.delOnly.starFirst.vcf.idx
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaReferenceMaker/reference_only.dict
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaReferenceMaker/reference_only.fasta
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaReferenceMaker/reference_only.fasta.fai
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaReferenceMaker/reference_only_contiguous_diff_contigs.dict
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaReferenceMaker/reference_only_contiguous_diff_contigs.fasta
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaReferenceMaker/reference_only_contiguous_diff_contigs.fasta.fai
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaReferenceMaker/reference_only_contiguous_same_contig.dict
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaReferenceMaker/reference_only_contiguous_same_contig.fasta
create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaReferenceMaker/reference_only_contiguous_same_contig.fasta.fai
create mode 100644 src/testUtils/java/org/broadinstitute/hellbender/testutils/FastaTestUtils.java
diff --git a/src/main/java/org/broadinstitute/hellbender/engine/ReferenceContext.java b/src/main/java/org/broadinstitute/hellbender/engine/ReferenceContext.java
index d0ee38eb375..4ad4fff65ac 100644
--- a/src/main/java/org/broadinstitute/hellbender/engine/ReferenceContext.java
+++ b/src/main/java/org/broadinstitute/hellbender/engine/ReferenceContext.java
@@ -2,13 +2,12 @@
import htsjdk.samtools.SAMSequenceRecord;
import htsjdk.samtools.reference.ReferenceSequence;
+import org.broadinstitute.hellbender.exceptions.GATKException;
import org.broadinstitute.hellbender.exceptions.UserException;
import org.broadinstitute.hellbender.utils.SimpleInterval;
-import org.broadinstitute.hellbender.exceptions.GATKException;
import org.broadinstitute.hellbender.utils.Utils;
import org.broadinstitute.hellbender.utils.iterators.ByteArrayIterator;
-import java.util.Arrays;
import java.util.Iterator;
/**
diff --git a/src/main/java/org/broadinstitute/hellbender/engine/ReferenceWalker.java b/src/main/java/org/broadinstitute/hellbender/engine/ReferenceWalker.java
new file mode 100644
index 00000000000..cbf3562e8b0
--- /dev/null
+++ b/src/main/java/org/broadinstitute/hellbender/engine/ReferenceWalker.java
@@ -0,0 +1,99 @@
+package org.broadinstitute.hellbender.engine;
+
+import org.broadinstitute.hellbender.engine.filters.CountingReadFilter;
+import org.broadinstitute.hellbender.utils.SimpleInterval;
+import org.broadinstitute.hellbender.utils.iterators.IntervalLocusIterator;
+
+/**
+ * A reference walker is a tool which process each position in a given reference.
+ *
+ * ReferenceWalker authors must implement the apply() method to process each position, and may optionally implement
+ * {@link #onTraversalStart()} and/or {@link #onTraversalSuccess()}. See the {@link ExampleReferenceWalker} walker for an example.
+ */
+public abstract class ReferenceWalker extends GATKTool {
+
+ @Override
+ public String getProgressMeterRecordLabel() { return "bases"; }
+
+ @Override
+ public final boolean requiresReference() { return true; }
+
+ /**
+ * Initialize data sources for traversal.
+ *
+ * Marked final so that tool authors don't override it. Tool authors should override onTraversalStart() instead.
+ */
+ @Override
+ protected final void onStartup() {
+ super.onStartup();
+ }
+
+ /**
+ * Implementation of reference-locus-based traversal.
+ * Subclasses can override to provide own behavior but default implementation should be suitable for most uses.
+ */
+ @Override
+ public void traverse() {
+ final CountingReadFilter readFilter = makeReadFilter();
+
+ for(SimpleInterval locus : getIntervalIterator()){
+ SimpleInterval referenceWindow = getReferenceWindow(locus);
+ final ReferenceContext referenceContext = new ReferenceContext(reference, locus, referenceWindow);
+ apply(referenceContext,
+ new ReadsContext(reads, referenceContext.getWindow(), readFilter), // Will create an empty ReadsContext if reads == null
+ new FeatureContext(features, referenceContext.getWindow())); // Will create an empty FeatureContext if features == null
+
+ progressMeter.update(referenceContext.getInterval());
+ };
+
+ }
+
+ /**
+ * Determine the window to use when creating the ReferenceContext in apply. This determines which reference bases are
+ * see at each position, as well as which reads / features are considered to overlap the reference site.
+ *
+ * The default implementation returns the single reference locus passed that is passed in, but subclasses may override
+ * this method in order to change the window size.
+ *
+ * @param locus the current locus being processed in the traversal
+ * @return the window to use when creating the ReferenceContext that is passed into {@link #apply(ReferenceContext, ReadsContext, FeatureContext)}
+ */
+ protected SimpleInterval getReferenceWindow(SimpleInterval locus){
+ return locus;
+ }
+
+ private Iterable getIntervalIterator(){
+ return () -> new IntervalLocusIterator(getTraversalIntervals().iterator());
+ }
+
+ /**
+ * Process an individual reference locus (with optional contextual information). Must be implemented by tool authors.
+ * In general, tool authors should simply stream their output from apply(), and maintain as little internal state
+ * as possible.
+ *
+ * @param referenceContext Reference bases at the current locus. The window around the single locus is provided by {@link #getReferenceWindow(SimpleInterval)}
+ * Additional bases my be retrieved by invoking the by invoking {@link ReferenceContext#setWindow}
+ * on this object before calling {@link ReferenceContext#getBases}, however this will not effect
+ * the set of reads and features that are considered overlapping which are based on the preset
+ * window passed in.
+ * @param readsContext Reads spanning the current reference window. Will be an empty, but non-null, context object
+ * if there is no backing source of Read data (in which case all queries on it will return an
+ * empty List).
+ * @param featureContext Features spanning the current reference window. Will be an empty, but non-null, context object
+ * if there is no backing source of Feature data (in which case all queries on it will return an
+ * empty List).
+ *
+ */
+ public abstract void apply(ReferenceContext referenceContext, ReadsContext readsContext, FeatureContext featureContext );
+
+ /**
+ * Shutdown data sources.
+ *
+ * Marked final so that tool authors don't override it. Tool authors should override {@link #onTraversalSuccess()} instead.
+ */
+ @Override
+ protected final void onShutdown() {
+ // Overridden only to make final so that concrete tool implementations don't override
+ super.onShutdown();
+ }
+}
diff --git a/src/main/java/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker.java b/src/main/java/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker.java
new file mode 100644
index 00000000000..a933455a0f2
--- /dev/null
+++ b/src/main/java/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker.java
@@ -0,0 +1,78 @@
+package org.broadinstitute.hellbender.tools.examples;
+
+import com.netflix.servo.util.VisibleForTesting;
+import htsjdk.variant.variantcontext.VariantContext;
+import org.broadinstitute.barclay.argparser.Argument;
+import org.broadinstitute.barclay.argparser.CommandLineProgramProperties;
+import org.broadinstitute.hellbender.cmdline.StandardArgumentDefinitions;
+import org.broadinstitute.hellbender.cmdline.programgroups.ExampleProgramGroup;
+import org.broadinstitute.hellbender.engine.*;
+import org.broadinstitute.hellbender.utils.SimpleInterval;
+
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * Counts the number of times each reference context is seen as well as how many times it's overlapped by reads and variants.
+ * Why you would want to do this is a mystery.
+ */
+@CommandLineProgramProperties(
+ summary = "Example of how to implement a ReferenceWalker that uses reads and features as well as a custom window",
+ oneLineSummary = "Example of how to implement a ReferenceWalker",
+ programGroup = ExampleProgramGroup.class,
+ omitFromCommandLine = true)
+public class ExampleReferenceWalker extends ReferenceWalker {
+
+ @Argument(fullName = StandardArgumentDefinitions.VARIANT_LONG_NAME,
+ shortName = StandardArgumentDefinitions.VARIANT_SHORT_NAME,
+ doc="variants to count overlaps of")
+ FeatureInput variants;
+
+ @VisibleForTesting
+ final Map contextCounts = new HashMap<>();
+
+ @Override
+ protected SimpleInterval getReferenceWindow(SimpleInterval locus) {
+ return new SimpleInterval(locus.getContig(), Math.max(locus.getStart() -1, 1), locus.getStart()+1);
+ }
+
+ @Override
+ public void apply(ReferenceContext referenceContext, ReadsContext readsContext, FeatureContext featureContext) {
+ final byte[] bases = referenceContext.getBases();
+ final String baseString = new String(bases);
+ final OverlapCounts counts = contextCounts.getOrDefault(baseString, new OverlapCounts());
+ if(readsContext.iterator().hasNext()){
+ counts.overlappedByReads++;
+ }
+
+ if(!featureContext.getValues(variants).isEmpty()){
+ counts.overlappedByVariants++;
+ }
+
+ counts.timesSeen++;
+
+ contextCounts.put(baseString, counts);
+ }
+
+ @Override
+ public Object onTraversalSuccess(){
+ contextCounts.entrySet().stream()
+ .sorted(Comparator.comparing(Entry::getKey))
+ .forEachOrdered(entry -> System.out.println(entry.getKey() + " " + entry.getValue().toString()));
+ return 0;
+ }
+
+ @VisibleForTesting
+ static class OverlapCounts {
+ long timesSeen = 0;
+ long overlappedByReads = 0;
+ long overlappedByVariants = 0;
+
+ @Override
+ public String toString(){
+ return String.format("Seen: %d Reads %d Variants %d", timesSeen, overlappedByReads, overlappedByVariants);
+ }
+ }
+}
diff --git a/src/main/java/org/broadinstitute/hellbender/tools/walkers/fasta/CountBasesInReference.java b/src/main/java/org/broadinstitute/hellbender/tools/walkers/fasta/CountBasesInReference.java
new file mode 100644
index 00000000000..ac1545878c6
--- /dev/null
+++ b/src/main/java/org/broadinstitute/hellbender/tools/walkers/fasta/CountBasesInReference.java
@@ -0,0 +1,37 @@
+package org.broadinstitute.hellbender.tools.walkers.fasta;
+
+import com.google.common.annotations.VisibleForTesting;
+import org.broadinstitute.barclay.argparser.CommandLineProgramProperties;
+import org.broadinstitute.barclay.help.DocumentedFeature;
+import org.broadinstitute.hellbender.engine.FeatureContext;
+import org.broadinstitute.hellbender.engine.ReadsContext;
+import org.broadinstitute.hellbender.engine.ReferenceContext;
+import org.broadinstitute.hellbender.engine.ReferenceWalker;
+import picard.cmdline.programgroups.ReferenceProgramGroup;
+
+@DocumentedFeature
+@CommandLineProgramProperties(
+ summary = "Count the numbers of each base in a reference file",
+ oneLineSummary = "Count the number of each individual base which occurs in a reference file.",
+ programGroup = ReferenceProgramGroup.class
+)
+public class CountBasesInReference extends ReferenceWalker {
+ @VisibleForTesting
+ final long[] baseCounts = new long[256];
+
+ @Override
+ public void apply(ReferenceContext referenceContext, ReadsContext read, FeatureContext featureContext) {
+ baseCounts[referenceContext.getBase()]++;
+ }
+
+ @Override
+ public Object onTraversalSuccess(){
+ for (int i = 0; i < 256; i++) {
+ final long count = baseCounts[i];
+ if (count > 0){
+ System.out.println((char)i + " : " + count );
+ }
+ }
+ return 0;
+ }
+}
diff --git a/src/main/java/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker.java b/src/main/java/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker.java
index 88f9a64455e..d56708ca6a5 100644
--- a/src/main/java/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker.java
+++ b/src/main/java/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker.java
@@ -1,55 +1,27 @@
-/*
- * Copyright 2012-2016 Broad Institute, Inc.
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
- * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
package org.broadinstitute.hellbender.tools.walkers.fasta;
-import org.broadinstitute.gatk.utils.commandline.Argument;
-import org.broadinstitute.gatk.utils.commandline.ArgumentCollection;
-import org.broadinstitute.gatk.utils.commandline.Input;
-import org.broadinstitute.gatk.utils.commandline.RodBinding;
-import org.broadinstitute.gatk.engine.CommandLineGATK;
-import org.broadinstitute.gatk.engine.arguments.StandardVariantContextInputArgumentCollection;
-import org.broadinstitute.gatk.utils.contexts.AlignmentContext;
-import org.broadinstitute.gatk.utils.contexts.ReferenceContext;
-import org.broadinstitute.gatk.utils.refdata.RefMetaDataTracker;
-import org.broadinstitute.gatk.engine.walkers.*;
-import org.broadinstitute.gatk.utils.BaseUtils;
-import org.broadinstitute.gatk.utils.GenomeLoc;
-import org.broadinstitute.gatk.engine.SampleUtils;
-import org.broadinstitute.gatk.utils.collections.Pair;
-import org.broadinstitute.gatk.utils.exceptions.UserException;
-import org.broadinstitute.gatk.utils.help.DocumentedGATKFeature;
-import org.broadinstitute.gatk.utils.help.HelpConstants;
import htsjdk.variant.variantcontext.Allele;
import htsjdk.variant.variantcontext.Genotype;
import htsjdk.variant.variantcontext.VariantContext;
-import org.broadinstitute.gatk.utils.variant.GATKVCFConstants;
+import htsjdk.variant.vcf.VCFHeader;
+import org.broadinstitute.barclay.argparser.Argument;
+import org.broadinstitute.barclay.argparser.CommandLineException;
+import org.broadinstitute.barclay.argparser.CommandLineProgramProperties;
+import org.broadinstitute.barclay.help.DocumentedFeature;
+import org.broadinstitute.hellbender.cmdline.StandardArgumentDefinitions;
+import org.broadinstitute.hellbender.engine.FeatureContext;
+import org.broadinstitute.hellbender.engine.FeatureInput;
+import org.broadinstitute.hellbender.engine.ReadsContext;
+import org.broadinstitute.hellbender.engine.ReferenceContext;
+import org.broadinstitute.hellbender.exceptions.UserException;
+import org.broadinstitute.hellbender.utils.BaseUtils;
+import org.broadinstitute.hellbender.utils.SimpleInterval;
+import org.broadinstitute.hellbender.utils.Utils;
+import org.broadinstitute.hellbender.utils.variant.GATKVCFConstants;
+import picard.cmdline.programgroups.ReferenceProgramGroup;
-import java.util.Arrays;
+import java.util.ArrayList;
import java.util.List;
-import java.util.Set;
import java.util.Optional;
@@ -57,7 +29,7 @@
* Generate an alternative reference sequence over the specified interval
*
* Given a variant callset, this tool replaces the reference bases at variation sites with the bases supplied in the
- * corresponding callset records. Additionally, it allows for one or more "snpmask" VCFs to set overlapping bases to 'N'.
+ * corresponding callset records. Additionally, it allows for one or more "snp-mask" VCFs to set overlapping bases to 'N'.
*
* The output format can be partially controlled using the provided command-line arguments.
* Specify intervals with the usual -L argument to output only the reference bases within your intervals.
@@ -73,7 +45,7 @@
*
Input
*
- * The reference, requested intervals, and any number of variant ROD files.
+ * The reference, requested intervals, and any number of variant files.
*
*
* Output
@@ -83,168 +55,208 @@
*
* Usage example
*
- * java -jar GenomeAnalysisTK.jar \
- * -T FastaAlternateReferenceMaker \
+ * gatk FastaAlternateReferenceMaker \
* -R reference.fasta \
- * -o output.fasta \
+ * -O output.fasta \
* -L input.intervals \
* -V input.vcf \
- * [--snpmask mask.vcf]
+ *
+ * [--snp-mask mask.vcf]
*
*
*/
-@DocumentedGATKFeature( groupName = HelpConstants.DOCS_CAT_REFUTILS, extraDocs = {CommandLineGATK.class} )
-@Reference(window=@Window(start=-1,stop=50))
-@Requires(value={DataSource.REFERENCE})
+@DocumentedFeature
+@CommandLineProgramProperties(summary = "Create an alternative fasta reference by inserting variants from a vcf into an existing reference sequence.",
+ oneLineSummary = "Create an alternative reference by combining a fasta with a vcf.",
+ programGroup = ReferenceProgramGroup.class)
public class FastaAlternateReferenceMaker extends FastaReferenceMaker {
- /**
- * Variants from this input file are used by this tool to construct an alternate reference.
- */
- @ArgumentCollection
- protected StandardVariantContextInputArgumentCollection variantCollection = new StandardVariantContextInputArgumentCollection();
-
- /**
- * SNPs from this file are used as a mask (inserting N's in the sequence) when constructing the alternate reference
- */
- @Input(fullName="snpmask", shortName = "snpmask", doc="SNP mask VCF file", required=false)
- protected RodBinding snpmask;
-
- /**
- * Gives priority to a SNP mask over an input VCF for a site. Only has an effect if the --snpmask argument is used.
- */
- @Argument(fullName="snpmaskPriority", shortName = "snpmaskPriority", doc="SNP mask priority", required=false)
- protected Boolean snpmaskPriority = false;
-
- /**
- * This option will generate an error if the specified sample does not exist in the VCF.
- * Non-diploid (or non-called) genotypes are ignored.
- */
- @Argument(fullName="use_IUPAC_sample", shortName="IUPAC", doc = "If specified, heterozygous SNP sites will be output using IUPAC ambiguity codes given the genotypes for this sample", required=false)
- private String iupacSample = null;
-
- private int deletionBasesRemaining = 0;
-
- private static final String EMPTY_BASE = " ";
-
- @Override
- public void initialize() {
- super.initialize();
- if ( iupacSample != null ) {
- final List rodName = Arrays.asList(variantCollection.variants.getName());
- final Set samples = SampleUtils.getUniqueSamplesFromRods(getToolkit(), rodName);
- if ( !samples.contains(iupacSample) )
- throw new UserException.BadInput("the IUPAC sample specified is not present in the provided VCF file");
- }
- }
+ //Pre-allocated as a lame optimization
+ private static final byte[] NO_BASES = new byte[0];
+ private static final byte[] N_BYTES = {'N'};
+ private static final byte[] n_BYTES = {'n'};
+ private static final byte[] A_BYTES = new byte[]{'A'};
+ private static final byte[] a_BYTES = new byte[]{'a'};
+ private static final byte[] G_BYTES = new byte[]{'G'};
+ private static final byte[] g_BYTES = new byte[]{'g'};
+ private static final byte[] C_BYTES = new byte[]{'C'};
+ private static final byte[] c_BYTES = new byte[]{'c'};
+ private static final byte[] T_BYTES = new byte[]{'T'};
+ private static final byte[] t_BYTES = new byte[]{'t'};
- @Override
- public Pair map(final RefMetaDataTracker tracker, final ReferenceContext ref, final AlignmentContext context) {
+ /**
+ * Variants from this input file are used by this tool to construct an alternate reference.
+ */
+ @Argument(fullName= StandardArgumentDefinitions.VARIANT_LONG_NAME,
+ shortName = StandardArgumentDefinitions.VARIANT_SHORT_NAME,
+ doc="VCF to merge with the reference sequence.")
+ protected FeatureInput variants;
- if (deletionBasesRemaining > 0) {
- deletionBasesRemaining--;
- return new Pair<>(context.getLocation(), "");
- }
+ public static final String SNP_MASK_LONG_NAME = "snp-mask";
- final String refBase = String.valueOf((char)ref.getBase());
+ /**
+ * SNPs from this file are used as a mask (inserting N's in the sequence) when constructing the alternate reference
+ */
+ @Argument(fullName= SNP_MASK_LONG_NAME, doc="SNP mask VCF file", optional=true)
+ protected FeatureInput snpmask;
- // If we have a mask at this site, use it
- if ( snpmaskPriority ){
- final Pair mask = maskSnp(tracker, context);
- if ( mask != null )
- return mask;
+ public static final String SNP_MASK_PRIORITY_LONG_NAME = "snp-mask-priority";
+ /**
+ * Gives priority to a SNP mask over an input VCF for a site. Only has an effect if the --snp-mask argument is used.
+ */
+ @Argument(fullName= SNP_MASK_PRIORITY_LONG_NAME, doc="Give the snp mask priority over the input VCF.", optional=true)
+ protected boolean snpmaskPriority = false;
+
+ public static final String USE_IUPAC_SAMPLE_LONG_NAME = "use-iupac-sample";
+ /**
+ * This option will generate an error if the specified sample does not exist in the VCF.
+ * Non-diploid (or non-called) genotypes are ignored.
+ */
+ @Argument(fullName= USE_IUPAC_SAMPLE_LONG_NAME, doc = "If specified, heterozygous SNP sites will be output using IUPAC ambiguity codes given the genotypes for this sample", optional=true)
+ private String iupacSample = null;
+
+ private int deletionBasesRemaining = 0;
+
+ private static final String EMPTY_BASE = " ";
+
+ @Override
+ public void onTraversalStart() {
+ super.onTraversalStart();
+
+ if (snpmaskPriority && snpmask == null){
+ throw new CommandLineException("Cannot specify --" + SNP_MASK_PRIORITY_LONG_NAME + " without " + " --" + SNP_MASK_LONG_NAME);
+ }
+
+ if ( iupacSample != null ) {
+ final VCFHeader variantHeader = (VCFHeader) getHeaderForFeatures(variants);
+ final ArrayList samples = variantHeader.getSampleNamesInOrder();
+ if( samples == null || !samples.contains(iupacSample)) {
+ throw new UserException.BadInput("the IUPAC sample specified is not present in the provided VCF file");
+ }
+ }
}
- // Check to see if we have a called snp
- for ( final VariantContext vc : tracker.getValues(variantCollection.variants, ref.getLocus()) ) {
- if ( vc.isFiltered() )
- continue;
-
- if ( vc.isSimpleDeletion()) {
- deletionBasesRemaining = vc.getReference().length() - 1;
- // delete the next n bases, not this one
- return new Pair<>(context.getLocation(), refBase);
- } else if ( vc.isSimpleInsertion() || vc.isSNP() ) {
- // Get the first alt allele that is not a spanning deletion. If none present, use the empty allele
- final Optional optionalAllele = getFirstNonSpanDelAltAllele(vc.getAlternateAlleles());
- final Allele allele = optionalAllele.isPresent() ? optionalAllele.get() : Allele.create(EMPTY_BASE, false);
- if ( vc.isSimpleInsertion() ) {
- return new Pair<>(context.getLocation(), allele.toString());
+ @Override
+ public void apply(final ReferenceContext ref, final ReadsContext reads, final FeatureContext features) {
+ final byte[] bases = handlePosition(ref.getInterval(), ref.getBase(), features);
+ final SimpleInterval interval = ref.getInterval();
+ if( bases.length == 0){
+ addToReference(interval, null);
} else {
- final String base = (iupacSample != null) ? getIUPACbase(vc.getGenotype(iupacSample), refBase) : allele.toString();
- return new Pair<>(context.getLocation(), base);
+ for( byte base : bases) {
+ addToReference(interval, base);
+ }
}
- }
}
- if ( !snpmaskPriority ){
- final Pair mask = maskSnp(tracker, context);
- if ( mask != null )
- return mask;
+ private byte[] handlePosition(SimpleInterval interval, byte base, FeatureContext features) {
+ if (deletionBasesRemaining > 0) {
+ deletionBasesRemaining--;
+ return NO_BASES;
+ }
+
+ final String refBase = String.valueOf((char) base);
+
+ // If we have a mask at this site, use it
+ if ( snpmaskPriority ){
+ if (isMasked(features) )
+ return N_BYTES;
+ }
+
+ // Check to see if we have a called snp
+ for ( final VariantContext vc : features.getValues(variants) ) {
+ if ( vc.isFiltered() || vc.getStart() != interval.getStart() )
+ continue;
+
+ if ( vc.isSimpleDeletion()) {
+ deletionBasesRemaining = vc.getReference().length() - 1;
+ // delete the next n bases, not this one
+ return baseToByteArray(base);
+ } else if ( vc.isSimpleInsertion() || vc.isSNP() ) {
+ // Get the first alt allele that is not a spanning deletion. If none present, use the empty allele
+ final Optional optionalAllele = getFirstNonSpanDelAltAllele(vc.getAlternateAlleles());
+ final Allele allele = optionalAllele.orElseGet(() -> Allele.create(EMPTY_BASE, false));
+ if ( vc.isSimpleInsertion() ) {
+ return allele.getBases();
+ } else {
+ final String iupacBase = (iupacSample != null) ? getIUPACBase(vc.getGenotype(iupacSample), refBase) : allele.toString();
+ return iupacBase.getBytes();
+ }
+ }
+ }
+
+ if ( !snpmaskPriority ){
+ if ( isMasked(features)) {
+ return N_BYTES;
+ }
+ }
+
+ // if we got here then we're just ref
+ return baseToByteArray(base);
}
- // if we got here then we're just ref
- return new Pair<>(context.getLocation(), refBase);
- }
-
- /**
- * Get the first non spanning deletion (* or <*:DEL>) alt allele
- * @param altAlleles the alternate alleles
- * @return the first non spanning deletion allele or null
- */
- private Optional getFirstNonSpanDelAltAllele( final List altAlleles ) {
- for (final Allele allele : altAlleles) {
- if (!allele.equals(Allele.SPAN_DEL) && !allele.equals(GATKVCFConstants.SPANNING_DELETION_SYMBOLIC_ALLELE_DEPRECATED)) {
- return Optional.of(allele);
- }
+ private byte[] baseToByteArray(byte base) {
+ switch(base) {
+ case 'A': return A_BYTES;
+ case 'a': return a_BYTES;
+ case 'C': return C_BYTES;
+ case 'c': return c_BYTES;
+ case 'G': return G_BYTES;
+ case 'g': return g_BYTES;
+ case 'T': return T_BYTES;
+ case 't': return t_BYTES;
+ case 'N': return N_BYTES;
+ case 'n': return n_BYTES;
+ default: return new byte[]{base};
+ }
}
- return Optional.empty();
- }
-
- /**
- * Mask a SNP (inserting N's in the sequence)
- *
- * @param tracker the Reference Metadata available at a particular site in the genome
- * @param context the locus context data
- * @return mask at the locus or null if no SNP at that locus
- */
- private Pair maskSnp(final RefMetaDataTracker tracker, final AlignmentContext context){
- for (final VariantContext vc : tracker.getValues(snpmask)) {
- if (vc.isSNP()) {
- return new Pair<>(context.getLocation(), "N");
- }
+ /**
+ * Get the first non spanning deletion (* or <*:DEL>) alt allele
+ * @param altAlleles the alternate alleles
+ * @return the first non spanning deletion allele or null
+ */
+ private Optional getFirstNonSpanDelAltAllele( final List altAlleles ) {
+ return altAlleles.stream()
+ .filter(allele -> !GATKVCFConstants.isSpanningDeletion(allele))
+ .findFirst();
}
- return null;
- }
-
- /**
- * Returns the IUPAC encoding for the given genotype or the reference base if not possible
- *
- * @param genotype the genotype to encode
- * @param ref the reference base
- * @return non-null, non-empty String of bases
- */
- private String getIUPACbase(final Genotype genotype, final String ref) {
- if ( genotype == null )
- throw new IllegalStateException("The genotype is null for sample " + iupacSample);
-
- // If have a spanning deletion, if both alleles are spanning deletions, use the empty allele. Otherwise, use the allele is not a
- // spanning deletion.
- if ( genotype.getAlleles().contains(Allele.SPAN_DEL) ) {
- if ( genotype.isHomVar() ) {
- return EMPTY_BASE;
- } else {
- return genotype.getAllele(0).equals(Allele.SPAN_DEL) ? genotype.getAllele(1).getBaseString() : genotype.getAllele(0).getBaseString();
- }
+ /**
+ * Mask a SNP (inserting N's in the sequence)
+ *
+ * @param features the Reference Metadata available at a particular site in the genome
+ * @return mask at the locus or null if no SNP at that locus
+ */
+ private boolean isMasked(final FeatureContext features){
+ return features.getValues(snpmask).stream().anyMatch(VariantContext::isSNP);
}
- if ( !genotype.isHet() )
- return genotype.isHom() ? genotype.getAllele(0).getBaseString() : ref;
+ /**
+ * Returns the IUPAC encoding for the given genotype or the reference base if not possible
+ *
+ * @param genotype the genotype to encode
+ * @param ref the reference base
+ * @return non-null, non-empty String of bases
+ */
+ private String getIUPACBase(final Genotype genotype, final String ref) {
+ Utils.nonNull(genotype, () -> "The genotype is null for sample " + iupacSample);
- final byte allele1 = genotype.getAllele(0).getBases()[0];
- final byte allele2 = genotype.getAllele(1).getBases()[0];
- return new String(new byte[] {BaseUtils.basesToIUPAC(allele1, allele2)});
- }
+ // If have a spanning deletion, if both alleles are spanning deletions, use the empty allele. Otherwise, use the allele is not a
+ // spanning deletion.
+ if ( genotype.getAlleles().contains(Allele.SPAN_DEL) ) {
+ if ( genotype.isHomVar() ) {
+ return EMPTY_BASE;
+ } else {
+ return genotype.getAllele(0).equals(Allele.SPAN_DEL) ? genotype.getAllele(1).getBaseString() : genotype.getAllele(0).getBaseString();
+ }
+ }
+
+ if ( !genotype.isHet() )
+ return genotype.isHom() ? genotype.getAllele(0).getBaseString() : ref;
+
+ final byte allele1 = genotype.getAllele(0).getBases()[0];
+ final byte allele2 = genotype.getAllele(1).getBases()[0];
+ return new String(new byte[] {BaseUtils.basesToIUPAC(allele1, allele2)});
+ }
}
\ No newline at end of file
diff --git a/src/main/java/org/broadinstitute/hellbender/tools/walkers/fasta/FastaReferenceMaker.java b/src/main/java/org/broadinstitute/hellbender/tools/walkers/fasta/FastaReferenceMaker.java
index e04b631b7db..b235bf2dd06 100644
--- a/src/main/java/org/broadinstitute/hellbender/tools/walkers/fasta/FastaReferenceMaker.java
+++ b/src/main/java/org/broadinstitute/hellbender/tools/walkers/fasta/FastaReferenceMaker.java
@@ -1,43 +1,24 @@
-/*
- * Copyright 2012-2016 Broad Institute, Inc.
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
- * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
package org.broadinstitute.hellbender.tools.walkers.fasta;
-import org.broadinstitute.gatk.utils.commandline.Argument;
-import org.broadinstitute.gatk.utils.commandline.Output;
-import org.broadinstitute.gatk.engine.CommandLineGATK;
-import org.broadinstitute.gatk.utils.contexts.AlignmentContext;
-import org.broadinstitute.gatk.utils.contexts.ReferenceContext;
-import org.broadinstitute.gatk.utils.refdata.RefMetaDataTracker;
-import org.broadinstitute.gatk.engine.walkers.RefWalker;
-import org.broadinstitute.gatk.utils.GenomeLoc;
-import org.broadinstitute.gatk.utils.collections.Pair;
-import org.broadinstitute.gatk.utils.help.DocumentedGATKFeature;
-import org.broadinstitute.gatk.utils.help.HelpConstants;
+import com.google.common.primitives.Bytes;
+import org.broadinstitute.barclay.argparser.Argument;
+import org.broadinstitute.barclay.argparser.CommandLineProgramProperties;
+import org.broadinstitute.barclay.help.DocumentedFeature;
+import org.broadinstitute.hellbender.cmdline.StandardArgumentDefinitions;
+import org.broadinstitute.hellbender.engine.FeatureContext;
+import org.broadinstitute.hellbender.engine.ReadsContext;
+import org.broadinstitute.hellbender.engine.ReferenceContext;
+import org.broadinstitute.hellbender.engine.ReferenceWalker;
+import org.broadinstitute.hellbender.exceptions.UserException;
+import org.broadinstitute.hellbender.utils.SimpleInterval;
+import org.broadinstitute.hellbender.utils.io.IOUtils;
+import org.broadinstitute.hellbender.utils.reference.FastaReferenceWriter;
+import picard.cmdline.programgroups.ReferenceProgramGroup;
-import java.io.PrintStream;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
/**
* Create a subset of a FASTA reference sequence
@@ -68,70 +49,100 @@
*
* Usage example
*
- * java -jar GenomeAnalysisTK.jar \
- * -T FastaReferenceMaker \
+ * gatk FastaReferenceMaker \
* -R reference.fasta \
- * -o output.fasta \
+ * -O output.fasta \
* -L input.intervals
*
*
*/
-@DocumentedGATKFeature( groupName = HelpConstants.DOCS_CAT_REFUTILS, extraDocs = {CommandLineGATK.class} )
-public class FastaReferenceMaker extends RefWalker, GenomeLoc> {
+@DocumentedFeature
+@CommandLineProgramProperties(
+ summary = "Create snippets of a fasta file by subsetting to an interval list",
+ oneLineSummary = "Create snippets of a fasta file",
+ programGroup = ReferenceProgramGroup.class
+)
+public class FastaReferenceMaker extends ReferenceWalker {
- @Output PrintStream out;
+ @Argument(fullName = StandardArgumentDefinitions.OUTPUT_LONG_NAME,
+ shortName = StandardArgumentDefinitions.OUTPUT_SHORT_NAME,
+ doc = "Path to write the output fasta to")
+ public String output;
- @Argument(fullName="lineWidth", shortName="lw", doc="Maximum length of sequence to write per line", required=false)
- public int fastaLineWidth=60;
+ public static final String LINE_WIDTH_LONG_NAME = "line-width";
+ @Argument(fullName= LINE_WIDTH_LONG_NAME, doc="Maximum length of sequence to write per line", optional=true)
+ public int basesPerLine = FastaReferenceWriter.DEFAULT_BASES_PER_LINE;
- /**
- * Please note that when using this argument adjacent intervals will automatically be merged.
- */
- @Argument(fullName="rawOnelineSeq", shortName="raw", doc="Print sequences with no FASTA header lines, one line per interval (i.e. lineWidth = infinity)", required=false)
- public boolean fastaRawSeqs=false;
+ protected FastaReferenceWriter writer;
+ private int contigCount = 0;
+ private int currentSequenceStartPosition = 0;
+ private SimpleInterval lastPosition = null;
+ private List sequence = new ArrayList<>(10000);
- protected FastaSequence fasta;
+ @Override
+ public void onTraversalStart() {
+ final Path path = IOUtils.getPath(output);
+ try {
+ writer = new FastaReferenceWriter(path, basesPerLine, true, true);
+ } catch (IOException e) {
+ throw new UserException.CouldNotCreateOutputFile("Couldn't create " + output + ", encountered exception: " + e.getMessage(), e);
+ }
+ }
- public void initialize() {
- if (fastaRawSeqs) fastaLineWidth = Integer.MAX_VALUE;
- fasta = new FastaSequence(out, fastaLineWidth, fastaRawSeqs);
- }
+ @Override
+ public void closeTool() {
+ super.closeTool();
+ try{
+ writer.close();
+ } catch (IllegalStateException e){
+ //sink this
+ } catch (IOException e) {
+ throw new UserException("Failed to write fasta due to " + e.getMessage(), e);
+ }
+ }
- public Pair map(RefMetaDataTracker rodData, ReferenceContext ref, AlignmentContext context) {
- return new Pair(context.getLocation(), String.valueOf((char)ref.getBase()));
- }
+ @Override
+ public void apply(ReferenceContext referenceContext, ReadsContext read, FeatureContext featureContext) {
+ addToReference(referenceContext.getInterval(), referenceContext.getBase());
+ }
- public GenomeLoc reduceInit() {
- return null;
- }
+ protected void addToReference(SimpleInterval interval, Byte base) {
+ if(lastPosition == null ){
+ initializeNewSequence(interval);
+ } else if ( !lastPosition.withinDistanceOf(interval, 1)) {
+ finalizeSequence();
+ initializeNewSequence(interval);
+ }
+ addToSequence(interval, base);
+ }
- public GenomeLoc reduce(Pair value, GenomeLoc sum) {
- if ( value == null )
- return sum;
+ private void addToSequence(SimpleInterval interval, Byte base) {
+ if (base != null) {
+ sequence.add(base);
+ }
+ lastPosition = interval;
- // if there is no interval to the left, then this is the first one
- if ( sum == null ) {
- sum = value.first;
- fasta.setName(fasta.getName() + " " + sum.toString());
- fasta.append(value.second);
}
- // if the intervals are not contiguous, print out the leftmost one and start a new one
- // (end of contig or new interval)
- else if ( value.first.getStart() != sum.getStop() + 1 || ! value.first.getContig().equals(sum.getContig()) ) {
- fasta.flush();
- sum = value.first;
- fasta.setName(fasta.getName() + " " + sum.toString());
- fasta.append(value.second);
+
+ private void finalizeSequence() {
+ final String description = lastPosition.getContig() + ":" + currentSequenceStartPosition + "-" + lastPosition.getEnd();
+ try {
+ writer.appendSequence(String.valueOf(contigCount), description, basesPerLine, Bytes.toArray(sequence));
+ } catch (IOException e) {
+ throw new UserException.CouldNotCreateOutputFile("Failed while writing " + output + ".", e);
+ }
}
- // otherwise, merge them
- else {
- sum = sum.setStop(sum, value.first.getStop());
- fasta.append(value.second);
+
+ private void initializeNewSequence(SimpleInterval interval) {
+ lastPosition = interval;
+ contigCount++;
+ currentSequenceStartPosition = lastPosition.getStart();
+ sequence.clear();
}
- return sum;
- }
- public void onTraversalDone(GenomeLoc sum) {
- fasta.flush();
- }
+ @Override
+ public Object onTraversalSuccess(){
+ finalizeSequence();
+ return null;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/org/broadinstitute/hellbender/utils/BaseUtils.java b/src/main/java/org/broadinstitute/hellbender/utils/BaseUtils.java
index 4464afc9c33..6a8d2d7426d 100644
--- a/src/main/java/org/broadinstitute/hellbender/utils/BaseUtils.java
+++ b/src/main/java/org/broadinstitute/hellbender/utils/BaseUtils.java
@@ -285,4 +285,38 @@ public static byte getComplement(final byte base) {
}
return Integer.compare(o1.length, o2.length);
};
+
+ /**
+ * Converts a pair of bases to their IUPAC ambiguity code
+ *
+ * @param base1 1st base
+ * @param base2 2nd base
+ * @return byte
+ */
+ static public byte basesToIUPAC(final byte base1, final byte base2) {
+ // ensure that the bases come in order
+ if (base2 < base1) {
+ return basesToIUPAC(base2, base1);
+
+ }
+ // ensure that the bases are regular ones
+ if (!isRegularBase(base1) || !isRegularBase(base2)) {
+ return Base.N.base;
+ }
+
+ // IUPAC codes are not needed if the bases are identical
+ if (basesAreEqual(base1, base2)) {
+ return base1;
+ }
+
+ if (base1 == Base.A.base) {
+ return (byte) (base2 == Base.C.base ? 'M' : (base2 == Base.G.base ? 'R' : 'W'));
+ }
+
+ if (base1 == Base.C.base) {
+ return (byte) (base2 == Base.G.base ? 'S' : 'Y');
+ }
+ // the only possibility left is G/T
+ return 'K';
+ }
}
diff --git a/src/main/java/org/broadinstitute/hellbender/utils/SimpleInterval.java b/src/main/java/org/broadinstitute/hellbender/utils/SimpleInterval.java
index cad25b71893..4d61fe05092 100644
--- a/src/main/java/org/broadinstitute/hellbender/utils/SimpleInterval.java
+++ b/src/main/java/org/broadinstitute/hellbender/utils/SimpleInterval.java
@@ -4,8 +4,6 @@
import htsjdk.samtools.SAMSequenceDictionary;
import htsjdk.samtools.SAMSequenceRecord;
import htsjdk.samtools.util.Locatable;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
import org.broadinstitute.hellbender.exceptions.GATKException;
import org.broadinstitute.hellbender.exceptions.UserException;
diff --git a/src/main/java/org/broadinstitute/hellbender/utils/help/HelpConstants.java b/src/main/java/org/broadinstitute/hellbender/utils/help/HelpConstants.java
index 95b2d5fa099..e552745a934 100644
--- a/src/main/java/org/broadinstitute/hellbender/utils/help/HelpConstants.java
+++ b/src/main/java/org/broadinstitute/hellbender/utils/help/HelpConstants.java
@@ -3,9 +3,7 @@
import org.broadinstitute.hellbender.utils.Utils;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Map;
-import java.util.Set;
public final class HelpConstants {
diff --git a/src/main/java/org/broadinstitute/hellbender/utils/iterators/IntervalLocusIterator.java b/src/main/java/org/broadinstitute/hellbender/utils/iterators/IntervalLocusIterator.java
index f4482798219..870ff5a7d8d 100644
--- a/src/main/java/org/broadinstitute/hellbender/utils/iterators/IntervalLocusIterator.java
+++ b/src/main/java/org/broadinstitute/hellbender/utils/iterators/IntervalLocusIterator.java
@@ -1,11 +1,12 @@
package org.broadinstitute.hellbender.utils.iterators;
-import org.broadinstitute.hellbender.utils.IntervalUtils;
import org.broadinstitute.hellbender.utils.SimpleInterval;
import org.broadinstitute.hellbender.utils.Utils;
-
-import java.util.*;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
/**
* Returns a SimpleInterval for each locus in a set of intervals. I.e. returns each genomic point location in an interval list.
diff --git a/src/main/java/org/broadinstitute/hellbender/utils/reference/FastaReferenceWriter.java b/src/main/java/org/broadinstitute/hellbender/utils/reference/FastaReferenceWriter.java
index b81be29cf8f..146039c2d22 100644
--- a/src/main/java/org/broadinstitute/hellbender/utils/reference/FastaReferenceWriter.java
+++ b/src/main/java/org/broadinstitute/hellbender/utils/reference/FastaReferenceWriter.java
@@ -10,11 +10,7 @@
import org.broadinstitute.hellbender.utils.param.ParamUtils;
import org.codehaus.plexus.util.StringUtils;
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
+import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -254,7 +250,7 @@ public FastaReferenceWriter(final Path fastaFile, final int basesPerLine, final
// for the sake of avoiding creating output if basesPerLine is invalid.
this.defaultBasePerLine = checkBasesPerLine(basesPerLine);
- this.fastaStream = new CountingOutputStream(Files.newOutputStream(Utils.nonNull(fastaFile)));
+ this.fastaStream = new CountingOutputStream(new BufferedOutputStream(Files.newOutputStream(Utils.nonNull(fastaFile))));
this.indexWriter = indexFile == null ? new NullWriter() : new OutputStreamWriter(Files.newOutputStream(indexFile), CHARSET);
final BufferedWriter dictWriter = new BufferedWriter(dictFile == null ? new NullWriter() : new OutputStreamWriter(Files.newOutputStream(dictFile), CHARSET));
this.dictWriter = dictWriter;
@@ -509,7 +505,7 @@ private void closeSequence()
{
if (currentSequenceName != null) {
if (currentBasesCount == 0) {
- throw new IllegalStateException("no base was added");
+ throw new IllegalStateException("startSequence was called but no base was added");
}
sequenceNamesAndSizes.put(currentSequenceName, currentBasesCount);
writeIndexEntry();
@@ -681,18 +677,22 @@ private void assertIsNotClosed() {
*
*
* @throws IOException if such exception is thrown when closing output writers and output streams.
+ * @throws IllegalStateException if closing without writing any sequences or closing when writing a sequence is in progress
*/
public void close() throws IOException
{
if (!closed) {
- closeSequence();
- if (sequenceNamesAndSizes.isEmpty()) {
- throw new IllegalStateException("no sequences where added to the reference");
+ try {
+ closeSequence();
+ if (sequenceNamesAndSizes.isEmpty()) {
+ throw new IllegalStateException("no sequences where added to the reference");
+ }
+ } finally {
+ closed = true;
+ fastaStream.close();
+ indexWriter.close();
+ dictWriter.close();
}
- fastaStream.close();
- indexWriter.close();
- dictWriter.close();
- closed = true;
}
}
diff --git a/src/test/java/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalkerIntegrationTest.java b/src/test/java/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalkerIntegrationTest.java
new file mode 100644
index 00000000000..16746bc3599
--- /dev/null
+++ b/src/test/java/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalkerIntegrationTest.java
@@ -0,0 +1,36 @@
+package org.broadinstitute.hellbender.tools.examples;
+
+import org.broadinstitute.hellbender.CommandLineProgramTest;
+import org.broadinstitute.hellbender.testutils.ArgumentsBuilder;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.util.Map;
+
+public class ExampleReferenceWalkerIntegrationTest extends CommandLineProgramTest {
+
+ @Test
+ public void testExampleReferenceWalker(){
+ final ArgumentsBuilder args = new ArgumentsBuilder();
+ args.addReference( getTestFile(("example.fasta")));
+ args.addInput(getTestFile("veryspecific.bam"));
+ args.addVCF(getTestFile("example.vcf"));
+
+ final ExampleReferenceWalker exampleReferenceWalker = new ExampleReferenceWalker();
+ exampleReferenceWalker.instanceMain(args.getArgsArray());
+
+ final Map contextCounts = exampleReferenceWalker.contextCounts;
+ final ExampleReferenceWalker.OverlapCounts aaaCounts = contextCounts.get("AAA");
+ final ExampleReferenceWalker.OverlapCounts nnnCounts = contextCounts.get("NNN");
+ final ExampleReferenceWalker.OverlapCounts aacCounts = contextCounts.get("AAC");
+ assertCountsEqual(aaaCounts, 78, 9, 3 );
+ assertCountsEqual(nnnCounts, 78, 1, 0);
+ assertCountsEqual(aacCounts, 1, 0, 1);
+ }
+
+ private static void assertCountsEqual(ExampleReferenceWalker.OverlapCounts counts, long seen, long reads, long variants){
+ Assert.assertEquals(counts.timesSeen, seen);
+ Assert.assertEquals(counts.overlappedByReads, reads);
+ Assert.assertEquals(counts.overlappedByVariants, variants);
+ }
+}
diff --git a/src/test/java/org/broadinstitute/hellbender/tools/genomicsdb/GenomicsDBImportIntegrationTest.java b/src/test/java/org/broadinstitute/hellbender/tools/genomicsdb/GenomicsDBImportIntegrationTest.java
index 1abafb94a3a..278568007a4 100644
--- a/src/test/java/org/broadinstitute/hellbender/tools/genomicsdb/GenomicsDBImportIntegrationTest.java
+++ b/src/test/java/org/broadinstitute/hellbender/tools/genomicsdb/GenomicsDBImportIntegrationTest.java
@@ -19,16 +19,14 @@
import org.broadinstitute.hellbender.CommandLineProgramTest;
import org.broadinstitute.hellbender.Main;
import org.broadinstitute.hellbender.cmdline.StandardArgumentDefinitions;
-import org.broadinstitute.hellbender.engine.FeatureDataSource;
import org.broadinstitute.hellbender.exceptions.UserException;
-import org.broadinstitute.hellbender.utils.IntervalUtils;
+import org.broadinstitute.hellbender.testutils.ArgumentsBuilder;
+import org.broadinstitute.hellbender.testutils.BaseTest;
+import org.broadinstitute.hellbender.testutils.VariantContextTestUtils;
import org.broadinstitute.hellbender.utils.SimpleInterval;
import org.broadinstitute.hellbender.utils.Utils;
import org.broadinstitute.hellbender.utils.gcs.BucketUtils;
import org.broadinstitute.hellbender.utils.io.IOUtils;
-import org.broadinstitute.hellbender.testutils.ArgumentsBuilder;
-import org.broadinstitute.hellbender.testutils.BaseTest;
-import org.broadinstitute.hellbender.testutils.VariantContextTestUtils;
import org.broadinstitute.hellbender.utils.variant.GATKVCFConstants;
import org.broadinstitute.hellbender.utils.variant.GATKVariantContextUtils;
import org.testng.Assert;
@@ -37,11 +35,11 @@
import java.io.File;
import java.io.IOException;
-import java.nio.file.*;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
import java.util.*;
-import java.util.concurrent.CompletionException;
import java.util.stream.Collectors;
-import java.util.stream.Stream;
@Test(groups = {"variantcalling"})
public final class GenomicsDBImportIntegrationTest extends CommandLineProgramTest {
@@ -281,7 +279,7 @@ private File runCombineGVCFs(final List inputs, final List args.addArgument("L", interval.toString()));
+ intervals.forEach(args::addInterval);
Arrays.stream(extraArgs).forEach(args::add);
Utils.resetRandomGenerator();
@@ -440,7 +438,7 @@ private void writeToGenomicsDB(final List vcfInputs, final List args.addArgument("L", IntervalUtils.locatableToString(interval)));
+ intervals.forEach(args::addInterval);
vcfInputs.forEach(vcf -> args.addArgument("V", vcf));
args.addArgument("batch-size", String.valueOf(batchSize));
args.addArgument(GenomicsDBImport.VCF_INITIALIZER_THREADS_LONG_NAME, String.valueOf(threads));
@@ -570,7 +568,7 @@ public void testSampleNameWithSpaces() throws IOException {
ArgumentsBuilder args = new ArgumentsBuilder()
.addArgument(GenomicsDBImport.BATCHSIZE_ARG_LONG_NAME, String.valueOf(2))
.addFileArgument(GenomicsDBImport.SAMPLE_NAME_MAP_LONG_NAME, outOfOrderSampleMap)
- .addArgument("L", IntervalUtils.locatableToString(SMALLER_INTERVAL.get(0)))
+ .addInterval(SMALLER_INTERVAL.get(0))
.addArgument(GenomicsDBImport.WORKSPACE_ARG_LONG_NAME, workspace);
runCommandLine(args);
@@ -582,7 +580,7 @@ public void testSampleNameWithSpaces() throws IOException {
public void testSampleNameOrdering(final ArgumentsBuilder args) throws IOException {
final String workspace = createTempDir("gendbtest").getAbsolutePath() + "/workspace";
- args.addArgument("L", IntervalUtils.locatableToString(INTERVAL.get(0)))
+ args.addInterval(INTERVAL.get(0))
.addArgument(GenomicsDBImport.WORKSPACE_ARG_LONG_NAME, workspace);
runCommandLine(args);
@@ -674,7 +672,7 @@ public void testRenamingSamples(final Map renamingMap, final int
.addArgument(GenomicsDBImport.WORKSPACE_ARG_LONG_NAME, new File(workspace).getAbsolutePath())
.addArgument(GenomicsDBImport.VCF_INITIALIZER_THREADS_LONG_NAME, String.valueOf(threads))
.addArgument(GenomicsDBImport.BATCHSIZE_ARG_LONG_NAME, String.valueOf(batchSize))
- .addArgument("L", IntervalUtils.locatableToString(INTERVAL.get(0)));
+ .addInterval(INTERVAL.get(0));
runCommandLine(args);
final Set expectedSampleNames = sampleMap.keySet();
@@ -730,7 +728,7 @@ public void testCantSpecifyVCFAndSampleNameFile(){
.addArgument(GenomicsDBImport.SAMPLE_NAME_MAP_LONG_NAME, createInOrderSampleMap().getAbsolutePath())
.addArgument(StandardArgumentDefinitions.VARIANT_LONG_NAME, HG_00096)
.addArgument(GenomicsDBImport.WORKSPACE_ARG_LONG_NAME, createTempDir("workspace").getAbsolutePath())
- .addArgument("L", IntervalUtils.locatableToString(INTERVAL.get(0)));
+ .addInterval(INTERVAL.get(0));
runCommandLine(args);
}
diff --git a/src/test/java/org/broadinstitute/hellbender/tools/walkers/fasta/CountBasesInReferenceIntegrationTest.java b/src/test/java/org/broadinstitute/hellbender/tools/walkers/fasta/CountBasesInReferenceIntegrationTest.java
new file mode 100644
index 00000000000..568e6a067cf
--- /dev/null
+++ b/src/test/java/org/broadinstitute/hellbender/tools/walkers/fasta/CountBasesInReferenceIntegrationTest.java
@@ -0,0 +1,38 @@
+package org.broadinstitute.hellbender.tools.walkers.fasta;
+
+import org.broadinstitute.hellbender.CommandLineProgramTest;
+import org.broadinstitute.hellbender.testutils.ArgumentsBuilder;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.io.File;
+
+public class CountBasesInReferenceIntegrationTest extends CommandLineProgramTest {
+
+ @Test
+ public void testExampleReferenceWalker(){
+ final ArgumentsBuilder args = new ArgumentsBuilder();
+ args.addReference(new File(hg19MiniReference))
+ .addArgument("L", "1:5000-6000");
+ final CountBasesInReference walker = new CountBasesInReference();
+ walker.instanceMain(args.getArgsArray());
+ final long[] baseCounts = walker.baseCounts;
+
+ Assert.assertEquals(baseCounts['N'], 1001L);
+ }
+
+ @Test
+ public void testExampleReferenceWalkerFull(){
+ final ArgumentsBuilder args = new ArgumentsBuilder();
+ args.addReference(new File(hg19MiniReference));
+ final CountBasesInReference walker = new CountBasesInReference();
+ walker.instanceMain(args.getArgsArray());
+ final long[] baseCounts = walker.baseCounts;
+
+ Assert.assertEquals(baseCounts['A'], 4546);
+ Assert.assertEquals(baseCounts['C'], 4995);
+ Assert.assertEquals(baseCounts['G'], 4559);
+ Assert.assertEquals(baseCounts['T'], 3900);
+ Assert.assertEquals(baseCounts['N'], 46000);
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMakerIntegrationTest.java b/src/test/java/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMakerIntegrationTest.java
new file mode 100644
index 00000000000..7fdcfbaeb15
--- /dev/null
+++ b/src/test/java/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMakerIntegrationTest.java
@@ -0,0 +1,155 @@
+package org.broadinstitute.hellbender.tools.walkers.fasta;
+
+import org.broadinstitute.hellbender.CommandLineProgramTest;
+import org.broadinstitute.hellbender.exceptions.UserException;
+import org.broadinstitute.hellbender.testutils.ArgumentsBuilder;
+import org.broadinstitute.hellbender.testutils.FastaTestUtils;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.io.File;
+
+public class FastaAlternateReferenceMakerIntegrationTest extends CommandLineProgramTest {
+ private final File spanningDelTestFile = getTestFile("spanningDel.delOnly.starFirst.vcf");
+ private final File iupacTestFile = getTestFile("NA12878.WGS.b37.chr20.firstMB.vcf.gz");
+ private final File snp1 = getTestFile("snps.vcf");
+ private final File snp2 = getTestFile("snps2.vcf");
+ private final File snpsAndIndels = getTestFile("snpsAndIndels.vcf");
+ private final File overlapsIndels = getTestFile("overlapsIndelsMask.vcf");
+
+ @Test
+ public void testAlternateReferenceContiguousSameContig() {
+ // Show that FastaAlternateReferenceMaker behaves the same as FastaReferenceMaker across contiguous intervals on the same contig.
+ // Note that there are variant locations in this interval.
+ ArgumentsBuilder args = new ArgumentsBuilder();
+ final File out = createTempFile("test", "fasta");
+ args.addVCF(getTestFile("NA12878.chr1_10mb_11mb.slx.indels.vcf"))
+ .addReference(new File(b37Reference))
+ .addArgument("L", "1:10,000,100-10,000,200")
+ .addArgument("L", "1:10,000,201-10,000,301")
+ .addOutput(out);
+ runCommandLine(args);
+ FastaTestUtils.assertFastaFilesContainTheSameSequence(out.toPath(), getTestFile("expected_alternate_reference_contiguous_same_contig.fasta").toPath());
+ }
+
+ @Test
+ public void testAlternateReferenceContiguousDiffContigs() {
+ // Show that FastaAlternateReferenceMaker behaves the same as FastaReferenceMaker across contiguous intervals on different contigs.
+ // Note that there are variant locations in this interval.
+ ArgumentsBuilder args = new ArgumentsBuilder();
+ final File out = createTempFile("test", "fasta");
+ args.addVCF(getTestFile("NA12878.chr1_10mb_11mb.slx.indels.vcf"))
+ .addReference(new File(b37Reference))
+ .addArgument("L", "1:10,000,100-10,000,200")
+ .addArgument("L", "2:10,000,201-10,000,301")
+ .addOutput(out);
+ runCommandLine(args);
+ FastaTestUtils.assertFastaFilesContainTheSameSequence(out.toPath(), getTestFile("expected_alternate_reference_contiguous_diff_contig.fasta").toPath());
+ }
+
+ @DataProvider
+ public Object[][] getSnpMaskVariants(){
+ return new Object[][]{
+ {snp1, snp2, getTestFile("expected_snp1_mask2.fasta"), false},
+ {snp1, snp2, getTestFile("expected_snp1_mask2_priority.fasta"), true},
+ {snp2, snp1, getTestFile("expected_snp2_mask1.fasta"), false},
+ {snp2, snp1, getTestFile("expected_snp2_mask1_priority.fasta"), true},
+ {snpsAndIndels, snp1, getTestFile("expected_snpsAndIndels_mask1.fasta"), false},
+ {snpsAndIndels, snp1, getTestFile("expected_snpsAndIndels_mask1_priority.fasta"), true},
+ {snpsAndIndels, overlapsIndels, getTestFile("expected_snpsAndIndels_maskOverlaps.fasta"), false},
+ {snpsAndIndels, overlapsIndels, getTestFile("expected_snpsAndIndels_maskOverlaps_priority.fasta"), true},
+ };
+ }
+
+ @Test(dataProvider = "getSnpMaskVariants")
+ public void testSnpMask(File vcf, File mask, File expected, boolean priority) {
+ ArgumentsBuilder args = new ArgumentsBuilder();
+ final File out = createTempFile("test", "fasta");
+ args.addVCF(vcf)
+ .addReference(new File(b37Reference))
+ .addFileArgument(FastaAlternateReferenceMaker.SNP_MASK_LONG_NAME, mask)
+ .addArgument("L", "1:10,000,000-10,000,100")
+ .addBooleanArgument(FastaAlternateReferenceMaker.SNP_MASK_PRIORITY_LONG_NAME, priority)
+ .addOutput(out);
+ runCommandLine(args);
+ FastaTestUtils.assertFastaFilesContainTheSameSequence(out.toPath(), expected.toPath());
+ }
+
+ @DataProvider
+ public Object[][] noMask() {
+ return new Object[][]{
+ {snp1, getTestFile("expected_snp1.fasta")},
+ {snp2, getTestFile("expected_snp2.fasta")},
+ };
+ }
+
+ @Test(dataProvider = "noMask")
+ public void testNoMask(File vcf, File expected) {
+ ArgumentsBuilder args = new ArgumentsBuilder();
+ final File out = createTempFile("test", "fasta");
+ args.addVCF(vcf)
+ .addReference(new File(b37Reference))
+ .addArgument("L", "1:10,000,000-10,000,100")
+ .addOutput(out);
+ runCommandLine(args);
+ FastaTestUtils.assertFastaFilesContainTheSameSequence(out.toPath(), expected.toPath());
+ }
+
+ @Test(expectedExceptions = UserException.BadInput.class)
+ public void testBadIupacInput() {
+ ArgumentsBuilder args = new ArgumentsBuilder();
+ args.addVCF(iupacTestFile)
+ .addOutput( createTempFile("alternate", "fasta"))
+ .addReference(new File(b37Reference))
+ .addArgument(FastaAlternateReferenceMaker.USE_IUPAC_SAMPLE_LONG_NAME, "SAMPLE_DOESNT_EXIST");
+ runCommandLine(args);
+ }
+
+ @Test
+ public void testIupac() {
+ final File out = createTempFile("alternate", "fasta");
+ ArgumentsBuilder args = new ArgumentsBuilder();
+ args.addVCF(iupacTestFile)
+ .addOutput(out)
+ .addReference(new File(b37Reference))
+ .addArgument(FastaAlternateReferenceMaker.USE_IUPAC_SAMPLE_LONG_NAME, "NA12878")
+ .addArgument("L", "20:61050-66380");
+
+ runCommandLine(args);
+ FastaTestUtils.assertFastaFilesContainTheSameSequence(out.toPath(), getTestFile("expected_test_iupac.fasta").toPath());
+ }
+
+ @Test
+ void testSpanDel() {
+ final File out = createTempFile("alternate", "fasta");
+ ArgumentsBuilder args = new ArgumentsBuilder();
+ args.addVCF(spanningDelTestFile)
+ .addOutput(out)
+ .addReference(new File(b37Reference))
+ .addArgument("L", "1:1273247");
+ runCommandLine(args);
+ FastaTestUtils.assertFastaFilesContainTheSameSequence(out.toPath(), getTestFile("iupac_sample_NA3.fasta").toPath());
+ }
+
+ @DataProvider(name = "iupacSample")
+ public Object[][] getIupacSampleData() {
+ return new Object[][]{
+ {"NA1", getTestFile("iupac_sample_NA1.fasta")},
+ // {"NA2", getTestFile("iupac_sample_NA2.fasta")}, this test disabled because gatk4 won't write a fasta with an empty reference sequence
+ {"NA3", getTestFile("iupac_sample_NA3.fasta")}
+ };
+ }
+
+ @Test(dataProvider = "iupacSample")
+ void testSpanDelIUPAC(final String sample, final File expected) {
+ final ArgumentsBuilder args = new ArgumentsBuilder();
+ final File out = createTempFile("alternate", "fasta");
+ args.addVCF(spanningDelTestFile)
+ .addOutput(out)
+ .addReference(new File(b37Reference))
+ .addArgument("L", "1:1273247")
+ .addArgument("use-iupac-sample", sample);
+ runCommandLine(args);
+ FastaTestUtils.assertFastaFilesContainTheSameSequence(out.toPath(), expected.toPath());
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/org/broadinstitute/hellbender/tools/walkers/fasta/FastaReferenceMakerIntegrationTest.java b/src/test/java/org/broadinstitute/hellbender/tools/walkers/fasta/FastaReferenceMakerIntegrationTest.java
new file mode 100644
index 00000000000..f7bb2b436ae
--- /dev/null
+++ b/src/test/java/org/broadinstitute/hellbender/tools/walkers/fasta/FastaReferenceMakerIntegrationTest.java
@@ -0,0 +1,69 @@
+package org.broadinstitute.hellbender.tools.walkers.fasta;
+
+import org.broadinstitute.hellbender.CommandLineProgramTest;
+import org.broadinstitute.hellbender.testutils.ArgumentsBuilder;
+import org.broadinstitute.hellbender.testutils.BaseTest;
+import org.broadinstitute.hellbender.testutils.FastaTestUtils;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.Arrays;
+import java.util.List;
+
+public class FastaReferenceMakerIntegrationTest extends CommandLineProgramTest {
+
+ @DataProvider
+ public Object[][] getFastaParameters(){
+ return new Object[][]{
+ {Arrays.asList("1:10,000,100-10,000,500", "1:10,100,000-10,101,000", "1:10,900,000-10,900,001"), getTestFile("reference_only.fasta")},
+ {Arrays.asList("1:10,000,100-10,000,200", "1:10,000,201-10,000,301"), getTestFile("reference_only_contiguous_same_contig.fasta")},
+ {Arrays.asList("1:10,000,100-10,000,200", "2:10,000,201-10,000,301"), getTestFile("reference_only_contiguous_diff_contigs.fasta")}
+ };
+ }
+
+ @Test(dataProvider = "getFastaParameters")
+ public void runMakeFastaTest(List intervals, File expected) throws IOException {
+ ArgumentsBuilder args = new ArgumentsBuilder();
+ final File out = BaseTest.createTempFile("subset", ".fasta");
+ args.addReference(new File(b37Reference))
+ .addOutput(out);
+ intervals.forEach(interval -> args.addArgument("L", interval));
+ runCommandLine(args);
+
+ FastaTestUtils.assertFastaFilesContainTheSameSequence(out.toPath(), expected.toPath());
+ }
+
+
+ @DataProvider
+ public Object[][] getBasesPerLine(){
+ return new Object[][]{
+ {13}, {60}, {100}
+ };
+ }
+
+ @Test(dataProvider = "getBasesPerLine")
+ public void testBasePerLine(int basesPerLine) throws IOException {
+ ArgumentsBuilder args = new ArgumentsBuilder();
+ final File out = BaseTest.createTempFile("subset", ".fasta");
+ final File hg19mini = new File(hg19MiniReference);
+ args.addReference(hg19mini)
+ .addOutput(out)
+ .addArgument(FastaReferenceMaker.LINE_WIDTH_LONG_NAME, String.valueOf(basesPerLine));
+
+ runCommandLine(args);
+
+ FastaTestUtils.assertFastaFilesContainTheSameSequence(out.toPath(), hg19mini.toPath());
+ final List lines = Files.readAllLines(out.toPath());
+ for(int i = 0; i < lines.size(); i++){
+ String line = lines.get(i);
+ if(!line.startsWith(">")){
+ Assert.assertTrue(line.length() == basesPerLine || i == lines.size()-1 || lines.get(i+1).startsWith(">"));
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/org/broadinstitute/hellbender/tools/walkers/variantutils/ReblockGVCFIntegrationTest.java b/src/test/java/org/broadinstitute/hellbender/tools/walkers/variantutils/ReblockGVCFIntegrationTest.java
index 9cc4d922b2f..2465790ef1e 100644
--- a/src/test/java/org/broadinstitute/hellbender/tools/walkers/variantutils/ReblockGVCFIntegrationTest.java
+++ b/src/test/java/org/broadinstitute/hellbender/tools/walkers/variantutils/ReblockGVCFIntegrationTest.java
@@ -5,8 +5,6 @@
import org.broadinstitute.hellbender.GATKBaseTest;
import org.broadinstitute.hellbender.cmdline.StandardArgumentDefinitions;
import org.broadinstitute.hellbender.engine.FeatureDataSource;
-import org.broadinstitute.hellbender.utils.IntervalUtils;
-import org.broadinstitute.hellbender.utils.SimpleInterval;
import org.broadinstitute.hellbender.testutils.ArgumentsBuilder;
import org.broadinstitute.hellbender.testutils.CommandLineProgramTester;
import org.broadinstitute.hellbender.testutils.IntegrationTestSpec;
@@ -49,7 +47,7 @@ public void testGVCFReblockingIsContiguous() throws Exception {
final ArgumentsBuilder args2 = new ArgumentsBuilder();
args2.addArgument("R", b37_reference_20_21);
args2.addArgument("V", output.getAbsolutePath());
- args2.addArgument("L", IntervalUtils.locatableToString(new SimpleInterval("20:60001-1000000")));
+ args2.addArgument("L", "20:60001-1000000");
args2.add("-gvcf");
validator.runCommandLine(args2); //will throw a UserException if GVCF isn't contiguous
diff --git a/src/test/java/org/broadinstitute/hellbender/utils/BaseUtilsUnitTest.java b/src/test/java/org/broadinstitute/hellbender/utils/BaseUtilsUnitTest.java
index 80280a204d3..e5b805a4ecd 100644
--- a/src/test/java/org/broadinstitute/hellbender/utils/BaseUtilsUnitTest.java
+++ b/src/test/java/org/broadinstitute/hellbender/utils/BaseUtilsUnitTest.java
@@ -165,4 +165,22 @@ public Object[][] baseComparatorData() {
}
return result;
}
+
+ @Test
+ public void testConvertBasesToIUPAC() {
+ for ( final BaseUtils.Base b : BaseUtils.Base.values() ) {
+ if ( BaseUtils.isRegularBase(b.base) ) {
+ Assert.assertEquals(BaseUtils.basesToIUPAC(b.base, b.base), b.base, "testing same base");
+ }
+ }
+
+ Assert.assertEquals(BaseUtils.basesToIUPAC((byte)'A', (byte)'X'), 'N', "testing non-standard base");
+ Assert.assertEquals(BaseUtils.basesToIUPAC((byte)'X', (byte)'A'), 'N', "testing non-standard base");
+ Assert.assertEquals(BaseUtils.basesToIUPAC((byte)'X', (byte)'X'), 'N', "testing non-standard base");
+
+ Assert.assertEquals(BaseUtils.basesToIUPAC((byte)'A', (byte)'T'), 'W', "testing A/T=W");
+ Assert.assertEquals(BaseUtils.basesToIUPAC((byte)'T', (byte)'A'), 'W', "testing T/A=W");
+ Assert.assertEquals(BaseUtils.basesToIUPAC((byte) 'G', (byte) 'T'), 'K', "testing G/T=K");
+ Assert.assertEquals(BaseUtils.basesToIUPAC((byte) 'T', (byte) 'G'), 'K', "testing T/G=K");
+ }
}
diff --git a/src/test/java/org/broadinstitute/hellbender/utils/reference/FastaReferenceWriterUnitTest.java b/src/test/java/org/broadinstitute/hellbender/utils/reference/FastaReferenceWriterUnitTest.java
index 064dd6f4c8b..6282f6590de 100644
--- a/src/test/java/org/broadinstitute/hellbender/utils/reference/FastaReferenceWriterUnitTest.java
+++ b/src/test/java/org/broadinstitute/hellbender/utils/reference/FastaReferenceWriterUnitTest.java
@@ -1,28 +1,20 @@
package org.broadinstitute.hellbender.utils.reference;
-import htsjdk.samtools.SAMFileHeader;
import htsjdk.samtools.SAMSequenceDictionary;
import htsjdk.samtools.SAMSequenceRecord;
-import htsjdk.samtools.reference.FastaSequenceIndex;
-import htsjdk.samtools.reference.IndexedFastaSequenceFile;
-import htsjdk.samtools.reference.ReferenceSequence;
import htsjdk.samtools.reference.ReferenceSequenceFileFactory;
-import htsjdk.samtools.util.SequenceUtil;
import org.broadinstitute.hellbender.GATKBaseTest;
-import org.broadinstitute.hellbender.engine.ReadsDataSource;
+import org.broadinstitute.hellbender.testutils.FastaTestUtils;
import org.broadinstitute.hellbender.utils.RandomDNA;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
-import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URISyntaxException;
-import java.nio.file.Path;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -218,7 +210,7 @@ public Object[][] invalidDescriptionData() {
public void testWriter(final SAMSequenceDictionary dictionary, final boolean withIndex, final boolean withDictionary,
final boolean withDescriptions, final int defaultBpl,
final int minBpl, final int maxBpl, final int seed)
- throws IOException, GeneralSecurityException, URISyntaxException {
+ throws IOException {
final Map bases = new LinkedHashMap<>(dictionary.getSequences().size());
final Map bpl = new LinkedHashMap<>(dictionary.getSequences().size());
final Random rdn = new Random(seed);
@@ -235,7 +227,7 @@ public void testWriter(final SAMSequenceDictionary dictionary, final boolean wit
: new FastaReferenceWriter(fastaFile.toPath(), defaultBpl, withIndex, withDictionary)) {
writeReference(writer, withDescriptions, rdn, dictionary, bases, bpl);
}
- assertOutput(fastaFile.toPath(), withIndex, withDictionary, withDescriptions, dictionary, defaultBpl, bases, bpl);
+ FastaTestUtils.assertOutput(fastaFile.toPath(), withIndex, withDictionary, withDescriptions, dictionary, defaultBpl, bases, bpl);
Assert.assertTrue(fastaFile.delete());
Assert.assertEquals(fastaIndexFile.delete(), withIndex);
Assert.assertEquals(dictFile.delete(), withDictionary);
@@ -251,7 +243,7 @@ public void testSingleSequenceStaticWithBpl() throws IOException, GeneralSecurit
);
FastaReferenceWriter.writeSingleSequenceReference(testOutputFile.toPath(), 42,
true, true, "seqA", null, seqs.get("seqA"));
- assertOutput(testOutputFile.toPath(), true, true, false, dictionary, 42, seqs, bpls);
+ FastaTestUtils.assertOutput(testOutputFile.toPath(), true, true, false, dictionary, 42, seqs, bpls);
Assert.assertTrue(testOutputFile.delete());
Assert.assertTrue(ReferenceSequenceFileFactory.getDefaultDictionaryForReferenceSequence(testOutputFile).delete());
Assert.assertTrue(ReferenceSequenceFileFactory.getFastaIndexFileName(testOutputFile.toPath()).toFile().delete());
@@ -267,7 +259,7 @@ public void testSingleSequenceStatic() throws IOException, GeneralSecurityExcept
);
FastaReferenceWriter.writeSingleSequenceReference(testOutputFile.toPath(),
true, true, "seqA", null, seqs.get("seqA"));
- assertOutput(testOutputFile.toPath(), true, true, false, dictionary, FastaReferenceWriter.DEFAULT_BASES_PER_LINE, seqs, bpls);
+ FastaTestUtils.assertOutput(testOutputFile.toPath(), true, true, false, dictionary, FastaReferenceWriter.DEFAULT_BASES_PER_LINE, seqs, bpls);
Assert.assertTrue(testOutputFile.delete());
Assert.assertTrue(ReferenceSequenceFileFactory.getDefaultDictionaryForReferenceSequence(testOutputFile).delete());
Assert.assertTrue(ReferenceSequenceFileFactory.getFastaIndexFileName(testOutputFile.toPath()).toFile().delete());
@@ -287,9 +279,9 @@ public void testAlternativeIndexAndDictFileNames() throws IOException, GeneralSe
writer.startSequence("seq1");
writer.appendBases(seqs.get("seq1"));
}
- assertFastaContent(testOutputFile.toPath(), false, testDictionary, -1, seqs, bpls);
- assertFastaIndexContent(testOutputFile.toPath(), testIndexOutputFile.toPath(), testDictionary, seqs);
- assertFastaDictionaryContent(testDictOutputFile.toPath(), testDictionary);
+ FastaTestUtils.assertFastaContent(testOutputFile.toPath(), false, testDictionary, -1, seqs, bpls);
+ FastaTestUtils.assertFastaIndexContent(testOutputFile.toPath(), testIndexOutputFile.toPath(), testDictionary, seqs);
+ FastaTestUtils.assertFastaDictionaryContent(testDictOutputFile.toPath(), testDictionary);
Assert.assertTrue(testOutputFile.delete());
Assert.assertTrue(testIndexOutputFile.delete());
Assert.assertTrue(testDictOutputFile.delete());
@@ -313,9 +305,9 @@ public void testDirectOutputStreams() throws IOException, GeneralSecurityExcepti
writer.appendBases(seqs.get("seq1"));
}
}
- assertFastaContent(testOutputFile.toPath(), false, testDictionary, 50, seqs, bpls);
- assertFastaIndexContent(testOutputFile.toPath(), testIndexOutputFile.toPath(), testDictionary, seqs);
- assertFastaDictionaryContent(testDictOutputFile.toPath(), testDictionary);
+ FastaTestUtils.assertFastaContent(testOutputFile.toPath(), false, testDictionary, 50, seqs, bpls);
+ FastaTestUtils.assertFastaIndexContent(testOutputFile.toPath(), testIndexOutputFile.toPath(), testDictionary, seqs);
+ FastaTestUtils.assertFastaDictionaryContent(testDictOutputFile.toPath(), testDictionary);
Assert.assertTrue(testOutputFile.delete());
Assert.assertTrue(testIndexOutputFile.delete());
Assert.assertTrue(testDictOutputFile.delete());
@@ -337,7 +329,7 @@ private void generateRandomBasesAndBpls(SAMSequenceDictionary dictionary, int mi
- private void writeReference(final FastaReferenceWriter writer, final boolean withDescriptions,
+ private static void writeReference(final FastaReferenceWriter writer, final boolean withDescriptions,
final Random rdn, final SAMSequenceDictionary dictionary,
final Map seqs,
final Map basesPerLine)
@@ -404,71 +396,6 @@ private void writeReference(final FastaReferenceWriter writer, final boolean wit
}
}
- private void assertOutput(final Path path, final boolean mustHaveIndex, final boolean mustHaveDictionary,
- final boolean withDescriptions, final SAMSequenceDictionary dictionary, final int defaultBpl,
- final Map bases, final Map basesPerLine)
- throws GeneralSecurityException, IOException, URISyntaxException {
- assertFastaContent(path, withDescriptions, dictionary, defaultBpl, bases, basesPerLine);
- if (mustHaveDictionary) {
- assertFastaDictionaryContent(ReferenceSequenceFileFactory.getDefaultDictionaryForReferenceSequence(path), dictionary);
- }
- if (mustHaveIndex) {
- assertFastaIndexContent(path, ReferenceSequenceFileFactory.getFastaIndexFileName(path), dictionary, bases);
- }
- }
-
- private void assertFastaContent(final Path path, final boolean withDescriptions, final SAMSequenceDictionary dictionary, final int defaultBpl,
- final Map bases, final Map basesPerLine)
- throws IOException {
- try (final BufferedReader reader = new BufferedReader(new InputStreamReader(path.getFileSystem().provider().newInputStream(path)))) {
- for (final SAMSequenceRecord sequence : dictionary.getSequences()) {
- final String description = String.format("index=%d\tlength=%d",
- dictionary.getSequenceIndex(sequence.getSequenceName()), sequence.getSequenceLength());
- final String expectedHeader =
- FastaReferenceWriter.HEADER_START_CHAR + sequence.getSequenceName()
- + ((withDescriptions) ? FastaReferenceWriter.HEADER_NAME_AND_DESCRIPTION_SEPARATOR + description : "");
- Assert.assertEquals(reader.readLine(), expectedHeader);
- final byte[] expectedBases = bases.get(sequence.getSequenceName());
- final int bpl_ = basesPerLine.get(sequence.getSequenceName());
- final int bpl = bpl_ < 0 ? (defaultBpl < 0 ? FastaReferenceWriter.DEFAULT_BASES_PER_LINE : defaultBpl) : bpl_;
- int offset = 0;
- while (offset < expectedBases.length) {
- final int expectedLength = Math.min(expectedBases.length - offset, bpl);
- final byte[] expectedBaseLine = SequenceUtil.upperCase(Arrays.copyOfRange(expectedBases, offset, offset + expectedLength));
- final byte[] actualBaseLine = SequenceUtil.upperCase(reader.readLine().getBytes());
- Assert.assertEquals(actualBaseLine, expectedBaseLine);
- offset += expectedLength;
- }
- }
- }
- }
-
- private void assertFastaIndexContent(final Path path, final Path indexPath, final SAMSequenceDictionary dictionary,
- final Map bases)
- throws IOException {
- final FastaSequenceIndex index = new FastaSequenceIndex(indexPath);
- final IndexedFastaSequenceFile indexedFasta = new IndexedFastaSequenceFile(path, index);
- for (final SAMSequenceRecord sequence : dictionary.getSequences()) {
- final String name = sequence.getSequenceName();
- final int length = sequence.getSequenceLength();
- final ReferenceSequence start = indexedFasta.getSubsequenceAt(name, 1, Math.min(length, 30));
- final ReferenceSequence end = indexedFasta.getSubsequenceAt(name, Math.max(1, length - 29), length);
- final int middlePos = Math.max(1, Math.min(length, length / 2));
- final ReferenceSequence middle = indexedFasta.getSubsequenceAt(name, middlePos, Math.min(middlePos + 29, length));
- Assert.assertEquals(start.getBases(), Arrays.copyOfRange(bases.get(name), 0, start.length()));
- Assert.assertEquals(end.getBases(), Arrays.copyOfRange(bases.get(name), Math.max(0, length - 30), length));
- Assert.assertEquals(middle.getBases(), Arrays.copyOfRange(bases.get(name), middlePos - 1, middlePos - 1 + middle.length()));
- }
- }
-
- private void assertFastaDictionaryContent(final Path dictPath, final SAMSequenceDictionary dictionary)
- throws IOException, GeneralSecurityException, URISyntaxException {
- final ReadsDataSource readsDataSource = new ReadsDataSource(dictPath);
- final SAMFileHeader actualHeader = readsDataSource.getHeader();
- final SAMSequenceDictionary actualDictionary = actualHeader.getSequenceDictionary();
- dictionary.assertSameDictionary(actualDictionary);
- }
-
@DataProvider(name = "testData")
public Object[][] testData() {
// data-signature: (SAMSequenceDictionary dictionary, boolean withDescriptions, int defaultBpl, int minBpl, int maxBpl, int seed
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/example.dict b/src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/example.dict
new file mode 100644
index 00000000000..dcec775543f
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/example.dict
@@ -0,0 +1,2 @@
+@HD VN:1.6
+@SQ SN:1 LN:400 M5:f9f1dd3e58bd7fb781819cf22639251e UR:file:/Users/louisb/Workspace/gatk/src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/example.fasta
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/example.fasta b/src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/example.fasta
new file mode 100644
index 00000000000..8434b8826af
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/example.fasta
@@ -0,0 +1,6 @@
+>1 very short reference
+NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
+GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
+TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
\ No newline at end of file
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/example.fasta.fai b/src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/example.fasta.fai
new file mode 100644
index 00000000000..f03689c440e
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/example.fasta.fai
@@ -0,0 +1 @@
+1 400 24 80 81
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/example.vcf b/src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/example.vcf
new file mode 100644
index 00000000000..0e654b54b5d
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/example.vcf
@@ -0,0 +1,26 @@
+##fileformat=VCFv4.2
+##FORMAT=
+##FORMAT=
+##FORMAT=
+##FORMAT=
+##FORMAT=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT NA12878
+1 84 . A C 232.46 . AC=1;AF=0.50;AN=2;BaseQRankSum=1.161;DP=42;Dels=0.00;FS=2.473;HRun=0;HaplotypeScore=13.4505;MQ=146.79;MQ0=7;MQRankSum=0.203;QD=5.53;ReadPosRankSum=0.755;SB=-71.63 AD:DP:GQ:PL 26,15:42:99:262,0,342
+1 161 . C T 232.46 . AC=1;AF=0.50;AN=2;BaseQRankSum=1.161;DP=42;Dels=0.00;FS=2.473;HRun=0;HaplotypeScore=13.4505;MQ=146.79;MQ0=7;MQRankSum=0.203;QD=5.53;ReadPosRankSum=0.755;SB=-71.63 AD:DP:GQ:PL 26,15:42:99:262,0,342
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/example.vcf.idx b/src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/example.vcf.idx
new file mode 100644
index 0000000000000000000000000000000000000000..c54d10c275d4e2401133d8f5c1e01b0ddd987daf
GIT binary patch
literal 307
zcmZ8b%TB{U3^Wf3A&&e<-E!m>HA|@kK?<9eTi9%!5VB;e^#<{2dkVX3FVqljQ3pTdIRIiOYu~({KgjqXm4O
R!GTS0k41exmnE2b{Q%3pQJDY$
literal 0
HcmV?d00001
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/veryspecific.bam b/src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/veryspecific.bam
new file mode 100644
index 0000000000000000000000000000000000000000..499b1106d98f69d25b3213762224401cd73058f4
GIT binary patch
literal 637
zcmV-@0)qV?iwFb&00000{{{d;LjnL`0)11#Qrj>P741x?&W(P7xOX!)LwoR{leAFc
zspA9!J@lqX>qJzRj3fvA7yX2OWv_IEamWDep1k{Z-@aY1K98q+e_j(ZnjA;pi!>R2
zj25%>xwusbbcCT$7vibrs+h!pPK3*n&)Yj=a9U7wH7sgFb#bzW7GxR%(BaOt_GBG>nHyNd1zhj|imzrtx*-=>~1cxA~h32>J^Q5gLunTB3z+eNxkYA
z$9YZxEHVKbrlep#)H!dZUZLhKU1a%5aX|qba-)TVCHfmg4Yf5Zi_Sq)3+B<$BpwDC
zLOQlo2oA3s)Eq%b9!QyOcUsVrDTfq*TVx&|_5({+fz$$TskhC`a3wzcqjNskVURxJbpo!~9HMpbW}4cc%GTi>nC%|r@;
zkD(3PrE$`?G%LQ&D8Siec5<A^kigYU|?VZVoxCk1`wNv1xSEFB1o9QYZ62rT^ytq8KCNg$N&J*>H`A+
literal 0
HcmV?d00001
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/veryspecific.sam b/src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/veryspecific.sam
new file mode 100644
index 00000000000..2f5bb6711dc
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/examples/ExampleReferenceWalker/veryspecific.sam
@@ -0,0 +1,5 @@
+@HD VN:1.5 SO:queryname
+@SQ SN:1 LN:400
+@RG ID:0 SM:Hi,Mom! PL:ILLUMINA
+@PG ID:1 VN:2.0 PN:Hey!
+read1 0 1 80 255 10M * 0 10 AAACAAAAAA )))))))))) RG:Z:0
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/NA12878.WGS.b37.chr20.firstMB.vcf.gz b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/NA12878.WGS.b37.chr20.firstMB.vcf.gz
new file mode 100644
index 0000000000000000000000000000000000000000..75d42f79d9ff76348c6ac6c72da360ad770c7d56
GIT binary patch
literal 23749
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
*t^W8^B8DoB
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
zJfU@c32jyLf=z_}FIH)kE(**503VA81ONa4009360763o02=@U00000000000RC3*
AqyPW_
literal 0
HcmV?d00001
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/NA12878.WGS.b37.chr20.firstMB.vcf.gz.tbi b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/NA12878.WGS.b37.chr20.firstMB.vcf.gz.tbi
new file mode 100644
index 0000000000000000000000000000000000000000..19439ace85519a7f8eb4af0c8ccb23cee83de72c
GIT binary patch
literal 570
zcmV-A0>%9wiwFb&00000{{{d;LjnLD0(F$VOO_e32Y~eec5KIP0G+jbWo1kD2QafOdjehR_8%h{4e2{@~6&wWimpSpeZdjig>+pB&ipkMvJ*UY9bR8a4iFE^6s
z)$NsA$qVZC=@#;$y1l%Uyrgb#-a}qix39L7SJdqbIr6HyJ>NkNsN0K&$w77du3qw*
zy8S?rEUMdImdGJ>d)F9wUESV1PTo+rf0`nP)$Nl{$&$ML^DH@{Zr?vg-c+~e7s*j|
zdwGStrEY)wjl8XHul!5iQMbQu_|uW~yXyAVR&q?;-hPlASGRZekY#oIaDlw1ZvQ<(
z-dDGeJ|QR6?S<#$q`H0K1^GbT{^~XPP~ATChMZEj&%YxdsoSR)MRj}iNAj_{9a!qi
z`rhoZ#xLH^cpKyGi?=P_w0N`PO^P=s-jsMV;!TJ}mxFc}~
z;*7@`jx!o(FwR(z>%
literal 0
HcmV?d00001
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/NA12878.chr1_10mb_11mb.slx.indels.vcf b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/NA12878.chr1_10mb_11mb.slx.indels.vcf
new file mode 100644
index 00000000000..69360287875
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/NA12878.chr1_10mb_11mb.slx.indels.vcf
@@ -0,0 +1,5 @@
+##fileformat=VCFv4.0
+#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT NA12878
+1 10075180 . G GAAAAG . PASS . GT 1/0
+1 10093647 . CTCT C . PASS . GT 1/0
+1 10271352 . G GTTTT . PASS . GT 1/0
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/NA12878.chr1_10mb_11mb.slx.indels.vcf.idx b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/NA12878.chr1_10mb_11mb.slx.indels.vcf.idx
new file mode 100644
index 0000000000000000000000000000000000000000..031c0ab17b033faa0cfb1cc814750050908b1c9d
GIT binary patch
literal 2211
zcmb_e%Wm676rG^mbdI-d5+sFo1S?iS(oKFO`)>0K`MTa2
z4g*ftB|w`vzC3g8xet1Cb@}$0G3E!o?~bSTdDAqvecScT>HKu;_syT@?xFu{cW9gY
z-SE)#-Ju!UerUS3KRq~)2x?BF~r5;Lx)?0kNYj+$Ni!|eO?@u
z@zgK=KHQmasyAKn_g}u=rv%dVPVX11<>vNgwSB!>zudgqUayvG!wdK?{>SEWd%1dJ
za1ofmL4@FZj3JOouWTopH_Mx=<@#b(aa{a%yWSW!msb~?=V-_ZIq-xdKngI5a3~RM
zP$H0`Fh*Df5S^vqN5C13An3@K2yZZ;hJX)aL@?+CIeK46qe1K0Tjd=iL;)mZJ$nQY
z46<`fc3cP!N?1fvq@O)S>DHa*QnHaOD$VXM>wu
z2__^53c}jsm#J
zw|B~^zJCw6-Wc@G%Sib0H2@HVg%Xo5(npZIg6cOEbp@4#iW)yBU{sWX7GsVgWYous
zmlK0JOm-g2E}>Q{Ge;ruvd77xQG-o#wa`ly$oyS<=3I)nxJ%mUQ^$r`hD0WwteM*1(Qx-h3K+sbV>|nTyi|kG0^;
z>!jv|lyO9!h9$@9(oj^iCF^Qtlzf~!sry7@5xh#Cr$I@C4w+WJf)j^M7EYr!io+xW
zIRvaag)+Bp5-EG6v{fDso#A@CFmrpvY3q#9luSaed#>^slOL$vT{i~iBelJ!NiUA%
zBhzlG(!rc%AhdH&2vfZ=5J?@KMn_?1YhOp$x>zNT`N$wzjmp7nRS++=-#MMAD{9WI
zdoUdtb=lP`BefGoA6?Bo!MNon>>@~7|xSN$pUp^>*`QaLi%Z$K2F8h
zbfm6tI|*E0YypA?-SpZG+VANbi^lx(v-wG%e$+c%>EDK5^V9$L`%B@QKJotoV;apg
literal 0
HcmV?d00001
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_diff_contig.dict b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_diff_contig.dict
new file mode 100644
index 00000000000..04e1860b9a1
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_diff_contig.dict
@@ -0,0 +1,3 @@
+@HD VN:1.5
+@SQ SN:1 LN:101 M5:8c41aecb370a27de4a5eea543bb5b5a3 UR:file:/Users/louisb/Workspace/gatk/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_diff_contig.fasta
+@SQ SN:2 LN:101 M5:151f2cbc5ef6bcf8dd21284da7f812cf UR:file:/Users/louisb/Workspace/gatk/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_diff_contig.fasta
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_diff_contig.fasta b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_diff_contig.fasta
new file mode 100644
index 00000000000..8d46c3fc964
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_diff_contig.fasta
@@ -0,0 +1,6 @@
+>1 1:10000100
+CTTGGAGGCAGAGGTTGCAGTGAGCTGAGATTGTGACACTGCACTCCAGCCTGGGAGACA
+GAGTGAGACTCCTACTCAAAAAAAAACAAAAAACAAAAAAC
+>2 2:10000201
+TAAAACAGTCAGATCTCATGAGAACTCCCTCACTATCACAAGAACAGCATGGGGGAAACT
+GCCCCCATGATCCAGTCACCTCCCACTAGGTCCCTCCCTCC
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_diff_contig.fasta.fai b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_diff_contig.fasta.fai
new file mode 100644
index 00000000000..2d3913cb646
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_diff_contig.fasta.fai
@@ -0,0 +1,2 @@
+1 101 14 60 61
+2 101 131 60 61
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_same_contig.dict b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_same_contig.dict
new file mode 100644
index 00000000000..0c01bfbaae8
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_same_contig.dict
@@ -0,0 +1,2 @@
+@HD VN:1.5
+@SQ SN:1 LN:202 M5:f2db2997e9aa1590b41c8c93029fc5bc UR:file:/Users/louisb/Workspace/gatk/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_same_contig.fasta
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_same_contig.fasta b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_same_contig.fasta
new file mode 100644
index 00000000000..7bd493f0020
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_same_contig.fasta
@@ -0,0 +1,5 @@
+>1 1:10000100
+CTTGGAGGCAGAGGTTGCAGTGAGCTGAGATTGTGACACTGCACTCCAGCCTGGGAGACA
+GAGTGAGACTCCTACTCAAAAAAAAACAAAAAACAAAAAACAAACCACAAAACTTTCCAG
+GTAACTTATTAAAACATGTTTTTTGTTTGTTTTGAGACAGAGTCTTGCTCTGTCGCCCAG
+GCTGGAGTGCAGTGGAGCAATC
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_same_contig.fasta.fai b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_same_contig.fasta.fai
new file mode 100644
index 00000000000..5d6ec3ffe06
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_alternate_reference_contiguous_same_contig.fasta.fai
@@ -0,0 +1 @@
+1 202 14 60 61
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_no_mask.dict b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_no_mask.dict
new file mode 100644
index 00000000000..716897905d3
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_no_mask.dict
@@ -0,0 +1,2 @@
+@HD VN:1.5
+@SQ SN:1 LN:101 M5:1be373fdf16d12090ef57b251c4f0d7d UR:file:/Users/louisb/Workspace/gatk/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_no_mask.fasta
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_no_mask.fasta b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_no_mask.fasta
new file mode 100644
index 00000000000..bcf491f98f2
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_no_mask.fasta
@@ -0,0 +1,3 @@
+>1 1:10000000
+AACCCCATCTCTACAATAAATGAAAATATTAGCTGGGCATTGTGGTGTGTGCTTGTAGTC
+CCAGCTACTTGGCGGGCTGAGGTGGGAGAATCATCCAAGCC
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_no_mask.fasta.fai b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_no_mask.fasta.fai
new file mode 100644
index 00000000000..33f57fd5d73
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_no_mask.fasta.fai
@@ -0,0 +1 @@
+1 101 14 60 61
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1.dict b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1.dict
new file mode 100644
index 00000000000..1f2450ee883
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1.dict
@@ -0,0 +1,2 @@
+@HD VN:1.5
+@SQ SN:1 LN:101 M5:1be373fdf16d12090ef57b251c4f0d7d UR:file:/Users/louisb/Workspace/gatk/FastaAlternateReferenceMaker/expected_snp1.fasta
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1.fasta b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1.fasta
new file mode 100644
index 00000000000..bcf491f98f2
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1.fasta
@@ -0,0 +1,3 @@
+>1 1:10000000
+AACCCCATCTCTACAATAAATGAAAATATTAGCTGGGCATTGTGGTGTGTGCTTGTAGTC
+CCAGCTACTTGGCGGGCTGAGGTGGGAGAATCATCCAAGCC
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1.fasta.fai b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1.fasta.fai
new file mode 100644
index 00000000000..33f57fd5d73
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1.fasta.fai
@@ -0,0 +1 @@
+1 101 14 60 61
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1_mask2.dict b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1_mask2.dict
new file mode 100644
index 00000000000..831ca1fcc32
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1_mask2.dict
@@ -0,0 +1,2 @@
+@HD VN:1.5
+@SQ SN:1 LN:101 M5:0c62618ad31bc3745ab01e59073a2145 UR:file:/Users/louisb/Workspace/gatk/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1_mask2.fasta
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1_mask2.fasta b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1_mask2.fasta
new file mode 100644
index 00000000000..c71a9576c86
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1_mask2.fasta
@@ -0,0 +1,3 @@
+>1 1:10000000
+AACCCCATCTCTACAATAAATGAAAATATTAGCTGGGCATTGTGGTGTGTGCTTGTAGTC
+CCAGCTACTTGGCGGGNTGAGGTGGGAGAATCATCCAAGCC
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1_mask2.fasta.fai b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1_mask2.fasta.fai
new file mode 100644
index 00000000000..33f57fd5d73
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1_mask2.fasta.fai
@@ -0,0 +1 @@
+1 101 14 60 61
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1_mask2_priority.dict b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1_mask2_priority.dict
new file mode 100644
index 00000000000..98788bc7b2d
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1_mask2_priority.dict
@@ -0,0 +1,2 @@
+@HD VN:1.5
+@SQ SN:1 LN:101 M5:facb25ff6a96440373bf5428abe616a1 UR:file:/Users/louisb/Workspace/gatk/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1_mask2_priority.fasta
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1_mask2_priority.fasta b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1_mask2_priority.fasta
new file mode 100644
index 00000000000..33286c1f1ec
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1_mask2_priority.fasta
@@ -0,0 +1,3 @@
+>1 1:10000000
+AACCCCNTCTCTACAATAAATGAAAATATTAGCTGGGCATNGTGGTGTGTGCTTGTAGTC
+CCAGCTACTTGGCGGGNTGAGGTGGGAGAATCATCCAAGCC
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1_mask2_priority.fasta.fai b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1_mask2_priority.fasta.fai
new file mode 100644
index 00000000000..33f57fd5d73
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp1_mask2_priority.fasta.fai
@@ -0,0 +1 @@
+1 101 14 60 61
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2.dict b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2.dict
new file mode 100644
index 00000000000..c38b58977bc
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2.dict
@@ -0,0 +1,2 @@
+@HD VN:1.5
+@SQ SN:1 LN:101 M5:673f1f9474cd09efedebc64b6644c78f UR:file:/Users/louisb/Workspace/gatk/FastaAlternateReferenceMaker/expected_snp2.fasta
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2.fasta b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2.fasta
new file mode 100644
index 00000000000..8f139e81c75
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2.fasta
@@ -0,0 +1,3 @@
+>1 1:10000000
+AACCCCATCTCTACAATAAATTAAAATATTAGCTGGGCATTGTGGTGTGTGCTTGTAGTC
+CCAGCTACTTGGCGGGATGAGGTGGGAGAATCATCCAAGCC
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2.fasta.fai b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2.fasta.fai
new file mode 100644
index 00000000000..33f57fd5d73
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2.fasta.fai
@@ -0,0 +1 @@
+1 101 14 60 61
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2_mask1.dict b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2_mask1.dict
new file mode 100644
index 00000000000..2558023a0d8
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2_mask1.dict
@@ -0,0 +1,2 @@
+@HD VN:1.5
+@SQ SN:1 LN:101 M5:a4f6c011bf2331baf9c75f1fe1ee2d95 UR:file:/Users/louisb/Workspace/gatk/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2_mask1.fasta
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2_mask1.fasta b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2_mask1.fasta
new file mode 100644
index 00000000000..972d466e3c1
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2_mask1.fasta
@@ -0,0 +1,3 @@
+>1 1:10000000
+AACCCCATCTCTACAATAAATNAAAATATTAGCTGGGCATTGTGGTGTGTGCTTGTAGTC
+CCAGCTACTTGGCGGGATGAGGTGGGAGAATCATCCAAGCC
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2_mask1.fasta.fai b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2_mask1.fasta.fai
new file mode 100644
index 00000000000..33f57fd5d73
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2_mask1.fasta.fai
@@ -0,0 +1 @@
+1 101 14 60 61
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2_mask1_priority.dict b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2_mask1_priority.dict
new file mode 100644
index 00000000000..da43dd7f267
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2_mask1_priority.dict
@@ -0,0 +1,2 @@
+@HD VN:1.5
+@SQ SN:1 LN:101 M5:3f17f93d6a70c11a6a5a31149eb25363 UR:file:/Users/louisb/Workspace/gatk/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2_mask1_priority.fasta
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2_mask1_priority.fasta b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2_mask1_priority.fasta
new file mode 100644
index 00000000000..1e402f88f3e
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2_mask1_priority.fasta
@@ -0,0 +1,3 @@
+>1 1:10000000
+AACCCCNTCTCTACAATAAATNAAAATATTAGCTGGGCATNGTGGTGTGTGCTTGTAGTC
+CCAGCTACTTGGCGGGATGAGGTGGGAGAATCATCCAAGCC
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2_mask1_priority.fasta.fai b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2_mask1_priority.fasta.fai
new file mode 100644
index 00000000000..33f57fd5d73
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp2_mask1_priority.fasta.fai
@@ -0,0 +1 @@
+1 101 14 60 61
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp_mask.dict b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp_mask.dict
new file mode 100644
index 00000000000..8655f943675
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp_mask.dict
@@ -0,0 +1,2 @@
+@HD VN:1.5
+@SQ SN:1 LN:101 M5:706b03a33b4a74ba44953ebb62c56e29 UR:file:/Users/louisb/Workspace/gatk/FastaAlternateReferenceMaker/expected_snp_mask.fasta
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp_mask.fasta b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp_mask.fasta
new file mode 100644
index 00000000000..a8dd0f991b1
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp_mask.fasta
@@ -0,0 +1,3 @@
+>1 1:10000000
+AACCCCATCTCTACAATAAATGAAAATATTAGCTGGGCATGGTGGTGTGTGCTTGTAGTC
+CCAGCTACTTGGCGGGCTGAGGTGGGAGAATCATCCAAGCC
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp_mask.fasta.fai b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp_mask.fasta.fai
new file mode 100644
index 00000000000..33f57fd5d73
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snp_mask.fasta.fai
@@ -0,0 +1 @@
+1 101 14 60 61
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels.dict b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels.dict
new file mode 100644
index 00000000000..db49ef33e2a
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels.dict
@@ -0,0 +1,2 @@
+@HD VN:1.5
+@SQ SN:1 LN:95 M5:fbfd08abb257112c4e8a349d1c0bf3f7 UR:file:/Users/louisb/Workspace/gatk/FastaAlternateReferenceMaker/expected_snpsAndIndels.fasta
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels.fasta b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels.fasta
new file mode 100644
index 00000000000..f47f27ce109
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels.fasta
@@ -0,0 +1,3 @@
+>1 1:10000000
+AACCCCATCTCTACAATAAATGAAAAAGCTGGGCATTGTGGTGTGTGCATAGTCCCAGCT
+ACTTGGCGGGCTGAGGTGGGAGAATCATCCAAGCC
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels.fasta.fai b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels.fasta.fai
new file mode 100644
index 00000000000..733c0cdda37
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels.fasta.fai
@@ -0,0 +1 @@
+1 95 14 60 61
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask1.dict b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask1.dict
new file mode 100644
index 00000000000..b5d87fff927
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask1.dict
@@ -0,0 +1,2 @@
+@HD VN:1.5
+@SQ SN:1 LN:95 M5:fbfd08abb257112c4e8a349d1c0bf3f7 UR:file:/Users/louisb/Workspace/gatk/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask1.fasta
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask1.fasta b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask1.fasta
new file mode 100644
index 00000000000..f47f27ce109
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask1.fasta
@@ -0,0 +1,3 @@
+>1 1:10000000
+AACCCCATCTCTACAATAAATGAAAAAGCTGGGCATTGTGGTGTGTGCATAGTCCCAGCT
+ACTTGGCGGGCTGAGGTGGGAGAATCATCCAAGCC
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask1.fasta.fai b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask1.fasta.fai
new file mode 100644
index 00000000000..733c0cdda37
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask1.fasta.fai
@@ -0,0 +1 @@
+1 95 14 60 61
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask1_priority.dict b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask1_priority.dict
new file mode 100644
index 00000000000..eb92c48fcc4
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask1_priority.dict
@@ -0,0 +1,2 @@
+@HD VN:1.5
+@SQ SN:1 LN:95 M5:fc6ceea2cd802bc8deca9d24da9505a6 UR:file:/Users/louisb/Workspace/gatk/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask1_priority.fasta
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask1_priority.fasta b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask1_priority.fasta
new file mode 100644
index 00000000000..3ef8b741176
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask1_priority.fasta
@@ -0,0 +1,3 @@
+>1 1:10000000
+AACCCCNTCTCTACAATAAATNAAAAAGCTGGGCATNGTGGTGTGTGCATAGTCCCAGCT
+ACTTGGCGGGCTGAGGTGGGAGAATCATCCAAGCC
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask1_priority.fasta.fai b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask1_priority.fasta.fai
new file mode 100644
index 00000000000..733c0cdda37
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask1_priority.fasta.fai
@@ -0,0 +1 @@
+1 95 14 60 61
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask2.fasta b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask2.fasta
new file mode 100644
index 00000000000..812e31afff6
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_mask2.fasta
@@ -0,0 +1,3 @@
+>1 1:10000000
+AACCCCATCTCTACAATAAATGAAAAAGCTGGGCATTGTGGTGTGTGCATAGTCCCAGCT
+ACTTGGCGGGNTGAGGTGGGAGAATCATCCAAGCC
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_maskOverlaps.dict b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_maskOverlaps.dict
new file mode 100644
index 00000000000..4e7ac5efc73
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_maskOverlaps.dict
@@ -0,0 +1,2 @@
+@HD VN:1.5
+@SQ SN:1 LN:95 M5:cc9e3cd4a56921da39ccb38260350580 UR:file:/Users/louisb/Workspace/gatk/FastaAlternateReferenceMaker/expected_snpsAndIndels_maskOverlaps.fasta
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_maskOverlaps.fasta b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_maskOverlaps.fasta
new file mode 100644
index 00000000000..637d65531b7
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_maskOverlaps.fasta
@@ -0,0 +1,3 @@
+>1 1:10000000
+AACCCCATCTCTACAATAAATGAAAAAGCTGGGCATTGTGGTGTGTGNATAGTCCCAGCT
+ACTTGGCGGGCTGAGGTGGGAGAATCATCCAAGCC
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_maskOverlaps.fasta.fai b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_maskOverlaps.fasta.fai
new file mode 100644
index 00000000000..733c0cdda37
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_maskOverlaps.fasta.fai
@@ -0,0 +1 @@
+1 95 14 60 61
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_maskOverlaps_priority.dict b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_maskOverlaps_priority.dict
new file mode 100644
index 00000000000..112c5d91614
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_maskOverlaps_priority.dict
@@ -0,0 +1,2 @@
+@HD VN:1.5
+@SQ SN:1 LN:99 M5:b0c42fcbbea5cc1987b3352d66642ca0 UR:file:/Users/louisb/Workspace/gatk/FastaAlternateReferenceMaker/expected_snpsAndIndels_maskOverlaps_priority.fasta
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_maskOverlaps_priority.fasta b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_maskOverlaps_priority.fasta
new file mode 100644
index 00000000000..68c5123abf0
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_maskOverlaps_priority.fasta
@@ -0,0 +1,3 @@
+>1 1:10000000
+AACCCCATCTCTACAATAAATGAAANNATTAGCTGGGCATTGTGGTGTGTGNNTAGTCCC
+AGCTACTTGGCGGGCTGAGGTGGGAGAATCATCCAAGCC
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_maskOverlaps_priority.fasta.fai b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_maskOverlaps_priority.fasta.fai
new file mode 100644
index 00000000000..939f7b8e704
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_snpsAndIndels_maskOverlaps_priority.fasta.fai
@@ -0,0 +1 @@
+1 99 14 60 61
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_test_iupac.dict b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_test_iupac.dict
new file mode 100644
index 00000000000..b058e0e17c6
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_test_iupac.dict
@@ -0,0 +1,2 @@
+@HD VN:1.5
+@SQ SN:1 LN:5331 M5:f09cbb7d1d84301472b166f3ebb93809 UR:file:/Users/louisb/Workspace/gatk/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_test_iupac.fasta
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_test_iupac.fasta b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_test_iupac.fasta
new file mode 100644
index 00000000000..d2c5182ab75
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_test_iupac.fasta
@@ -0,0 +1,90 @@
+>1 20:61050
+CAGATATACTTCACAGCCCACGCTGACTCTGCCAAGCACAGACAACCAYTGGGCCCCAGG
+GGAGCTGCAGGTCTCCTGGTCACCTAATCTTTTTTTTTTTTATACTTTAAGTTTTGGGGT
+ACATGTGCACAACGTGCAGGTTACATATGTATACATGTGCCATGTTCATGTGCTGCACCC
+ATTAACTCGTCATTTAACATTAGGTATATCTCCTAATGCTATCCCTCCCCCCTCCCCCCA
+CCCCACAACAGGCCCTGGTGCCATGGAATACTATGCAGCCATAAAAAATGATGAGTTCAT
+GCCCTTTGCAGGGACATGGATGAAGCTGGAAACCATCATTCTCAGCAAACTATCAAACTA
+TCACAAGGACAAAAAACCAAACACTGCATGTTTTCACTCATAGGTGGGAATTGAATAATG
+AGAACACATGGACACAGGAAGGGGAACATCACACATCGGGACCTAATCTTAAGCTAAGTG
+TGGCTAAGAGCCTATCTGCTGGCCTTTACTATTAAGCACTGCCCACTGGATTGCAGCCTG
+AATTACACCGCCAAACAAATACTGTTTCAGCATACATTACCAGTGAAACCCAATGCAGGA
+ACATAGTCAAAAATAAACACCTGGCATAGAGACTTGGCCCTCTGAAAACACCCAGAAAAA
+AGCCAGCTATATTCAACATACATCACTGTCAAAATATCAAGGAAAATGAAGAAGAATAAA
+ACAAAAAGTCAAAACCAAATGATAGGAACTTCAAAAAGATAAAGTAACACCAGCTGTCTT
+AGATGAGAAAGAATCAGCACACATTCTTGCAATTCAAAAAGTCAGAATGTCTCCTTACCT
+CCAAACAATCATACTAGCTCTCATCAGATTGAAATGGCTGAAATGACAGACATAGAATTC
+ATGATCTGGAAGGTAAGGAAGCTCAAGAACATTCAGGAGAAAGTTGAAACCCAGTCCAAG
+GAAGCCAGTAAAGCAATCCAAGAGTACAGAGATAACATAGCCATTTTAAGAAAGAACCAA
+AAGAAACTTCTGCAATTGACAAATTCATTATAGGAATTTTGTAATACATTCAGAAGCATT
+AACAACAGAATAGATCAAGTTGAGGAAAGAATCTCAGAGCTCAAAGATCAGTCCTTTGAA
+TCAACACAGTCAGACAAAACTAAAGAAAAAAATTTAAAAATAAAACCTCTAAAAAAATAT
+GGAATTATGTAAAGATACCAAACTTACAACTTATGGGCATTCCTGAAAGAGGAGAAAGAA
+TAAGTAACTTGGAAAACATATTTGAGGATAGTCCATGAAAATTTCCCCAATCTCCCTAGA
+GAGGCTGACATGCAAATTCAAGAAATGCAAATAACCCCTGTGAGATAACTACAAGATAAC
+TATCCCCAAGACACATAGTCATAAGATTCTCCAAGGTCAACGTGAAAGAAAAAAATCTTA
+AGGGCAGCTAGAGAAAAGCCTGAGGTCACTTATGAAGGGAAGCTCATCAGACTAACAGCA
+GACTTCTCAGCAGAAACCTTACAAACCAAGCAAGATTAGGGGCCTATTTTTAGCATCCTT
+AAAGAAAAGAAATTTCAGTGAAGAATTCCATATCCTGCAAAACTAAGCTTCATAAAAGAA
+GGAGAAATAGGCTGGGCATGGTGGCTCACACCTGTAATACCAGCATTTTGGGAGGCTCAG
+GCAGGAGGATTGCTTGAGCTCAAGAGTTTGAGACCAGCCTGGGCAACATGGCAAAACCCT
+GTCTCTTCTAAAAATACAAAAATTACCTGGGCAAGACTCCATCACAAACAAACTAACAAA
+CCAAAACTATCAGGTACTATGCTCACTACCTGGGTGACAAAATCATTTTTACACCAAACC
+CAGTGACAAGCAATTTACCCATGTAACAAACCTGCATGTGTATCCCCTGAACCTAAAATA
+AAAGTTAAAAAAAAAAGAACTTTCATCAACATTTCTTGCAGTGAAGGTATGTTAGTGATG
+AACATTCTCTGCTTTTATTGCCTGAAAATATCTTTATTTTGTATTCATATTTGACATATA
+TTCTCACTGGGCATAAAAATTCTAAATTACAAGTTTTTCCCCTTTTTTGTATTAAAAATT
+TCATTCCAATATCTTTCATATTGCCTTATTTGTAATGATGCCTTCTATCCTTCTTATCTT
+TGTTCCATTTATAAGAAGTGTTCCCCAACCCCAGMCTGATTAAAACCATTTTTTTAATTA
+AAAAAGCAAAAGAAAGAAACATTTTTATCTGAAGCTGTCTCAGACTCAGACACCACCCAA
+TCTTCAGATTTCAAATAGCTTATACTCAAACATTTGGTAATATCAGCCCCTTAATGGTCT
+TCCTGGAGGGCAGATGCATTCTAGAGATGAGAACACGATCATGATTACGAATGCTACCAC
+CACTACGAACGCACAAAAGTCACTGGTGTGATCCTTTCTCAGAACACTGTGGTAACTTCT
+GGACATTCTCTGCTGTTATCATTGCTTCTTCCTTCTGGGTTTTTTTCCCCCTTATATGGG
+CAGATAATTTTCTCCATTGGAATGAAAAAGTCTTGCTTCATGCTCTTTAACTGTGTGACC
+TTGGGCGTATTACTTTACTTTGGGGCAAACCATTTTCCTTCTTGAGGACCAAATGTGCTC
+TTTTATAAAACGAGCAGTTAGAATTAGATTGTCTCTCTGGACACGGCTTATGTTGACAAC
+CTGGATCACATTAGAGGATCACACTGAGACCTTTATGTCGGCCTCAGTTCCTCCATCTGT
+AAAGTAGAGGTTGGGCTTAGATTATAGATGATAAAGACACCAACTTTCCTGGAAAGGATT
+CTGGAAAGGATTCTGAACTTAGGCTCAGCCTCAGTAAGAAGGAGTTCTGTGATTAAACAG
+GGATGCCCACACATCAGCAACAGAAATGGGCAGGTCAACCATGTATGCTGTGCCTCAGTG
+AAGATTTTATGCTATGCTGTGCATTTGATATCCATTCTCTATATTTGATATCCAATCTAA
+GATTATCTAGAAGGTCCTTTCCAAGACACTGATGAGATACATCTGTATAAATATATAACT
+CAGGATGAAAGCAACTTTTAACATTTAGCGTGTGCCTCTGCCTCTGATCTGATTACAGCC
+CACAGAGAAATATAAACAATACACAATACAGGCTAATGAAGAAGGGTGATAAGATTTTTT
+TTTTTTTTTGAGACGGAATTTCACTCTTGTCACCCAGGCTGGAGTGCAATGGTGCAATCT
+TGGCTCACTGCAACCTTCGCCTCCCGGTTCAAGCGATTCTCCTGCCTCAGCCTCCTGAGT
+AGATGGGATTGGAGGTGCCCACCACCACGCCCGGCTAATTTTTGTATTTTTTAGTAGAGA
+CAGGGTTTCACCATGTTGTCCACGCTGGTCTCGAACTCCTGACCTCAGGTGATCCGCCAG
+CCTCAGCCTCCCAAAGTGCTAGGATTACAGGTGTGAGCCACTGCAACCGGCCAAGGGTGA
+TAAGATTTTAAAAATTTATTTAAAATACAGAAATTTCAAAAAGAGAGAAGTGCAGTGATA
+GCAAAATTGATGCAAACTGTGCAAGCATGAAATCTATTTTATAGCTGAATCTACTTTTCT
+TGGTCCCAAGATTCTATTTCCATTGGTTTTCAAATAGTTAATTCTATTGTTTTTTCAGGG
+AGATTACTAAAATCACTAATAATTATTTTCCTACTGACACAAAATCTAAAAAGCACCATA
+TAGACCTTCTCTCTCCATCTCCCCTTATCCTTATGTCACCTTACCCTACCCCAATACTCC
+AATGGCAGAGTATCTACCCATGGCAGAGTAGAGAATATGTACACTAACAAAACCAGATGC
+ACAGAGGTGGGGTATCCATCTCTGACTTGGCTGAGCTAGTCTAAGGAAGGAAGGCTCTGT
+GGCCATTGTCCTTGGAAGTCATTCTCACAGGTTGGTGGTATTCTCAAGTAGGTGGTGCTT
+GAGTGGCCCAAGAGCACCCACATGCTGCTATGCATTTTTCTGACAACCTCTTTATGATCT
+CTGACTTTGGCAGATCATCTTGCATCTCTCAATTGGAGAGTCACTTTTCTTATCTCCACA
+GAAAATTCTTAATCAAGCTCCTGGTTTTCCTTTATAGCTTCTACTTTTTAAACTCACTTC
+TCCAACTTCACCGCTACATCTCTGACAGATGAGAACATTAGAGATTCCCTGTTTTTCAAA
+AACAAAACAAAACTCAGCAAAACTATAAATATACTAAGGGTAAGTCTGTATTATCTCCTG
+CCAAAATACACCACCCTGCATTTTTTTAAATTTTTATCTTTTGTAGGTACATAGTAGGTG
+TCTATATTTGTGGGGTACATGAGATGTTTTGATACAAGCATGCAATGCATAATAACCACA
+TCATGGAAAATGGGGTATCCATCCCCTCAAGCATTTATCCTTTGTGTTACAAATTATCTA
+ATTATACTTTATTATTTTAAAATGTACAATTAAATTATTTTTGACTATAGTCACCTCGTT
+ATGCTATTAAATACCAGGTCTTATTCATTCTTTCTAACTATTTTTTGTACCCAGTAACCA
+TCCTCACCTTCCCACACACGCCCACCACCTTTCCCAGCCTCTGATAACCATCCTTCTACT
+CTCTATCTCCCTTGAATTCAGTAGTTTTGATTTTTAGATTTCACAAATAAGTGAGAACAT
+GCAATATTTGTCTTTATGTTCCTGGCTTATTTCACTTAGCATAATGGCCTCCAGTTCCAT
+CCATGTTATTGCAAATGACAGCATCTCTTTCTTTTTTATGGCTGAATAATACTCCACTGT
+GTATAAGTTCCACATTTTCTTTATCCACTCATTTGTTGATTGACACTTACRTTGCTTCTA
+AATCTTGGCTATTGTGAATAGTGCTGCAACAAGCACAGGTGTGCAGATATCTATTCAATA
+TTCTTATTTCCTTTTGGAGGGGAGTGTGTACCTAGCAGTGGGATTGCTGGATTGTATGGT
+AACTCTATTTTCAGTTTTTTTAGGAACCTCCAAACTGTTCTCCATAGTGGTTGTACTATC
+TTACGTTCACACCAGTAGCATACAAGGGTTTCCCTTTCTCCAAATCCTTGCCAGCATTTG
+CTATTGCCTGTCTTTTGGATAAAAGCCATTTTAACTGGAGTGAGATGATATTCCATTGTA
+GCTTGATTTTCATTTCTCTGATGATCAGTGATTTTGAGCACCTTTTCATCTGCCTGTTTG
+CCATTTGTATGTCTTCTTTTGAGAATATCTATTCAGATACTTTGCCCATTTTTAAGTTGG
+ATCATTAGATTTTTTTCCTATAGAATTGTTTGAGCTCTTTRTATTTCCTGT
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_test_iupac.fasta.fai b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_test_iupac.fasta.fai
new file mode 100644
index 00000000000..72a4546698e
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/expected_test_iupac.fasta.fai
@@ -0,0 +1 @@
+1 5331 12 60 61
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA1.dict b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA1.dict
new file mode 100644
index 00000000000..644c9d969c4
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA1.dict
@@ -0,0 +1,2 @@
+@HD VN:1.5
+@SQ SN:1 LN:1 M5:b9ece18c950afbfa6b0fdbfa4ff731d3 UR:file:/Users/louisb/Workspace/gatk/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA1.fasta
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA1.fasta b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA1.fasta
new file mode 100644
index 00000000000..61763682496
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA1.fasta
@@ -0,0 +1,2 @@
+>1 1:1273247
+T
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA1.fasta.fai b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA1.fasta.fai
new file mode 100644
index 00000000000..83f731e8ace
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA1.fasta.fai
@@ -0,0 +1 @@
+1 1 13 1 2
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA2.dict b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA2.dict
new file mode 100644
index 00000000000..530deb275ac
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA2.dict
@@ -0,0 +1 @@
+@HD VN:1.5
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA2.fasta b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA2.fasta
new file mode 100644
index 00000000000..4e82c549e59
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA2.fasta
@@ -0,0 +1,2 @@
+>1 1:1273247
+
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA2.fasta.fai b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA2.fasta.fai
new file mode 100644
index 00000000000..3eac6fe3a19
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA2.fasta.fai
@@ -0,0 +1 @@
+1 0 13 0 2
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA3.dict b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA3.dict
new file mode 100644
index 00000000000..cfd70b1ee54
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA3.dict
@@ -0,0 +1,2 @@
+@HD VN:1.5
+@SQ SN:1 LN:1 M5:dfcf28d0734569a6a693bc8194de62bf UR:file:/Users/louisb/Workspace/gatk/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA3.fasta
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA3.fasta b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA3.fasta
new file mode 100644
index 00000000000..3b18766eea4
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA3.fasta
@@ -0,0 +1,2 @@
+>1 1:1273247
+G
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA3.fasta.fai b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA3.fasta.fai
new file mode 100644
index 00000000000..83f731e8ace
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/iupac_sample_NA3.fasta.fai
@@ -0,0 +1 @@
+1 1 13 1 2
diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/overlapsIndelsMask.vcf b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/overlapsIndelsMask.vcf
new file mode 100644
index 00000000000..8d568434c3d
--- /dev/null
+++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/fasta/FastaAlternateReferenceMaker/overlapsIndelsMask.vcf
@@ -0,0 +1,164 @@
+##fileformat=VCFv4.2
+##FILTER=
+##GATKCommandLine.SelectVariants=
+##GATKCommandLine=
+##GATKCommandLine=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO== 1% and for which 2 or more founders contribute to that minor allele frequency.">
+##INFO=
+##INFO=
+##INFO=5% minor allele frequency in 1+ populations">
+##INFO=5% minor allele frequency in each and all populations">
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=
+##INFO=