internal static IEnumerable <IVcfVariant> ProcessVariants([NotNull] IWittyerResult result, bool?isTruth) { var sampleIndex = isTruth == false ? 1 : 0; foreach (var variants in result.Variants.Values) { foreach (var variant in variants) { foreach (var ret in ConvertToVcfVariant(variant)) { yield return(ret); } } } foreach (var variants in result.BreakendPairsAndInsertions.Values) { foreach (var variant in variants) { foreach (var ret in ConvertToVcfVariant(variant)) { yield return(ret); } } } foreach (var ret in result.NotAssessedVariants.Select(ConvertToUnsupportedVcfVariant)) { yield return(ret); } IVcfVariant ConvertToUnsupportedVcfVariant(IVcfVariant originalVariant) => isTruth == null ? originalVariant : originalVariant.ToBuilder().SetSamples( GetClearedSampleBuilder(originalVariant.Samples[0].SampleDictionary, DefaultTruthSampleName, DefaultQuerySampleName).Build()) .Build(); IEnumerable <IVcfVariant> ConvertToVcfVariant(IWittyerSimpleVariant originalVariant) { //Info tag var win = originalVariant.Win.ToString(); var annotations = originalVariant.OverlapInfo; if (annotations.Count > WittyerConstants.MaxNumberOfAnnotations) { annotations = annotations.Take(WittyerConstants.MaxNumberOfAnnotations).ToList(); } var where = annotations.Count == 0 ? MissingValueString : annotations.Select(x => x.Where.ToString()) .StringJoin(WittyerConstants.InfoValueDel); var who = annotations.Count == 0 ? MissingValueString : annotations.Select(x => x.Who).StringJoin(WittyerConstants.InfoValueDel); var wow = !originalVariant.VariantType.HasOverlappingWindows || annotations.Count == 0 ? MissingValueString : annotations.Select(x => ToWowString(x.Wow)) .StringJoin(WittyerConstants.InfoValueDel); var infoDict = new Dictionary <string, string> { { Win, win }, { Where, where }, { Who, who }, { Wow, wow } }; var samples = AddWitTags(originalVariant.Sample.GetOriginalSample()?.SampleDictionary, isTruth == null ? new[] { originalVariant.Sample.GetOriginalSample()?.SampleName ?? "SAMPLE" } : DefaultSampleNamesPair); var updatedInfo = originalVariant.OriginalVariant.Info.ToImmutableDictionary().SetItems(infoDict); var firstVariant = originalVariant.OriginalVariant.ToBuilder().SetInfo(updatedInfo).SetSamples(samples); yield return(firstVariant.Build()); // insertions are secretly two breakends repeated. if (originalVariant is IWittyerBnd bnd && !ReferenceEquals(bnd.OriginalVariant, bnd.EndOriginalVariant)) { var sample = bnd.EndOriginalVariant.Samples.Values.FirstOrDefault(); samples = AddWitTags(sample?.SampleDictionary, isTruth == null ? new[] { sample?.SampleName ?? "SAMPLE" } : DefaultSampleNamesPair); yield return(bnd.EndOriginalVariant.ToBuilder() .SetInfo(bnd.EndOriginalVariant.Info.ToImmutableDictionary().SetItems(infoDict)).SetSamples(samples).Build()); } string ToWowString(IInterval <uint> interval) => interval == null ? MissingValueString : $"{interval.Start}-{interval.Stop}"; SampleDictionaries AddWitTags(IReadOnlyDictionary <string, string> sampleDict, string[] sampleNames) => GetClearedSampleBuilder(sampleDict, sampleNames) .SetSampleField(sampleIndex, (Wit, originalVariant.Sample.Wit.ToStringDescription())) .SetSampleField(sampleIndex, (Why, originalVariant.Sample.Why.Count == 0 ? NoOverlapString : originalVariant.Sample.Why.Select(x => x.ToStringDescription()) .StringJoin(WittyerConstants.SampleValueDel))) .SetSampleField(sampleIndex, (What, originalVariant.Sample.What.Count == 0 ? MissingValueString : originalVariant.Sample.What.Select(x => x.ToStringDescription()) .StringJoin(WittyerConstants.SampleValueDel))).Build(); } SampleDictionaryBuilder GetClearedSampleBuilder(IReadOnlyDictionary <string, string> sampleDict, params string[] sampleNames) { var builder = SampleDictionaries.CreateBuilder(); foreach (var sampleName in sampleNames) { builder.AddSample(sampleName); } var ret = builder.MoveOnToDictionaries(); if (sampleDict == null) { return(ret); } foreach (var kvp in sampleDict) { ret.SetSampleField(sampleIndex, (kvp.Key, kvp.Value)); } return(ret); } }
internal static IEnumerable <string> GenerateVcfStrings([CanBeNull] IWittyerResult queryResult, [CanBeNull] IWittyerResult truthResult, [CanBeNull] string cmdLine) { if (truthResult == null && queryResult == null) { throw new InvalidOperationException( $"called {nameof(GenerateVcfStrings)} when both {nameof(truthResult)} & {nameof(queryResult)} was null!"); } if (truthResult?.IsTruth == false || queryResult?.IsTruth == true) { throw new InvalidDataException( $"Passed in the wrong {nameof(IWittyerResult)} for {nameof(truthResult)} or {nameof(queryResult)}!"); } IEnumerable <(IVcfVariant variant, bool?isTruth)> elements = ImmutableList <(IVcfVariant, bool?)> .Empty; if (truthResult != null) { var isTruthValue = queryResult == null ? null : (bool?)true; elements = elements.Concat(ProcessVariants(truthResult, isTruthValue).Select(v => (v, isTruthValue))); } if (queryResult != null) { var isTruthValue = truthResult == null ? null : (bool?)false; elements = elements.Concat(ProcessVariants(queryResult, isTruthValue).Select(v => (v, isTruthValue))); } var count = 0U; var comparer = CreateComparer(queryResult?.Contigs, truthResult?.Contigs); foreach (var line in GetMergedWittyerVcfHeaderLocal()) { yield return(line); } foreach (var line in elements.OrderBy(x => x.variant, comparer) .Select(x => ToString(x.variant, x.isTruth))) { count++; yield return(line); } if (truthResult is IMutableWittyerResult truth && queryResult is IMutableWittyerResult query && count != truth.NumEntries + query.NumEntries) { throw new InvalidDataException( "Final VCF entry count was not the same as expected. Please contact witty.er developer!"); } IEnumerable <string> GetMergedWittyerVcfHeaderLocal() { if (truthResult == null) { return(ToSingleSampleHeader(queryResult)); } if (queryResult == null) { return(ToSingleSampleHeader(truthResult)); } return(truthResult.VcfHeader.MergedWith(queryResult.VcfHeader, SamplePair.Create(truthResult.SampleName, queryResult.SampleName), cmdLine)); IEnumerable <string> ToSingleSampleHeader(IWittyerResult result) { var builder = result.VcfHeader.ToBuilder(); var wittyerLines = VcfHeaderUtils.GenerateWittyerLines( result.VcfHeader.ColumnMetaInfoLines.InfoLines.Values, result.VcfHeader.ColumnMetaInfoLines.SampleFormatLines.Values, cmdLine); foreach (var line in wittyerLines) { builder.AddLine(line); } return(builder.Build().ToStrings().Select(line => line.StartsWith(Header.MetaPrefix) ? line : Header.Prefix + Header.ColumnNames.MinimumRequiredPlusSampleFormat .FollowedWith(result.SampleName) .StringJoin(ColumnDelimiter))); } } }
public static SampleMetrics GenerateSampleMetrics([NotNull] IWittyerResult truth, [NotNull] IWittyerResult query, bool isGenotypeEvaluated, [NotNull] IReadOnlyDictionary <WittyerType, InputSpec> inputSpecs) => Quantify.GenerateSampleStats(truth, query, isGenotypeEvaluated, inputSpecs);