Example #1
0
        /// <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));
            }
        }