Ejemplo n.º 1
0
 public override void GatherPathStats(GamePath gamePath, Board board)
 {
     gamePath.MaxArea   = (float)MaxArea.MaximalRectangle(board.Cells) / 64;
     gamePath.FragScore = Fragmentation.GetFragmentationScore(board.Cells);
     //here the gamePath get the result from the addition function
     gamePath.Tsiun = GetMaxArea(board);
 }
Ejemplo n.º 2
0
        /// <summary>
        /// This function computes the b and y fragments needed
        /// for the computation of XCorr.
        /// </summary>
        /// <param name="peptide">A peptide sequence</param>
        /// <param name="maxIonCharge">Max charge state for a fragment</param>
        /// <param name="frags">A reference map to hold the fragment masses and their charges states</param>
        /// <param name="fragTypes">A reference map to hold the fragment masses and their ion types</param>
        public static void calculateSequenceIons(Peptide peptide, int maxIonCharge, ref Map <double, int> frags, ref Map <double, char> fragTypes)
        {
            Fragmentation fragmentation = peptide.fragmentation(true, true);

            for (int i = 1; i <= maxIonCharge; ++i)
            {
                for (int c = 0; c < peptide.sequence.Length; ++c)
                {
                    int nLength = c;
                    int cLength = peptide.sequence.Length - c;
                    if (nLength > 0)
                    {
                        double mass = fragmentation.b(nLength, i);
                        frags.Insert(new MutableKeyValuePair <double, int>(mass, i));
                        fragTypes.Insert(new MutableKeyValuePair <double, char>(mass, 'b'));
                    }
                    if (cLength > 0)
                    {
                        double mass = fragmentation.y(cLength, i);
                        frags.Insert(new MutableKeyValuePair <double, int>(mass, i));
                        fragTypes.Insert(new MutableKeyValuePair <double, char>(mass, 'y'));
                    }
                }
            }
        }
Ejemplo n.º 3
0
        public void NoFragsTest()
        {
            Board board = new Board();

            Assert.IsTrue(Math.Abs(1F - Fragmentation.GetFragmentationScore(board.Cells)) < 0.0001);
            Assert.AreEqual(0, Fragmentation.SurroundedSignals(board.Cells));
        }
Ejemplo n.º 4
0
        public void SomeFragsTest()
        {
            Board board = new Board();

            board.Cells[0][0] = true;

            Assert.IsTrue(Math.Abs(0.966666639F - Fragmentation.GetFragmentationScore(board.Cells)) < 0.0001);
            Assert.AreEqual(0, Fragmentation.SurroundedSignals(board.Cells));
        }
Ejemplo n.º 5
0
        public void MaxFragTest()
        {
            Board board = new Board();

            for (int x = 0; x < 8; x = x + 2)
            {
                for (int y = 0; y < 8; y++)
                {
                    board.Cells[x + (y % 2)][y] = true;
                }
            }

            Assert.IsTrue(Math.Abs(0F - Fragmentation.GetFragmentationScore(board.Cells)) < 0.0001);
            Assert.AreEqual(32, Fragmentation.SurroundedSignals(board.Cells));
        }
Ejemplo n.º 6
0
        public void MakeAMove(out int shapeId, out string placement, Board board, IDictionary <int, Shape> shapes, IGameDrawer renderer)
        {
            placement = "";
            shapeId   = 0;
            var candidates = new List <Candidate>();

            foreach (var shape in shapes)
            {
                for (int x = 0; x < 8; x++)
                {
                    for (int y = 0; y < 8; y++)
                    {
                        var newBoard     = new Board(board);
                        var curPlacement = "" + (char)(97 + x) + (char)(49 + y);
                        if (newBoard.TryPlace(shape.Value, curPlacement))
                        {
                            var candidate = new Candidate()
                            {
                                Placement  = curPlacement,
                                ShapeId    = shape.Key,
                                ScoreGain  = (newBoard.Score - shape.Value.Score) - board.Score,
                                CellsGain  = newBoard.CellCount() - board.CellCount(),
                                LinesScore = newBoard.LinesScore(),
                                MaxArea    = MaxArea.MaximalRectangle(newBoard.Cells),
                                FragScore  = Fragmentation.GetFragmentationScore(newBoard.Cells)
                            };
                            candidates.Add(candidate);
                        }
                    }
                }
            }

            var maxAreaList = from x in candidates orderby x.MaxArea descending, x.FragScore descending select x;
            var fragScoreList = from x in candidates orderby x.FragScore descending, x.MaxArea descending select x;

            var maxArea   = maxAreaList.First();
            var fragScore = fragScoreList.First();

            var final = fragScore.MaxArea < 0.32F ? maxArea : fragScore;

            placement = final.Placement;
            shapeId   = final.ShapeId;
        }
Ejemplo n.º 7
0
        public void SurroundFragsTest()
        {
            Board board = new Board();

            board.Cells[1][0] = true;
            board.Cells[0][1] = true;

            board.Cells[6][0] = true;
            board.Cells[7][1] = true;

            board.Cells[0][6] = true;
            board.Cells[1][7] = true;

            board.Cells[6][7] = true;
            board.Cells[7][6] = true;

            Assert.IsTrue(Math.Abs(0.7666667F - Fragmentation.GetFragmentationScore(board.Cells)) < 0.0001);
            Assert.AreEqual(4, Fragmentation.SurroundedSignals(board.Cells));
        }
Ejemplo n.º 8
0
        /// <summary>
        /// This function takes a peptide and predicts the b/y sequence ions associated with it.
        /// </summary>
        /// <param name="peptide"></param>
        /// <param name="maxIonCharge"></param>
        /// <param name="fragMasses"></param>
        public static void calculateSequenceIons(Peptide peptide, int maxIonCharge, ref Set <double> fragMasses)
        {
            Fragmentation fragmentation = peptide.fragmentation(true, true);

            for (int i = 1; i <= maxIonCharge; ++i)
            {
                for (int c = 0; c < peptide.sequence.Length; ++c)
                {
                    int nLength = c;
                    int cLength = peptide.sequence.Length - c;
                    if (nLength > 0)
                    {
                        fragMasses.Add(fragmentation.b(nLength, i));
                    }
                    if (cLength > 0)
                    {
                        fragMasses.Add(fragmentation.y(cLength, i));
                    }
                }
            }
        }
