private static Tuple <int, int> StageMNVdata(StitchingScenario scenario) { int MNVPosition = 0; int MNVLength = 0; if (scenario.Category.ToLower().Contains("mnv")) { MNVPosition = int.Parse(scenario.VarLoading.Substring(0, 1)); MNVLength = scenario.VarLoading.Length - 1; } return(Tuple.Create(MNVPosition, MNVLength)); }
public void RunStitchingScenarios(StitchingScenario scenario, string resultFile) { Console.WriteLine(scenario.Category + " " + scenario.Id); bool resultLogged = false; try { var stitcher = new BasicStitcher(10); var inputRead1 = scenario.InputRead1.ToRead(); var inputRead2 = scenario.InputRead2.ToRead(); var alignmentSet = new AlignmentSet(inputRead1, inputRead2); var didStitch = stitcher.TryStitch(alignmentSet); LogResult(resultFile, scenario, didStitch, alignmentSet); resultLogged = true; if (scenario.ShouldStitch) { Assert.Equal(scenario.ShouldStitch, didStitch); Assert.True(OutputDirectionsMatch(scenario, alignmentSet)); Assert.True(OutputCigarsMatch(scenario, alignmentSet)); } if (didStitch) { // TODO fix scenario source files so we can turn this back on. Assert.True(OutputCigarsMatch(scenario, alignmentSet)); } } catch (Exception ex) { if (!resultLogged) { LogResult(resultFile, scenario, false, null, message: "Threw exception: " + ex.Message); } throw; } }
public static string CheckLoading( StitchingScenario scenario, int readNumber, Dictionary <int, List <LoadTestResult> > counts, bool isVariantRead) { string expectedLoading = scenario.RefLoading.Split(';')[readNumber - 1]; if (isVariantRead) { expectedLoading = scenario.VarLoading.Split(';')[readNumber - 1]; } if (expectedLoading == "NA") { return("NA"); } int startPos = int.Parse(expectedLoading[0].ToString()); StringBuilder observedLoading = new StringBuilder(startPos.ToString()); for (int i = 0; i < expectedLoading.Length - 1; i++) { DirectionType expectedDir = LetterToDirection(expectedLoading[i].ToString()); int pos = startPos + i; if (counts[pos].Count == 0) { observedLoading.Append("0"); } else { observedLoading.Append(counts[pos][0].BaseDirection.ToString()[0]); } } return(observedLoading.ToString()); }
public static string[] CheckReadLoading(BamAlignment read, PiscesApplicationOptions options, ChrReference chrInfo, bool isVariant, StitchingScenario scenario) { string expectedVarLoading = scenario.RefLoading; string expectedCandidateDireciton = "0"; if (isVariant) { expectedVarLoading = scenario.VarLoading; expectedCandidateDireciton = scenario.CandidateDirection; } var loadingResults = LoadReads(new List <BamAlignment>() { read }, options, chrInfo, isVariant, expectedVarLoading, expectedCandidateDireciton); if (loadingResults == null) { return(new string[] { "total fail to parse variant reads" }); } //coverage check var variantReadLoadResult = CheckLoading(scenario, 1, loadingResults.Item1, isVariant); var variantReadCandidateDirection = CheckCandidateDirection(isVariant, loadingResults.Item2, expectedCandidateDireciton); if (variantReadLoadResult == null) { return(new string[] { "total fail to check loading" }); } if (variantReadCandidateDirection == null) { return(new string[] { "total fail to check direction" }); } return(new string[] { variantReadLoadResult, variantReadCandidateDirection }); }
public void TestReadLoadingOnStitchingScenarios(StitchingScenario scenario, string resultFile) { //limit the scope of concern for now. if (scenario.ShouldStitch != true) { return; } //limit the scope of concern for now. if (scenario.ShouldRefStitch != true) { return; } var resultsSummary = Path.Combine(Options.OutputFolder, LoadingSummaryFileName); using (StreamWriter sw = new StreamWriter(resultsSummary, true)) { var sb = new StringBuilder( string.Join(",", DateTime.Today.ToShortDateString(), DateTime.Now.ToLongTimeString(), scenario.Category, scenario.Id)); // If it was supposed to stitch, there should only be one read in the output reads, and it's the stitched one. var factory = new AmpliconTestFactory(RefGenomeSequence); try { byte qualityForAll = 30; var MNVdata = StageMNVdata(scenario); var varRead = BuildRead(scenario.OutputRead1, qualityForAll, MNVdata); var refRead = BuildRead(scenario.OutputRefRead1, qualityForAll, NoMNVdata(scenario)); if ((varRead == null) || (refRead == null)) { //total fail. sb.Append(",total fail to build reads"); sw.WriteLine(sb.ToString()); return; } //check the reads all loaded with the right counts into the right directions. var varLoadingResults = StitchedReadLoadingHelper.CheckReadLoading(varRead, Options, ChrInfo, true, scenario); if (varLoadingResults.Length == 1) { //total fail. get error msg sb.Append("," + varLoadingResults[0]); sw.WriteLine(sb.ToString()); return; } var refLoadingResults = StitchedReadLoadingHelper.CheckReadLoading(refRead, Options, ChrInfo, false, scenario); if (refLoadingResults.Length == 1) { //total fail. get error msg sb.Append("," + refLoadingResults[0]); sw.WriteLine(sb.ToString()); return; } List <string> expectedValues = new List <string>() { scenario.VarLoading, scenario.RefLoading, scenario.CandidateDirection, "0" }; List <string> observedValues = new List <string>() { varLoadingResults[0], refLoadingResults[0], varLoadingResults[1], refLoadingResults[1] }; sb.Append(GetResultString(expectedValues, observedValues)); sw.WriteLine(sb.ToString()); } catch (Exception ex) { sb.Append(",Fail: " + ex); sw.WriteLine(sb.ToString()); } } }
private static Tuple <int, int> NoMNVdata(StitchingScenario scenario) { return(Tuple.Create(-1, 0)); }
public void TestForStrandBiasOnStitchingScenarios(StitchingScenario scenario, string resultFile) { //limit the scope of concern for now. if (scenario.ShouldRefStitch != true) { return; } //limit the scope of concern for now. if (scenario.ShouldStitch != true) { return; } var resultsSummary = Path.Combine(Options.OutputFolder, StrandBiasSummaryFileName); using (StreamWriter sw = new StreamWriter(resultsSummary, true)) { var sb = new StringBuilder( string.Join(",", DateTime.Today.ToShortDateString(), DateTime.Now.ToLongTimeString(), scenario.Category, scenario.Id)); try { if (!Directory.Exists(Options.OutputFolder)) { Directory.CreateDirectory(Options.OutputFolder); } var factory = new AmpliconTestFactory(new string('A', 100), sourceIsStitched: true); byte qualityForAll = 30; int numVariantCounts = 2; // 10; int numReferenceCounts = 2; // 90; var varRead = BuildRead(scenario.OutputRead1, qualityForAll, StageMNVdata(scenario)); var refRead = BuildRead(scenario.OutputRefRead1, qualityForAll, NoMNVdata(scenario)); if (refRead == null) { return; } factory.StageStitchedVariant( varRead, numVariantCounts, refRead, numReferenceCounts); var outputFileName = string.Format("{0}_{1}.vcf", scenario.Category, scenario.Id); var vcfOutputPath = Path.Combine(Options.OutputFolder, outputFileName); var biasOutputPath = StrandBiasFileWriter.GetBiasFilePath(vcfOutputPath); File.Delete(vcfOutputPath); File.Delete(biasOutputPath); StitchedReadBiasHelper.CallStrandedVariantsWithMockData(vcfOutputPath, Options, factory); var varResults = StitchedReadBiasHelper.GetResults(VcfReader.GetAllVariantsInFile(vcfOutputPath)); var biasResults = StitchedReadBiasHelper.GetStrandResultsFromFile(biasOutputPath); var observedFrequency = (varResults.Count == 0) ? "0": ""; var observedSB = (biasResults.Count == 0) ? "FN": ""; for (int i = 0; i < varResults.Count; i++) { var varResult = varResults[i]; if (i != 0) { observedFrequency += ";"; } observedFrequency += varResult.VariantFrequency; } for (int i = 0; i < biasResults.Count; i++) { var biasResult = biasResults[i]; if (i != 0) { observedSB += ";"; } observedSB += biasResult.HasStrandBias; //there should be no SB on our current set of stitched scenarios. Assert.True(!biasResult.HasStrandBias); } var expectedValues = new List <string>() { "1", scenario.Frequency, scenario.ShouldBias }; var observedValues = new List <string>() { varResults.Count.ToString(), observedFrequency, observedSB }; sb.Append(GetResultString(expectedValues, observedValues)); sw.WriteLine(sb.ToString()); } catch (Exception ex) { sb.Append(",Fail: " + ex); sw.WriteLine(sb.ToString()); } } }
/// <summary> /// Log result info to a result file. Doesn't directly impact test, just useful for looking at the results all together. /// (Also useful for a deliverable output summary). /// </summary> /// <param name="resultFile"></param> /// <param name="scenario"></param> /// <param name="didStitch"></param> /// <param name="resultSet"></param> private void LogResult(string resultFile, StitchingScenario scenario, bool didStitch, AlignmentSet resultSet = null, string message = null) { var diagramLength = 12; // This is useful for looking at the results across the full test set. const string delimiter = ","; var visualResultsFile = resultFile + ".visuals.csv"; if (!File.Exists(visualResultsFile)) { using (var sw = File.CreateText(visualResultsFile)) { var leftOfDiagram = new List <string>() { "ID", "Pos", "Cigar", "Dirs", "Diagram Var" }; var varDiagram = Enumerable.Repeat("", diagramLength); var leftOfRef = new List <string>() { "Pos", "Cigar", "Dirs", "Diagram Ref" }; var refDiagram = Enumerable.Repeat("", diagramLength); var leftOfStitched = new List <string>() { "Pos", "Cigar", "Dirs", "Diagram Stitched" }; var stitchedDiagram = Enumerable.Repeat("", diagramLength); sw.WriteLine(string.Join(delimiter, leftOfDiagram. Concat(varDiagram). Concat(leftOfRef). Concat(refDiagram). Concat(leftOfStitched). Concat(stitchedDiagram))); } } using (var sw = File.AppendText(visualResultsFile)) { Read stitchedRead = null; if (resultSet != null && resultSet.ReadsForProcessing.Any()) { stitchedRead = resultSet.ReadsForProcessing.First(); } // First row var leftOfDiagram = new List <string>() { scenario.Category + "-" + scenario.Id, scenario.InputRead1.Position.ToString(), scenario.InputRead1.Cigar, scenario.InputRead1.Directions }; var r1Cigar = new CigarAlignment(scenario.InputRead1.Cigar); var r2Cigar = new CigarAlignment(scenario.InputRead2.Cigar); var r1BasesStart = scenario.InputRead1.Position - 1 - (int)r1Cigar.GetPrefixClip(); var r2BasesStart = scenario.InputRead2.Position - 1 - (int)r2Cigar.GetPrefixClip(); if (r1BasesStart < 0 || r2BasesStart < 0) { throw new ArgumentException("Test scenario has invalid position/cigar combination: " + scenario.InputRead1.Position + ":" + scenario.InputRead1.Cigar + " or " + scenario.InputRead2.Position + ":" + scenario.InputRead2.Cigar); } if (r1BasesStart < 0) { r1BasesStart = 0; } if (r2BasesStart < 0) { r2BasesStart = 0; } var r2CigarLength = 0; foreach (CigarOp op in r2Cigar) { r2CigarLength += (int)op.Length; } var r2BasesEnd = r2BasesStart + r2CigarLength; var preOverlapCigar = new CigarAlignment(scenario.InputRead1.Cigar).GetClippedCigar(0, (int)(r2BasesStart - r1BasesStart) + 1, includeWholeEndIns: true); var insertionsPreOverlap = preOverlapCigar.CountOperations('I'); var expectedReadLength = r2BasesEnd - r1BasesStart + insertionsPreOverlap; r2BasesStart = r2BasesStart + insertionsPreOverlap; var varDiagram = Enumerable.Repeat("", r1BasesStart).Concat(ExpandCigar(r1Cigar, new CigarDirection(scenario.InputRead1.Directions))).ToList(); varDiagram = varDiagram.Concat(Enumerable.Repeat("", diagramLength - varDiagram.Count()).ToList()).ToList(); var leftOfRef = new List <string>() { scenario.InputRead2.Position.ToString(), scenario.InputRead2.Cigar, scenario.InputRead2.Directions }; var refDiagram = Enumerable.Repeat("", diagramLength); var leftOfStitched = Enumerable.Repeat("", 3).ToList(); var stitchedDiagram = Enumerable.Repeat("NA", diagramLength); if (stitchedRead != null && stitchedRead.CigarDirections != null) { var stitchedBasesStart = stitchedRead.Position - 1 - (int)stitchedRead.CigarData.GetPrefixClip(); leftOfStitched = new List <string>() { stitchedRead.Position.ToString(), stitchedRead.CigarData.ToString(), GetDirectionsString(stitchedRead) }; stitchedDiagram = Enumerable.Repeat("", stitchedBasesStart).Concat(ExpandCigar(stitchedRead.CigarData, stitchedRead.CigarDirections)); } sw.WriteLine(string.Join(delimiter, leftOfDiagram. Concat(varDiagram). Concat(leftOfRef). Concat(refDiagram). Concat(leftOfStitched). Concat(stitchedDiagram))); // Second row var varDiagramR2 = Enumerable.Repeat("", r2BasesStart) .Concat(ExpandCigar(r2Cigar, new CigarDirection(scenario.InputRead2.Directions))); varDiagramR2 = varDiagramR2.Concat(Enumerable.Repeat("", diagramLength - varDiagramR2.Count())).ToList(); var leftOfDiagramPad = new List <string>() { "", scenario.InputRead2.Position.ToString(), scenario.InputRead2.Cigar, scenario.InputRead2.Directions }; var leftOfRefPad = Enumerable.Repeat("", leftOfRef.Count); var leftOfStitchedPad = Enumerable.Repeat("", leftOfStitched.Count); var refDiagramR2 = Enumerable.Repeat("", diagramLength); var totalBasesCovered = Enumerable.Repeat("", r1BasesStart).Concat(Enumerable.Repeat("+", expectedReadLength)).ToList(); sw.WriteLine(string.Join(delimiter, leftOfDiagramPad. Concat(varDiagramR2). Concat(leftOfRefPad). Concat(refDiagramR2). Concat(leftOfStitchedPad). Concat(totalBasesCovered) )); sw.WriteLine(); } if (!File.Exists(resultFile)) { // Create a file to write to, and write the header. using (var sw = File.CreateText(resultFile)) { sw.WriteLine(string.Join(delimiter, new[] { "ID", "R1_Pos", "R1_Cigar", "R1_Dirs", "R2_Pos", "R2_Cigar", "R2_Dirs", "ShouldStitch", "DidStitch", "Exp_SR_Pos", "Exp_SR_Cigar", "Exp_SR_Dirs", "Actual_SR_Pos", "Actual_SR_Cigar", "Actual_SR_Dirs", "Notes", "Pass", "Message" })); } } using (var sw = File.AppendText(resultFile)) { // Add everything we know from the input scenario, and whether it did stitch. var fields = new List <string>() { scenario.Category + "-" + scenario.Id, scenario.InputRead1.Position.ToString(), scenario.InputRead1.Cigar, scenario.InputRead1.Directions, scenario.InputRead2.Position.ToString(), scenario.InputRead2.Cigar, scenario.InputRead2.Directions, scenario.ShouldStitch.ToString(), didStitch.ToString(), scenario.OutputRead1.Position.ToString(), scenario.OutputRead1.Cigar, scenario.OutputRead1.Directions, }; var stitchResultsMatch = false; var cigarResultsMatch = false; var directionResultsMatch = false; stitchResultsMatch = scenario.ShouldStitch == didStitch; // Add the info from the output reads if (resultSet != null && resultSet.ReadsForProcessing.Any() && resultSet.ReadsForProcessing.First().CigarDirections != null) { var stitchedRead = resultSet.ReadsForProcessing.First(); var directions = GetDirectionsString(stitchedRead); fields.AddRange(new List <string>() { stitchedRead.Position.ToString(), stitchedRead.CigarData.ToString(), directions }); cigarResultsMatch = !scenario.ShouldStitch || OutputCigarsMatch(scenario, resultSet); directionResultsMatch = !scenario.ShouldStitch || OutputDirectionsMatch(scenario, resultSet); } else { fields.AddRange(new List <string>() { "", "", "" }); } // Determine if this scenario "Passed" (i.e. matched expectations). (TODO if the resultSet is null, it failed -- is that valid?) var testResult = (!scenario.ShouldStitch && stitchResultsMatch) || (stitchResultsMatch && cigarResultsMatch && directionResultsMatch); fields.Add(Sanitize(scenario.Notes, Convert.ToChar(delimiter))); fields.Add(testResult.ToString()); fields.Add(message); // Write scenario results to file sw.WriteLine(string.Join(delimiter, fields)); } }
private bool OutputCigarsMatch(StitchingScenario scenario, AlignmentSet alignmentSet) { return(scenario.OutputRead1.Cigar == alignmentSet.ReadsForProcessing.First().CigarData.ToString()); }
private bool OutputDirectionsMatch(StitchingScenario scenario, AlignmentSet alignmentSet) { var directions = GetDirectionsString(alignmentSet.ReadsForProcessing.First()); return(scenario.OutputRead1.Directions == directions); }