StructuralVariantFactory { @NotNull public static StructuralVariant create(@NotNull VariantContext first, @NotNull VariantContext second) { Preconditions.checkArgument(StructuralVariantType.BND.equals(type(first))); Preconditions.checkArgument(StructuralVariantType.BND.equals(type(second))); final int start = first.getStart(); final int end = second.getStart(); final String alt = first.getAlternateAllele(0).getDisplayString(); final Matcher match = BREAKEND_REGEX.matcher(alt); if (!match.matches()) { throw new IllegalArgumentException(String.format("ALT %s is not in breakend notation", alt)); } final byte startOrientation = (byte) (match.group(1).length() > 0 ? 1 : -1); final byte endOrientation = (byte) (match.group(2).equals("]") ? 1 : -1); String insertedSequence = match.group(1).length() > 0 ? match.group(1).substring(1) : match.group(4).substring(0, match.group(4).length() - 1); if (Strings.isNullOrEmpty(insertedSequence)) { insertedSequence = first.getAttributeAsString(INS_SEQ, ""); } final boolean isSmallDelDup = first.getContig().equals(second.getContig()) && Math.abs(first.getStart() - second.getStart()) <= SMALL_DELDUP_SIZE && startOrientation != endOrientation; final StructuralVariantLeg startLeg = setLegCommon(ImmutableStructuralVariantLegImpl.builder(), first, isSmallDelDup, startOrientation).position(start) .homology(first.getAttributeAsString(HOM_SEQ, "")) .alleleFrequency(unadjustedAllelicFrequency(first)) .build(); final StructuralVariantLeg endLeg = setLegCommon(ImmutableStructuralVariantLegImpl.builder(), second, isSmallDelDup, endOrientation) .position(end) .homology(second.getAttributeAsString(HOM_SEQ, "")) .alleleFrequency(unadjustedAllelicFrequency(second)) .build(); StructuralVariantType inferredType = StructuralVariantType.BND; if (startLeg.chromosome().equals(endLeg.chromosome())) { if (startLeg.orientation() == endLeg.orientation()) { inferredType = StructuralVariantType.INV; } else if (startLeg.orientation() == -1) { inferredType = StructuralVariantType.DUP; } else if (insertedSequence != null && insertedSequence.length() > 0 && Math.abs(endLeg.position() - startLeg.position()) <= 1) { inferredType = StructuralVariantType.INS; } else { inferredType = StructuralVariantType.DEL; } } return setCommon(ImmutableStructuralVariantImpl.builder(), first).start(startLeg) .end(endLeg) .mateId(second.getID()) .insertSequence(insertedSequence) .type(inferredType) .filter(filters(first, second)) .startContext(first) .endContext(second) .build(); } StructuralVariantFactory(final @NotNull VariantContextFilter filter); void addVariantContext(final @NotNull VariantContext context); @Nullable static String mateId(@NotNull VariantContext context); @NotNull List<StructuralVariant> results(); @NotNull List<VariantContext> unmatched(); @NotNull static StructuralVariant create(@NotNull VariantContext first, @NotNull VariantContext second); static Double unadjustedAllelicFrequency(@NotNull VariantContext context); @NotNull static StructuralVariant createSingleBreakend(@NotNull VariantContext context); static final String RECOVERED; static final String RECOVERY_METHOD; static final String RECOVERY_FILTER; static final String PASS; static final String INFERRED; static final String CIPOS; static final String SVTYPE; static final String PON_FILTER_PON; static final String IMPRECISE; }
@Test public void testUseAFValueOfLeg() { final String line1 = "2\t321681\tbnd_W\tG\tG]17:198982]\t6\tPASS\tSVTYPE=BND;BPI_AF=1.1,1.2\tGT\t./."; final String line2 = "17\t198982\tbnd_W\tG\tG]2:321681]\t6\tPASS\tSVTYPE=BND\tGT\t./."; final StructuralVariant variant = StructuralVariantFactory.create(codec.decode(line1), codec.decode(line2)); assertEquals(1.1, variant.start().alleleFrequency(), 0.01); assertNull( variant.end().alleleFrequency()); }
@Test public void testFavourTAFOverBPI_AF() { final String line1 = "2\t321681\tbnd_W\tG\tG]17:198982]\t6\tPASS\tSVTYPE=BND;BPI_AF=1.1,1.2;TAF=2.1,2.2\tGT\t./."; final String line2 = "17\t198982\tbnd_W\tG\tG]2:321681]\t6\tPASS\tSVTYPE=BND;BPI_AF=1.2,1.1;TAF=2.3,2.4\tGT\t./."; final StructuralVariant variant = StructuralVariantFactory.create(codec.decode(line1), codec.decode(line2)); assertEquals(2.1, variant.start().alleleFrequency(), 0.01); assertEquals(2.3, variant.end().alleleFrequency(), 0.01); }
@Test public void testOrientation() { final String line1 = "2\t321681\tbnd_W\tG\tG]17:198982]\t6\tPASS\tSVTYPE=BND\tGT\t./."; final String line2 = "2\t321682\tbnd_V\tT\t]13:123456]T\t6\tPASS\tSVTYPE=BND\tGT\t./."; final String line3 = "13\t123456\tbnd_U\tC\tC[2:321682[\t6\tPASS\tSVTYPE=BND\tGT\t./."; final String line4 = "13\t123457\tbnd_X\tA\t[17:198983[A\t6\tPASS\tSVTYPE=BND\tGT\t./."; final String line5 = "17\t198982\tbnd_Y\tA\tA]2:321681]\t6\tPASS\tSVTYPE=BND\tGT\t./."; final String line6 = "17\t198983\tbnd_Z\tC\t[13:123457[C\t6\tPASS\tSVTYPE=BND\tGT\t./."; VariantContext c1 = codec.decode(line1); VariantContext c2 = codec.decode(line2); VariantContext c3 = codec.decode(line3); VariantContext c4 = codec.decode(line4); VariantContext c5 = codec.decode(line5); VariantContext c6 = codec.decode(line6); StructuralVariant variant = StructuralVariantFactory.create(c1, c5); final StructuralVariantLeg leg1 = variant.start(); final StructuralVariantLeg leg5 = variant.end(); variant = StructuralVariantFactory.create(c2, c3); final StructuralVariantLeg leg2 = variant.start(); final StructuralVariantLeg leg3 = variant.end(); variant = StructuralVariantFactory.create(c4, c6); final StructuralVariantLeg leg4 = variant.start(); final StructuralVariantLeg leg6 = variant.end(); assertEquals(1, leg1.orientation()); assertEquals(-1, leg2.orientation()); assertEquals(1, leg3.orientation()); assertEquals(-1, leg4.orientation()); assertEquals(1, leg5.orientation()); assertEquals(-1, leg6.orientation()); }