Ejemplo n.º 9
0
        ///<summary>Adds user requested ion series on top of the chart.</summary>
        private void addIonSeries (GraphObjList list, pwiz.MSGraph.MSPointList points, Peptide peptide, Fragmentation fragmentation, string topSeries, string bottomSeries)
        {
            int ionSeriesChargeState = min;
            string sequence = peptide.sequence;
            ModificationMap modifications = peptide.modifications();

            // Select the color for the ion series.
            Color topSeriesColor;
            Color bottomSeriesColor;
            switch (topSeries)
            {
                default: topSeriesColor = Color.Gray; break;
                case "a": topSeriesColor = Color.YellowGreen; break;
                case "b": topSeriesColor = Color.BlueViolet; break;
                case "c": topSeriesColor = Color.Orange; break;
            }

            switch (bottomSeries)
            {
                default: bottomSeriesColor = Color.Gray; break;
                case "x": bottomSeriesColor = Color.Green; break;
                case "y": bottomSeriesColor = Color.Blue; break;
                case "z": bottomSeriesColor = Color.OrangeRed; break;
                case "z*": bottomSeriesColor = Color.Crimson; break;
            }
            // Ion series offsets. These offsets control where on the chart a particular ion series
            // get displayed
            double topSeriesOffset = 0.025;
            double bottomSeriesOffset = 0.1;
            if (topSeries.Length == 0)
                bottomSeriesOffset = topSeriesOffset;

            double topSeriesLeftPoint = 0.0;
            double bottomSeriesLeftPoint = 0.0;

            // Step through each fragmentation site
            for (int i = 1; i <= sequence.Length; ++i)
            {
                // Paint the top series first
                double rightPoint = 0.0;
                // Figure out the right mz for this fragmentaion site
                switch (topSeries)
                {
                    case "a": rightPoint = fragmentation.a(i, ionSeriesChargeState); break;
                    case "b": rightPoint = fragmentation.b(i, ionSeriesChargeState); break;
                    case "c": if (i < sequence.Length) rightPoint = fragmentation.c(i, ionSeriesChargeState); break;
                    default: continue;
                }

                // If the left mz and right mz are different
                if (rightPoint > 0 && topSeriesLeftPoint != rightPoint)
                {
                    LineObj line;
                    // Use a dashed line format if there are fragment ions supporting this
                    // amino acid
                    if (!aminoAcidHasFragmentEvidence(points, topSeriesLeftPoint, rightPoint))
                    {
                        // Draw the line from previous mz to site to this mz in trasparent color.
                        line = new LineObj(Color.FromArgb(115, topSeriesColor), topSeriesLeftPoint, topSeriesOffset, rightPoint, topSeriesOffset);
                        line.Line.Style = System.Drawing.Drawing2D.DashStyle.Dash;
                    }
                    else
                    {
                        // Draw the line from previous mz to site to this mz in solid color.
                        line = new LineObj(topSeriesColor, topSeriesLeftPoint, topSeriesOffset, rightPoint, topSeriesOffset);
                    }
                    line.Location.CoordinateFrame = CoordType.XScaleYChartFraction;
                    line.Line.Width = 2;
                    line.ZOrder = ZOrder.F_BehindGrid;
                    line.IsClippedToChartRect = true;
                    list.Add(line);
                    // Add a tick demarking the fragmentation site.
                    LineObj tick = new LineObj(topSeriesColor, rightPoint, (topSeriesOffset - 0.015), rightPoint, (topSeriesOffset + 0.015));
                    tick.Location.CoordinateFrame = CoordType.XScaleYChartFraction;
                    tick.Line.Width = 2;
                    tick.IsClippedToChartRect = true;
                    list.Add(tick);
                    // Add a text box in the middle of the left and right mz boundaries
                    StringBuilder label = new StringBuilder(sequence[i - 1].ToString());
                    // Figure out if any mods are there on this amino acid
                    double deltaMass = modifications[i - 1].monoisotopicDeltaMass();
                    // Round the mod mass and append it to the amino acid as a string
                    if (deltaMass > 0.0)
                    {
                        label.Append("+" + Math.Round(deltaMass));
                    }
                    else if (deltaMass < 0.0)
                    {
                        label.Append(Math.Round(deltaMass));
                    }
                    TextObj text = new TextObj(label.ToString(), (topSeriesLeftPoint + rightPoint) / 2.0,
                        topSeriesOffset, CoordType.XScaleYChartFraction, AlignH.Center, AlignV.Center);
                    text.ZOrder = ZOrder.A_InFront;
                    text.FontSpec = new FontSpec("Arial", 13, Color.Black, true, false, false);
                    text.FontSpec.Border.IsVisible = false;
                    text.FontSpec.Fill.Color = Color.White;
                    text.IsClippedToChartRect = true;
                    list.Add(text);
                    topSeriesLeftPoint = rightPoint;
                }

                // Time to paint the bottom series
                // Get the right mz for this series
                switch (bottomSeries)
                {
                    case "x": if (i < sequence.Length) rightPoint = fragmentation.x(i, ionSeriesChargeState); break;
                    case "y": rightPoint = fragmentation.y(i, ionSeriesChargeState); break;
                    case "z": rightPoint = fragmentation.z(i, ionSeriesChargeState); break;
                    case "z*": rightPoint = fragmentation.zRadical(i, ionSeriesChargeState); break;
                    default: rightPoint = 0.0; break;
                }

                // If the left and right mz are different
                if (rightPoint > 0 && bottomSeriesLeftPoint != rightPoint)
                {
                    LineObj line;
                    // Use a dashed line format if there are fragment ions supporting this
                    // amino acid
                    if (!aminoAcidHasFragmentEvidence(points, bottomSeriesLeftPoint, rightPoint))
                    {
                        // Draw the line from previous mz to site to this mz in trasparent color.
                        line = new LineObj(Color.FromArgb(115, bottomSeriesColor), bottomSeriesLeftPoint, bottomSeriesOffset, rightPoint, bottomSeriesOffset);
                        line.Line.Style = System.Drawing.Drawing2D.DashStyle.Dash;
                    }
                    else
                    {
                        // Draw the line from previous mz to site to this mz in solid color.
                        line = new LineObj(bottomSeriesColor, bottomSeriesLeftPoint, bottomSeriesOffset, rightPoint, bottomSeriesOffset);
                    }
                    line.Location.CoordinateFrame = CoordType.XScaleYChartFraction;
                    line.Line.Width = 2;
                    line.ZOrder = ZOrder.F_BehindGrid;
                    line.IsClippedToChartRect = true;
                    list.Add(line);
                    // Draw a tick mark demarking the fragmentation site
                    LineObj tick = new LineObj(bottomSeriesColor, rightPoint, (bottomSeriesOffset - 0.015), rightPoint, (bottomSeriesOffset + 0.015));
                    tick.Location.CoordinateFrame = CoordType.XScaleYChartFraction;
                    tick.Line.Width = 2;
                    tick.IsClippedToChartRect = true;
                    list.Add(tick);
                    // Add the text label containing the amino acid
                    StringBuilder label = new StringBuilder(sequence[sequence.Length - i].ToString());
                    // Figure out if any mods are there on this amino acid
                    double deltaMass = modifications[sequence.Length - i].monoisotopicDeltaMass();
                    // Round the mod mass and append it to the amino acid as a string
                    if (deltaMass > 0.0)
                    {
                        label.Append("+" + Math.Round(deltaMass));
                    }
                    else if (deltaMass < 0.0)
                    {
                        label.Append(Math.Round(deltaMass));
                    }
                    TextObj text = new TextObj(label.ToString(), (bottomSeriesLeftPoint + rightPoint) / 2.0,
                        bottomSeriesOffset, CoordType.XScaleYChartFraction, AlignH.Center, AlignV.Center);
                    text.ZOrder = ZOrder.A_InFront;
                    text.FontSpec = new FontSpec("Arial", 13, Color.Black, true, false, false);
                    text.FontSpec.Border.IsVisible = false;
                    text.FontSpec.Fill.Color = Color.White;
                    text.IsClippedToChartRect = true;
                    list.Add(text);
                    bottomSeriesLeftPoint = rightPoint;
                }
            }
        }
