///<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; } } }
private void addFragment (GraphObjList list, pwiz.MSGraph.MSPointList points, string series, int length, int charge, double mz) { string label = String.Format("{0}{1}{2}", series, (length > 0 ? length.ToString() : ""), (charge > 1 ? "+" + charge.ToString() : "")); Color color; double offset; switch (series) { default: color = series.StartsWith("immonium") ? Color.Black : Color.Gray; offset = 0.1; break; case "a": color = Color.YellowGreen; offset = 0.1; break; case "x": color = Color.Green; offset = 0.12; break; case "b": color = Color.BlueViolet; offset = 0.14; break; case "y": color = Color.Blue; offset = 0.16; break; case "c": color = Color.Orange; offset = 0.18; break; case "z": color = Color.OrangeRed; offset = 0.2; break; case "z*": color = Color.Crimson; offset = 0.4; break; } int index = -1; if (points != null) index = findPointWithTolerance(points, mz, tolerance); if (index == -1) // no matching point: present a "missed" fragment annotation { if (!showMisses) return; color = Color.FromArgb(115, color); // transparent to emphasize miss if (list.Count(o => o.Location.X == mz) == 0) { LineObj stick = new LineObj(color, mz, offset, mz, 1); stick.Location.CoordinateFrame = CoordType.XScaleYChartFraction; stick.Line.Width = 2; stick.Line.Style = System.Drawing.Drawing2D.DashStyle.Dot; stick.IsClippedToChartRect = true; list.Add(stick); if (showLabels) { TextObj text = new TextObj(label, mz, offset, CoordType.XScaleYChartFraction, AlignH.Center, AlignV.Bottom); text.ZOrder = ZOrder.A_InFront; text.FontSpec = new FontSpec("Arial", 12, color, false, false, false); text.FontSpec.Border.IsVisible = false; //text.IsClippedToChartRect = true; list.Add(text); } } } else // matching point found: present the point as the fragment { if (list.Count(o => o.Location.X == mz) == 0) { LineObj stick = new LineObj(color, mz, points.FullList[index].Y, mz, 0); stick.Location.CoordinateFrame = CoordType.AxisXYScale; stick.Line.Width = 2; stick.IsClippedToChartRect = true; list.Add(stick); } if (showLabels) { // use an existing text point annotation if possible TextObj text = null; double minError = Double.MaxValue; foreach (GraphObj obj in list) { if (obj is TextObj && (obj.Location.CoordinateFrame == CoordType.AxisXYScale || obj.Location.CoordinateFrame == CoordType.XScaleYChartFraction)) { double curError = Math.Abs(obj.Location.X - points.FullList[index].X); if (curError < 1e-4 && curError < minError) { minError = curError; text = obj as TextObj; if (!text.Text.Contains(label)) text.Text = String.Format("{0}\n{1}", label, text.Text); } } } if (text == null) { text = new TextObj(label, mz, points.FullList[index].Y, CoordType.AxisXYScale, AlignH.Center, AlignV.Bottom); list.Add(text); } text.ZOrder = ZOrder.A_InFront; text.FontSpec = new FontSpec("Arial", 12, color, false, false, false); text.FontSpec.Border.IsVisible = false; //text.IsClippedToChartRect = true; } } }
///<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; } }
private void addFragment(GraphObjList list, pwiz.MSGraph.MSPointList points, string series, int length, int charge, double mz) { ///<summary> /// IMPORTANT: INORDER TO ADAPT TO ORBI-ORBI DATA, I NEED TO CHANGE THE TOLERANCE TO 30PPM! ///</summary> double basePeakIntensity = 0; double cutoff = 0; foreach (var pointlist in points) { if (basePeakIntensity < pointlist.Y) basePeakIntensity = pointlist.Y; } cutoff = basePeakIntensity * basePeakPercentage * 0.01; double tolerance = mz * 30 * Math.Pow(10.0, -6); //define the max of scaled list //double maxScaledIntensity = 0; //foreach (var pointlist in points.ScaledList) //{ // if (maxScaledIntensity < pointlist.Y) // maxScaledIntensity = pointlist.Y; //} //test neutral loss string label = String.Format("{0}{1}{2}", series, length, (charge > 1 ? "+" + charge.ToString() : "")); Color color; double offset; switch (series) { default: color = Color.Gray; offset = 0.1; break; case "a": color = Color.YellowGreen; offset = 0.1; break; case "x": color = Color.Green; offset = 0.12; break; case "b": color = Color.Red; offset = 0.14; break; case "y": color = Color.Blue; offset = 0.16; break; case "c": color = Color.Orange; offset = 0.18; break; case "z": color = Color.OrangeRed; offset = 0.2; break; case "z*": color = Color.Crimson; offset = 0.4; break; //test neutral loss case "a-water": color = Color.YellowGreen; offset = 0.1; label = String.Format("{0}{1}{2}{3}", "a", length, (charge > 1 ? "+" + charge.ToString() : ""), "-H2O"); break; case "x-water": color = Color.Green; offset = 0.12; label = String.Format("{0}{1}{2}{3}", "x", length, (charge > 1 ? "+" + charge.ToString() : ""), "-H2O"); break; case "b-water": color = Color.Red; offset = 0.14; label = String.Format("{0}{1}{2}{3}", "b", length, (charge > 1 ? "+" + charge.ToString() : ""), "-H2O"); break; case "y-water": color = Color.Blue; offset = 0.16; label = String.Format("{0}{1}{2}{3}", "y", length, (charge > 1 ? "+" + charge.ToString() : ""), "-H2O"); break; case "c-water": color = Color.Orange; offset = 0.18; label = String.Format("{0}{1}{2}{3}", "c", length, (charge > 1 ? "+" + charge.ToString() : ""), "-H2O"); break; case "z-water": color = Color.OrangeRed; offset = 0.2; label = String.Format("{0}{1}{2}{3}", "z", length, (charge > 1 ? "+" + charge.ToString() : ""), "-H2O"); break; case "z*-water": color = Color.Crimson; offset = 0.4; label = String.Format("{0}{1}{2}{3}", "z*", length, (charge > 1 ? "+" + charge.ToString() : ""), "-H2O"); break; //test neutral loss case "a-ammonium": color = Color.YellowGreen; offset = 0.1; label = String.Format("{0}{1}{2}{3}", "a", length, (charge > 1 ? "+" + charge.ToString() : ""), "-NH3"); break; case "x-ammonium": color = Color.Green; offset = 0.12; label = String.Format("{0}{1}{2}{3}", "x", length, (charge > 1 ? "+" + charge.ToString() : ""), "-NH3"); break; case "b-ammonium": color = Color.Red; offset = 0.14; label = String.Format("{0}{1}{2}{3}", "b", length, (charge > 1 ? "+" + charge.ToString() : ""), "-NH3"); break; case "y-ammonium": color = Color.Blue; offset = 0.16; label = String.Format("{0}{1}{2}{3}", "y", length, (charge > 1 ? "+" + charge.ToString() : ""), "-NH3"); break; case "c-ammonium": color = Color.Orange; offset = 0.18; label = String.Format("{0}{1}{2}{3}", "c", length, (charge > 1 ? "+" + charge.ToString() : ""), "-NH3"); break; case "z-ammonium": color = Color.OrangeRed; offset = 0.2; label = String.Format("{0}{1}{2}{3}", "z", length, (charge > 1 ? "+" + charge.ToString() : ""), "-NH3"); break; case "z*-ammonium": color = Color.Crimson; offset = 0.4; label = String.Format("{0}{1}{2}{3}", "z*", length, (charge > 1 ? "+" + charge.ToString() : ""), "-NH3"); break; case "a-1phos": color = Color.YellowGreen; offset = 0.1; label = String.Format("{0}{1}{2}{3}", "a", length, (charge > 1 ? "+" + charge.ToString() : ""), "-H3PO4"); break; case "x-1phos": color = Color.Green; offset = 0.12; label = String.Format("{0}{1}{2}{3}", "x", length, (charge > 1 ? "+" + charge.ToString() : ""), "-H3PO4"); break; case "b-1phos": color = Color.Red; offset = 0.14; label = String.Format("{0}{1}{2}{3}", "b", length, (charge > 1 ? "+" + charge.ToString() : ""), "-H3PO4"); break; case "y-1phos": color = Color.Blue; offset = 0.16; label = String.Format("{0}{1}{2}{3}", "y", length, (charge > 1 ? "+" + charge.ToString() : ""), "-H3PO4"); break; case "c-1phos": color = Color.Orange; offset = 0.18; label = String.Format("{0}{1}{2}{3}", "c", length, (charge > 1 ? "+" + charge.ToString() : ""), "-H3PO4"); break; case "z-1phos": color = Color.OrangeRed; offset = 0.2; label = String.Format("{0}{1}{2}{3}", "z", length, (charge > 1 ? "+" + charge.ToString() : ""), "-H3PO4"); break; case "z*-1phos": color = Color.Crimson; offset = 0.4; label = String.Format("{0}{1}{2}{3}", "z*", length, (charge > 1 ? "+" + charge.ToString() : ""), "-H3PO4"); break; case "a-2phos": color = Color.YellowGreen; offset = 0.1; label = String.Format("{0}{1}{2}{3}", "a", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)2"); break; case "x-2phos": color = Color.Green; offset = 0.12; label = String.Format("{0}{1}{2}{3}", "x", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)2"); break; case "b-2phos": color = Color.Red; offset = 0.14; label = String.Format("{0}{1}{2}{3}", "b", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)2"); break; case "y-2phos": color = Color.Blue; offset = 0.16; label = String.Format("{0}{1}{2}{3}", "y", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)2"); break; case "c-2phos": color = Color.Orange; offset = 0.18; label = String.Format("{0}{1}{2}{3}", "c", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)2"); break; case "z-2phos": color = Color.OrangeRed; offset = 0.2; label = String.Format("{0}{1}{2}{3}", "z", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)2"); break; case "z*-2phos": color = Color.Crimson; offset = 0.4; label = String.Format("{0}{1}{2}{3}", "z*", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)2"); break; case "a-3phos": color = Color.YellowGreen; offset = 0.1; label = String.Format("{0}{1}{2}{3}", "a", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)3"); break; case "x-3phos": color = Color.Green; offset = 0.12; label = String.Format("{0}{1}{2}{3}", "x", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)3"); break; case "b-3phos": color = Color.Red; offset = 0.14; label = String.Format("{0}{1}{2}{3}", "b", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)3"); break; case "y-3phos": color = Color.Blue; offset = 0.16; label = String.Format("{0}{1}{2}{3}", "y", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)3"); break; case "c-3phos": color = Color.Orange; offset = 0.18; label = String.Format("{0}{1}{2}{3}", "c", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)3"); break; case "z-3phos": color = Color.OrangeRed; offset = 0.2; label = String.Format("{0}{1}{2}{3}", "z", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)3"); break; case "z*-3phos": color = Color.Crimson; offset = 0.4; label = String.Format("{0}{1}{2}{3}", "z*", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)3"); break; case "a-4phos": color = Color.YellowGreen; offset = 0.1; label = String.Format("{0}{1}{2}{3}", "a", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)4"); break; case "x-4phos": color = Color.Green; offset = 0.12; label = String.Format("{0}{1}{2}{3}", "x", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)4"); break; case "b-4phos": color = Color.Red; offset = 0.14; label = String.Format("{0}{1}{2}{3}", "b", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)4"); break; case "y-4phos": color = Color.Blue; offset = 0.16; label = String.Format("{0}{1}{2}{3}", "y", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)4"); break; case "c-4phos": color = Color.Orange; offset = 0.18; label = String.Format("{0}{1}{2}{3}", "c", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)4"); break; case "z-4phos": color = Color.OrangeRed; offset = 0.2; label = String.Format("{0}{1}{2}{3}", "z", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)4"); break; case "z*-4phos": color = Color.Crimson; offset = 0.4; label = String.Format("{0}{1}{2}{3}", "z*", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)4"); break; case "a-5phos": color = Color.YellowGreen; offset = 0.1; label = String.Format("{0}{1}{2}{3}", "a", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)5"); break; case "x-5phos": color = Color.Green; offset = 0.12; label = String.Format("{0}{1}{2}{3}", "x", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)5"); break; case "b-5phos": color = Color.Red; offset = 0.14; label = String.Format("{0}{1}{2}{3}", "b", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)5"); break; case "y-5phos": color = Color.Blue; offset = 0.16; label = String.Format("{0}{1}{2}{3}", "y", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)5"); break; case "c-5phos": color = Color.Orange; offset = 0.18; label = String.Format("{0}{1}{2}{3}", "c", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)5"); break; case "z-5phos": color = Color.OrangeRed; offset = 0.2; label = String.Format("{0}{1}{2}{3}", "z", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)5"); break; case "z*-5phos": color = Color.Crimson; offset = 0.4; label = String.Format("{0}{1}{2}{3}", "z*", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)5"); break; case "a-6phos": color = Color.YellowGreen; offset = 0.1; label = String.Format("{0}{1}{2}{3}", "a", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)6"); break; case "x-6phos": color = Color.Green; offset = 0.12; label = String.Format("{0}{1}{2}{3}", "x", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)6"); break; case "b-6phos": color = Color.Red; offset = 0.14; label = String.Format("{0}{1}{2}{3}", "b", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)6"); break; case "y-6phos": color = Color.Blue; offset = 0.16; label = String.Format("{0}{1}{2}{3}", "y", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)6"); break; case "c-6phos": color = Color.Orange; offset = 0.18; label = String.Format("{0}{1}{2}{3}", "c", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)6"); break; case "z-6phos": color = Color.OrangeRed; offset = 0.2; label = String.Format("{0}{1}{2}{3}", "z", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)6"); break; case "z*-6phos": color = Color.Crimson; offset = 0.4; label = String.Format("{0}{1}{2}{3}", "z*", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)6"); break; case "a-7phos": color = Color.YellowGreen; offset = 0.1; label = String.Format("{0}{1}{2}{3}", "a", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)7"); break; case "x-7phos": color = Color.Green; offset = 0.12; label = String.Format("{0}{1}{2}{3}", "x", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)7"); break; case "b-7phos": color = Color.Red; offset = 0.14; label = String.Format("{0}{1}{2}{3}", "b", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)7"); break; case "y-7phos": color = Color.Blue; offset = 0.16; label = String.Format("{0}{1}{2}{3}", "y", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)7"); break; case "c-7phos": color = Color.Orange; offset = 0.18; label = String.Format("{0}{1}{2}{3}", "c", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)7"); break; case "z-7phos": color = Color.OrangeRed; offset = 0.2; label = String.Format("{0}{1}{2}{3}", "z", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)7"); break; case "z*-7phos": color = Color.Crimson; offset = 0.4; label = String.Format("{0}{1}{2}{3}", "z*", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)7"); break; case "a-8phos": color = Color.YellowGreen; offset = 0.1; label = String.Format("{0}{1}{2}{3}", "a", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)8"); break; case "x-8phos": color = Color.Green; offset = 0.12; label = String.Format("{0}{1}{2}{3}", "x", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)8"); break; case "b-8phos": color = Color.Red; offset = 0.14; label = String.Format("{0}{1}{2}{3}", "b", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)8"); break; case "y-8phos": color = Color.Blue; offset = 0.16; label = String.Format("{0}{1}{2}{3}", "y", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)8"); break; case "c-8phos": color = Color.Orange; offset = 0.18; label = String.Format("{0}{1}{2}{3}", "c", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)8"); break; case "z-8phos": color = Color.OrangeRed; offset = 0.2; label = String.Format("{0}{1}{2}{3}", "z", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)8"); break; case "z*-8phos": color = Color.Crimson; offset = 0.4; label = String.Format("{0}{1}{2}{3}", "z*", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)8"); break; case "a-9phos": color = Color.YellowGreen; offset = 0.1; label = String.Format("{0}{1}{2}{3}", "a", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)9"); break; case "x-9phos": color = Color.Green; offset = 0.12; label = String.Format("{0}{1}{2}{3}", "x", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)9"); break; case "b-9phos": color = Color.Red; offset = 0.14; label = String.Format("{0}{1}{2}{3}", "b", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)9"); break; case "y-9phos": color = Color.Blue; offset = 0.16; label = String.Format("{0}{1}{2}{3}", "y", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)9"); break; case "c-9phos": color = Color.Orange; offset = 0.18; label = String.Format("{0}{1}{2}{3}", "c", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)9"); break; case "z-9phos": color = Color.OrangeRed; offset = 0.2; label = String.Format("{0}{1}{2}{3}", "z", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)9"); break; case "z*-9phos": color = Color.Crimson; offset = 0.4; label = String.Format("{0}{1}{2}{3}", "z*", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)9"); break; case "a-10phos": color = Color.YellowGreen; offset = 0.1; label = String.Format("{0}{1}{2}{3}", "a", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)10"); break; case "x-10phos": color = Color.Green; offset = 0.12; label = String.Format("{0}{1}{2}{3}", "x", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)10"); break; case "b-10phos": color = Color.Red; offset = 0.14; label = String.Format("{0}{1}{2}{3}", "b", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)10"); break; case "y-10phos": color = Color.Blue; offset = 0.16; label = String.Format("{0}{1}{2}{3}", "y", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)10"); break; case "c-10phos": color = Color.Orange; offset = 0.18; label = String.Format("{0}{1}{2}{3}", "c", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)10"); break; case "z-10phos": color = Color.OrangeRed; offset = 0.2; label = String.Format("{0}{1}{2}{3}", "z", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)10"); break; case "z*-10phos": color = Color.Crimson; offset = 0.4; label = String.Format("{0}{1}{2}{3}", "z*", length, (charge > 1 ? "+" + charge.ToString() : ""), "-(H3PO4)10"); break; } int index = -1; if (points != null) index = points.ScaledLowerBound(mz - tolerance); /// #region regular ion series a/b/c/x/y/z/z* keep unchanged if (series == "a" || series == "b" || series == "c" || series == "x" || series == "y" || series == "z" || series == "z*") { if (index == -1 || points.ScaledList[index].X > (mz + tolerance)) // no matching point: present a "missed" fragment annotation { if (!showMisses) return; color = Color.FromArgb(115, color); // transparent to emphasize miss LineObj stick = new LineObj(color, mz, offset, mz, 1); stick.Location.CoordinateFrame = CoordType.XScaleYChartFraction; stick.Line.Width = 2; stick.Line.Style = System.Drawing.Drawing2D.DashStyle.Dot; list.Add(stick); if (showLabels) { TextObj text = new TextObj(label, mz, offset, CoordType.XScaleYChartFraction, AlignH.Left, AlignV.Center); text.ZOrder = ZOrder.A_InFront; text.FontSpec = new FontSpec("Arial", 12, color, false, false, false); text.FontSpec.Border.IsVisible = false; text.FontSpec.Angle = 90; //text.IsClippedToChartRect = true; list.Add(text); } } else // matching point found: present the point as the fragment { LineObj stick = new LineObj(color, mz, points.ScaledList[index].Y, mz, 0); stick.Location.CoordinateFrame = CoordType.AxisXYScale; stick.Line.Width = 2; list.Add(stick); if (showLabels) { // use an existing text point annotation if possible TextObj text = null; foreach (GraphObj obj in list) { if (obj is TextObj && (obj.Location.CoordinateFrame == CoordType.AxisXYScale || obj.Location.CoordinateFrame == CoordType.XScaleYChartFraction) && Math.Abs(obj.Location.X - mz) < tolerance) { text = obj as TextObj; text.Text = String.Format("{0}\n{1}", label, text.Text); break; } } if (text == null) { text = new TextObj(label, mz, points.ScaledList[index].Y, CoordType.AxisXYScale, AlignH.Left, AlignV.Center); list.Add(text); } text.ZOrder = ZOrder.A_InFront; text.FontSpec = new FontSpec("Arial", 12, color, false, false, false); text.FontSpec.Border.IsVisible = false; text.FontSpec.Fill.IsVisible = false; text.FontSpec.Angle = 90; //SizeF size = text.LayoutArea; //float width = size.Width; //pwiz.MSGraph.MSGraphPane g = new pwiz.MSGraph.MSGraphPane(); //YAxis y = g.YAxis; //double scaled2pixel = width + y.Scale.Transform(points.ScaledList[index].Y) ; //double width2Scale = width / 0.75 * maxScaledIntensity*1.1; //text.IsClippedToChartRect = true; //if (charge > 1) //{ // //calculate the Y value to actual size in CharFraction // TextObj chargeLabel = new TextObj("+" + charge, mz, 1-scaled2pixel, CoordType.XScaleYChartFraction, // AlignH.Left, AlignV.Bottom); // chargeLabel.ZOrder = ZOrder.A_InFront; // chargeLabel.FontSpec = new FontSpec("Arial", 8, color, false, false, false); // chargeLabel.FontSpec.Border.IsVisible = false; // chargeLabel.FontSpec.Fill.IsVisible = false; // chargeLabel.FontSpec.Angle = 90; // list.Add(chargeLabel); //} } } } #endregion else //if neutral loss ion series { /// #region basepeakthresholding is false if (basePeakThresholding == false) { if (index == -1 || points.ScaledList[index].X > (mz + 0.5)) // no matching point: present a "missed" fragment annotation { if (!showMisses) return; color = Color.FromArgb(115, color); // transparent to emphasize miss LineObj stick = new LineObj(color, mz, offset, mz, 1); stick.Location.CoordinateFrame = CoordType.XScaleYChartFraction; stick.Line.Width = 2; stick.Line.Style = System.Drawing.Drawing2D.DashStyle.Dot; list.Add(stick); if (showLabels) { TextObj text = new TextObj(label, mz, offset, CoordType.XScaleYChartFraction, AlignH.Left, AlignV.Center); text.ZOrder = ZOrder.A_InFront; text.FontSpec = new FontSpec("Arial", 12, color, false, false, false); text.FontSpec.Border.IsVisible = false; text.FontSpec.Angle = 90; //text.IsClippedToChartRect = true; list.Add(text); } } else // matching point found: present the point as the fragment { LineObj stick = new LineObj(color, mz, points.ScaledList[index].Y, mz, 0); stick.Location.CoordinateFrame = CoordType.AxisXYScale; stick.Line.Width = 2; list.Add(stick); if (showLabels) { // use an existing text point annotation if possible TextObj text = null; foreach (GraphObj obj in list) { if (obj is TextObj && (obj.Location.CoordinateFrame == CoordType.AxisXYScale || obj.Location.CoordinateFrame == CoordType.XScaleYChartFraction) && Math.Abs(obj.Location.X - mz) < 0.5) { text = obj as TextObj; text.Text = String.Format("{0}\n{1}", label, text.Text); break; } } if (text == null) { text = new TextObj(label, mz, points.ScaledList[index].Y, CoordType.AxisXYScale, AlignH.Left, AlignV.Center); list.Add(text); } text.ZOrder = ZOrder.A_InFront; text.FontSpec = new FontSpec("Arial", 12, color, false, false, false); text.FontSpec.Border.IsVisible = false; text.FontSpec.Fill.IsVisible = false; text.FontSpec.Angle = 90; //text.IsClippedToChartRect = true; } } } #endregion /// #region basepeakthresholding is true else //if basepeakthresholding is true { if (index == -1 || points.ScaledList[index].X > (mz + 0.5) || points.FullList[index].Y < cutoff) // no matching point: present a "missed" fragment annotation { if (!showMisses) return; color = Color.FromArgb(115, color); // transparent to emphasize miss LineObj stick = new LineObj(color, mz, offset, mz, 1); stick.Location.CoordinateFrame = CoordType.XScaleYChartFraction; stick.Line.Width = 2; stick.Line.Style = System.Drawing.Drawing2D.DashStyle.Dot; list.Add(stick); if (showLabels) { TextObj text = new TextObj(label, mz, offset, CoordType.XScaleYChartFraction, AlignH.Left, AlignV.Center); text.ZOrder = ZOrder.A_InFront; text.FontSpec = new FontSpec("Arial", 12, color, false, false, false); text.FontSpec.Border.IsVisible = false; text.FontSpec.Angle = 90; //text.IsClippedToChartRect = true; list.Add(text); } } else // matching point found: present the point as the fragment { LineObj stick = new LineObj(color, mz, points.ScaledList[index].Y, mz, 0); stick.Location.CoordinateFrame = CoordType.AxisXYScale; stick.Line.Width = 2; list.Add(stick); if (showLabels) { // use an existing text point annotation if possible TextObj text = null; foreach (GraphObj obj in list) { if (obj is TextObj && (obj.Location.CoordinateFrame == CoordType.AxisXYScale || obj.Location.CoordinateFrame == CoordType.XScaleYChartFraction) && Math.Abs(obj.Location.X - mz) < 0.5) { text = obj as TextObj; text.Text = String.Format("{0}\n{1}", label, text.Text); break; } } if (text == null) { text = new TextObj(label, mz, points.ScaledList[index].Y, CoordType.AxisXYScale, AlignH.Left, AlignV.Center); list.Add(text); } text.ZOrder = ZOrder.A_InFront; text.FontSpec = new FontSpec("Arial", 12, color, false, false, false); text.FontSpec.Border.IsVisible = false; text.FontSpec.Fill.IsVisible = false; text.FontSpec.Angle = 90; //text.IsClippedToChartRect = true; } } } #endregion } }
///<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 }
private void AddRetentionTimeAnnotation(MSGraphPane graphPane, Graphics g, GraphObjList annotations, PointF ptTop, string title, GraphObjType graphObjType, Color color, ScaledRetentionTime retentionTime) { string label = string.Format("{0}\n{1:F01}", title, retentionTime.DisplayTime); // Not L10N FontSpec fontLabel = CreateFontSpec(color, _fontSpec.Size); SizeF sizeLabel = fontLabel.MeasureString(g, label, graphPane.CalcScaleFactor()); PointF realTopPoint = ptTop; ptTop = new PointF(0, ptTop.Y + sizeLabel.Height + 15); float chartHeightWithLabel = graphPane.Chart.Rect.Height + sizeLabel.Height + 15; double intensityChartFraction = (ptTop.Y - realTopPoint.Y) / chartHeightWithLabel; LineObj stick = new LineObj(color, retentionTime.DisplayTime, intensityChartFraction, retentionTime.DisplayTime, 1) { IsClippedToChartRect = true, Location = { CoordinateFrame = CoordType.XScaleYChartFraction }, ZOrder = ZOrder.E_BehindCurves, Line = { Width = 1 }, Tag = new GraphObjTag(this, graphObjType, retentionTime), }; annotations.Add(stick); ptTop = new PointF(0, ptTop.Y - 5); intensityChartFraction = (ptTop.Y - realTopPoint.Y) / chartHeightWithLabel; TextObj text = new TextObj(label, retentionTime.DisplayTime, intensityChartFraction, CoordType.XScaleYChartFraction, AlignH.Center, AlignV.Bottom) { IsClippedToChartRect = true, ZOrder = ZOrder.E_BehindCurves, FontSpec = CreateFontSpec(color, _fontSpec.Size), Tag = new GraphObjTag(this, graphObjType, retentionTime), }; annotations.Add(text); }
public override void AddPreCurveAnnotations(MSGraphPane graphPane, Graphics g, MSPointList pointList, GraphObjList annotations) { if (Chromatogram == null) return; // Give priority to showing the best peak text object above all other annotations if (DragInfo != null || (!HideBest && TransitionChromInfo != null) || CurveAnnotation != null) { // Show text and arrow for the best peak double intensityBest = 0; if (_bestPeakTimeIndex != -1) { ScaledRetentionTime timeBest = new ScaledRetentionTime(_measuredTimes[_bestPeakTimeIndex], _displayTimes[_bestPeakTimeIndex]); float xBest = graphPane.XAxis.Scale.Transform(timeBest.DisplayTime); intensityBest = _intensities[_bestPeakTimeIndex]; float yBest = graphPane.YAxis.Scale.Transform(intensityBest); if (GraphChromatogram.ShowRT != ShowRTChrom.none || DragInfo != null) { // Best peak gets its own label to avoid curve overlap detection double intensityLabel = graphPane.YAxis.Scale.ReverseTransform(yBest - 5); float? massError = Settings.Default.ShowMassError && TransitionChromInfo != null ? TransitionChromInfo.MassError : null; double dotProduct = _dotProducts != null ? _bestProduct : 0; TextObj text; if (CurveAnnotation != null) { // Darken peptide name a little so light colors stand out against the white background. var color = FontSpec.FontColor; if (!GraphInfo.IsSelected) color = Color.FromArgb(color.R*7/10, color.G*7/10, color.B*7/10); var fontSpec = new FontSpec(FontSpec) { FontColor = color, Angle = 90 }; if (GraphInfo.IsSelected) fontSpec = new FontSpec(fontSpec) {IsBold = true, Size = fontSpec.Size + 2, IsAntiAlias = true}; // Display peptide name label using vertical text. text = new TextObj(CurveAnnotation, timeBest.DisplayTime, intensityLabel, CoordType.AxisXYScale, AlignH.Left, AlignV.Center) { ZOrder = ZOrder.A_InFront, IsClippedToChartRect = true, FontSpec = fontSpec, Tag = new GraphObjTag(this, GraphObjType.best_peak, timeBest), }; } else { string label = FormatTimeLabel(timeBest.DisplayTime, massError, dotProduct); text = new TextObj(label, timeBest.DisplayTime, intensityLabel, CoordType.AxisXYScale, AlignH.Center, AlignV.Bottom) { ZOrder = ZOrder.A_InFront, IsClippedToChartRect = true, FontSpec = FontSpec, Tag = new GraphObjTag(this, GraphObjType.best_peak, timeBest), }; } annotations.Add(text); } // If showing multiple peptides, skip the best peak arrow indicator. if (CurveAnnotation == null) { // Show the best peak arrow indicator double timeArrow = graphPane.XAxis.Scale.ReverseTransform(xBest - 4); double intensityArrow = graphPane.YAxis.Scale.ReverseTransform(yBest - 2); ArrowObj arrow = new ArrowObj(COLOR_BEST_PEAK, 12f, timeArrow, intensityArrow, timeArrow, intensityArrow) { Location = {CoordinateFrame = CoordType.AxisXYScale}, IsArrowHead = true, IsClippedToChartRect = true, ZOrder = ZOrder.A_InFront }; annotations.Add(arrow); } } // Show the best peak boundary lines if (CurveAnnotation == null) { double startTime = 0, endTime = 0; if (DragInfo != null) { startTime = DragInfo.StartTime.MeasuredTime; endTime = DragInfo.EndTime.MeasuredTime; } else if (TransitionChromInfo != null) { var tranPeakInfo = TransitionChromInfo; startTime = tranPeakInfo.StartRetentionTime; endTime = tranPeakInfo.EndRetentionTime; } AddPeakBoundaries(graphPane, annotations, true, ScaleRetentionTime(startTime), ScaleRetentionTime(endTime), intensityBest); } } }
public override void AddAnnotations(MSGraphPane graphPane, Graphics g, MSPointList pointList, GraphObjList annotations) { if (Chromatogram == null) return; // Calculate maximum y for potential retention time indicators PointF ptTop = new PointF(0, graphPane.Chart.Rect.Top); if (GraphChromatogram.ShowRT != ShowRTChrom.none) { if (RetentionMsMs != null) { foreach (double retentionTime in RetentionMsMs) { Color color = COLOR_MSMSID_TIME; if (SelectedRetentionMsMs.HasValue && Equals((float) retentionTime, (float) SelectedRetentionMsMs)) { color = ColorSelected; } AddRetentionTimeAnnotation(graphPane, g, annotations, ptTop, Resources.ChromGraphItem_AddAnnotations_ID, GraphObjType.ms_ms_id, color, ScaleRetentionTime(retentionTime)); } } if (AlignedRetentionMsMs != null) { foreach (var time in AlignedRetentionMsMs) { var scaledTime = ScaleRetentionTime(time); var line = new LineObj(COLOR_ALIGNED_MSMSID_TIME, scaledTime.DisplayTime, 0, scaledTime.DisplayTime, 1) { ZOrder = ZOrder.F_BehindGrid, Location = { CoordinateFrame = CoordType.XScaleYChartFraction }, IsClippedToChartRect = true, Tag = new GraphObjTag(this, GraphObjType.aligned_ms_id, scaledTime), }; annotations.Add(line); } } if (UnalignedRetentionMsMs != null) { foreach (var time in UnalignedRetentionMsMs) { var scaledTime = ScaleRetentionTime(time); var line = new LineObj(COLOR_UNALIGNED_MSMSID_TIME, scaledTime.DisplayTime, 0, scaledTime.DisplayTime, 1) { ZOrder = ZOrder.F_BehindGrid, Location = { CoordinateFrame = CoordType.XScaleYChartFraction }, IsClippedToChartRect = true, Tag = new GraphObjTag(this, GraphObjType.unaligned_ms_id, scaledTime), }; annotations.Add(line); } } } // Draw retention time indicator, if set if (RetentionPrediction.HasValue) { double time = RetentionPrediction.Value; // Create temporary label to calculate positions if (GraphChromatogram.ShowRT != ShowRTChrom.none) { AddRetentionTimeAnnotation(graphPane, g, annotations, ptTop, Resources.ChromGraphItem_AddAnnotations_Predicted, GraphObjType.predicted_rt_window, COLOR_RETENTION_TIME, ScaleRetentionTime(time)); } // Draw background for retention time window if (RetentionWindow > 0) { double x1 = ScaleRetentionTime(time - RetentionWindow/2).DisplayTime; double x2 = ScaleRetentionTime(time + RetentionWindow/2).DisplayTime; BoxObj box = new BoxObj(x1, 0, x2-x1, 1, COLOR_RETENTION_WINDOW, COLOR_RETENTION_WINDOW) { Location = { CoordinateFrame = CoordType.XScaleYChartFraction }, IsClippedToChartRect = true, ZOrder = ZOrder.F_BehindGrid }; annotations.Add(box); } } if (RetentionExplicit != null && GraphChromatogram.ShowRT != ShowRTChrom.none) { // Create temporary label to calculate positions AddRetentionTimeAnnotation(graphPane, g, annotations, ptTop, Resources.ChromGraphItem_AddAnnotations_Explicit, GraphObjType.predicted_rt_window, COLOR_RETENTION_TIME, ScaleRetentionTime(RetentionExplicit.RetentionTime)); } for (int i = 0, len = Chromatogram.NumPeaks; i < len; i++) { if (_arrayLabelIndexes[i] == -1) continue; double maxIntensity = _intensities[_arrayLabelIndexes[i]]; // Show peak extent indicators, if they are far enough apart ChromPeak peak = Chromatogram.GetPeak(i); AddPeakBoundaries(graphPane, annotations, false, ScaleRetentionTime(peak.StartTime), ScaleRetentionTime(peak.EndTime), maxIntensity); } }
public override void AddAnnotations(MSGraphPane graphPane, Graphics g, MSPointList pointList, GraphObjList annotations) { // ReSharper disable UseObjectOrCollectionInitializer foreach (var rmi in SpectrumInfo.PeaksMatched) { if (!IsVisibleIon(rmi)) continue; IonType type = IsVisibleIon(rmi.IonType, rmi.Ordinal, rmi.Charge) ? rmi.IonType : rmi.IonType2; Color color; switch (type) { default: color = COLOR_NONE; break; case IonType.a: color = COLOR_A; break; case IonType.x: color = COLOR_X; break; case IonType.b: color = COLOR_B; break; case IonType.y: color = COLOR_Y; break; case IonType.c: color = COLOR_C; break; case IonType.z: color = COLOR_Z; break; // FUTURE: Add custom ions when LibraryRankedSpectrumInfo can support them case IonType.precursor: color = COLOR_PRECURSOR; break; } if (IsMatch(rmi.PredictedMz)) { color = COLOR_SELECTED; } double mz = rmi.ObservedMz; var stick = new LineObj(color, mz, rmi.Intensity, mz, 0); stick.IsClippedToChartRect = true; stick.Location.CoordinateFrame = CoordType.AxisXYScale; stick.Line.Width = LineWidth + 1; annotations.Add(stick); } //ReSharper restore UseObjectOrCollectionInitializer }
private void addFragment( GraphObjList list, pwiz.MSGraph.MSPointList points, string series, int length, int charge, double mz ) { string label = String.Format("{0}{1}{2}", series, length, (charge > 1 ? "+" + charge.ToString() : "")); Color color; double offset; switch( series ) { default: color = Color.Gray; offset = 0.1; break; case "a": color = Color.YellowGreen; offset = 0.1; break; case "x": color = Color.Green; offset = 0.12; break; case "b": color = Color.BlueViolet; offset = 0.14; break; case "y": color = Color.Blue; offset = 0.16; break; case "c": color = Color.Orange; offset = 0.18; break; case "z": color = Color.OrangeRed; offset = 0.2; break; case "z*": color = Color.Crimson; offset = 0.4; break; } numFragmentsPredicted[series+(charge > 1 ? "+" + charge.ToString() : "")].Add(mz); int index = -1; if( points != null ) index = points.LowerBound( mz - 0.5 ); if( index == -1 || points.ScaledList[index].X > ( mz + 0.5 ) ) // no matching point: present a "missed" fragment annotation { if( !showMisses ) return; color = Color.FromArgb( 115, color ); // transparent to emphasize miss LineObj stick = new LineObj( color, mz, offset, mz, 1 ); stick.Location.CoordinateFrame = CoordType.XScaleYChartFraction; stick.Line.Width = 2; stick.Line.Style = System.Drawing.Drawing2D.DashStyle.Dot; list.Add( stick ); if( showLabels ) { TextObj text = new TextObj( label, mz, offset, CoordType.XScaleYChartFraction, AlignH.Center, AlignV.Bottom ); text.ZOrder = ZOrder.A_InFront; text.FontSpec = new FontSpec( "Arial", 12, color, false, false, false ); text.FontSpec.Border.IsVisible = false; //text.IsClippedToChartRect = true; list.Add( text ); } } else // matching point found: present the point as the fragment { numFragmentsMatched[series + (charge > 1 ? "+" + charge.ToString() : "")].Add(mz); LineObj stick = new LineObj( color, mz, points.ScaledList[index].Y, mz, 0 ); stick.Location.CoordinateFrame = CoordType.AxisXYScale; stick.Line.Width = 2; list.Add( stick ); if( showLabels ) { // use an existing text point annotation if possible TextObj text = null; foreach( GraphObj obj in list ) { if( obj is TextObj && ( obj.Location.CoordinateFrame == CoordType.AxisXYScale || obj.Location.CoordinateFrame == CoordType.XScaleYChartFraction ) && Math.Abs( obj.Location.X - mz ) < 0.5 ) { text = obj as TextObj; text.Text = String.Format( "{0}\n{1}", label, text.Text ); break; } } if( text == null ) { text = new TextObj( label, mz, points.ScaledList[index].Y, CoordType.AxisXYScale, AlignH.Center, AlignV.Bottom ); list.Add( text ); } text.ZOrder = ZOrder.A_InFront; text.FontSpec = new FontSpec( "Arial", 12, color, false, false, false ); text.FontSpec.Border.IsVisible = false; //text.IsClippedToChartRect = true; } } }