diff --git a/src/main/java/org/broadinstitute/hellbender/tools/spark/sv/utils/GATKSVVCFConstants.java b/src/main/java/org/broadinstitute/hellbender/tools/spark/sv/utils/GATKSVVCFConstants.java index c7586265990..de91be5e5b6 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/spark/sv/utils/GATKSVVCFConstants.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/spark/sv/utils/GATKSVVCFConstants.java @@ -91,7 +91,8 @@ public enum ComplexVariantSubtype { dDUP_iDEL, INS_iDEL, CTX_PP_QQ, - CTX_PQ_QP + CTX_PQ_QP, + CTX_INV } // not defined in output vcf header but used in internal id that is currently output in the ID column diff --git a/src/main/java/org/broadinstitute/hellbender/tools/walkers/sv/SVAnnotateEngine.java b/src/main/java/org/broadinstitute/hellbender/tools/walkers/sv/SVAnnotateEngine.java index 7c977602303..0e840e4652d 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/walkers/sv/SVAnnotateEngine.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/walkers/sv/SVAnnotateEngine.java @@ -570,9 +570,9 @@ protected static List parseComplexIntervals(final List cpxInt * protein-coding consequences */ @VisibleForTesting - protected static List getComplexAnnotationIntervals(final List cpxIntervals, + protected static ArrayList getComplexAnnotationIntervals(final List cpxIntervals, final GATKSVVCFConstants.ComplexVariantSubtype complexType) { - final List segments = new ArrayList<>(cpxIntervals.size()); + final ArrayList segments = new ArrayList<>(cpxIntervals.size()); final List dupIntervals = new ArrayList<>(cpxIntervals.size()); SimpleInterval inversionIntervalToAdjust = null; boolean keepSegment; @@ -679,8 +679,8 @@ protected static List getSVSegments(final VariantContext variant, final int pos = variant.getStart(); final String chr2 = variant.getAttributeAsString(GATKSVVCFConstants.CONTIG2_ATTRIBUTE, null); final int end2 = variant.getAttributeAsInt(GATKSVVCFConstants.END2_ATTRIBUTE, pos); + final List cpxIntervals = variant.getAttributeAsStringList(GATKSVVCFConstants.CPX_INTERVALS, null); if (overallSVType.equals(GATKSVVCFConstants.StructuralVariantAnnotationType.CPX)) { - final List cpxIntervals = variant.getAttributeAsStringList(GATKSVVCFConstants.CPX_INTERVALS, null); if (cpxIntervals.isEmpty()) { throw new UserException("Complex (CPX) variant must contain CPX_INTERVALS INFO field"); } @@ -695,14 +695,22 @@ protected static List getSVSegments(final VariantContext variant, new SimpleInterval(chrom, pos, pos + 1))); } } else if (overallSVType.equals(GATKSVVCFConstants.StructuralVariantAnnotationType.CTX)) { - intervals = new ArrayList<>(2); - intervals.add(new SVSegment(overallSVType, new SimpleInterval(variant))); // CHROM:POS-POS+1 - // annotate both breakpoints of translocation - CHR2:END2-END2+1 + // if SVTYPE is CTX and CPX_TYPE is CTX_INV, add INV from CTX_INTERVALS + if (complexType == GATKSVVCFConstants.ComplexVariantSubtype.CTX_INV && !cpxIntervals.isEmpty()) { + intervals = getComplexAnnotationIntervals(parseComplexIntervals(cpxIntervals), complexType); + } else { + intervals = new ArrayList<>(2); + } + // annotate POS and END separately in case END != POS+1, such as in the case of CTX_INV + intervals.add(new SVSegment(overallSVType, new SimpleInterval(chrom, pos, pos))); + intervals.add(new SVSegment(overallSVType, new SimpleInterval(chrom, variant.getEnd(), variant.getEnd()))); + // annotate breakpoints of translocation on CHR2 - END2 and END2+1 + // TODO: update if POS2 is added to accommodate complex translocations if (chr2 == null) { throw new UserException("Translocation (CTX) variant represented as a single record must contain CHR2 INFO field"); } - intervals.add(new SVSegment(overallSVType, - new SimpleInterval(chr2, end2, end2 + 1))); + intervals.add(new SVSegment(overallSVType, new SimpleInterval(chr2, end2, end2))); + intervals.add(new SVSegment(overallSVType, new SimpleInterval(chr2, end2 + 1, end2 + 1))); } else if (overallSVType.equals(GATKSVVCFConstants.StructuralVariantAnnotationType.BND)){ intervals = new ArrayList<>(2); final int svLen = variant.getAttributeAsInt(GATKSVVCFConstants.SVLEN, 0); diff --git a/src/test/java/org/broadinstitute/hellbender/tools/walkers/sv/SVAnnotateEngineUnitTest.java b/src/test/java/org/broadinstitute/hellbender/tools/walkers/sv/SVAnnotateEngineUnitTest.java index 80f8312ff0c..dbcf2152b8f 100644 --- a/src/test/java/org/broadinstitute/hellbender/tools/walkers/sv/SVAnnotateEngineUnitTest.java +++ b/src/test/java/org/broadinstitute/hellbender/tools/walkers/sv/SVAnnotateEngineUnitTest.java @@ -481,7 +481,8 @@ public Object[][] getComplexSubtypes() { { GATKSVVCFConstants.ComplexVariantSubtype.dDUP_iDEL, true }, { GATKSVVCFConstants.ComplexVariantSubtype.INS_iDEL, false }, { GATKSVVCFConstants.ComplexVariantSubtype.CTX_PP_QQ, false }, - { GATKSVVCFConstants.ComplexVariantSubtype.CTX_PQ_QP, false } + { GATKSVVCFConstants.ComplexVariantSubtype.CTX_PQ_QP, false }, + { GATKSVVCFConstants.ComplexVariantSubtype.CTX_INV, false } }; } @@ -564,8 +565,10 @@ public Object[][] getSVTypesAndSegmentsTestData() { GATKSVVCFConstants.ComplexVariantSubtype.CTX_PP_QQ, GATKSVVCFConstants.StructuralVariantAnnotationType.CTX, createListOfSVSegments(GATKSVVCFConstants.StructuralVariantAnnotationType.CTX, - new SimpleInterval[]{ new SimpleInterval("chr2", 86263976, 86263977), - new SimpleInterval("chr19", 424309, 424310) }), + new SimpleInterval[]{ new SimpleInterval("chr2", 86263976, 86263976), + new SimpleInterval("chr2", 86263977, 86263977), + new SimpleInterval("chr19", 424309, 424309), + new SimpleInterval("chr19", 424310, 424310) }), null }, { createVariantContext("chr2", 86263976, 86263976, null, 424309, "G", "G]chr19:424309]", null, null,"CTX_PP/QQ", null), @@ -575,12 +578,28 @@ public Object[][] getSVTypesAndSegmentsTestData() { new SimpleInterval("chr2", 86263976, 86263976))), null}, { createVariantContext("chr2", 86263977, 86263977, null, 424309, "A", - "[chr19:424310[A", null, null, "CTX_PP/QQ", null), + "[chr19:424310[A", -1, null, "CTX_PP/QQ", null), GATKSVVCFConstants.ComplexVariantSubtype.CTX_PP_QQ, GATKSVVCFConstants.StructuralVariantAnnotationType.BND, Arrays.asList(new SVAnnotateEngine.SVSegment(GATKSVVCFConstants.StructuralVariantAnnotationType.CTX, new SimpleInterval("chr2", 86263977, 86263977))), null }, + { createVariantContext("chr4", 21923233, 22506191, "chr8", 107912008, "N", + "", null, null, "CTX_INV", + Collections.singletonList("INV_chr4:21923233-22506191")), + GATKSVVCFConstants.ComplexVariantSubtype.CTX_INV, + GATKSVVCFConstants.StructuralVariantAnnotationType.CTX, + Arrays.asList(new SVAnnotateEngine.SVSegment(GATKSVVCFConstants.StructuralVariantAnnotationType.INV, + new SimpleInterval("chr4", 21923233, 22506191)), + new SVAnnotateEngine.SVSegment(GATKSVVCFConstants.StructuralVariantAnnotationType.CTX, + new SimpleInterval("chr4", 21923233, 21923233)), + new SVAnnotateEngine.SVSegment(GATKSVVCFConstants.StructuralVariantAnnotationType.CTX, + new SimpleInterval("chr4", 22506191, 22506191)), + new SVAnnotateEngine.SVSegment(GATKSVVCFConstants.StructuralVariantAnnotationType.CTX, + new SimpleInterval("chr8", 107912008, 107912008)), + new SVAnnotateEngine.SVSegment(GATKSVVCFConstants.StructuralVariantAnnotationType.CTX, + new SimpleInterval("chr8", 107912009, 107912009)) ), + null }, { createVariantContext("chr2", 205522308, 205522384, "chr2", null, "N", "", 76, null, null, null), null, @@ -862,6 +881,13 @@ public Object[][] getAnnotateStructuralVariantTestData() { createAttributesMap( Arrays.asList(GATKSVVCFConstants.PROMOTER,GATKSVVCFConstants.INTERGENIC), Arrays.asList("EMMA2", true)) }, + // CTX_INV - this test case is not interchromosomal because the test GTF only has chr1 + { createVariantContext("chr1", 10, 1010, "chr1", 2300, null, + "", -1, null, "CTX_INV", Arrays.asList("INV_chr1:10-1010")), + createAttributesMap( + Arrays.asList(GATKSVVCFConstants.INV_SPAN, GATKSVVCFConstants.NONCODING_SPAN, + GATKSVVCFConstants.LOF, GATKSVVCFConstants.INTERGENIC), + Arrays.asList("EMMA1", "DNase", "EMMA2", false))}, // check annotate promoter for all segments in multi-segment SV { createVariantContext("chr1", 30, 30, "chr1", 3030, null, "", null, "-+", null, null),