Ejemplo n.º 10
0
        ///<summary>Adds user requested ion series to the fragmentation summary.</summary>
        private void addFragmentationSummary (GraphObjList list, pwiz.MSGraph.MSPointList points, Peptide peptide, Fragmentation fragmentation, string topSeries, string bottomSeries)
        {
            int ionSeriesChargeState = min;
            string sequence = peptide.sequence;
            ModificationMap modifications = peptide.modifications();

            // Select the color for the ion series.
            Color topSeriesColor;
            Color bottomSeriesColor;
            switch (topSeries)
            {
                default: topSeriesColor = Color.Gray; break;
                case "a": topSeriesColor = Color.YellowGreen; break;
                case "b": topSeriesColor = Color.BlueViolet; break;
                case "c": topSeriesColor = Color.Orange; break;
            }

            switch (bottomSeries)
            {
                default: bottomSeriesColor = Color.Gray; break;
                case "x": bottomSeriesColor = Color.Green; break;
                case "y": bottomSeriesColor = Color.Blue; break;
                case "z": bottomSeriesColor = Color.OrangeRed; break;
                case "z*": bottomSeriesColor = Color.Crimson; break;
            }

            // Ion series offsets. These offsets control where on the chart a particular ion series get displayed
            double seriesTopLeftOffset = 0.2;

            // Set the constants for starting the label paint
            double topSeriesLeftPoint = 0.025;
            double residueWidth = 0.5 / ((double) sequence.Length);
            double topSeriesRightPoint = topSeriesLeftPoint + 0.5 - residueWidth;
            double tickStart = residueWidth / 2.0;

            // Process all the series except c and x
            for (int i = 1; i <= sequence.Length; ++i)
            {
                double topSeriesFragmentMZ = 0.0;
                double bottomSeriesFragmentMZ = 0.0;
                switch (topSeries)
                {
                    case "a": topSeriesFragmentMZ = fragmentation.a(i, ionSeriesChargeState); break;
                    case "b": topSeriesFragmentMZ = fragmentation.b(i, ionSeriesChargeState); break;
                    case "c": if (i < sequence.Length) topSeriesFragmentMZ = fragmentation.c(i, ionSeriesChargeState); break;
                    default: continue;
                }
                switch (bottomSeries)
                {
                    case "x": if (i < sequence.Length) bottomSeriesFragmentMZ = fragmentation.x(i, ionSeriesChargeState); break;
                    case "y": bottomSeriesFragmentMZ = fragmentation.y(i, ionSeriesChargeState); break;
                    case "z": bottomSeriesFragmentMZ = fragmentation.z(i, ionSeriesChargeState); break;
                    case "z*": bottomSeriesFragmentMZ = fragmentation.zRadical(i, ionSeriesChargeState); break;
                    default: continue;
                }

                // Check if the top and bottom fragments have evidence
                bool topSeriesHasMatch = false;
                bool bottomSeriesHasMatch = false;
                if (points != null)
                {
                    topSeriesHasMatch = topSeriesFragmentMZ > 0 && findPointWithTolerance(points, topSeriesFragmentMZ, tolerance) > -1;
                    bottomSeriesHasMatch = bottomSeriesFragmentMZ > 0 && findPointWithTolerance(points, bottomSeriesFragmentMZ, tolerance) > -1;
                }

                // Build the label for the amino acid
                // Add a text box in the middle of the left and right mz boundaries
                StringBuilder label = new StringBuilder(sequence[i - 1].ToString());

                // Figure out if any mods are there on this amino acid
                double deltaMass = modifications[i - 1].monoisotopicDeltaMass();

                // Round the mod mass and append it to the amino acid as a string
                if (deltaMass > 0.0)
                {
                    label.Append("+" + Math.Round(deltaMass));
                }
                else if (deltaMass < 0.0)
                {
                    label.Append(Math.Round(deltaMass));
                }

                TextObj text = new TextObj(label.ToString(), topSeriesLeftPoint, seriesTopLeftOffset, CoordType.ChartFraction, AlignH.Center, AlignV.Center);
                text.ZOrder = ZOrder.A_InFront;
                text.FontSpec = new FontSpec("Arial", 13, Color.Black, true, false, false);
                text.FontSpec.Border.IsVisible = false;
                text.FontSpec.Fill.Color = Color.White;
                text.IsClippedToChartRect = false;
                list.Add(text);

                if (topSeriesHasMatch)
                {
                    // Paint the tick in the middle
                    LineObj tick = new LineObj(topSeriesColor, topSeriesLeftPoint + tickStart, (seriesTopLeftOffset - 0.05), topSeriesLeftPoint + tickStart, seriesTopLeftOffset);
                    tick.Location.CoordinateFrame = CoordType.ChartFraction;
                    tick.Line.Width = 2;
                    tick.IsClippedToChartRect = true;
                    list.Add(tick);
                    // Paint the hook
                    LineObj hook = new LineObj(topSeriesColor, topSeriesLeftPoint, (seriesTopLeftOffset - 0.08), topSeriesLeftPoint + tickStart, seriesTopLeftOffset - 0.05);
                    hook.Location.CoordinateFrame = CoordType.ChartFraction;
                    hook.Line.Width = 2;
                    hook.IsClippedToChartRect = true;
                    list.Add(hook);
                }

                if (bottomSeriesHasMatch)
                {
                    // Paint the tick in the middle
                    LineObj tick = new LineObj(bottomSeriesColor, topSeriesRightPoint + tickStart, seriesTopLeftOffset, topSeriesRightPoint + tickStart, seriesTopLeftOffset + 0.05);
                    tick.Location.CoordinateFrame = CoordType.ChartFraction;
                    tick.Line.Width = 2;
                    tick.IsClippedToChartRect = true;
                    list.Add(tick);
                    // Paint the hook
                    LineObj hook = new LineObj(bottomSeriesColor, topSeriesRightPoint + tickStart, seriesTopLeftOffset + 0.05, topSeriesRightPoint + 2.0 * tickStart, seriesTopLeftOffset + 0.08);
                    hook.Location.CoordinateFrame = CoordType.ChartFraction;
                    hook.Line.Width = 2;
                    hook.IsClippedToChartRect = true;
                    list.Add(hook);
                }
                // Update the next paint point
                topSeriesLeftPoint += residueWidth;
                topSeriesRightPoint -= residueWidth;
            }
        }
