diff --git a/src/main/java/org/broadinstitute/hellbender/tools/sv/SVCallRecord.java b/src/main/java/org/broadinstitute/hellbender/tools/sv/SVCallRecord.java index 0dd65d47b67..8df33f96136 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/sv/SVCallRecord.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/sv/SVCallRecord.java @@ -1,6 +1,8 @@ package org.broadinstitute.hellbender.tools.sv; import com.google.common.collect.Lists; +import htsjdk.samtools.SAMSequenceDictionary; +import htsjdk.samtools.SAMSequenceRecord; import htsjdk.samtools.util.CoordMath; import htsjdk.variant.variantcontext.Allele; import htsjdk.variant.variantcontext.Genotype; @@ -9,6 +11,7 @@ import htsjdk.variant.vcf.VCFConstants; import org.apache.commons.lang3.tuple.Pair; import org.broadinstitute.hellbender.tools.spark.sv.utils.GATKSVVCFConstants; +import org.broadinstitute.hellbender.utils.IntervalUtils; import org.broadinstitute.hellbender.utils.SimpleInterval; import org.broadinstitute.hellbender.utils.Utils; import org.broadinstitute.hellbender.utils.variant.VariantContextGetters; @@ -62,10 +65,26 @@ public SVCallRecord(final String id, final List algorithms, final List alleles, final List genotypes, - final Map attributes) { + final Map attributes, + final SAMSequenceDictionary dictionary) { + this(id, contigA, positionA, strandA, contigB, positionB, strandB, type, length, algorithms, alleles, genotypes, attributes); + validateCoordinates(dictionary); + } + + protected SVCallRecord(final String id, + final String contigA, + final int positionA, + final Boolean strandA, + final String contigB, + final int positionB, + final Boolean strandB, + final StructuralVariantType type, + final Integer length, + final List algorithms, + final List alleles, + final List genotypes, + final Map attributes) { Utils.nonNull(id); - Utils.nonNull(contigA); - Utils.nonNull(contigB); Utils.nonNull(type); Utils.nonNull(algorithms); Utils.nonNull(alleles); @@ -91,19 +110,40 @@ public SVCallRecord(final String id, this.strandB = strands.getRight(); } - public SVCallRecord(final String id, - final String contigA, - final int positionA, + /** + * Convenience constructor without extra attributes + */ + public SVCallRecord(final SVCallRecord baseRecord, + final String id, final Boolean strandA, - final String contigB, - final int positionB, final Boolean strandB, final StructuralVariantType type, final Integer length, final List algorithms, final List alleles, - final List genotypes) { - this(id, contigA, positionA, strandA, contigB, positionB, strandB, type, length, algorithms, alleles, genotypes, Collections.emptyMap()); + final List genotypes, + final Map attributes) { + this(id, baseRecord.getContigA(), baseRecord.getPositionA(), strandA, baseRecord.getContigB(), + baseRecord.getPositionB(), strandB, type, length, algorithms, alleles, genotypes, attributes); + } + + /** + * Ensures start/end loci are valid and ordered + */ + private void validateCoordinates(final SAMSequenceDictionary dictionary) { + Utils.nonNull(contigA); + Utils.nonNull(contigB); + Utils.nonNull(dictionary); + validatePosition(contigA, positionA, dictionary); + validatePosition(contigB, positionB, dictionary); + Utils.validateArg(IntervalUtils.compareLocatables(getPositionAInterval(), getPositionBInterval(), dictionary) <= 0, + "End coordinate cannot precede start"); + } + + private static void validatePosition(final String contig, final int position, final SAMSequenceDictionary dictionary) { + final SAMSequenceRecord seq = dictionary.getSequence(contig); + Utils.validateArg(seq != null, "Contig " + contig + " not found in dictionary"); + Utils.validateArg(position > 0 && position <= seq.getSequenceLength(), "Invalid position " + contig + ":" + position); } private static Map validateAttributes(final Map attributes) { diff --git a/src/main/java/org/broadinstitute/hellbender/tools/sv/SVCallRecordUtils.java b/src/main/java/org/broadinstitute/hellbender/tools/sv/SVCallRecordUtils.java index 57f2108f0d3..f4ce37acbdc 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/sv/SVCallRecordUtils.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/sv/SVCallRecordUtils.java @@ -238,17 +238,17 @@ public static int compareCalls(final SVCallRecord first, final SVCallRecord seco * @param record inversion record * @return stream of BND records pair, or the original record if not an INV */ - public static Stream convertInversionsToBreakends(final SVCallRecord record) { + public static Stream convertInversionsToBreakends(final SVCallRecord record, final SAMSequenceDictionary dictionary) { if (!record.getType().equals(StructuralVariantType.INV)) { return Stream.of(record); } Utils.validateArg(record.isIntrachromosomal(), "Inversion " + record.getId() + " is not intrachromosomal"); final SVCallRecord positiveBreakend = new SVCallRecord(record.getId(), record.getContigA(), record.getPositionA(), true, record.getContigB(), record.getPositionB(), true, StructuralVariantType.BND, null, - record.getAlgorithms(), record.getAlleles(), record.getGenotypes(), record.getAttributes()); + record.getAlgorithms(), record.getAlleles(), record.getGenotypes(), record.getAttributes(), dictionary); final SVCallRecord negativeBreakend = new SVCallRecord(record.getId(), record.getContigA(), record.getPositionA(), false, record.getContigB(), record.getPositionB(), false, StructuralVariantType.BND, null, - record.getAlgorithms(), record.getAlleles(), record.getGenotypes(), record.getAttributes()); + record.getAlgorithms(), record.getAlleles(), record.getGenotypes(), record.getAttributes(), dictionary); return Stream.of(positiveBreakend, negativeBreakend); } diff --git a/src/main/java/org/broadinstitute/hellbender/tools/sv/SVCallRecordWithEvidence.java b/src/main/java/org/broadinstitute/hellbender/tools/sv/SVCallRecordWithEvidence.java deleted file mode 100644 index c35b0de3e5f..00000000000 --- a/src/main/java/org/broadinstitute/hellbender/tools/sv/SVCallRecordWithEvidence.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.broadinstitute.hellbender.tools.sv; - -import htsjdk.variant.variantcontext.Allele; -import htsjdk.variant.variantcontext.Genotype; -import htsjdk.variant.variantcontext.StructuralVariantType; -import org.broadinstitute.hellbender.tools.copynumber.formats.records.CopyNumberPosteriorDistribution; -import org.broadinstitute.hellbender.utils.Utils; - -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -public class SVCallRecordWithEvidence extends SVCallRecord { - - private final List startSplitReadSites; - private final List endSplitReadSites; - private final List discordantPairs; - private final CopyNumberPosteriorDistribution copyNumberDistribution; - - public SVCallRecordWithEvidence(final SVCallRecord record) { - this(record, Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), null); - } - - public SVCallRecordWithEvidence(final SVCallRecord record, - final List startSplitReadSites, - final List endSplitReadSites, - final List discordantPairs, - final CopyNumberPosteriorDistribution copyNumberDistribution) { - this(record.getId(), record.getContigA(), record.getPositionA(), record.getStrandA(), record.getContigB(), - record.getPositionB(), record.getStrandB(), record.getType(), record.getLength(), record.getAlgorithms(), - record.getAlleles(), record.getGenotypes(), record.getAttributes(), startSplitReadSites, endSplitReadSites, - discordantPairs, copyNumberDistribution); - } - - public SVCallRecordWithEvidence(final String id, - final String startContig, - final int position1, - final boolean strand1, - final String contig2, - final int position2, - final boolean strand2, - final StructuralVariantType type, - final int length, - final List algorithms, - final List alleles, - final List genotypes, - final Map attributes, - final List startSplitReadSites, - final List endSplitReadSites, - final List discordantPairs, - final CopyNumberPosteriorDistribution copyNumberDistribution) { - super(id, startContig, position1, strand1, contig2, position2, strand2, type, length, algorithms, alleles, genotypes, attributes); - Utils.nonNull(startSplitReadSites); - Utils.nonNull(endSplitReadSites); - Utils.nonNull(discordantPairs); - this.startSplitReadSites = Collections.unmodifiableList(startSplitReadSites); - this.endSplitReadSites = Collections.unmodifiableList(endSplitReadSites); - this.discordantPairs = Collections.unmodifiableList(discordantPairs); - this.copyNumberDistribution = copyNumberDistribution; - } - - public List getDiscordantPairs() { - return discordantPairs; - } - - public List getStartSplitReadSites() { - return startSplitReadSites; - } - - public List getEndSplitReadSites() { - return endSplitReadSites; - } - - public CopyNumberPosteriorDistribution getCopyNumberDistribution() { return copyNumberDistribution; } - - @Override - public boolean equals(final Object obj) { - if (!super.equals(obj)) { - return false; - } - if (this.getClass() != obj.getClass()) { - return false; - } - final SVCallRecordWithEvidence b = (SVCallRecordWithEvidence)obj; - boolean areEqual = this.getDiscordantPairs().containsAll(b.getDiscordantPairs()); - areEqual &= b.getDiscordantPairs().containsAll(this.getDiscordantPairs()); - areEqual &= this.getEndSplitReadSites().containsAll(b.getEndSplitReadSites()); - areEqual &= b.getEndSplitReadSites().containsAll(this.getEndSplitReadSites()); - areEqual &= this.getStartSplitReadSites().containsAll(b.getStartSplitReadSites()); - areEqual &= b.getStartSplitReadSites().containsAll(this.getStartSplitReadSites()); - areEqual &= b.getCopyNumberDistribution() == this.getCopyNumberDistribution() - || (this.getCopyNumberDistribution() != null && this.getCopyNumberDistribution().equals(b.getCopyNumberDistribution())); - return areEqual; - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), discordantPairs, endSplitReadSites, startSplitReadSites, copyNumberDistribution); - } - -} diff --git a/src/main/java/org/broadinstitute/hellbender/tools/sv/cluster/CNVLinkage.java b/src/main/java/org/broadinstitute/hellbender/tools/sv/cluster/CNVLinkage.java index 978878e3e0d..4f72bd36b4c 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/sv/cluster/CNVLinkage.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/sv/cluster/CNVLinkage.java @@ -49,8 +49,14 @@ public boolean areClusterable(final SVCallRecord a, final SVCallRecord b) { if (a.getType() != b.getType()) return false; // Interval overlap - if (!getPaddedRecordInterval(a.getContigA(), a.getPositionA(), a.getPositionB()) - .overlaps(getPaddedRecordInterval(b.getContigA(), b.getPositionA(), b.getPositionB()))) return false; + // Positions should be validated already by the SVCallRecord class - these checks are for thoroughness + final SimpleInterval intervalA = getPaddedRecordInterval(a.getContigA(), a.getPositionA(), a.getPositionB()); + Utils.nonNull(intervalA, "Invalid interval " + new SimpleInterval(a.getContigA(), a.getPositionA(), + a.getPositionB()) + " for record " + a.getId()); + final SimpleInterval intervalB = getPaddedRecordInterval(b.getContigA(), b.getPositionA(), b.getPositionB()); + Utils.nonNull(intervalB, "Invalid interval " + new SimpleInterval(b.getContigA(), b.getPositionA(), + b.getPositionB()) + " for record " + b.getId()); + if (!intervalA.overlaps(intervalB)) return false; // Sample overlap if (!hasSampleOverlap(a, b, minSampleOverlap)) { diff --git a/src/main/java/org/broadinstitute/hellbender/tools/sv/cluster/CanonicalSVCollapser.java b/src/main/java/org/broadinstitute/hellbender/tools/sv/cluster/CanonicalSVCollapser.java index 16cde33b2a2..be1af87ca5a 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/sv/cluster/CanonicalSVCollapser.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/sv/cluster/CanonicalSVCollapser.java @@ -2,6 +2,7 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Sets; +import htsjdk.samtools.SAMSequenceDictionary; import htsjdk.samtools.reference.ReferenceSequenceFile; import htsjdk.variant.variantcontext.*; import org.apache.commons.lang3.tuple.Pair; @@ -93,6 +94,7 @@ public enum InsertionLengthSummaryStrategy { private final BreakpointSummaryStrategy breakpointSummaryStrategy; private final InsertionLengthSummaryStrategy insertionLengthSummaryStrategy; private final ReferenceSequenceFile reference; + private final SAMSequenceDictionary dictionary; private static final AlleleCollectionCollapserComparator ALLELE_COMPARATOR = new AlleleCollectionCollapserComparator(); @@ -101,6 +103,7 @@ public CanonicalSVCollapser(final ReferenceSequenceFile reference, final BreakpointSummaryStrategy breakpointSummaryStrategy, final InsertionLengthSummaryStrategy insertionLengthSummaryStrategy) { this.reference = Utils.nonNull(reference); + this.dictionary = reference.getSequenceDictionary(); this.altAlleleSummaryStrategy = altAlleleSummaryStrategy; this.breakpointSummaryStrategy = breakpointSummaryStrategy; this.insertionLengthSummaryStrategy = insertionLengthSummaryStrategy; @@ -135,7 +138,7 @@ public SVCallRecord collapse(final Collection items) { final List harmonizedGenotypes = harmonizeAltAlleles(altAlleles, genotypes); return new SVCallRecord(id, exampleCall.getContigA(), start, exampleCall.getStrandA(), exampleCall.getContigB(), - end, exampleCall.getStrandB(), type, length, algorithms, alleles, harmonizedGenotypes, attributes); + end, exampleCall.getStrandB(), type, length, algorithms, alleles, harmonizedGenotypes, attributes, dictionary); } /** @@ -807,9 +810,12 @@ protected Pair collapseInterval(final Collection if (exampleCall.getType().equals(StructuralVariantType.INS)) { // Insertions are a single locus return Pair.of(newStart, newStart); - } else { + } else if (exampleCall.getContigA().equals(exampleCall.getContigB())) { // Do not let end precede start - return Pair.of(newStart, Math.max(newEnd, newStart)); + return Pair.of(newStart, Math.max(newStart, newEnd)); + } else { + // Different contigs, so no constraint on position order + return Pair.of(newStart, newEnd); } } diff --git a/src/main/java/org/broadinstitute/hellbender/tools/sv/cluster/CanonicalSVLinkage.java b/src/main/java/org/broadinstitute/hellbender/tools/sv/cluster/CanonicalSVLinkage.java index 2d2e658693e..20814cbeb2d 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/sv/cluster/CanonicalSVLinkage.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/sv/cluster/CanonicalSVLinkage.java @@ -136,6 +136,8 @@ private static boolean clusterTogetherWithParams(final SVCallRecord a, final SVC // Breakend proximity final SimpleInterval intervalA1 = a.getPositionAInterval().expandWithinContig(params.getWindow(), dictionary); final SimpleInterval intervalA2 = a.getPositionBInterval().expandWithinContig(params.getWindow(), dictionary); + Utils.nonNull(intervalA1, "Invalid start position " + a.getPositionA() + " in record " + a.getId()); + Utils.nonNull(intervalA2, "Invalid end position " + a.getPositionB() + " in record " + a.getId()); final SimpleInterval intervalB1 = b.getPositionAInterval(); final SimpleInterval intervalB2 = b.getPositionBInterval(); if (!(intervalA1.overlaps(intervalB1) && intervalA2.overlaps(intervalB2))) { diff --git a/src/main/java/org/broadinstitute/hellbender/tools/walkers/sv/SVCluster.java b/src/main/java/org/broadinstitute/hellbender/tools/walkers/sv/SVCluster.java index 602d296528c..f2f1b242324 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/walkers/sv/SVCluster.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/walkers/sv/SVCluster.java @@ -405,7 +405,7 @@ public void apply(final VariantContext variant, final ReadsContext readsContext, // Add to clustering buffer if (convertInversions) { - SVCallRecordUtils.convertInversionsToBreakends(filteredCall).forEachOrdered(clusterEngine::add); + SVCallRecordUtils.convertInversionsToBreakends(filteredCall, dictionary).forEachOrdered(clusterEngine::add); } else { clusterEngine.add(filteredCall); } @@ -461,7 +461,7 @@ public VariantContext buildVariantContext(final SVCallRecord call) { // Build new variant final SVCallRecord finalCall = new SVCallRecord(newId, call.getContigA(), call.getPositionA(), call.getStrandA(), call.getContigB(), call.getPositionB(), call.getStrandB(), call.getType(), call.getLength(), - call.getAlgorithms(), call.getAlleles(), filledGenotypes, call.getAttributes()); + call.getAlgorithms(), call.getAlleles(), filledGenotypes, call.getAttributes(), dictionary); final VariantContextBuilder builder = SVCallRecordUtils.getVariantBuilder(finalCall); if (omitMembers) { builder.rmAttribute(GATKSVVCFConstants.CLUSTER_MEMBER_IDS_KEY); diff --git a/src/test/java/org/broadinstitute/hellbender/tools/sv/SVCallRecordUnitTest.java b/src/test/java/org/broadinstitute/hellbender/tools/sv/SVCallRecordUnitTest.java index 50d8d2a1636..f1b86ab877b 100644 --- a/src/test/java/org/broadinstitute/hellbender/tools/sv/SVCallRecordUnitTest.java +++ b/src/test/java/org/broadinstitute/hellbender/tools/sv/SVCallRecordUnitTest.java @@ -55,4 +55,40 @@ public Object[][] testIsCNVData() { public void testIsCNV(final SVCallRecord record, final boolean expected) { Assert.assertEquals(record.isSimpleCNV(), expected); } + + @DataProvider(name = "testCreateInvalidCoordinatesData") + public Object[][] testCreateInvalidCoordinatesData() { + return new Object[][]{ + {"chr1", 0, "chr1", 248956422}, + {"chr1", 1, "chr1", 248956423}, + {"chr1", 1, "chr1", 248956423}, + {"chr1", 1, "chr2", 242193530}, + {"chr1", 2, "chr1", 1}, + {"chr2", 1, "chr1", 2} + }; + } + + @Test(dataProvider="testCreateInvalidCoordinatesData", expectedExceptions = { IllegalArgumentException.class }) + public void testCreateInvalidCoordinates(final String contigA, final int posA, final String contigB, final int posB) { + new SVCallRecord("var1", contigA, posA, true, contigB, posB, false, StructuralVariantType.BND, + null, SVTestUtils.PESR_ONLY_ALGORITHM_LIST, Collections.emptyList(), Collections.emptyList(), + Collections.emptyMap(), SVTestUtils.hg38Dict); + Assert.fail("Expected exception not thrown"); + } + + @DataProvider(name = "testCreateValidCoordinatesData") + public Object[][] testCreateValidCoordinatesData() { + return new Object[][]{ + {"chr1", 1, "chr1", 1}, // Start == END should be valid, e.g. for insertions + {"chr1", 1, "chr1", 2}, + {"chr1", 2, "chr2", 1} + }; + } + + @Test(dataProvider="testCreateValidCoordinatesData") + public void testCreateValidCoordinates(final String contigA, final int posA, final String contigB, final int posB) { + new SVCallRecord("var1", contigA, posA, true, contigB, posB, false, StructuralVariantType.BND, + null, SVTestUtils.PESR_ONLY_ALGORITHM_LIST, Collections.emptyList(), Collections.emptyList(), + Collections.emptyMap(), SVTestUtils.hg38Dict); + } } \ No newline at end of file diff --git a/src/test/java/org/broadinstitute/hellbender/tools/sv/SVCallRecordUtilsUnitTest.java b/src/test/java/org/broadinstitute/hellbender/tools/sv/SVCallRecordUtilsUnitTest.java index 4685bc938c6..dac9f5ff669 100644 --- a/src/test/java/org/broadinstitute/hellbender/tools/sv/SVCallRecordUtilsUnitTest.java +++ b/src/test/java/org/broadinstitute/hellbender/tools/sv/SVCallRecordUtilsUnitTest.java @@ -348,7 +348,7 @@ public void testGetCallComparator(final SVCallRecord record1, final SVCallRecord @Test public void testConvertInversionsToBreakends() { final SVCallRecord nonInversion = SVTestUtils.newCallRecordWithIntervalAndType(1000, 1999, StructuralVariantType.DEL); - final List nonInversionResult = SVCallRecordUtils.convertInversionsToBreakends(nonInversion).collect(Collectors.toList()); + final List nonInversionResult = SVCallRecordUtils.convertInversionsToBreakends(nonInversion, SVTestUtils.hg38Dict).collect(Collectors.toList()); Assert.assertEquals(nonInversionResult.size(), 1); Assert.assertNotNull(nonInversionResult.get(0)); SVTestUtils.assertEqualsExceptMembership(nonInversionResult.get(0), nonInversion); @@ -358,7 +358,7 @@ public void testConvertInversionsToBreakends() { Collections.emptyList(), Collections.emptyList(), Collections.emptyMap()); - final List inversionResult = SVCallRecordUtils.convertInversionsToBreakends(inversion).collect(Collectors.toList()); + final List inversionResult = SVCallRecordUtils.convertInversionsToBreakends(inversion, SVTestUtils.hg38Dict).collect(Collectors.toList()); Assert.assertEquals(inversionResult.size(), 2); final SVCallRecord bnd1 = inversionResult.get(0); diff --git a/src/test/java/org/broadinstitute/hellbender/tools/sv/SVTestUtils.java b/src/test/java/org/broadinstitute/hellbender/tools/sv/SVTestUtils.java index 51a92dcc342..4116b1fecc5 100644 --- a/src/test/java/org/broadinstitute/hellbender/tools/sv/SVTestUtils.java +++ b/src/test/java/org/broadinstitute/hellbender/tools/sv/SVTestUtils.java @@ -135,7 +135,7 @@ public final static SVCallRecord makeRecord(final String id, genotypes.add(makeGenotypeWithRefAllele(builder, refAllele)); } return new SVCallRecord(id, contigA, positionA, strandA, contigB, positionB, strandB, type, length, algorithms, - newAlleles, genotypes); + newAlleles, genotypes, Collections.emptyMap(), hg38Dict); } public static final Genotype makeGenotypeWithRefAllele(final GenotypeBuilder builder, final Allele refAllele) { @@ -415,6 +415,13 @@ svtype, getLength(start, end, svtype), PESR_ONLY_ALGORITHM_LIST, Collections.emp Collections.emptyList(), Collections.emptyMap()); } + // Note strands and length may not be set properly + public static SVCallRecord newCallRecordWithContigsIntervalAndType(final String startContig, final int start, final String endContig, final int end, final StructuralVariantType svtype) { + return new SVCallRecord("", startContig, start, getValidTestStrandA(svtype), endContig, end, getValidTestStrandB(svtype), + svtype, getLength(start, end, svtype), PESR_ONLY_ALGORITHM_LIST, Collections.emptyList(), + Collections.emptyList(), Collections.emptyMap()); + } + public static Integer getLength(final int start, final int end, final StructuralVariantType type) { if (type.equals(StructuralVariantType.BND) || type.equals(StructuralVariantType.INS)) { return null; diff --git a/src/test/java/org/broadinstitute/hellbender/tools/sv/cluster/CNVDefragmenterTest.java b/src/test/java/org/broadinstitute/hellbender/tools/sv/cluster/CNVDefragmenterTest.java index 57c5a25177e..48e4cc362e8 100644 --- a/src/test/java/org/broadinstitute/hellbender/tools/sv/cluster/CNVDefragmenterTest.java +++ b/src/test/java/org/broadinstitute/hellbender/tools/sv/cluster/CNVDefragmenterTest.java @@ -24,47 +24,47 @@ public void testClusterTogether() { final SVCallRecord deletion = new SVCallRecord("test_del", "chr1", 1000, true, "chr1", 1999, false, StructuralVariantType.DEL, 1000, Collections.singletonList(GATKSVVCFConstants.DEPTH_ALGORITHM), Lists.newArrayList(Allele.REF_N, Allele.SV_SIMPLE_DEL), - Collections.emptyList(), Collections.emptyMap()); + Collections.emptyList(), Collections.emptyMap(), dictionary); final SVCallRecord duplication = new SVCallRecord("test_dup", "chr1", 1000, false, "chr1", 1999, true, StructuralVariantType.DUP, 1000, Collections.singletonList(GATKSVVCFConstants.DEPTH_ALGORITHM), Lists.newArrayList(Allele.REF_N, Allele.SV_SIMPLE_DUP), - Collections.emptyList(), Collections.emptyMap()); + Collections.emptyList(), Collections.emptyMap(), dictionary); Assert.assertFalse(defragmenter.areClusterable(deletion, duplication), "Different sv types should not cluster"); final SVCallRecord duplicationNonDepthOnly = new SVCallRecord("test_dup", "chr1", 1000, false, "chr1", 1999, true, StructuralVariantType.DUP, 1000, Lists.newArrayList(GATKSVVCFConstants.DEPTH_ALGORITHM, SVTestUtils.PESR_ALGORITHM), Lists.newArrayList(Allele.REF_N, Allele.SV_SIMPLE_DUP), - Collections.emptyList(), Collections.emptyMap()); + Collections.emptyList(), Collections.emptyMap(), dictionary); Assert.assertFalse(defragmenter.areClusterable(duplication, duplicationNonDepthOnly), "Clustered records must be depth-only"); final SVCallRecord cnv = new SVCallRecord("test_cnv", "chr1", 1000, null, "chr1", 1999, null, StructuralVariantType.CNV, 1000, Collections.singletonList(GATKSVVCFConstants.DEPTH_ALGORITHM), Lists.newArrayList(Allele.REF_N, Allele.SV_SIMPLE_DEL, Allele.SV_SIMPLE_DUP), - Collections.emptyList(), Collections.emptyMap()); + Collections.emptyList(), Collections.emptyMap(), dictionary); Assert.assertFalse(defragmenter.areClusterable(deletion, cnv), "Different sv types should not cluster"); final SVCallRecord insertion = new SVCallRecord("test_ins", "chr1", 1000, true, "chr1", 1001, false, StructuralVariantType.INS, 1000, SVTestUtils.PESR_ONLY_ALGORITHM_LIST, Lists.newArrayList(Allele.REF_N, Allele.SV_SIMPLE_INS), - Collections.emptyList(), Collections.emptyMap()); + Collections.emptyList(), Collections.emptyMap(), dictionary); Assert.assertFalse(defragmenter.areClusterable(insertion, insertion), "Only CNVs should be valid"); final SVCallRecord deletion2 = new SVCallRecord("test_del2", "chr1", 1000, true, "chr1", 1999, false, StructuralVariantType.DEL, 1000, Collections.singletonList(GATKSVVCFConstants.DEPTH_ALGORITHM), Lists.newArrayList(Allele.REF_N, Allele.SV_SIMPLE_DEL), - Collections.emptyList(), Collections.emptyMap()); + Collections.emptyList(), Collections.emptyMap(), dictionary); Assert.assertTrue(defragmenter.areClusterable(deletion, deletion2), "Valid identical records should cluster"); final SVCallRecord deletion3 = new SVCallRecord("test_del3", "chr1", 2999, true, "chr1", 3998, false, StructuralVariantType.DEL, 1000, Collections.singletonList(GATKSVVCFConstants.DEPTH_ALGORITHM), Lists.newArrayList(Allele.REF_N, Allele.SV_SIMPLE_DEL), - Collections.emptyList(), Collections.emptyMap()); + Collections.emptyList(), Collections.emptyMap(), dictionary); Assert.assertTrue(defragmenter.areClusterable(deletion, deletion3), "Should cluster due to overlap"); final SVCallRecord deletion4 = new SVCallRecord("test_del3", "chr1", 3000, true, "chr1", 3999, false, StructuralVariantType.DEL, 1000, Collections.singletonList(GATKSVVCFConstants.DEPTH_ALGORITHM), Lists.newArrayList(Allele.REF_N, Allele.SV_SIMPLE_DEL), - Collections.emptyList(), Collections.emptyMap()); + Collections.emptyList(), Collections.emptyMap(), dictionary); Assert.assertFalse(defragmenter.areClusterable(deletion, deletion4), "Should barely not cluster"); } @@ -193,7 +193,7 @@ public void testGetMaxClusterableStartingPosition(final int start, final int end final SVCallRecord call1 = new SVCallRecord("call1", "chr1", start, true, "chr1", end, false, StructuralVariantType.DEL, end - start + 1, Collections.singletonList(GATKSVVCFConstants.DEPTH_ALGORITHM), Lists.newArrayList(Allele.REF_N, Allele.SV_SIMPLE_DEL), - Collections.emptyList(), Collections.emptyMap()); + Collections.emptyList(), Collections.emptyMap(), dictionary); final int maxClusterableStart = defragmenter.getMaxClusterableStartingPosition(call1); final int call2Start = maxClusterableStart; @@ -201,7 +201,7 @@ public void testGetMaxClusterableStartingPosition(final int start, final int end final SVCallRecord call2 = new SVCallRecord("call2", "chr1", call2Start, true, "chr1", call2End, false, StructuralVariantType.DEL, call2End - call2Start + 1, Collections.singletonList(GATKSVVCFConstants.DEPTH_ALGORITHM), Lists.newArrayList(Allele.REF_N, Allele.SV_SIMPLE_DEL), - Collections.emptyList(), Collections.emptyMap()); + Collections.emptyList(), Collections.emptyMap(), dictionary); Assert.assertTrue(defragmenter.areClusterable(call1, call2)); final int call3Start = maxClusterableStart + 1; @@ -209,8 +209,7 @@ public void testGetMaxClusterableStartingPosition(final int start, final int end final SVCallRecord call3 = new SVCallRecord("call3", "chr1", call3Start, true, "chr1", call3End, false, StructuralVariantType.DEL, call3End - call3Start + 1, Collections.singletonList(GATKSVVCFConstants.DEPTH_ALGORITHM), Lists.newArrayList(Allele.REF_N, Allele.SV_SIMPLE_DEL), - Collections.emptyList(), Collections.emptyMap()); + Collections.emptyList(), Collections.emptyMap(), dictionary); Assert.assertFalse(defragmenter.areClusterable(call1, call3)); } - } \ No newline at end of file diff --git a/src/test/java/org/broadinstitute/hellbender/tools/sv/cluster/CanonicalSVCollapserUnitTest.java b/src/test/java/org/broadinstitute/hellbender/tools/sv/cluster/CanonicalSVCollapserUnitTest.java index 23ff598afe1..04d109ffa34 100644 --- a/src/test/java/org/broadinstitute/hellbender/tools/sv/cluster/CanonicalSVCollapserUnitTest.java +++ b/src/test/java/org/broadinstitute/hellbender/tools/sv/cluster/CanonicalSVCollapserUnitTest.java @@ -1617,6 +1617,7 @@ public Object[][] collapseIntervalTestData() { return new Object[][]{ // 1 variant { + new String[] {"chr1", "chr1"}, new int[]{1001}, // starts new int[]{1100}, // ends StructuralVariantType.DEL, @@ -1627,6 +1628,7 @@ public Object[][] collapseIntervalTestData() { }, // 2 variants { + new String[] {"chr1", "chr1"}, new int[]{1001, 1011}, new int[]{1100, 1110}, StructuralVariantType.DEL, @@ -1635,8 +1637,20 @@ public Object[][] collapseIntervalTestData() { new int[]{1011, 1100}, new int[]{1006, 1105} }, + // 2 variants + { + new String[] {"chr1", "chr1"}, + new int[]{1001, 1011}, + new int[]{1000, 1110}, + StructuralVariantType.DEL, + new int[]{1001, 1001}, // true median second position is 1000 but not allowed since < 1001 + new int[]{1001, 1110}, + new int[]{1011, 1011}, // true min second position is 1000 but not allowed since < 1011 + new int[]{1006, 1055} + }, // 3 variants { + new String[] {"chr1", "chr1"}, new int[]{1001, 1011, 1021}, new int[]{1100, 1110, 1121}, StructuralVariantType.DUP, @@ -1647,6 +1661,7 @@ public Object[][] collapseIntervalTestData() { }, // 3 variants, ends overlap starts { + new String[] {"chr1", "chr1"}, new int[]{1001, 1011, 1021}, new int[]{1031, 1011, 1021}, StructuralVariantType.DUP, @@ -1655,8 +1670,9 @@ public Object[][] collapseIntervalTestData() { new int[]{1021, 1021}, // min end before max start new int[]{1011, 1021} }, - // BND + // BND, same contig { + new String[] {"chr1", "chr1"}, new int[]{1001, 1011, 1021}, new int[]{1100, 1110, 1121}, StructuralVariantType.BND, @@ -1665,8 +1681,20 @@ public Object[][] collapseIntervalTestData() { new int[]{1021, 1100}, new int[]{1011, 1110} }, + // BND, different contigs + { + new String[] {"chr1", "chr2"}, + new int[]{1001, 1011, 1021}, + new int[]{1000, 1110, 1121}, + StructuralVariantType.BND, + new int[]{1011, 1110}, + new int[]{1001, 1121}, + new int[]{1021, 1000}, // 1000 < 1021, but ok because on diff contigs + new int[]{1011, 1077} + }, // INS, same start/end { + new String[] {"chr1", "chr1"}, new int[]{1001, 1011, 1021}, new int[]{1001, 1011, 1021}, StructuralVariantType.INS, @@ -1677,6 +1705,7 @@ public Object[][] collapseIntervalTestData() { }, // INS, different start/end { + new String[] {"chr1", "chr1"}, new int[]{1001, 1011, 1021}, new int[]{1011, 1021, 1031}, StructuralVariantType.INS, @@ -1689,27 +1718,27 @@ public Object[][] collapseIntervalTestData() { } @Test(dataProvider= "collapseIntervalTestData") - public void collapseIntervalTest(final int[] starts, final int[] ends, final StructuralVariantType svtype, + public void collapseIntervalTest(final String[] contigs, final int[] starts, final int[] ends, final StructuralVariantType svtype, final int[] expectedMedian, final int[] expectedMinMax, final int[] expectedMaxMin, final int[] expectedMean) { final List records = IntStream.range(0, starts.length) - .mapToObj(i -> SVTestUtils.newCallRecordWithIntervalAndType(starts[i], ends[i], svtype)).collect(Collectors.toList()); - - final Pair resultMedian = collapser.collapseInterval(records); - Assert.assertEquals((int) resultMedian.getKey(), expectedMedian[0]); - Assert.assertEquals((int) resultMedian.getValue(), expectedMedian[1]); - - final Pair resultMinMax = collapserMinMax.collapseInterval(records); - Assert.assertEquals((int) resultMinMax.getKey(), expectedMinMax[0]); - Assert.assertEquals((int) resultMinMax.getValue(), expectedMinMax[1]); - - final Pair resultMaxMin = collapserMaxMin.collapseInterval(records); - Assert.assertEquals((int) resultMaxMin.getKey(), expectedMaxMin[0]); - Assert.assertEquals((int) resultMaxMin.getValue(), expectedMaxMin[1]); + .mapToObj(i -> SVTestUtils.newCallRecordWithContigsIntervalAndType(contigs[0], starts[i], contigs[1], ends[i], svtype)).collect(Collectors.toList()); + collapseIntervalTestHelper(collapser, svtype, contigs, records, expectedMedian); + collapseIntervalTestHelper(collapserMinMax, svtype, contigs, records, expectedMinMax); + collapseIntervalTestHelper(collapserMaxMin, svtype, contigs, records, expectedMaxMin); + collapseIntervalTestHelper(collapserMean, svtype, contigs, records, expectedMean); + } - final Pair resultMean = collapserMean.collapseInterval(records); - Assert.assertEquals((int) resultMean.getKey(), expectedMean[0]); - Assert.assertEquals((int) resultMean.getValue(), expectedMean[1]); + private static void collapseIntervalTestHelper(final CanonicalSVCollapser collapser, + final StructuralVariantType svtype, + final String[] contigs, + final List records, + final int[] expected) { + final Pair result = collapser.collapseInterval(records); + Assert.assertEquals((int) result.getKey(), expected[0]); + Assert.assertEquals((int) result.getValue(), expected[1]); + // Test that the coordinates validate when we try to create a new record + SVTestUtils.newCallRecordWithContigsIntervalAndType(contigs[0], result.getKey(), contigs[1], result.getValue(), svtype); } @DataProvider(name = "collapseTypesTestData") diff --git a/src/test/java/org/broadinstitute/hellbender/tools/sv/cluster/SVClusterEngineTest.java b/src/test/java/org/broadinstitute/hellbender/tools/sv/cluster/SVClusterEngineTest.java index 039053310f0..d3e7de3f864 100644 --- a/src/test/java/org/broadinstitute/hellbender/tools/sv/cluster/SVClusterEngineTest.java +++ b/src/test/java/org/broadinstitute/hellbender/tools/sv/cluster/SVClusterEngineTest.java @@ -77,6 +77,21 @@ public void testClusterTogether() { Assert.assertTrue(engine.getLinkage().areClusterable(SVTestUtils.call1, SVTestUtils.overlapsCall1)); } + @Test(expectedExceptions = { IllegalArgumentException.class }) + public void testClusterTogetherInvalidInterval() { + // End position beyond contig end after padding + final SVCallRecord deletion1 = new SVCallRecord("test_del", "chr1", 1000, true, "chr1", 248956423 + SVTestUtils.defaultEvidenceParameters.getWindow(), false, StructuralVariantType.DEL, + null, Collections.singletonList(SVTestUtils.PESR_ALGORITHM), + Lists.newArrayList(Allele.REF_N, Allele.SV_SIMPLE_DEL), + Collections.emptyList(), Collections.emptyMap(), SVTestUtils.hg38Dict); + final SVCallRecord deletion2 = new SVCallRecord("test_del", "chr1", 1000, true, "chr1", 248956422, false, StructuralVariantType.DEL, + null, Collections.singletonList(SVTestUtils.PESR_ALGORITHM), + Lists.newArrayList(Allele.REF_N, Allele.SV_SIMPLE_DEL), + Collections.emptyList(), Collections.emptyMap(), SVTestUtils.hg38Dict); + engine.getLinkage().areClusterable(deletion1, deletion2); + Assert.fail("Expected exception not thrown"); + } + @Test public void testGetClusteringIntervalEdge() { //edge case - end of contig @@ -103,29 +118,29 @@ private void testGetMaxClusterableStartingPositionWithAlgorithm(final int start, final SVCallRecord call1 = new SVCallRecord("call1", "chr1", start, true, "chr1", end, false, StructuralVariantType.DEL, end - start + 1, Collections.singletonList(algorithm), Lists.newArrayList(Allele.REF_N, Allele.SV_SIMPLE_DEL), - Collections.emptyList(), Collections.emptyMap()); + Collections.emptyList(), Collections.emptyMap(), SVTestUtils.hg38Dict); final int maxClusterableStart = engine.getLinkage().getMaxClusterableStartingPosition(call1); final int call2Start = maxClusterableStart; final SVCallRecord call2Depth = new SVCallRecord("call2", "chr1", call2Start, true, "chr1", call2Start + call1.getLength() - 1, false, StructuralVariantType.DEL, call1.getLength(), Collections.singletonList(GATKSVVCFConstants.DEPTH_ALGORITHM), Lists.newArrayList(Allele.REF_N, Allele.SV_SIMPLE_DEL), - Collections.emptyList(), Collections.emptyMap()); + Collections.emptyList(), Collections.emptyMap(), SVTestUtils.hg38Dict); final SVCallRecord call2Pesr = new SVCallRecord("call2", "chr1", call2Start, true, "chr1", call2Start + call1.getLength() - 1, false, StructuralVariantType.DEL, call1.getLength(), SVTestUtils.PESR_ONLY_ALGORITHM_LIST, Lists.newArrayList(Allele.REF_N, Allele.SV_SIMPLE_DEL), - Collections.emptyList(), Collections.emptyMap()); + Collections.emptyList(), Collections.emptyMap(), SVTestUtils.hg38Dict); Assert.assertTrue(engine.getLinkage().areClusterable(call1, call2Depth) || engine.getLinkage().areClusterable(call1, call2Pesr)); final int call3Start = maxClusterableStart + 1; final SVCallRecord call3Depth = new SVCallRecord("call2", "chr1", call3Start, true, "chr1", call3Start + call1.getLength() - 1, false, StructuralVariantType.DEL, call1.getLength(), Collections.singletonList(GATKSVVCFConstants.DEPTH_ALGORITHM), Lists.newArrayList(Allele.REF_N, Allele.SV_SIMPLE_DEL), - Collections.emptyList(), Collections.emptyMap()); + Collections.emptyList(), Collections.emptyMap(), SVTestUtils.hg38Dict); final SVCallRecord call3Pesr = new SVCallRecord("call2", "chr1", call3Start, true, "chr1", call3Start + call1.getLength() - 1, false, StructuralVariantType.DEL, call1.getLength(), SVTestUtils.PESR_ONLY_ALGORITHM_LIST, Lists.newArrayList(Allele.REF_N, Allele.SV_SIMPLE_DEL), - Collections.emptyList(), Collections.emptyMap()); + Collections.emptyList(), Collections.emptyMap(), SVTestUtils.hg38Dict); Assert.assertFalse(engine.getLinkage().areClusterable(call1, call3Depth) || engine.getLinkage().areClusterable(call1, call3Pesr)); } @@ -181,12 +196,12 @@ public void testClusterTogetherVaryPositions(final int start1, final int end1, f "chr1", end1, false, StructuralVariantType.DEL, end1 - start1 + 1, SVTestUtils.PESR_ONLY_ALGORITHM_LIST, Lists.newArrayList(Allele.REF_N, Allele.SV_SIMPLE_DEL, Allele.SV_SIMPLE_DUP), - SVTestUtils.threeGenotypes, Collections.emptyMap()); + SVTestUtils.threeGenotypes, Collections.emptyMap(), SVTestUtils.hg38Dict); final SVCallRecord call2 = new SVCallRecord("call2", "chr1", start2, true, "chr1", end2, false, StructuralVariantType.DEL, end2 - start2 + 1, Lists.newArrayList(GATKSVVCFConstants.DEPTH_ALGORITHM), Lists.newArrayList(Allele.REF_N, Allele.SV_SIMPLE_DEL, Allele.SV_SIMPLE_DUP), - SVTestUtils.threeGenotypes, Collections.emptyMap()); + SVTestUtils.threeGenotypes, Collections.emptyMap(), SVTestUtils.hg38Dict); Assert.assertEquals(engine.getLinkage().areClusterable(call1, call2), result); } @@ -197,12 +212,12 @@ public void testClusterTogetherVaryTypes() { final SVCallRecord call1 = new SVCallRecord("call1", "chr1", 1000, SVTestUtils.getValidTestStrandA(type1), "chr1", 2001, SVTestUtils.getValidTestStrandB(type1), type1, SVTestUtils.getLength(1000, 2001, type1), Lists.newArrayList(GATKSVVCFConstants.DEPTH_ALGORITHM), - Collections.emptyList(), Collections.emptyList(), Collections.emptyMap()); + Collections.emptyList(), Collections.emptyList(), Collections.emptyMap(), SVTestUtils.hg38Dict); for (final StructuralVariantType type2 : StructuralVariantType.values()) { final SVCallRecord call2 = new SVCallRecord("call2", "chr1", 1000, SVTestUtils.getValidTestStrandA(type2), "chr1", 2001, SVTestUtils.getValidTestStrandB(type2), type2, SVTestUtils.getLength(1000, 2001, type2), Lists.newArrayList(GATKSVVCFConstants.DEPTH_ALGORITHM), - Collections.emptyList(), Collections.emptyList(), Collections.emptyMap()); + Collections.emptyList(), Collections.emptyList(), Collections.emptyMap(), SVTestUtils.hg38Dict); // Should only cluster together if same type Assert.assertEquals(engine.getLinkage().areClusterable(call1, call2), type1 == type2); } @@ -217,13 +232,13 @@ public void testClusterTogetherVaryStrands() { final SVCallRecord call1 = new SVCallRecord("call1", "chr1", 1000, strand1A, "chr1", 2001, strand1B, StructuralVariantType.BND, null, Lists.newArrayList(GATKSVVCFConstants.DEPTH_ALGORITHM), - Collections.emptyList(), Collections.emptyList(), Collections.emptyMap()); + Collections.emptyList(), Collections.emptyList(), Collections.emptyMap(), SVTestUtils.hg38Dict); for (final Boolean strand2A : bools) { for (final Boolean strand2B : bools) { final SVCallRecord call2 = new SVCallRecord("call2", "chr1", 1000, strand2A, "chr1", 2001, strand2B, StructuralVariantType.BND, null, Lists.newArrayList(GATKSVVCFConstants.DEPTH_ALGORITHM), - Collections.emptyList(), Collections.emptyList(), Collections.emptyMap()); + Collections.emptyList(), Collections.emptyList(), Collections.emptyMap(), SVTestUtils.hg38Dict); // Should only cluster if strands match Assert.assertEquals(engine.getLinkage().areClusterable(call1, call2), strand1A == strand2A && strand1B == strand2B); } @@ -235,18 +250,22 @@ public void testClusterTogetherVaryStrands() { @Test public void testClusterTogetherVaryContigs() { final List contigs = Lists.newArrayList("chr1", "chrX"); - for (final String contig1A : contigs) { - for (final String contig1B : contigs) { + for (int i = 0; i < contigs.size(); i++) { + final String contig1A = contigs.get(i); + for (int j = i; j < contigs.size(); j++) { + final String contig1B = contigs.get(j); final SVCallRecord call1 = new SVCallRecord("call1", contig1A, 1000, true, contig1B, 2001, false, StructuralVariantType.BND, null, SVTestUtils.PESR_ONLY_ALGORITHM_LIST, - Collections.emptyList(), Collections.emptyList(), Collections.emptyMap()); - for (final String contig2A : contigs) { - for (final String contig2B : contigs) { + Collections.emptyList(), Collections.emptyList(), Collections.emptyMap(), SVTestUtils.hg38Dict); + for (int k = 0; k < contigs.size(); k++) { + final String contig2A = contigs.get(k); + for (int m = k; m < contigs.size(); m++) { + final String contig2B = contigs.get(m); final SVCallRecord call2 = new SVCallRecord("call2", contig2A, 1000, true, contig2B, 2001, false, StructuralVariantType.BND, null, SVTestUtils.PESR_ONLY_ALGORITHM_LIST, - Collections.emptyList(), Collections.emptyList(), Collections.emptyMap()); + Collections.emptyList(), Collections.emptyList(), Collections.emptyMap(), SVTestUtils.hg38Dict); // Should only cluster if contigs match Assert.assertEquals(engine.getLinkage().areClusterable(call1, call2), contig1A.equals(contig2A) && contig1B.equals(contig2B)); } @@ -265,11 +284,11 @@ public void testClusterTogetherVaryAlgorithms() { for (final List algorithms1 : algorithmsList) { final SVCallRecord call1 = new SVCallRecord("call1", "chr1", 1000, true, "chr1", 2001, false, StructuralVariantType.DEL, - 1002, algorithms1, Collections.emptyList(), Collections.emptyList(), Collections.emptyMap()); + 1002, algorithms1, Collections.emptyList(), Collections.emptyList(), Collections.emptyMap(), SVTestUtils.hg38Dict); for (final List algorithms2 : algorithmsList) { final SVCallRecord call2 = new SVCallRecord("call2", "chr1", 1000, true, "chr1", 2001, false, StructuralVariantType.DEL, - 1002, algorithms2, Collections.emptyList(), Collections.emptyList(), Collections.emptyMap()); + 1002, algorithms2, Collections.emptyList(), Collections.emptyList(), Collections.emptyMap(), SVTestUtils.hg38Dict); // All combinations should cluster Assert.assertTrue(engine.getLinkage().areClusterable(call1, call2)); } @@ -281,10 +300,10 @@ public void testClusterTogetherVaryParameters() { final SVClusterEngine testEngine1 = SVTestUtils.getNewDefaultSingleLinkageEngine(); final SVCallRecord call1 = new SVCallRecord("call1", "chr1", 1000, true, "chr1", 2001, false, StructuralVariantType.DEL, - 1002, Collections.singletonList(GATKSVVCFConstants.DEPTH_ALGORITHM), Collections.emptyList(), Collections.emptyList(), Collections.emptyMap()); + 1002, Collections.singletonList(GATKSVVCFConstants.DEPTH_ALGORITHM), Collections.emptyList(), Collections.emptyList(), Collections.emptyMap(), SVTestUtils.hg38Dict); final SVCallRecord call2 = new SVCallRecord("call2", "chr1", 1100, true, "chr1", 2101, false, StructuralVariantType.DEL, - 1002, Collections.singletonList(GATKSVVCFConstants.DEPTH_ALGORITHM), Collections.emptyList(), Collections.emptyList(), Collections.emptyMap()); + 1002, Collections.singletonList(GATKSVVCFConstants.DEPTH_ALGORITHM), Collections.emptyList(), Collections.emptyList(), Collections.emptyMap(), SVTestUtils.hg38Dict); // Cluster with default parameters Assert.assertTrue(testEngine1.getLinkage().areClusterable(call1, call2)); final ClusteringParameters exactMatchParameters = ClusteringParameters.createDepthParameters(1.0, 0, 1.0); @@ -324,15 +343,15 @@ public void testAddVaryPositions(final int positionA1, final int positionB1, final SVCallRecord call1 = new SVCallRecord("call1", "chr1", positionA1, true, "chr1", positionB1, false, StructuralVariantType.DEL, positionB1 - positionA1 + 1, Collections.singletonList(GATKSVVCFConstants.DEPTH_ALGORITHM), - Collections.emptyList(), Collections.emptyList(), Collections.emptyMap()); + Collections.emptyList(), Collections.emptyList(), Collections.emptyMap(), SVTestUtils.hg38Dict); final SVCallRecord call2 = new SVCallRecord("call1", "chr1", positionA2, true, "chr1", positionB2, false, StructuralVariantType.DEL, positionB2 - positionA2 + 1, Collections.singletonList(GATKSVVCFConstants.DEPTH_ALGORITHM), - Collections.emptyList(), Collections.emptyList(), Collections.emptyMap()); + Collections.emptyList(), Collections.emptyList(), Collections.emptyMap(), SVTestUtils.hg38Dict); final SVCallRecord call3 = new SVCallRecord("call1", "chr1", positionA3, true, "chr1", positionB3, false, StructuralVariantType.DEL, positionB3 - positionA3 + 1, Collections.singletonList(GATKSVVCFConstants.DEPTH_ALGORITHM), - Collections.emptyList(), Collections.emptyList(), Collections.emptyMap()); + Collections.emptyList(), Collections.emptyList(), Collections.emptyMap(), SVTestUtils.hg38Dict); engine.add(call1); engine.add(call2); engine.add(call3); @@ -461,7 +480,7 @@ public void testGetCarrierSamplesBiallelic(final int ploidy, final Allele refAll final SVCallRecord recordWithCopyNumber = new SVCallRecord("", "chr1", 1000, SVTestUtils.getValidTestStrandA(svtype), "chr1", 1999, SVTestUtils.getValidTestStrandB(svtype), svtype, 1000, Collections.singletonList(GATKSVVCFConstants.DEPTH_ALGORITHM), - alleles, GenotypesContext.copy(genotypesWithCopyNumber), Collections.emptyMap()); + alleles, GenotypesContext.copy(genotypesWithCopyNumber), Collections.emptyMap(), SVTestUtils.hg38Dict); final Set resultWithCopyNumber = recordWithCopyNumber.getCarrierSampleSet(); Assert.assertEquals(resultWithCopyNumber, expectedResult); @@ -476,7 +495,7 @@ public void testGetCarrierSamplesBiallelic(final int ploidy, final Allele refAll final SVCallRecord recordWithGenotype = new SVCallRecord("", "chr1", 1000, SVTestUtils.getValidTestStrandA(svtype), "chr1", 1999, SVTestUtils.getValidTestStrandB(svtype), svtype, 1000, Collections.singletonList(GATKSVVCFConstants.DEPTH_ALGORITHM), - alleles, GenotypesContext.copy(genotypesWithGenotype), Collections.emptyMap()); + alleles, GenotypesContext.copy(genotypesWithGenotype), Collections.emptyMap(), SVTestUtils.hg38Dict); final Set resultWithGenotype = recordWithGenotype.getCarrierSampleSet(); Assert.assertEquals(resultWithGenotype, expectedResult);