public void GenerateVcfStrings_IncludeHeaders() { if (MiscUtils.IsRunningAnyLinux) { return; // currently failing on linux :( } var parser = VcfVariantParserSettings.Create(ImmutableList.Create(SampleName)); var variants = VcfVariant.TryParse(Bnd1, parser).FollowedBy(VcfVariant.TryParse(Bnd2, parser)).EnumerateSuccesses().ToList(); var wittyerVariant = WittyerBndInternal.Create(variants[0], variants[0].ToTryOfGenotypedVcfVariant(VariantNormalizer.TrimCommonBases).GetOrThrow().Samples.Values.First(), WittyerType.IntraChromosomeBreakend, new List <uint>(), uint.MinValue, null, variants[1]); var headerLines = WittyerVcfWriter.GenerateVcfStrings( WittyerResult.Create(VcfHeader.CreateBuilder(VcfVersion.FourPointOne).Build(), SampleName, variants.Select(v => v.Contig).Distinct().ToList(), false, new Dictionary <WittyerType, IReadOnlyList <IWittyerVariant> >(), new Dictionary <WittyerType, IReadOnlyList <IWittyerBnd> > { { WittyerType.IntraChromosomeBreakend, new List <IWittyerBnd> { wittyerVariant } } }, new List <IVcfVariant>()), null, null) .TakeWhile(line => line.StartsWith(VcfConstants.Header.Prefix)).ToList(); // 11 = VcfVersion, WHO, WHAT, WHERE, WHY, WIT, WIN, WOW, date, version, column names Assert.Equal(11, headerLines.Count); }
private static IWittyerBnd CreateWittyerBnd([NotNull] string bndLine1, [NotNull] string bndLine2) { var variant = VcfVariant.TryParse(bndLine1, VcfVariantParserSettings.Create(ImmutableList.Create("normal"), GenomeAssembly.Grch37)) .GetOrThrowDebug(); return(WittyerBndInternal.Create(variant, variant.Samples["normal"], WittyerType.TranslocationBreakend, Bins, BasepairDistance, PercentDistance, VcfVariant.TryParse(bndLine2, VcfVariantParserSettings.Create(ImmutableList.Create("normal"), GenomeAssembly.Grch37)) .GetOrThrowDebug())); }
public static void WittyerIntraBndWorkCorrectly() { var vcfSettings = VcfVariantParserSettings.Create(ImmutableList.Create("proband", "father"), GenomeAssembly.Grch37); var bnd1 = VcfVariant.TryParse(GenotypedIntraBnd, vcfSettings).GetOrThrowDebug(); var bnd2 = VcfVariant.TryParse(GenotypedIntraBndPair, vcfSettings).GetOrThrowDebug(); var wittyerBnd = WittyerBndInternal .Create(bnd2, bnd2.Samples["father"], WittyerType.IntraChromosomeBreakend, Bins, BasepairDistance, PercentDistance, bnd1); var distance = Math.Round(Math.Abs(bnd1.Position - bnd2.Position) * PercentDistance); var expectedEndInterval = ContigAndInterval.Create(wittyerBnd.Contig, bnd1.Position - (uint)distance - 1, bnd1.Position + (uint)distance); MultiAssert.Equal(expectedEndInterval, wittyerBnd.EndInterval); MultiAssert.Equal(10000U, wittyerBnd.Win.End); MultiAssert.AssertAll(); Assert.IsType <WittyerGenotypedSample>(wittyerBnd.Sample); }
public static void WittyerBndCreateCorrectly() { var vcfSettings = VcfVariantParserSettings.Create(ImmutableList.Create("proband", "father"), GenomeAssembly.Grch37); var bnd1 = VcfVariant.TryParse(GenotypedBnd, vcfSettings).GetOrThrowDebug(); var bnd2 = VcfVariant.TryParse(GenotypedBndPair, vcfSettings).GetOrThrowDebug(); var wittyerBnd = WittyerBndInternal .Create(bnd2, bnd2.Samples["father"], WittyerType.TranslocationBreakend, Bins, BasepairDistance, PercentDistance, bnd1); var expectedContig = ContigInfo.Create("1"); var expectedEndInterval = ContigAndInterval.Create(ContigInfo.Create("4"), 191034451, 191035452); MultiAssert.Equal(expectedContig, wittyerBnd.Contig); MultiAssert.Equal(expectedEndInterval, wittyerBnd.EndInterval); MultiAssert.Equal(230675U, wittyerBnd.Start); MultiAssert.Equal(231676U, wittyerBnd.Stop); MultiAssert.Equal(WittyerConstants.StartingBin, wittyerBnd.Win.Start); MultiAssert.Equal(null, wittyerBnd.Win.End); MultiAssert.AssertAll(); }
internal static IContigProvider CreateVariant([NotNull] IVcfVariant vcfVariant, [CanBeNull] IVcfSample sample, bool isTruth, [CanBeNull] string sampleName, IReadOnlyDictionary <WittyerType, InputSpec> inputSpecDict, IDictionary <IGeneralBnd, IVcfVariant> bndSet, List <string> errorList, bool isCrossTypeOn) { var failedReason = WittyerType.ParseFromVariant(vcfVariant, isCrossTypeOn, sampleName, out var svType); if (failedReason != null) { return(CreateUnsupportedVariant(vcfVariant, sample, failedReason.Value == FailedReason.Unset ? throw new ArgumentOutOfRangeException( $"Got {nameof(FailedReason)}.{FailedReason.Unset} which means bug in {nameof(WittyerType.TryParse)}") : failedReason.Value, isTruth)); } if (svType == null) { throw new InvalidDataException("svType should not be null with no failed reason"); } //User does not specify this SVTYPE in input spec, consider user want to exlude this particular SVTYPE comparison entirely if (!inputSpecDict.TryGetValue(svType, out var inputSpec)) { return(CreateUnsupportedVariant(vcfVariant, sample, FailedReason.VariantTypeSkipped, isTruth)); } var isSupportedVariant = IsSupportedVariant(); if (!isSupportedVariant.Equals(FailedReason.Unset)) { return(CreateUnsupportedVariant(vcfVariant, sample, isSupportedVariant, isTruth)); } var bpd = inputSpec.BasepairDistance; var pd = inputSpec.PercentDistance; var bins = inputSpec.BinSizes; if (svType == WittyerType.Insertion) { //insertion is basically using one same record as the both entries of the breakend pair return(WittyerBndInternal.Create(vcfVariant, sample, inputSpec.VariantType, bins.Select(sizeSkipTuple => sizeSkipTuple.size).ToReadOnlyList(), bpd, pd, vcfVariant)); } if (svType == WittyerType.CopyNumberReference && vcfVariant.Info.TryGetValue(VcfConstants.SvTypeKey, out var svTypeString) && !WittyerConstants.BaseLevelStatsTypeStrings.Contains(svTypeString)) { // any non-DEL/DUP/CNV that is determined to be reference copy number is not supported. return(CreateUnsupportedVariant(vcfVariant, sample, FailedReason.UnsupportedRefCall, isTruth)); } if (svType == WittyerType.TranslocationBreakend || svType == WittyerType.IntraChromosomeBreakend) { var currentBnd = GeneralBnd.CreateFromVariant(vcfVariant); //Note: this means the paired BND is found as a key in dictionary. Checkout the comparer for details if (bndSet.TryGetValue(currentBnd, out var secondVariant)) { if (!bndSet.Remove(currentBnd)) { throw new InvalidOperationException( $"Cannot remove {secondVariant} from breakend dictionary when pair is found: {vcfVariant}! Find a developer to debug!"); } return(WittyerBndInternal.Create(vcfVariant, sample, svType, bins.Select(sizeSkipTuple => sizeSkipTuple.size).ToReadOnlyList(), bpd, pd, secondVariant)); } bndSet.Add(currentBnd, vcfVariant); return(currentBnd); } try { return(WittyerVariantInternal.Create(vcfVariant, sample, svType, bins.Select(sizeSkipTuple => sizeSkipTuple.size).ToReadOnlyList(), pd, bpd)); } catch (Exception e) { if (errorList.Count <= MaxNonSupportedVariantToPrint) { errorList.Add( new[] { "Exception caught:", e.ToString(), vcfVariant.ToString() } .StringJoin(Environment.NewLine)); } return(CreateUnsupportedVariant(vcfVariant, sample, FailedReason.Other, isTruth)); } FailedReason IsSupportedVariant() { // Check filters. IReadOnlyCollection <string> includedFilters, excludedFilters; if (isTruth) { includedFilters = WittyerConstants.DefaultIncludeFilters; excludedFilters = WittyerConstants.DefaultExcludeFilters; } else { includedFilters = inputSpec.IncludedFilters; excludedFilters = inputSpec.ExcludedFilters; } if (vcfVariant.Filters.Any(excludedFilters.Contains) || includedFilters.Count > 0 && (vcfVariant.Filters.Count == 0 || !vcfVariant.Filters.Any(includedFilters.Contains))) { return(FailedReason.FilteredBySettings); } // SVLEN = 0 when they are supposed to have overlaps (svlen is needed for overlapping windows) are ignored if (svType.HasOverlappingWindows && (vcfVariant.Info.TryGetValue(VcfConstants.EndTagKey, out var endString) && vcfVariant.Position.ToString() == endString || vcfVariant.Info.TryGetValue(VcfConstants.SvLenKey, out var svLenString) && svLenString == "0")) { return(FailedReason.InvalidSvLen); } // Bnd with pos and alt to be same position (temporarily to accomendate the situation of SVLEN=0 INV representing as bnd) if (svType == WittyerType.IntraChromosomeBreakend) { var mate = SimpleBreakEnd.TryParse(vcfVariant.GetSingleAlt()).GetOrThrow(); return(vcfVariant.Position == mate.Position ? FailedReason.InvalidSvLen : FailedReason.Unset); } // todo: truth does not care about Sample FT tag, is that ok? var sampleFilterOk = isTruth || !includedFilters.Contains(VcfConstants.PassFilter) || !vcfVariant.IsPassFilter() || IsSampleFtPassFilter(); if (!sampleFilterOk) { return(FailedReason.FailedSampleFilter); } // used include bed and variant is completely within a single contig and the bed doesn't include the contig if (inputSpec.IncludedRegions != null && svType != WittyerType.TranslocationBreakend && !inputSpec.IncludedRegions.IntervalTree.ContainsKey(vcfVariant.Contig)) { return(FailedReason.OutsideBedRegion); } return(FailedReason.Unset); bool IsSampleFtPassFilter() => sample != null && (!sample.SampleDictionary.TryGetValue(WittyerConstants.Ft, out var ft) || ft.Equals(VcfConstants.PassFilter)); } }