Ejemplo n.º 11
0
        ///<summary>Adds user requested ion series to the fragmentation summary.</summary>
        private void addFragmentationSummary(GraphObjList list, pwiz.MSGraph.MSPointList points, Peptide peptide, Fragmentation fragmentation, string topSeries, string bottomSeries)
        {
            ///cutoff definition for neutral loss
            double basePeakIntensity = 0;
            double cutoff = 0;
            foreach (var pointlist in points)
            {
                if (basePeakIntensity < pointlist.Y)
                    basePeakIntensity = pointlist.Y;
            }
            cutoff = basePeakIntensity * basePeakPercentage * 0.01;
            ///

            int ionSeriesChargeState = min;
            string sequence = peptide.sequence;
            int sequenceLength = peptide.sequence.Length;
            ModificationMap modifications = peptide.modifications();

            // Select the color for the ion series.
            Color topSeriesColor;
            Color bottomSeriesColor;
            switch (topSeries)
            {
                default: topSeriesColor = Color.Gray; break;
                case "a": topSeriesColor = Color.YellowGreen; break;
                case "b": topSeriesColor = Color.Red; break;
                case "c": topSeriesColor = Color.Orange; break;
            }

            switch (bottomSeries)
            {
                default: bottomSeriesColor = Color.Gray; break;
                case "x": bottomSeriesColor = Color.Green; break;
                case "y": bottomSeriesColor = Color.Blue; break;
                case "z": bottomSeriesColor = Color.OrangeRed; break;
                case "z*": bottomSeriesColor = Color.Crimson; break;
            }
            // Ion series offsets. These offsets control where on the chart a particular ion series
            // get displayed
            //change the seriesTopLeftOffset value to 0.1 to make the label higher in the image.
            //original is 0.031
            double seriesTopLeftOffset = 0.05;
            // Set the constants for starting the label paint
            double topSeriesLeftPoint = 0.025;
            //test and looks reasonalbe
            double residueWidth = 0.031;
            //double residueWidth = 0.25 / ((double)sequence.Length);

            // Process all the series except c and x

            //small block modified
            //here is a big bug: if go like orignal code, then the y ions is just the like the order of b ions, which are not right.
            //My modification is to seperate a/b/c and x/y/z ions, and then it will solve this problem.
            //it seems works well.

            ///
            #region Process a/b ions
            //first we are going to touch only a/b ions
            ///
            for (int i = 1; i <= sequence.Length; ++i)
            {
                double tickStart = residueWidth * 4 / 5.0;
                double topSeriesFragmentMZ = 0.0;

                //test neutral loss
                //this block is to give clear clue for phospate loss
                //exact number of phosphated amino acids are counted.
                string Nseq = peptide.sequence.Substring(0, i);
                char[] Nseqchars = Nseq.ToCharArray();
                int Nphosmodi = 0;
                for (int k = 0; k < i; k++)
                {
                    if (Math.Round(modifications[k].monoisotopicDeltaMass()) == 80 && (Nseqchars[k] == 'S' || Nseqchars[k] == 'T' || Nseqchars[k] == 'Y'))
                    {
                        Nphosmodi++;
                    }
                }

                //correct the bug:
                //when multiple charges allowed for fragmentation, then there is no tick thing showing the existance of the fragment
                //what I did is: make top/bottomSeriesHasMatch true if there is fragment of any charges matched.
                //bug fixed
                bool topSeriesHasMatch = false;
                for (int z = min; z <= max; z++)
                {
                    switch (topSeries)
                    {
                        case "a": topSeriesFragmentMZ = fragmentation.a(i, z); break;
                        case "b": topSeriesFragmentMZ = fragmentation.b(i, z); break;
                        default: topSeriesFragmentMZ = 0.0; break;
                    }

                    // Check if the top and bottom fragments have evidence
                    if (points != null)
                    {
                        // Search index
                        int index = -1;
                        // Find the left mz value using a mass tolerance of 0.5 da.
                        index = points.FullLowerBound(topSeriesFragmentMZ - 0.5);
                        if (index != -1 && points.FullList[index].X <= (topSeriesFragmentMZ + 0.5))
                        {
                            topSeriesHasMatch = true;
                            break;
                        }
                    }

                    //test neutral loss
                    #region water loss a/b top series
                    if (waterLoss == true)
                    {
                        if (Nseq.Contains("S") || Nseq.Contains("T") || Nseq.Contains("E") || Nseq.Contains("D"))
                        {
                            // Check if the top and bottom fragments have evidence
                            if (points != null)
                            {
                                // Search index
                                int index = -1;
                                // Find the left mz value using a mass tolerance of 0.5 da.
                                index = points.FullLowerBound(topSeriesFragmentMZ - WATERMONOMASS/z - 0.5);
                                if (basePeakThresholding == false)
                                {
                                    if (index != -1 && points.FullList[index].X <= (topSeriesFragmentMZ - WATERMONOMASS / z + 0.5))
                                    {
                                        topSeriesHasMatch = true;
                                        break;
                                    }
                                }
                                else
                                {
                                    if (index != -1 && points.FullList[index].X <= (topSeriesFragmentMZ - WATERMONOMASS / z + 0.5) && points.FullList[index].Y >= cutoff)
                                    {
                                        topSeriesHasMatch = true;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    #endregion

                    //test neutral loss
                    #region ammonium loss a/b top series
                    if (ammoniumLoss == true)
                    {
                        if (Nseq.Contains("R") || Nseq.Contains("K") || Nseq.Contains("Q") || Nseq.Contains("N"))
                        {
                            if (points != null)
                            {
                                // Search index
                                int index = -1;
                                // Find the left mz value using a mass tolerance of 0.5 da.
                                index = points.FullLowerBound(topSeriesFragmentMZ - AMMONIUMMONOMASS / z - 0.5);
                                if (basePeakThresholding == false)
                                {
                                    if (index != -1 && points.FullList[index].X <= (topSeriesFragmentMZ - AMMONIUMMONOMASS / z + 0.5))
                                    {
                                        topSeriesHasMatch = true;
                                        break;
                                    }
                                }
                                else
                                {
                                    if (index != -1 && points.FullList[index].X <= (topSeriesFragmentMZ - AMMONIUMMONOMASS / z + 0.5) && points.FullList[index].Y > cutoff)
                                    {
                                        topSeriesHasMatch = true;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    #endregion

                    //test neutral loss
                    #region phosphate loss a/b top series
                    if (phosphateLoss == true)
                    {
                        //need to judge qualified number of AAs;
                        int minPhosphate = Math.Min(Nphosmodi, numPhosphate);

                        if (minPhosphate > 0)
                        {
                            for (int k = 1; k <= minPhosphate; k++)
                            {
                                //first need to judge if there are as many as phos AAs
                                //then if AA <= phos, then deal with AA;
                                //if AA > phos, then deal with phos.
                                if (points != null)
                                {
                                    // Search index
                                    int index = -1;
                                    // Find the left mz value using a mass tolerance of 0.5 da.
                                    index = points.FullLowerBound(topSeriesFragmentMZ - k * PHOSPHATEMONOMASS / z - 0.5);
                                    if (basePeakThresholding == false)
                                    {
                                        if (index != -1 && points.FullList[index].X <= (topSeriesFragmentMZ - k * PHOSPHATEMONOMASS / z + 0.5))
                                        {
                                            topSeriesHasMatch = true;
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        if (index != -1 && points.FullList[index].X <= (topSeriesFragmentMZ - k * PHOSPHATEMONOMASS / z + 0.5) && points.FullList[index].Y > cutoff)
                                        {
                                            topSeriesHasMatch = true;
                                            break;
                                        }
                                    }
                                }
                            }
                        }

                    }
                    #endregion
                }

                // Build the label for the amino acid
                // Add a text box in the middle of the left and right mz boundaries
                StringBuilder label = new StringBuilder(sequence[i - 1].ToString());
                // Figure out if any mods are there on this amino acid
                double deltaMass = modifications[i - 1].monoisotopicDeltaMass();
                string deltaMassString = deltaMass.ToString();

                TextObj text = new TextObj(label.ToString(), topSeriesLeftPoint,
                       seriesTopLeftOffset, CoordType.ChartFraction, AlignH.Left, AlignV.Center);
                text.ZOrder = ZOrder.E_BehindCurves;
                text.FontSpec = new FontSpec("Arial", 13, Color.Black, true, false, false);
                text.FontSpec.Border.IsVisible = false;
                text.FontSpec.Fill.IsVisible = false;
                text.IsClippedToChartRect = true;
                list.Add(text);

                SizeF size = text.LayoutArea;
                float width = size.Width;

                if (deltaMass > 0.0)
                {
                    deltaMassString = "+" + Math.Round(deltaMass).ToString();
                    TextObj textModi = new TextObj(deltaMassString, topSeriesLeftPoint + 0.011,
                       seriesTopLeftOffset, CoordType.ChartFraction, AlignH.Left, AlignV.Center);

                    textModi.ZOrder = ZOrder.A_InFront;
                    textModi.FontSpec = new FontSpec("Arial", 8, Color.Black, true, false, false);
                    textModi.FontSpec.Border.IsVisible = false;
                    textModi.FontSpec.Fill.IsVisible = false ;
                    textModi.IsClippedToChartRect = true;
                    list.Add(textModi);

                }
                else if (deltaMass < 0.0)
                {
                    deltaMassString = Math.Round(deltaMass).ToString();
                    TextObj textModi = new TextObj(deltaMassString, topSeriesLeftPoint + 0.01,
                       seriesTopLeftOffset, CoordType.ChartFraction, AlignH.Left, AlignV.Center);

                    textModi.ZOrder = ZOrder.B_BehindLegend;
                    textModi.FontSpec = new FontSpec("Arial", 8, Color.Black, true, false, false);
                    textModi.FontSpec.Border.IsVisible = false;
                    textModi.FontSpec.Fill.IsVisible = false ;
                    textModi.IsClippedToChartRect = true;
                    list.Add(textModi);
                }

                if (topSeriesHasMatch)
                {
                    // Paint the tick in the middle
                    LineObj tick = new LineObj(topSeriesColor, topSeriesLeftPoint + tickStart, (seriesTopLeftOffset - 0.03), topSeriesLeftPoint + tickStart, seriesTopLeftOffset);
                    tick.Location.CoordinateFrame = CoordType.ChartFraction;
                    tick.Line.Width = 2;
                    tick.IsClippedToChartRect = true;
                    list.Add(tick);
                    // Paint the hook
                    LineObj hook = new LineObj(topSeriesColor, topSeriesLeftPoint, (seriesTopLeftOffset - 0.05), topSeriesLeftPoint + tickStart, seriesTopLeftOffset - 0.03);
                    hook.Location.CoordinateFrame = CoordType.ChartFraction;
                    hook.Line.Width = 2;
                    hook.IsClippedToChartRect = true;
                    list.Add(hook);
                }
                // Update the next paint point
                topSeriesLeftPoint += residueWidth;
            }

            // Reset the series starting point
            topSeriesLeftPoint = 0.025;
            #endregion

            ///
            #region Process y/z ions
            //then for y/z ions:
            //note: since the fragmentsummary starts the ticking/lining from left to right,
            //so we need to adjust the starting point of bottoms series from the highest to lowest.
            ///
            for (int i = sequence.Length; i >= 1; --i)
            {
                double tickStart = residueWidth / 5.0;
                double bottomSeriesFragmentMZ = 0.0;
                bool bottomSeriesHasMatch = false;
                //test neutral
                string Cseq = peptide.sequence.Substring(sequenceLength - i, i);
                char[] seqchars = peptide.sequence.ToCharArray();
                int Cphosmodi = 0;
                for (int k = sequenceLength - i; k < sequenceLength; k++)
                {
                    if (Math.Round(modifications[k].monoisotopicDeltaMass()) == 80 && (seqchars[k] == 'S' || seqchars[k] == 'T' || seqchars[k] == 'Y'))
                    {
                        Cphosmodi++;
                    }
                }

                for (int z = min; z <= max; z++)
                {
                    switch (bottomSeries)
                    {
                        case "y": bottomSeriesFragmentMZ = fragmentation.y(i, z); break;
                        case "z": bottomSeriesFragmentMZ = fragmentation.z(i, z); break;
                        case "z*": bottomSeriesFragmentMZ = fragmentation.zRadical(i, z); break;
                        default: bottomSeriesFragmentMZ = 0.0; break;
                    }

                    // Check if the top and bottom fragments have evidence

                    if (points != null)
                    {
                        // Search index
                        int index = -1;
                        // Find the left mz value using a mass tolerance of 0.5 da.
                        index = points.FullLowerBound(bottomSeriesFragmentMZ - 0.5);
                        if (index != -1 && points.FullList[index].X <= (bottomSeriesFragmentMZ + 0.5))
                        {
                            bottomSeriesHasMatch = true;
                            break;
                        }
                    }

                    //test neutral loss
                    #region water loss y/z bottom series
                    if (waterLoss == true)
                    {
                        if (Cseq.Contains("S") || Cseq.Contains("T") || Cseq.Contains("E") || Cseq.Contains("D"))
                        {
                            if (points != null)
                            {
                                // Search index
                                int index = -1;
                                // Find the left mz value using a mass tolerance of 0.5 da.
                                index = points.FullLowerBound(bottomSeriesFragmentMZ - WATERMONOMASS / z - 0.5);
                                if (basePeakThresholding == false)
                                {
                                    if (index != -1 && points.FullList[index].X <= (bottomSeriesFragmentMZ - WATERMONOMASS / z + 0.5))
                                    {
                                        bottomSeriesHasMatch = true;
                                        break;
                                    }
                                }
                                else
                                {
                                    if (index != -1 && points.FullList[index].X <= (bottomSeriesFragmentMZ - WATERMONOMASS / z + 0.5) && points.FullList[index].Y > cutoff)
                                    {
                                        bottomSeriesHasMatch = true;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    #endregion

                    //test neutral loss
                    #region ammonium loss y/z bottom series
                    if (ammoniumLoss == true)
                    {
                        if (Cseq.Contains("R") || Cseq.Contains("K") || Cseq.Contains("Q") || Cseq.Contains("N"))
                        if (points != null)
                        {
                            // Search index
                            int index = -1;
                            // Find the left mz value using a mass tolerance of 0.5 da.
                            index = points.FullLowerBound(bottomSeriesFragmentMZ - AMMONIUMMONOMASS / z - 0.5);
                            if (basePeakThresholding == false)
                            {
                                if (index != -1 && points.FullList[index].X <= (bottomSeriesFragmentMZ - AMMONIUMMONOMASS / z + 0.5))
                                {
                                    bottomSeriesHasMatch = true;
                                    break;
                                }
                            }
                            else
                            {
                                if (index != -1 && points.FullList[index].X <= (bottomSeriesFragmentMZ - AMMONIUMMONOMASS / z + 0.5) && points.FullList[index].Y > cutoff)
                                {
                                    bottomSeriesHasMatch = true;
                                    break;
                                }
                            }
                        }
                    }
                    #endregion

                    //test neutral loss
                    #region phosphate loss y/z bottom series
                    if (phosphateLoss == true)
                    {
                        int minPhosphate = Math.Min(Cphosmodi, numPhosphate);
                        if (minPhosphate > 0)
                        {
                            for (int k = 1; k <= minPhosphate; k++)
                            {
                                if (points != null)
                                {
                                    // Search index
                                    int index = -1;
                                    // Find the left mz value using a mass tolerance of 0.5 da.
                                    index = points.FullLowerBound(bottomSeriesFragmentMZ - k * PHOSPHATEMONOMASS / z - 0.5);
                                    if (basePeakThresholding == false)
                                    {
                                        if (index != -1 && points.FullList[index].X <= (bottomSeriesFragmentMZ - k * PHOSPHATEMONOMASS / z + 0.5))
                                        {
                                            bottomSeriesHasMatch = true;
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        if (index != -1 && points.FullList[index].X <= (bottomSeriesFragmentMZ - k * PHOSPHATEMONOMASS / z + 0.5) && points.FullList[index].Y > cutoff)
                                        {
                                            bottomSeriesHasMatch = true;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    #endregion
                }

                if (bottomSeriesHasMatch)
                {
                    // Paint the tick in the middle
                    LineObj tick = new LineObj(bottomSeriesColor, topSeriesLeftPoint - tickStart, seriesTopLeftOffset, topSeriesLeftPoint - tickStart, seriesTopLeftOffset + 0.03);
                    tick.Location.CoordinateFrame = CoordType.ChartFraction;
                    tick.Line.Width = 2;
                    tick.IsClippedToChartRect = true;
                    list.Add(tick);
                    // Paint the hook
                    LineObj hook = new LineObj(bottomSeriesColor, topSeriesLeftPoint - tickStart, seriesTopLeftOffset + 0.03, topSeriesLeftPoint + 2.0 * tickStart, seriesTopLeftOffset + 0.05);
                    hook.Location.CoordinateFrame = CoordType.ChartFraction;
                    hook.Line.Width = 2;
                    hook.IsClippedToChartRect = true;
                    list.Add(hook);
                }
                // Update the next paint point
                topSeriesLeftPoint += residueWidth;
            }

            // Reset the series starting point
            topSeriesLeftPoint = 0.025;
            #endregion

            ///
            #region Process x/c series
            ///
            //the reason that I didn't split c/x as ab/yz, is that c/x doesn't have to deal with the termini. so good to go.
            //disable the function of neutral losses
            for (int i = 1; i < sequence.Length; ++i)
            {
                double tickStart = residueWidth *4 / 5.0;
                double topSeriesFragmentMZ = 0.0;
                double bottomSeriesFragmentMZ = 0.0;
                // Check if the top and bottom fragments have evidence
                bool topSeriesHasMatch = false;
                bool bottomSeriesHasMatch = false;

                ///
                //test neutral loss
                //test neutral
                //adjust the "i" accordingly, must let the C ions be left=>right.
                //if it goes from left to right, then N series is i;
                //C series is more tricky. Get a NTempSeq from 0 to sequenceLength-i; then get C from total.
                ///
                string Nseq = peptide.sequence.Substring(0, i);
                string NTempSeq = peptide.sequence.Substring(0, sequenceLength - i);
                string Cseq = peptide.sequence.Substring(i, sequenceLength-i);
                char[] Nseqchars = Nseq.ToCharArray();
                char[] seqchars = peptide.sequence.ToCharArray();
                char[] NTempSeqChars = NTempSeq.ToCharArray();
                int Nphosmodi = 0;
                int NTempPhosmodi = 0;
                int Cphosmodi = 0;
                int phosmodi = 0;
                for (int k = 0; k < i; k++)
                {
                    if (Math.Round(modifications[k].monoisotopicDeltaMass()) == 80 && (Nseqchars[k] == 'S' || Nseqchars[k] == 'T' || Nseqchars[k] == 'Y'))
                    {
                        Nphosmodi++;
                    }
                }

                for (int k = 0; k < sequenceLength - i; k++)
                {
                    if (Math.Round(modifications[k].monoisotopicDeltaMass()) == 80 && (NTempSeqChars[k] == 'S' || NTempSeqChars[k] == 'T' || NTempSeqChars[k] == 'Y'))
                    {
                        NTempPhosmodi++;
                    }
                }
                for (int k = 0; k < sequenceLength; k++)
                {
                    if (Math.Round(modifications[k].monoisotopicDeltaMass()) == 80 && (seqchars[k] == 'S' || seqchars[k] == 'T' || seqchars[k] == 'Y'))
                    {
                        phosmodi++;
                    }
                }
                Cphosmodi = phosmodi - NTempPhosmodi;

                for (int z = min; z <= max; z++)
                {
                    switch (topSeries)
                    {
                        case "c": topSeriesFragmentMZ = fragmentation.c(i, z); break;
                        default: topSeriesFragmentMZ = 0.0; break;
                    }
                    switch (bottomSeries)
                    {
                        case "x": bottomSeriesFragmentMZ = fragmentation.x(sequence.Length - i, z); break;
                        default: bottomSeriesFragmentMZ = 0.0; break;
                    }

                    if (points != null)
                    {
                        // Search index
                        int index = -1;
                        // Find the left mz value using a mass tolerance of 0.5 da.
                        index = points.FullLowerBound(topSeriesFragmentMZ - 0.5);
                        if (index != -1 && points.FullList[index].X <= (topSeriesFragmentMZ + 0.5))
                            topSeriesHasMatch = true;

                        // Reset the search index
                        index = -1;
                        // Find the left mz value using a mass tolerance of 0.5 da.
                        index = points.FullLowerBound(bottomSeriesFragmentMZ - 0.5);
                        if (index != -1 && points.FullList[index].X <= (bottomSeriesFragmentMZ + 0.5))
                            bottomSeriesHasMatch = true;
                    }

                    //disable neutral losses for c/x series
                    //test neutral loss
                    #region water loss c/x
                    if (waterLoss == true)
                    {
                        if (Nseq.Contains("S") || Nseq.Contains("T") || Nseq.Contains("E") || Nseq.Contains("D"))
                        {
                            if (points != null)
                            {
                                // Search index
                                int index = -1;
                                // Find the left mz value using a mass tolerance of 0.5 da.
                                index = points.FullLowerBound(topSeriesFragmentMZ - WATERMONOMASS / z - 0.5);
                                if (basePeakThresholding == false)
                                {
                                    if (index != -1 && points.FullList[index].X <= (topSeriesFragmentMZ - WATERMONOMASS / z + 0.5))
                                        topSeriesHasMatch = true;
                                }
                                else
                                {
                                    if (index != -1 && points.FullList[index].X <= (topSeriesFragmentMZ - WATERMONOMASS / z + 0.5) && points.FullList[index].Y > cutoff)
                                        topSeriesHasMatch = true;
                                }
                            }
                        }
                        if (Cseq.Contains("S") || Cseq.Contains("T") || Cseq.Contains("E") || Cseq.Contains("D"))
                        {
                            if (points != null)
                            {
                                // Search index
                                int index = -1;
                                // Find the left mz value using a mass tolerance of 0.5 da.
                                index = points.FullLowerBound(bottomSeriesFragmentMZ - WATERMONOMASS / z - 0.5);
                                if (basePeakThresholding == false)
                                {
                                    if (index != -1 && points.FullList[index].X <= (bottomSeriesFragmentMZ - WATERMONOMASS / z + 0.5))
                                        bottomSeriesHasMatch = true;
                                }
                                else
                                {
                                    if (index != -1 && points.FullList[index].X <= (bottomSeriesFragmentMZ - WATERMONOMASS / z + 0.5) && points.FullList[index].Y > cutoff)
                                        bottomSeriesHasMatch = true;
                                }
                            }
                        }
                    }
                    #endregion

                    ////test neutral loss
                    #region ammonium loss c/x
                    if (ammoniumLoss == true)
                    {
                        if (points != null)
                        {
                            if (Nseq.Contains("R") || Nseq.Contains("K") || Nseq.Contains("Q") || Nseq.Contains("N"))
                            {
                                // Search index
                                int index = -1;
                                // Find the left mz value using a mass tolerance of 0.5 da.
                                index = points.FullLowerBound(topSeriesFragmentMZ - AMMONIUMMONOMASS / z - 0.5);
                                if (basePeakThresholding == false)
                                {
                                    if (index != -1 && points.FullList[index].X <= (topSeriesFragmentMZ - AMMONIUMMONOMASS / z + 0.5))
                                        topSeriesHasMatch = true;
                                }
                                else
                                {
                                    if (index != -1 && points.FullList[index].X <= (topSeriesFragmentMZ - AMMONIUMMONOMASS / z + 0.5) && points.FullList[index].Y > cutoff)
                                        topSeriesHasMatch = true;
                                }

                            }

                            if (Cseq.Contains("R") || Cseq.Contains("K") || Cseq.Contains("Q") || Cseq.Contains("N"))
                            {
                                // Reset the search index
                                int index = -1;
                                // Find the left mz value using a mass tolerance of 0.5 da.
                                index = points.FullLowerBound(bottomSeriesFragmentMZ - AMMONIUMMONOMASS / z - 0.5);
                                if (basePeakThresholding == false)
                                {
                                    if (index != -1 && points.FullList[index].X <= (bottomSeriesFragmentMZ - AMMONIUMMONOMASS / z + 0.5))
                                        bottomSeriesHasMatch = true;
                                }
                                else
                                {
                                    if (index != -1 && points.FullList[index].X <= (bottomSeriesFragmentMZ - AMMONIUMMONOMASS / z + 0.5) && points.FullList[index].Y > cutoff)
                                        bottomSeriesHasMatch = true;
                                }

                            }
                        }
                    }
                    #endregion

                    ////test neutral loss
                    #region phosphate loss c/x
                    if (phosphateLoss == true)
                    {
                        int minPhosphate = Math.Min(Nphosmodi, numPhosphate);
                        if (minPhosphate > 0)
                        {
                            for (int k = 1; k <= minPhosphate; k++)
                            {
                                if (points != null)
                                {
                                    // Search index
                                    int index = -1;
                                    // Find the left mz value using a mass tolerance of 0.5 da.
                                    index = points.FullLowerBound(topSeriesFragmentMZ - k * PHOSPHATEMONOMASS / z - 0.5);
                                    if (basePeakThresholding == false)
                                    {
                                        if (index != -1 && points.FullList[index].X <= (topSeriesFragmentMZ - k * PHOSPHATEMONOMASS / z + 0.5))
                                        {
                                            topSeriesHasMatch = true;
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        if (index != -1 && points.FullList[index].X <= (topSeriesFragmentMZ - k * PHOSPHATEMONOMASS / z + 0.5) && points.FullList[index].Y > cutoff)
                                        {
                                            topSeriesHasMatch = true;
                                            break;
                                        }
                                    }
                                }
                            }
                        }

                        minPhosphate = Math.Min(Cphosmodi, numPhosphate);
                        {
                            if (minPhosphate > 0)
                            {
                                for (int k = 1; k <= minPhosphate; k++)
                                {
                                    if (points != null)
                                    {
                                        // Search index
                                        int index = -1;
                                        // Find the left mz value using a mass tolerance of 0.5 da.
                                        index = points.FullLowerBound(bottomSeriesFragmentMZ - k * PHOSPHATEMONOMASS / z - 0.5);
                                        if (basePeakThresholding == false)
                                        {
                                            if (index != -1 && points.FullList[index].X <= (bottomSeriesFragmentMZ - k * PHOSPHATEMONOMASS / z + 0.5))
                                            {
                                                bottomSeriesHasMatch = true;
                                                break;
                                            }
                                        }
                                        else
                                        {
                                            if (index != -1 && points.FullList[index].X <= (bottomSeriesFragmentMZ - k * PHOSPHATEMONOMASS / z + 0.5) && points.FullList[index].Y > cutoff)
                                            {
                                                bottomSeriesHasMatch = true;
                                                break;
                                            }
                                        }
                                    }
                                }
                            }

                        }
                    }
                    #endregion

                }

                // Build the label for the amino acid
                // Add a text box in the middle of the left and right mz boundaries
                StringBuilder label = new StringBuilder(sequence[i - 1].ToString());
                // Figure out if any mods are there on this amino acid
                double deltaMass = modifications[i - 1].monoisotopicDeltaMass();
                string deltaMassString = deltaMass.ToString();
                // Round the mod mass and append it to the amino acid as a string
                //if (deltaMass > 0.0)
                //{
                //    label.Append("+" + Math.Round(deltaMass));
                //}
                //else if (deltaMass < 0.0)
                //{
                //    label.Append(Math.Round(deltaMass));
                //}
                TextObj text = new TextObj(label.ToString(), topSeriesLeftPoint,
                            seriesTopLeftOffset, CoordType.ChartFraction, AlignH.Left, AlignV.Center);
                text.ZOrder = ZOrder.B_BehindLegend;
                text.FontSpec = new FontSpec("Arial", 13, Color.Black, true, false, false);
                text.FontSpec.Border.IsVisible = false;
                text.FontSpec.Fill.IsVisible = false;
                text.IsClippedToChartRect = true;
                list.Add(text);

                SizeF size = text.LayoutArea;
                float width = size.Width;

                if (deltaMass > 0.0)
                {
                    deltaMassString = "+" + Math.Round(deltaMass).ToString();
                    TextObj textModi = new TextObj(deltaMassString, topSeriesLeftPoint + 0.01,
                       seriesTopLeftOffset, CoordType.ChartFraction, AlignH.Left, AlignV.Center);

                    textModi.ZOrder = ZOrder.B_BehindLegend;
                    textModi.FontSpec = new FontSpec("Arial", 8, Color.Black, true, false, false);
                    textModi.FontSpec.Border.IsVisible = false;
                    textModi.FontSpec.Fill.IsVisible = false;
                    textModi.IsClippedToChartRect = true;
                    list.Add(textModi);

                }
                else if (deltaMass < 0.0)
                {
                    deltaMassString = Math.Round(deltaMass).ToString();
                    TextObj textModi = new TextObj(deltaMassString, topSeriesLeftPoint + 0.01,
                       seriesTopLeftOffset, CoordType.ChartFraction, AlignH.Left, AlignV.Center);

                    textModi.ZOrder = ZOrder.B_BehindLegend;
                    textModi.FontSpec = new FontSpec("Arial", 8, Color.Black, true, false, false);
                    textModi.FontSpec.Border.IsVisible = false;
                    textModi.FontSpec.Fill.IsVisible = false;
                    textModi.IsClippedToChartRect = true;
                    list.Add(textModi);
                }

                if (topSeriesHasMatch)
                {
                    // Paint the tick in the middle
                    LineObj tick = new LineObj(topSeriesColor, topSeriesLeftPoint + tickStart, (seriesTopLeftOffset - 0.03), topSeriesLeftPoint + tickStart, seriesTopLeftOffset);
                    tick.Location.CoordinateFrame = CoordType.ChartFraction;
                    tick.Line.Width = 2;
                    tick.IsClippedToChartRect = true;
                    list.Add(tick);
                    // Paint the hook
                    LineObj hook = new LineObj(topSeriesColor, topSeriesLeftPoint, (seriesTopLeftOffset - 0.05), topSeriesLeftPoint + tickStart, seriesTopLeftOffset - 0.03);
                    hook.Location.CoordinateFrame = CoordType.ChartFraction;
                    hook.Line.Width = 2;
                    hook.IsClippedToChartRect = true;
                    list.Add(hook);
                }
                if (bottomSeriesHasMatch)
                {
                    // Paint the tick in the middle
                    LineObj tick = new LineObj(bottomSeriesColor, topSeriesLeftPoint + tickStart, seriesTopLeftOffset, topSeriesLeftPoint + tickStart, seriesTopLeftOffset + 0.03);
                    tick.Location.CoordinateFrame = CoordType.ChartFraction;
                    tick.Line.Width = 2;
                    tick.IsClippedToChartRect = true;
                    list.Add(tick);
                    // Paint the hook
                    LineObj hook = new LineObj(bottomSeriesColor, topSeriesLeftPoint + tickStart, seriesTopLeftOffset + 0.03, topSeriesLeftPoint + 2.0 * tickStart, seriesTopLeftOffset + 0.05);
                    hook.Location.CoordinateFrame = CoordType.ChartFraction;
                    hook.Line.Width = 2;
                    hook.IsClippedToChartRect = true;
                    list.Add(hook);
                }
                // Update the next paint point
                topSeriesLeftPoint += residueWidth;
            }
            #endregion
        }
Ejemplo n.º 12
0
 public override void GatherPathStats(GamePath gamePath, Board board)
 {
     gamePath.MaxArea   = (float)MaxArea.MaximalRectangle(board.Cells) / 64;
     gamePath.FragScore = Fragmentation.GetFragmentationScore(board.Cells);
 }