/// <summary>
        /// The Copy Constructor
        /// </summary>
        /// <param name="rhs">The <see cref="PaneBase"/> object from which to copy</param>
        public PaneBase(PaneBase rhs)
        {
            // copy over all the value types
            _isFontsScaled    = rhs._isFontsScaled;
            _isPenWidthScaled = rhs._isPenWidthScaled;

            _titleGap      = rhs._titleGap;
            _baseDimension = rhs._baseDimension;
            _margin        = rhs._margin.Clone();
            _rect          = rhs._rect;

            // Copy the reference types by cloning
            _fill   = rhs._fill.Clone();
            _border = rhs._border.Clone();
            _title  = rhs._title.Clone();

            _legend       = rhs.Legend.Clone();
            _title        = rhs._title.Clone();
            _graphObjList = rhs._graphObjList.Clone();

            if (rhs._tag is ICloneable)
            {
                _tag = ((ICloneable)rhs._tag).Clone();
            }
            else
            {
                _tag = rhs._tag;
            }
        }
        /// <summary>
        /// Default constructor for the <see cref="PaneBase"/> class.  Specifies the <see cref="Title"/> of
        /// the <see cref="PaneBase"/>, and the size of the <see cref="Rect"/>.
        /// </summary>
        public PaneBase(string title, RectangleF paneRect)
        {
            _rect = paneRect;

            _legend = new Legend();

            _baseDimension = Default.BaseDimension;
            _margin        = new Margin();
            _titleGap      = Default.TitleGap;

            _isFontsScaled    = Default.IsFontsScaled;
            _isPenWidthScaled = Default.IsPenWidthScaled;
            _fill             = new Fill(Default.FillColor);
            _border           = new Border(Default.IsBorderVisible, Default.BorderColor,
                                           Default.BorderPenWidth);

            _title = new GapLabel(title, Default.FontFamily,
                                  Default.FontSize, Default.FontColor, Default.FontBold,
                                  Default.FontItalic, Default.FontUnderline);
            _title._fontSpec.Fill.IsVisible   = false;
            _title._fontSpec.Border.IsVisible = false;

            _graphObjList = new GraphObjList();

            _tag = null;
        }
Esempio n. 3
0
 /// <summary>
 /// The Copy Constructor
 /// </summary>
 /// <param name="rhs">The <see cref="GraphObjList"/> object from which to copy</param>
 public GraphObjList(GraphObjList rhs)
 {
     foreach (GraphObj item in rhs)
     {
         this.Add((GraphObj)((ICloneable)item).Clone());
     }
 }
Esempio n. 4
0
 /// <summary>
 /// The Copy Constructor
 /// </summary>
 /// <param name="rhs">The <see cref="GraphObjList"/> object from which to copy</param>
 public GraphObjList(GraphObjList rhs)
 {
     for (var i = 0; i < rhs.list.Count; i++)
     {
         var item = rhs.list[i];
         list.Add((GraphObj)((ICloneable)item).Clone());
     }
 }
Esempio n. 5
0
 public MSGraphPane(MSGraphPane other)
     : base(other)
 {
     _currentItemType = other._currentItemType;
     _pointAnnotations = new GraphObjList();
     _manualLabels = new Dictionary<TextObj, RectangleF>();
     _labelBoundsCache = other._labelBoundsCache;
 }
Esempio n. 6
0
        /// <summary>
        /// Find the pane and the object within that pane that lies closest to the specified
        /// mouse (screen) point.
        /// </summary>
        /// <remarks>
        /// This method first finds the <see cref="GraphPane"/> within the list that contains
        /// the specified mouse point.  It then calls the <see cref="GraphPane.FindNearestObject"/>
        /// method to determine which object, if any, was clicked.  With the exception of the
        /// <see paramref="pane"/>, all the parameters in this method are identical to those
        /// in the <see cref="GraphPane.FindNearestObject"/> method.
        /// If the mouse point lies within the <see cref="PaneBase.Rect"/> of any
        /// <see cref="GraphPane"/> item, then that pane will be returned (otherwise it will be
        /// null).  Further, within the selected pane, if the mouse point is within the
        /// bounding box of any of the items (or in the case
        /// of <see cref="ArrowObj"/> and <see cref="CurveItem"/>, within
        /// <see cref="GraphPane.Default.NearestTol"/> pixels), then the object will be returned.
        /// You must check the type of the object to determine what object was
        /// selected (for example, "if ( object is Legend ) ...").  The
        /// <see paramref="index"/> parameter returns the index number of the item
        /// within the selected object (such as the point number within a
        /// <see cref="CurveItem"/> object.
        /// </remarks>
        /// <param name="mousePt">The screen point, in pixel coordinates.</param>
        /// <param name="g">
        /// A graphic device object to be drawn into.  This is normally e.Graphics from the
        /// PaintEventArgs argument to the Paint() method.
        /// </param>
        /// <param name="pane">A reference to the <see cref="GraphPane"/> object that was clicked.</param>
        /// <param name="nearestObj">A reference to the nearest object to the
        /// specified screen point.  This can be any of <see cref="Axis"/>,
        /// <see cref="Legend"/>, <see cref="PaneBase.Title"/>,
        /// <see cref="TextObj"/>, <see cref="ArrowObj"/>, or <see cref="CurveItem"/>.
        /// Note: If the pane title is selected, then the <see cref="GraphPane"/> object
        /// will be returned.
        /// </param>
        /// <param name="index">The index number of the item within the selected object
        /// (where applicable).  For example, for a <see cref="CurveItem"/> object,
        /// <see paramref="index"/> will be the index number of the nearest data point,
        /// accessible via <see cref="CurveItem.Points">CurveItem.Points[index]</see>.
        /// index will be -1 if no data points are available.</param>
        /// <returns>true if a <see cref="GraphPane"/> was found, false otherwise.</returns>
        /// <seealso cref="GraphPane.FindNearestObject"/>
        public bool FindNearestPaneObject(PointF mousePt, Graphics g, out GraphPane pane,
                                          out object nearestObj, out int index)
        {
            pane       = null;
            nearestObj = null;
            index      = -1;

            GraphObj saveGraphItem = null;
            int      saveIndex     = -1;
            float    scaleFactor   = CalcScaleFactor();

            // See if the point is in a GraphObj
            // If so, just save the object and index so we can see if other overlying objects were
            // intersected as well.
            if (GraphObjList.FindPoint(mousePt, this, g, scaleFactor, out index))
            {
                saveGraphItem = GraphObjList[index];
                saveIndex     = index;

                // If it's an "In-Front" item, then just return it
                if (saveGraphItem.ZOrder == ZOrder.A_InFront)
                {
                    nearestObj = saveGraphItem;
                    index      = saveIndex;
                    return(true);
                }
            }

            foreach (GraphPane tPane in _paneList)
            {
                if (tPane.Rect.Contains(mousePt))
                {
                    pane = tPane;
                    return(tPane.FindNearestObject(mousePt, g, out nearestObj, out index));
                }
            }

            // If no items were found in the GraphPanes, then return the item found on the MasterPane (if any)
            if (saveGraphItem != null)
            {
                nearestObj = saveGraphItem;
                index      = saveIndex;
                return(true);
            }

            return(false);
        }
Esempio n. 7
0
        public MSGraphPane(LabelBoundsCache labelBoundsCache = null)
        {
            Title.IsVisible = false;
            Chart.Border.IsVisible = false;
            Y2Axis.IsVisible = false;
            X2Axis.IsVisible = false;
            XAxis.MajorTic.IsOpposite = false;
            YAxis.MajorTic.IsOpposite = false;
            XAxis.MinorTic.IsOpposite = false;
            YAxis.MinorTic.IsOpposite = false;
            IsFontsScaled = false;
            YAxis.Scale.MaxGrace = 0.1;
            YAxis.MajorGrid.IsZeroLine = false; // Hide the y=0 line
            LockYAxisAtZero = true;

            _currentItemType = MSGraphItemType.unknown;
            _pointAnnotations = new GraphObjList();
            _manualLabels = new Dictionary<TextObj, RectangleF>();
            _labelBoundsCache = labelBoundsCache ?? new LabelBoundsCache();
        }
        /// <summary>
        /// Constructor for deserializing objects
        /// </summary>
        /// <param name="info">A <see cref="SerializationInfo"/> instance that defines the serialized data
        /// </param>
        /// <param name="context">A <see cref="StreamingContext"/> instance that contains the serialized data
        /// </param>
        protected PaneBase(SerializationInfo info, StreamingContext context)
        {
            // The schema value is just a file version parameter.  You can use it to make future versions
            // backwards compatible as new member variables are added to classes
            int sch = info.GetInt32("schema");

            _rect   = (RectangleF)info.GetValue("rect", typeof(RectangleF));
            _legend = (Legend)info.GetValue("legend", typeof(Legend));
            _title  = (GapLabel)info.GetValue("title", typeof(GapLabel));
            //this.isShowTitle = info.GetBoolean( "isShowTitle" );
            _isFontsScaled    = info.GetBoolean("isFontsScaled");
            _isPenWidthScaled = info.GetBoolean("isPenWidthScaled");
            //this.fontSpec = (FontSpec) info.GetValue( "fontSpec" , typeof(FontSpec) );
            _titleGap      = info.GetSingle("titleGap");
            _fill          = (Fill)info.GetValue("fill", typeof(Fill));
            _border        = (Border)info.GetValue("border", typeof(Border));
            _baseDimension = info.GetSingle("baseDimension");
            _margin        = (Margin)info.GetValue("margin", typeof(Margin));
            _graphObjList  = (GraphObjList)info.GetValue("graphObjList", typeof(GraphObjList));

            _tag = info.GetValue("tag", typeof(object));
        }
Esempio n. 9
0
 public virtual void Update (GraphItem item, pwiz.MSGraph.MSPointList pointList, GraphObjList annotations)
 {
     throw new NotImplementedException();
 }
Esempio n. 10
0
        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;
                }
            }
        }
Esempio 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
        }
Esempio n. 12
0
        public override void Update( GraphItem item, pwiz.MSGraph.MSPointList points, GraphObjList annotations )
        {
            double basePeakIntensity = 0;
            double cutoff = 0;
            foreach (var pointlist in points)
            {
                if (basePeakIntensity < pointlist.Y)
                    basePeakIntensity = pointlist.Y;
            }
            cutoff = basePeakIntensity * basePeakPercentage * 0.01;

            if( !Enabled )
                return;

            if( !( item is MassSpectrum ) )
                return; // throw exception?

            GraphObjList list = annotations;
            Peptide peptide;

            try
            {
                peptide = new Peptide( sequence,
                    pwiz.CLI.proteome.ModificationParsing.ModificationParsing_Auto,
                    pwiz.CLI.proteome.ModificationDelimiter.ModificationDelimiter_Brackets );
            } catch( Exception )
            {
                return;
            }

            //if (annotationPanels.peptideInfoGridView.InvokeRequired)
            //{
            //    annotationPanels.peptideInfoGridView.BeginInvoke(new MethodInvoker(() => Update(item, points, annotations)));
            //    //return;
            //}

            var spectrum = ( item as MassSpectrum ).Element;

            if (spectrum.precursors.Count > 0 && ionSeriesIsEnabled(IonSeries.Auto))
            {
                bool cid = (item as MassSpectrum).Element.precursors[0].activation.hasCVParam(CVID.MS_CID);
                bool etd = (item as MassSpectrum).Element.precursors[0].activation.hasCVParam(CVID.MS_ETD);
                ionSeries |= cid ? IonSeries.b | IonSeries.y : IonSeries.Off;
                ionSeries |= etd ? IonSeries.c | IonSeries.zRadical : IonSeries.Off;
            }

            string unmodifiedSequence = peptide.sequence;
            int sequenceLength = unmodifiedSequence.Length;
            Fragmentation fragmentation = peptide.fragmentation( fragmentMassType == 0 ? true : false, true );

            //test neutral
            ModificationMap modifications = peptide.modifications();
            ///
            #region adding labels for series a/b/c/x/y/z:::::::::naive fragmentation modeling

            if (!showBasophileModel)
            {
                for (int i = 1; i < sequenceLength; ++i)
                {
                    //test neutral loss
                    //note here the Cseq is slightly different than those in addFragmentSummary
                    string Nseq = peptide.sequence.Substring(0, i);
                    string Cseq = peptide.sequence.Substring(sequenceLength - i, i);
                    string NTempSeq = peptide.sequence.Substring(0, sequenceLength - i);
                    char[] Nseqchars = Nseq.ToCharArray();
                    char[] NTempSeqchars = NTempSeq.ToCharArray();
                    char[] seqchars = peptide.sequence.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 && (seqchars[k] == 'S' || seqchars[k] == 'T' || seqchars[k] == 'Y'))
                        {
                            Nphosmodi++;
                        }
                    }
                    for (int k = 0; k < sequenceLength - i; k++)
                    {
                        if (Math.Round(modifications[k].monoisotopicDeltaMass()) == 80 && (seqchars[k] == 'S' || seqchars[k] == 'T' || seqchars[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 charge = min; charge <= max; ++charge)
                    {
                        if (ionSeriesIsEnabled(IonSeries.a)) addFragment(list, points, "a", i, charge, fragmentation.a(i, charge));
                        if (ionSeriesIsEnabled(IonSeries.b)) addFragment(list, points, "b", i, charge, fragmentation.b(i, charge));
                        if (ionSeriesIsEnabled(IonSeries.y)) addFragment(list, points, "y", i, charge, fragmentation.y(i, charge));
                        if (ionSeriesIsEnabled(IonSeries.z)) addFragment(list, points, "z", i, charge, fragmentation.z(i, charge));
                        if (ionSeriesIsEnabled(IonSeries.zRadical)) addFragment(list, points, "z*", i, charge, fragmentation.zRadical(i, charge));

                        if (i < sequenceLength)
                        {
                            if (ionSeriesIsEnabled(IonSeries.c)) addFragment(list, points, "c", i, charge, fragmentation.c(i, charge));
                            if (ionSeriesIsEnabled(IonSeries.x)) addFragment(list, points, "x", i, charge, fragmentation.x(i, charge));
                        }

                        //test neutral loss
                        #region water loss
                        if (waterLoss == true)
                        {
                            if (Nseq.Contains("S") || Nseq.Contains("T") || Nseq.Contains("E") || Nseq.Contains("D"))
                            {
                                if (ionSeriesIsEnabled(IonSeries.a)) addFragment(list, points, "a-water", i, charge, fragmentation.a(i, charge) - WATERMONOMASS / charge);
                                if (ionSeriesIsEnabled(IonSeries.b)) addFragment(list, points, "b-water", i, charge, fragmentation.b(i, charge) - WATERMONOMASS / charge);
                                if (i < sequenceLength)
                                {
                                    if (ionSeriesIsEnabled(IonSeries.c)) addFragment(list, points, "c-water", i, charge, fragmentation.c(i, charge) - WATERMONOMASS / charge);
                                }
                            }

                            if (Cseq.Contains("S") || Cseq.Contains("T") || Cseq.Contains("E") || Cseq.Contains("D"))
                            {
                                if (ionSeriesIsEnabled(IonSeries.y)) addFragment(list, points, "y-water", i, charge, fragmentation.y(i, charge) - WATERMONOMASS / charge);
                                if (ionSeriesIsEnabled(IonSeries.z)) addFragment(list, points, "z-water", i, charge, fragmentation.z(i, charge) - WATERMONOMASS / charge);
                                if (ionSeriesIsEnabled(IonSeries.zRadical)) addFragment(list, points, "z*-water", i, charge, fragmentation.zRadical(i, charge) - WATERMONOMASS / charge);

                                if (i < sequenceLength)
                                {
                                    if (ionSeriesIsEnabled(IonSeries.x)) addFragment(list, points, "x-water", i, charge, fragmentation.x(i, charge) - WATERMONOMASS / charge);
                                }
                            }
                        }
                        #endregion

                        //test neutral loss
                        #region ammonium loss
                        if (ammoniumLoss == true)
                        {
                            if (Nseq.Contains("R") || Nseq.Contains("K") || Nseq.Contains("Q") || Nseq.Contains("N"))
                            {
                                if (ionSeriesIsEnabled(IonSeries.a)) addFragment(list, points, "a-ammonium", i, charge, fragmentation.a(i, charge) - AMMONIUMMONOMASS / charge);
                                if (ionSeriesIsEnabled(IonSeries.b)) addFragment(list, points, "b-ammonium", i, charge, fragmentation.b(i, charge) - AMMONIUMMONOMASS / charge);
                                if (i < sequenceLength)
                                {
                                    if (ionSeriesIsEnabled(IonSeries.c)) addFragment(list, points, "c-ammonium", i, charge, fragmentation.c(i, charge) - AMMONIUMMONOMASS / charge);
                                }
                            }

                            if (Cseq.Contains("R") || Cseq.Contains("K") || Cseq.Contains("Q") || Cseq.Contains("N"))
                            {
                                if (ionSeriesIsEnabled(IonSeries.y)) addFragment(list, points, "y-ammonium", i, charge, fragmentation.y(i, charge) - AMMONIUMMONOMASS / charge);
                                if (ionSeriesIsEnabled(IonSeries.z)) addFragment(list, points, "z-ammonium", i, charge, fragmentation.z(i, charge) - AMMONIUMMONOMASS / charge);
                                if (ionSeriesIsEnabled(IonSeries.zRadical)) addFragment(list, points, "z*-ammonium", i, charge, fragmentation.zRadical(i, charge) - AMMONIUMMONOMASS / charge);

                                if (i < sequenceLength)
                                {
                                    if (ionSeriesIsEnabled(IonSeries.x)) addFragment(list, points, "x-ammonium", i, charge, fragmentation.x(i, charge) - AMMONIUMMONOMASS / charge);
                                }
                            }
                        }
                        #endregion

                        //test neutral loss
                        #region phosphate loss
                        if (phosphateLoss == true)
                        {
                            int minNPhosphate = Math.Min(Nphosmodi, numPhosphate);
                            if (minNPhosphate > 0)
                            {
                                if (ionSeriesIsEnabled(IonSeries.a))
                                {
                                    for (int k = 1; k <= minNPhosphate; k++)
                                    {
                                        addFragment(list, points, "a-" + k + "phos", i, charge, fragmentation.a(i, charge) - k * PHOSPHATEMONOMASS / charge);
                                    }
                                }
                                if (ionSeriesIsEnabled(IonSeries.b))
                                {
                                    for (int k = 1; k <= minNPhosphate; k++)
                                    {
                                        addFragment(list, points, "b-" + k + "phos", i, charge, fragmentation.b(i, charge) - k * PHOSPHATEMONOMASS / charge);
                                    }
                                }
                                if (i < sequenceLength)
                                {
                                    if (ionSeriesIsEnabled(IonSeries.c))
                                    {
                                        for (int k = 1; k <= minNPhosphate; k++)
                                        {
                                            addFragment(list, points, "c-" + k + "phos", i, charge, fragmentation.c(i, charge) - k * PHOSPHATEMONOMASS / charge);
                                        }
                                    }
                                }

                            }

                            int minCPhosphate = Math.Min(Cphosmodi, numPhosphate);
                            if (minCPhosphate > 0)
                            {

                                if (ionSeriesIsEnabled(IonSeries.y))
                                {
                                    for (int k = 1; k <= minCPhosphate; k++)
                                    {
                                        addFragment(list, points, "y-" + k + "phos", i, charge, fragmentation.y(i, charge) - k * PHOSPHATEMONOMASS / charge);
                                    }
                                }
                                if (ionSeriesIsEnabled(IonSeries.z))
                                {
                                    for (int k = 1; k <= minCPhosphate; k++)
                                        addFragment(list, points, "z-" + k + "phos", i, charge, fragmentation.z(i, charge) - k * PHOSPHATEMONOMASS / charge);
                                }
                                if (ionSeriesIsEnabled(IonSeries.zRadical))
                                {
                                    for (int k = 1; k <= minCPhosphate; k++)
                                        addFragment(list, points, "z*-" + k + "phos", i, charge, fragmentation.zRadical(i, charge) - k * PHOSPHATEMONOMASS / charge);
                                }

                                if (i < sequenceLength)
                                {
                                    if (ionSeriesIsEnabled(IonSeries.x))
                                    {
                                        for (int k = 1; k <= minCPhosphate; k++)
                                            addFragment(list, points, "x-" + k + "phos", i, charge, fragmentation.x(i, charge) - k * PHOSPHATEMONOMASS / charge);
                                    }
                                }
                            }

                        }
                        #endregion

                    }
                }
            }

            //for basophile fragmentation modeling
            else if (showBasophileModel)
            {
                //clear the panel
                //annotationPanels.bCheckBox.Checked = false;
                //annotationPanels.yCheckBox.Checked = false;
                String peptideSeq = peptide.sequence;
                int seqLength = peptideSeq.Length;
                char[] seq = peptideSeq.ToCharArray();
                int totalR = 0, totalK = 0, totalH = 0;

                for (int i = 0; i < seqLength; ++i)
                {
                    if (seq[i] == 'R')
                        ++totalR;
                    else if (seq[i] == 'K')
                        ++totalK;
                    else if (seq[i] == 'H')
                        ++totalH;
                }

                for (int c = 1; c < seqLength; c++)
                {
                    int totalNR = 0, totalNK = 0, totalNH = 0, totalNL = 0;
                    int totalCR = 0, totalCK = 0, totalCH = 0, totalCL = 0;
                    for (int i = 0; i < c; ++i)
                    {
                        if (seq[i] == 'R') { ++totalNR; }
                        else if (seq[i] == 'K') { ++totalNK; }
                        else if (seq[i] == 'H') { ++totalNH; }
                    }
                    totalNL = c;
                    totalCR = totalR - totalNR;
                    totalCK = totalK - totalNK;
                    totalCH = totalH - totalNH;
                    totalCL = seqLength - totalNL;

                    double y1_logit = 0.1098112 * totalNR + 0.2085831 * totalNK + 0.1512109 * totalNH + 0.0460839 * totalNL
                                    - 0.3872417 * totalCR - 0.3684911 * totalCK - 0.1634741 * totalCH - 0.1693931 * totalCL + 1.2632997;
                    double y2_logit = -0.6345364 * totalNR - 0.3365917 * totalNK - 0.4577882 * totalNH - 0.1492703 * totalNL
                                     + 0.7738133 * totalCR + 0.6036758 * totalCK + 0.5942542 * totalCH + 0.0701467 * totalCL + 0.0806280;
                    double b1_logit = 0.0801432 * totalNR - 0.1088081 * totalNK - 0.1338220 * totalNH - 0.1413059 * totalNL
                                    - 0.3157957 * totalCR - 0.2708274 * totalCK - 0.3703136 * totalCH + 0.0157418 * totalCL + 1.2124699;
                    double b2_logit = 0.8606449 * totalNR + 0.2763119 * totalNK + 0.4969152 * totalNH + 0.0685712 * totalNL
                                    - 1.3346995 * totalCR - 1.0977316 * totalCK - 1.0973677 * totalCH - 0.2028884 * totalCL + 1.9355980;

                    if (ionSeriesIsEnabled(IonSeries.b))
                    {
                        if (b1_logit > -0.5) addFragment(list, points, "b", c, 1, fragmentation.b(c, 1));
                        if (b2_logit > 0)    addFragment(list, points, "b", c, 2, fragmentation.b(c, 2));
                    }
                    if (ionSeriesIsEnabled(IonSeries.y))
                    {
                        if (y1_logit > -0.5) addFragment(list, points, "y", seqLength - c, 1, fragmentation.y(seqLength - c, 1));
                        if (y2_logit > -0.5) addFragment(list, points, "y", seqLength - c, 2, fragmentation.y(seqLength - c, 2));
                    }
                                            //if (b1_logit > -0.5)
                                            //    if (ionSeriesIsEnabled(IonSeries.b))
                                            //        addFragment(list, points, "b", c, 1, fragmentation.b(c, 1));
                                            //if (b2_logit > 0)
                                            //    if (ionSeriesIsEnabled(IonSeries.b))
                                            //        addFragment(list, points, "b", c, 2, fragmentation.b(c, 2));
                                            //if (y1_logit > -0.5)
                                            //    if (ionSeriesIsEnabled(IonSeries.y))
                                            //        addFragment(list, points, "y", seqLength - c, 1, fragmentation.y(seqLength - c, 1));
                                            //if (y2_logit > -0.5)
                                            //    if (ionSeriesIsEnabled(IonSeries.y))
                                            //        addFragment(list, points, "y", seqLength - c, 2, fragmentation.y(seqLength - c, 2));

                }
            }

            #endregion

            if ( showLadders || showFragmentationSummary)
            {
                //test neutral loss
                //string topSeries = ionSeriesIsEnabled(IonSeries.a) ? "a" : ionSeriesIsEnabled(IonSeries.b) ? "b" : ionSeriesIsEnabled(IonSeries.c) ? "c" : "";
                //string bottomSeries = ionSeriesIsEnabled(IonSeries.x) ? "x" : ionSeriesIsEnabled(IonSeries.y) ? "y" : ionSeriesIsEnabled(IonSeries.z) ? "z" : ionSeriesIsEnabled(IonSeries.zRadical) ? "z*" : "";
                //if (showLadders)
                //    addIonSeries(list, points, peptide, fragmentation, topSeries, bottomSeries);
                //if (showFragmentationSummary)
                //    addFragmentationSummary(list, points, peptide, fragmentation, topSeries, bottomSeries);
                string topSeries = "";
                string bottomSeries = "";

                if (ionSeriesIsEnabled(IonSeries.a))
                {
                    topSeries = "a";
                    if (showLadders)
                        addIonSeries(list, points, peptide, fragmentation, topSeries, bottomSeries);
                    if (showFragmentationSummary)
                        addFragmentationSummary(list, points, peptide, fragmentation, topSeries, bottomSeries);
                }
                if (ionSeriesIsEnabled(IonSeries.b))
                {
                    topSeries = "b";
                    if (showLadders)
                        addIonSeries(list, points, peptide, fragmentation, topSeries, bottomSeries);
                    if (showFragmentationSummary)
                        addFragmentationSummary(list, points, peptide, fragmentation, topSeries, bottomSeries);
                }
                if (ionSeriesIsEnabled(IonSeries.c))
                {
                    topSeries = "c";
                    if (showLadders)
                        addIonSeries(list, points, peptide, fragmentation, topSeries, bottomSeries);
                    if (showFragmentationSummary)
                        addFragmentationSummary(list, points, peptide, fragmentation, topSeries, bottomSeries);
                }
                if (ionSeriesIsEnabled(IonSeries.x))
                {
                    bottomSeries = "x";
                    if (showLadders)
                        addIonSeries(list, points, peptide, fragmentation, topSeries, bottomSeries);
                    if (showFragmentationSummary)
                        addFragmentationSummary(list, points, peptide, fragmentation, topSeries, bottomSeries);
                }
                if (ionSeriesIsEnabled(IonSeries.y))
                {
                    bottomSeries = "y";
                    if (showLadders)
                        addIonSeries(list, points, peptide, fragmentation, topSeries, bottomSeries);
                    if (showFragmentationSummary)
                        addFragmentationSummary(list, points, peptide, fragmentation, topSeries, bottomSeries);
                }
                if (ionSeriesIsEnabled(IonSeries.z))
                {
                    bottomSeries = "z";
                    if (showLadders)
                        addIonSeries(list, points, peptide, fragmentation, topSeries, bottomSeries);
                    if (showFragmentationSummary)
                        addFragmentationSummary(list, points, peptide, fragmentation, topSeries, bottomSeries);
                }
                if (ionSeriesIsEnabled(IonSeries.zRadical))
                {
                    bottomSeries = "z*";
                    if (showLadders)
                        addIonSeries(list, points, peptide, fragmentation, topSeries, bottomSeries);
                    if (showFragmentationSummary)
                        addFragmentationSummary(list, points, peptide, fragmentation, topSeries, bottomSeries);
                }
            }

            annotationPanels.peptideInfoGridView.Rows.Clear();

            if( spectrum.precursors.Count > 0 &&
                spectrum.precursors[0].selectedIons.Count > 0 &&
                spectrum.precursors[0].selectedIons[0].hasCVParam( CVID.MS_selected_ion_m_z ) &&
                spectrum.precursors[0].selectedIons[0].hasCVParam( CVID.MS_charge_state ) )
            {
                double selectedMz = (double) spectrum.precursors[0].selectedIons[0].cvParam( CVID.MS_selected_ion_m_z ).value;
                int chargeState = (int) spectrum.precursors[0].selectedIons[0].cvParam( CVID.MS_charge_state ).value;
                double calculatedMass = ( precursorMassType == 0 ? peptide.monoisotopicMass( chargeState ) : peptide.molecularWeight( chargeState ) ) * chargeState;
                double observedMass = selectedMz * chargeState;
                annotationPanels.peptideInfoGridView.Rows.Add( "Calculated mass:", calculatedMass, "Mass error (daltons):", observedMass - calculatedMass );
                annotationPanels.peptideInfoGridView.Rows.Add( "Observed mass:", observedMass, "Mass error (ppm):", ( ( observedMass - calculatedMass ) / calculatedMass ) * 1e6 );
            } else
                annotationPanels.peptideInfoGridView.Rows.Add( "Calculated neutral mass:", precursorMassType == 0 ? peptide.monoisotopicMass() : peptide.molecularWeight() );

            annotationPanels.peptideInfoGridView.Columns[1].DefaultCellStyle.Format = "F4";
            foreach( DataGridViewRow row in annotationPanels.peptideInfoGridView.Rows )
                row.Height = row.InheritedStyle.Font.Height + 2;

            // TODO: fragmentInfoGridView is slow: make it faster, optional, or both!

            annotationPanels.fragmentInfoGridView.SuspendLayout();

            if( ionSeries > IonSeries.Auto )
            {
                if( annotationPanels.fragmentInfoGridView.Columns.Count == 0 )
                {
                    if (ionSeriesIsEnabled(IonSeries.a))
                        for (int charge = min; charge <= max; ++charge)
                            annotationPanels.fragmentInfoGridView.Columns.Add(
                                "a" + charge.ToString(),
                                "a" + (charge > 1 ? "(+" + charge.ToString() + ")" : ""));
                    if (ionSeriesIsEnabled(IonSeries.b))
                        for (int charge = min; charge <= max; ++charge)
                            annotationPanels.fragmentInfoGridView.Columns.Add(
                                "b" + charge.ToString(),
                                "b" + (charge > 1 ? "(+" + charge.ToString() + ")" : ""));
                    if (ionSeriesIsEnabled(IonSeries.c))
                        for (int charge = min; charge <= max; ++charge)
                            annotationPanels.fragmentInfoGridView.Columns.Add(
                                "c" + charge.ToString(),
                                "c" + (charge > 1 ? "(+" + charge.ToString() + ")" : ""));

                    annotationPanels.fragmentInfoGridView.Columns.Add("N", "#");
                    annotationPanels.fragmentInfoGridView.Columns.Add("Sequence", "seq");
                    annotationPanels.fragmentInfoGridView.Columns.Add("C", "#");

                    if (ionSeriesIsEnabled(IonSeries.x))
                        for (int charge = min; charge <= max; ++charge)
                            annotationPanels.fragmentInfoGridView.Columns.Add(
                                "x" + charge.ToString(),
                                "x" + (charge > 1 ? "(+" + charge.ToString() + ")" : ""));
                    if (ionSeriesIsEnabled(IonSeries.y))
                        for (int charge = min; charge <= max; ++charge)
                            annotationPanels.fragmentInfoGridView.Columns.Add(
                                "y" + charge.ToString(),
                                "y" + (charge > 1 ? "(+" + charge.ToString() + ")" : ""));
                    if (ionSeriesIsEnabled(IonSeries.z))
                        for (int charge = min; charge <= max; ++charge)
                            annotationPanels.fragmentInfoGridView.Columns.Add(
                                "z" + charge.ToString(),
                                "z" + (charge > 1 ? "(+" + charge.ToString() + ")" : ""));
                    if (ionSeriesIsEnabled(IonSeries.zRadical))
                        for (int charge = min; charge <= max; ++charge)
                            annotationPanels.fragmentInfoGridView.Columns.Add(
                                "z*" + charge.ToString(),
                                "z*" + (charge > 1 ? "(+" + charge.ToString() + ")" : ""));

                    foreach( DataGridViewColumn column in annotationPanels.fragmentInfoGridView.Columns )
                    {
                        column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
                        if( column.Name != "N" && column.Name != "C" && column.Name != "Sequence" )
                            column.DefaultCellStyle.Format = "F3";
                    }
                }

                while( annotationPanels.fragmentInfoGridView.Rows.Count > sequenceLength )
                    annotationPanels.fragmentInfoGridView.Rows.RemoveAt( annotationPanels.fragmentInfoGridView.Rows.Count - 1 );
                if( sequenceLength - annotationPanels.fragmentInfoGridView.Rows.Count > 0 )
                    annotationPanels.fragmentInfoGridView.Rows.Add( sequenceLength - annotationPanels.fragmentInfoGridView.Rows.Count );

                for( int i = 1; i <= sequenceLength; ++i )
                {
                    int cTerminalLength = sequenceLength - i + 1;
                    var row = annotationPanels.fragmentInfoGridView.Rows[i - 1];
                    var values = new List<object>(10);
                    //var row = annotationPanels.fragmentInfoGridView.Rows.Add()];

                    if (ionSeriesIsEnabled(IonSeries.a))
                        for (int charge = min; charge <= max; ++charge)
                            values.Add(fragmentation.a(i, charge));
                    if (ionSeriesIsEnabled(IonSeries.b))
                        for (int charge = min; charge <= max; ++charge)
                            values.Add(fragmentation.b(i, charge));
                    if (ionSeriesIsEnabled(IonSeries.c))
                        for (int charge = min; charge <= max; ++charge)
                            if (i < sequenceLength)
                                values.Add(fragmentation.c(i, charge));
                            else
                                values.Add("");

                    values.Add(i);
                    values.Add(unmodifiedSequence[i - 1]);
                    values.Add(cTerminalLength);

                    if (ionSeriesIsEnabled(IonSeries.x))
                        for (int charge = min; charge <= max; ++charge)
                            if (i > 1)
                                values.Add(fragmentation.x(cTerminalLength, charge));
                            else
                                values.Add("");
                    if (ionSeriesIsEnabled(IonSeries.y))
                        for (int charge = min; charge <= max; ++charge)
                            values.Add(fragmentation.y(cTerminalLength, charge));
                    if (ionSeriesIsEnabled(IonSeries.z))
                        for (int charge = min; charge <= max; ++charge)
                            values.Add(fragmentation.z(cTerminalLength, charge));
                    if (ionSeriesIsEnabled(IonSeries.zRadical))
                        for (int charge = min; charge <= max; ++charge)
                            values.Add(fragmentation.zRadical(cTerminalLength, charge));
                    row.SetValues(values.ToArray());
                }

                //add my code in between
                //the purpose is to switch the fragmentInfoGridView table into a html
                //to solve the bug that the table can be copied, but the bold font information can not be copied
                //basically, a stringbuilder object is created and going to copy values, formats from gridview, and then output
                //currently the html output is only stored in local, and I am trying to adapt it into a applet-like viewer.

                //first a stringbuilder is created
                StringBuilder sb_original = new StringBuilder();
                //Setting HTML and table tags
                sb_original.Append("<html>");
                sb_original.Append("<head>");
                sb_original.Append("<title>fragmentGridView2HTML</title>");
                sb_original.Append("</head>");
                sb_original.Append("<body>");
                sb_original.Append("<br>");
                sb_original.AppendLine("<" + "table border='2' cellpadding='1' cellspacing='1'>");
                sb_original.AppendLine("<tr>");
                //setting table headers
                //make them bold
                for (int i = 0; i < annotationPanels.fragmentInfoGridView.Columns.Count; i++)
                {
                    sb_original.AppendLine("<th>" + annotationPanels.fragmentInfoGridView.Columns[i].HeaderText + "</th>");
                }
                sb_original.AppendLine("</tr>");

                //starting copying cells to html
                foreach( DataGridViewRow row in annotationPanels.fragmentInfoGridView.Rows )
                {
                    sb_original.AppendLine("<tr>");
                    row.Height = row.InheritedStyle.Font.Height + 2;

                    foreach( DataGridViewCell cell in row.Cells )
                    {
                        if (!(cell.Value is double))
                        {
                            //note: added two line here
                            sb_original.AppendLine("<td>" + cell.FormattedValue + "</td>");
                            continue;
                        }

                        double mz = (double) cell.Value;

                        int index = -1;
                        if( points != null )
                            index = points.FullLowerBound(mz - 0.5);

                        if (index == -1 || points.FullList[index].X > (mz + 0.5))
                        {
                            //note: added two line here
                            //first is to pass value to sb;
                            //second is to change the cell fontstyle back to regular, if previouly bold
                            sb_original.AppendLine("<td>" + cell.FormattedValue + "</td>");
                            cell.Style.Font = new Font(annotationPanels.fragmentInfoGridView.Font, FontStyle.Regular);
                            continue;
                        }

                        cell.Style.Font = new Font(annotationPanels.fragmentInfoGridView.Font, FontStyle.Bold);
                        //note: added one line here
                        sb_original.AppendLine("<td><b>" + cell.FormattedValue + "</b></td>");
                    }
                }

                sb_original.AppendLine("</tr>");
                sb_original.AppendLine("</body>");
                sb_original.AppendLine("</head>");
                sb_original.AppendLine("</html>");
                //for storation of stringbuilder into local file
                //test only

                string file_original = "C:\\Temp\\originalTable.html";
                Directory.CreateDirectory(Path.GetDirectoryName(file_original));
                TextWriter tw_original = new StreamWriter(file_original);
                tw_original.WriteLine(sb_original.ToString());
                tw_original.Flush();
                tw_original.Close();

                /////////////////////////////////////////////////////////
                /////////////////////////////////////////////////////////
                //test neutral loss
                #region Neutral Loss
                StringBuilder sb_neutral = new StringBuilder();

                if (waterLoss == false && ammoniumLoss == false && phosphateLoss == false)
                {
                    sb_neutral = sb_original;
                }
                else //if any of the neutral loss is clicked
                {
                    #region if any of the neutral loss is clicked
                    DataGridView neutralLossDataGridView = new DataGridView();

                    ///
                    #region add first columns part

                    if (ionSeriesIsEnabled(IonSeries.a))
                        for (int charge = min; charge <= max; ++charge)
                        {
                            neutralLossDataGridView.Columns.Add(
                                "a" + charge.ToString(),
                                "a" + (charge > 1 ? "(+" + charge.ToString() + ")" : ""));
                            if (waterLoss == true)
                                neutralLossDataGridView.Columns.Add(
                                    "a" + charge.ToString() + "waterLoss",
                                    "a" + (charge > 1 ? "(+" + charge.ToString() + ")-H2O" : "-H2O"));
                            if (ammoniumLoss == true)
                                neutralLossDataGridView.Columns.Add(
                                    "a" + charge.ToString() + "ammoniumLoss",
                                    "a" + (charge > 1 ? "(+" + charge.ToString() + ")-NH3" : "-NH3"));
                            if (phosphateLoss == true)
                            {
                                for (int k = 1; k<= numPhosphate; k++)
                                {
                                    if (k == 1)
                                    {
                                        neutralLossDataGridView.Columns.Add(
                                            "a" + charge.ToString() + "phosphateLoss",
                                            "a" + (charge > 1 ? "(+" + charge.ToString() + ")-PHO" : "-PHO"));
                                    }
                                    else
                                    {
                                        neutralLossDataGridView.Columns.Add(
                                            "a" + charge.ToString() + "phosphateLoss",
                                            "a" + (charge > 1 ? "(+" + charge.ToString() + ")-"+k+"PHO" : "-"+k+"PHO"));
                                    }
                                }
                            }

                        }

                    if (ionSeriesIsEnabled(IonSeries.b))
                        for (int charge = min; charge <= max; ++charge)
                        {
                            neutralLossDataGridView.Columns.Add(
                                "b" + charge.ToString(),
                                "b" + (charge > 1 ? "(+" + charge.ToString() + ")" : ""));
                            if (waterLoss == true)
                                neutralLossDataGridView.Columns.Add(
                                    "b" + charge.ToString() + "waterLoss",
                                    "b" + (charge > 1 ? "(+" + charge.ToString() + ")-H2O" : "-H2O"));
                            if (ammoniumLoss == true)
                                neutralLossDataGridView.Columns.Add(
                                    "b" + charge.ToString() + "ammoniumLoss",
                                    "b" + (charge > 1 ? "(+" + charge.ToString() + ")-NH3" : "-NH3"));
                            if (phosphateLoss == true)
                            {
                                for (int k = 1; k<= numPhosphate; k++)
                                {
                                    if (k == 1)
                                    {
                                        neutralLossDataGridView.Columns.Add(
                                            "b" + charge.ToString() + "phosphateLoss",
                                            "b" + (charge > 1 ? "(+" + charge.ToString() + ")-PHO" : "-PHO"));
                                    }
                                    else
                                    {
                                        neutralLossDataGridView.Columns.Add(
                                            "b" + charge.ToString() + "phosphateLoss",
                                            "b" + (charge > 1 ? "(+" + charge.ToString() + ")-" + k + "PHO" : "-" + k + "PHO"));
                                    }
                                }
                            }
                        }

                    if (ionSeriesIsEnabled(IonSeries.c))
                        for (int charge = min; charge <= max; ++charge)
                        {
                            neutralLossDataGridView.Columns.Add(
                                "c" + charge.ToString(),
                                "c" + (charge > 1 ? "(+" + charge.ToString() + ")" : ""));
                            if (waterLoss == true)
                                neutralLossDataGridView.Columns.Add(
                                    "c" + charge.ToString() + "waterLoss",
                                    "c" + (charge > 1 ? "(+" + charge.ToString() + ")-H2O" : "-H2O"));
                            if (ammoniumLoss == true)
                                neutralLossDataGridView.Columns.Add(
                                    "c" + charge.ToString() + "ammoniumLoss",
                                    "c" + (charge > 1 ? "(+" + charge.ToString() + ")-NH3" : "-NH3"));
                            if (phosphateLoss == true)
                            {
                                for (int k = 1; k<= numPhosphate; k++)
                                {
                                    if (k == 1)
                                    {
                                        neutralLossDataGridView.Columns.Add(
                                            "c" + charge.ToString() + "phosphateLoss",
                                            "c" + (charge > 1 ? "(+" + charge.ToString() + ")-PHO" : "-PHO"));
                                    }
                                    else
                                    {
                                        neutralLossDataGridView.Columns.Add(
                                            "c" + charge.ToString() + "phosphateLoss",
                                            "c" + (charge > 1 ? "(+" + charge.ToString() + ")-" + k + "PHO" : "-" + k + "PHO"));
                                    }
                                }
                            }

                        }
                    #endregion

                    neutralLossDataGridView.Columns.Add("N", "#");
                    neutralLossDataGridView.Columns.Add("Sequence", "seq");
                    neutralLossDataGridView.Columns.Add("C", "#");
                    ///
                    #region add second columns part
                        if (ionSeriesIsEnabled(IonSeries.x))
                            for (int charge = min; charge <= max; ++charge)
                            {
                                neutralLossDataGridView.Columns.Add(
                                   "x" + charge.ToString(),
                                   "x" + (charge > 1 ? "(+" + charge.ToString() + ")" : ""));
                                if (waterLoss == true)
                                    neutralLossDataGridView.Columns.Add(
                                        "x" + charge.ToString() + "waterLoss",
                                        "x" + (charge > 1 ? "(+" + charge.ToString() + ")-H2O" : "-H2O"));
                                if (ammoniumLoss == true)
                                    neutralLossDataGridView.Columns.Add(
                                        "x" + charge.ToString() + "ammoniumLoss",
                                        "x" + (charge > 1 ? "(+" + charge.ToString() + ")-NH3" : "-NH3"));
                                if (phosphateLoss == true)
                                {
                                    for (int k = 1; k<= numPhosphate; k++)
                                    {
                                        if (k == 1)
                                        {
                                            neutralLossDataGridView.Columns.Add(
                                                "x" + charge.ToString() + "phosphateLoss",
                                                "x" + (charge > 1 ? "(+" + charge.ToString() + ")-PHO" : "-PHO"));
                                        }
                                        else
                                        {
                                            neutralLossDataGridView.Columns.Add(
                                                "x" + charge.ToString() + "phosphateLoss",
                                                "x" + (charge > 1 ? "(+" + charge.ToString() + ")-" + k + "PHO" : "-" + k + "PHO"));
                                        }
                                    }
                                }
                            }

                        if (ionSeriesIsEnabled(IonSeries.y))
                            for (int charge = min; charge <= max; ++charge)
                            {
                                neutralLossDataGridView.Columns.Add(
                                    "y" + charge.ToString(),
                                    "y" + (charge > 1 ? "(+" + charge.ToString() + ")" : ""));
                                if (waterLoss == true)
                                    neutralLossDataGridView.Columns.Add(
                                        "y" + charge.ToString() + "waterLoss",
                                        "y" + (charge > 1 ? "(+" + charge.ToString() + ")-H2O" : "-H2O"));
                                if (ammoniumLoss == true)
                                    neutralLossDataGridView.Columns.Add(
                                        "y" + charge.ToString() + "ammoniumLoss",
                                        "y" + (charge > 1 ? "(+" + charge.ToString() + ")-NH3" : "-NH3"));
                                if (phosphateLoss == true)
                                {
                                    for (int k = 1; k<= numPhosphate; k++)
                                    {
                                        if (k == 1)
                                        {
                                            neutralLossDataGridView.Columns.Add(
                                                "y" + charge.ToString() + "phosphateLoss",
                                                "y" + (charge > 1 ? "(+" + charge.ToString() + ")-PHO" : "-PHO"));
                                        }
                                        else
                                        {
                                            neutralLossDataGridView.Columns.Add(
                                                "y" + charge.ToString() + "phosphateLoss",
                                                "y" + (charge > 1 ? "(+" + charge.ToString() + ")-" + k + "PHO" : "-" + k + "PHO"));
                                        }
                                    }
                                }
                            }

                        if (ionSeriesIsEnabled(IonSeries.z))
                            for (int charge = min; charge <= max; ++charge)
                            {
                                neutralLossDataGridView.Columns.Add(
                                    "z" + charge.ToString(),
                                    "z" + (charge > 1 ? "(+" + charge.ToString() + ")" : ""));
                                if (waterLoss == true)
                                    neutralLossDataGridView.Columns.Add(
                                        "z" + charge.ToString() + "waterLoss",
                                        "z" + (charge > 1 ? "(+" + charge.ToString() + ")-H2O" : "-H2O"));
                                if (ammoniumLoss == true)
                                    neutralLossDataGridView.Columns.Add(
                                        "z" + charge.ToString() + "ammoniumLoss",
                                        "z" + (charge > 1 ? "(+" + charge.ToString() + ")-NH3" : "-NH3"));
                                if (phosphateLoss == true)
                                {
                                    for (int k = 1; k<= numPhosphate; k++)
                                    {
                                        if (k == 1)
                                        {
                                            neutralLossDataGridView.Columns.Add(
                                                "z" + charge.ToString() + "phosphateLoss",
                                                "z" + (charge > 1 ? "(+" + charge.ToString() + ")-PHO" : "-PHO"));
                                        }
                                        else
                                        {
                                            neutralLossDataGridView.Columns.Add(
                                                "z" + charge.ToString() + "phosphateLoss",
                                                "z" + (charge > 1 ? "(+" + charge.ToString() + ")-" + k + "PHO" : "-" + k + "PHO"));
                                        }
                                    }
                                }
                            }

                        if (ionSeriesIsEnabled(IonSeries.zRadical))
                            for (int charge = min; charge <= max; ++charge)
                            {
                                neutralLossDataGridView.Columns.Add(
                                   "z*" + charge.ToString(),
                                   "z*" + (charge > 1 ? "(+" + charge.ToString() + ")" : ""));
                                if (waterLoss == true)
                                    neutralLossDataGridView.Columns.Add(
                                        "z*" + charge.ToString() + "waterLoss",
                                        "z*" + (charge > 1 ? "(+" + charge.ToString() + ")-H2O" : "-H2O"));
                                if (ammoniumLoss == true)
                                    neutralLossDataGridView.Columns.Add(
                                        "z*" + charge.ToString() + "ammoniumLoss",
                                        "z*" + (charge > 1 ? "(+" + charge.ToString() + ")-NH3" : "-NH3"));
                                if (phosphateLoss == true)
                                {
                                    for (int k = 1; k<= numPhosphate; k++)
                                    {
                                        if (k == 1)
                                        {
                                            neutralLossDataGridView.Columns.Add(
                                                "z*" + charge.ToString() + "phosphateLoss",
                                                "z*" + (charge > 1 ? "(+" + charge.ToString() + ")-PHO" : "-PHO"));
                                        }
                                        else
                                        {
                                            neutralLossDataGridView.Columns.Add(
                                                "z*" + charge.ToString() + "phosphateLoss",
                                                "z*" + (charge > 1 ? "(+" + charge.ToString() + ")-" + k + "PHO" : "-" + k + "PHO"));
                                        }
                                    }
                                }
                            }
                        #endregion

                    while (neutralLossDataGridView.Rows.Count > sequenceLength)
                        neutralLossDataGridView.Rows.RemoveAt(neutralLossDataGridView.Rows.Count - 1);
                    if (sequenceLength - neutralLossDataGridView.Rows.Count > 0)
                        neutralLossDataGridView.Rows.Add(sequenceLength - neutralLossDataGridView.Rows.Count);

                    char[] aminoAcids = peptide.sequence.ToCharArray();
                    for (int i = 1; i <= sequenceLength; ++i)
                    {
                        int Nphosmodi = 0;
                        int Cphosmodi = 0;

                        int cTerminalLength = sequenceLength - i + 1;
                        var row = neutralLossDataGridView.Rows[i - 1];
                        var values = new List<object>();

                        //define the amino acides that are capable of losing water
                        //AA = S,T,E,D
                        bool nSTED = false;
                        bool cSTED = false;
                        bool nRKQN = false;
                        bool cRKQN = false;

                        for (int index = 0; index < i; index++)
                        {
                            if (aminoAcids[index] == 'S' || aminoAcids[index] == 'T' || aminoAcids[index] == 'E' || aminoAcids[index] == 'D')
                                nSTED = true;
                            if (aminoAcids[index] == 'R' || aminoAcids[index] == 'K' || aminoAcids[index] == 'Q' || aminoAcids[index] == 'N')
                                nRKQN = true;
                            if (Math.Round(modifications[index].monoisotopicDeltaMass()) == 80 && (aminoAcids[index] == 'S' || aminoAcids[index] == 'T' || aminoAcids[index] == 'Y'))
                                Nphosmodi++;
                        }

                        //here is more tricky. since the display is
                        //b1    -----     y(seq-1+1)
                        //b2    -----     y(seq-2+1)
                        for (int index = sequenceLength - 1; index >= i - 1; index--)
                        {
                            if (aminoAcids[index] == 'S' || aminoAcids[index] == 'T' || aminoAcids[index] == 'E' || aminoAcids[index] == 'D')
                                cSTED = true;
                            if (aminoAcids[index] == 'R' || aminoAcids[index] == 'K' || aminoAcids[index] == 'Q' || aminoAcids[index] == 'N')
                                cRKQN = true;
                            if (Math.Round(modifications[index].monoisotopicDeltaMass()) == 80 && (aminoAcids[index] == 'S' || aminoAcids[index] == 'T' || aminoAcids[index] == 'Y'))
                                Cphosmodi++;

                        }

                        int minNPhosphate = Math.Min(numPhosphate, Nphosmodi);
                        int minCPhosphate = Math.Min(numPhosphate, Cphosmodi);
                        if (ionSeriesIsEnabled(IonSeries.a))
                            for (int charge = min; charge <= max; ++charge)
                            {
                                values.Add(Math.Round(fragmentation.a(i, charge), 3));
                                if (waterLoss == true)
                                {
                                    if (nSTED) values.Add(Math.Round(fragmentation.a(i, charge) - WATERMONOMASS / charge, 3));
                                    else values.Add("-");
                                }
                                if (ammoniumLoss == true)
                                {
                                    if (nRKQN) values.Add(Math.Round(fragmentation.a(i, charge) - AMMONIUMMONOMASS / charge, 3));
                                    else values.Add("-");
                                }
                                if (phosphateLoss == true)
                                {
                                    for (int k = 1; k <= numPhosphate; k++)
                                    {
                                        if (k <= minNPhosphate)
                                        {
                                            values.Add(Math.Round(fragmentation.a(i, charge) - k*PHOSPHATEMONOMASS / charge, 3));
                                        }
                                        else
                                        {
                                            values.Add("-");
                                        }

                                    }
                                }

                            }

                        if (ionSeriesIsEnabled(IonSeries.b))
                            for (int charge = min; charge <= max; ++charge)
                            {
                                values.Add(Math.Round(fragmentation.b(i, charge), 3));
                                if (waterLoss == true)
                                {
                                    if (nSTED) values.Add(Math.Round(fragmentation.b(i, charge) - WATERMONOMASS / charge, 3));
                                    else values.Add("-");
                                }
                                if (ammoniumLoss == true)
                                {
                                    if (nRKQN) values.Add(Math.Round(fragmentation.b(i, charge) - AMMONIUMMONOMASS / charge, 3));
                                    else values.Add("-");
                                }
                                if (phosphateLoss == true)
                                {
                                    for (int k = 1; k <= numPhosphate; k++)
                                    {
                                        if (k <= minNPhosphate)
                                        {
                                            values.Add(Math.Round(fragmentation.b(i, charge) - k * PHOSPHATEMONOMASS / charge, 3));
                                        }
                                        else
                                        {
                                            values.Add("-");
                                        }
                                    }
                                }
                            }

                        if (ionSeriesIsEnabled(IonSeries.c))
                            for (int charge = min; charge <= max; ++charge)
                            {
                                if (i < sequenceLength)
                                    values.Add(Math.Round(fragmentation.c(i, charge), 3));
                                else
                                    values.Add("-");
                                if (waterLoss == true)
                                {
                                    if (nSTED && i < sequenceLength)
                                        values.Add(Math.Round(fragmentation.c(i, charge) - WATERMONOMASS / charge, 3));
                                    else values.Add("-");
                                }
                                if (ammoniumLoss == true)
                                {
                                    if (nRKQN && i < sequenceLength)
                                        values.Add(Math.Round(fragmentation.c(i, charge) - AMMONIUMMONOMASS / charge, 3));
                                    else values.Add("-");
                                }
                                if (phosphateLoss == true)
                                {
                                    if (i < sequenceLength)
                                    {
                                        for (int k = 1; k <= numPhosphate; k++)
                                        {
                                            if (k <= minNPhosphate)
                                            {
                                                values.Add(Math.Round(fragmentation.c(i, charge) - k * PHOSPHATEMONOMASS / charge, 3));
                                            }
                                            else
                                            {
                                                values.Add("-");
                                            }
                                        }
                                    }
                                    else values.Add("-");

                                }
                            }

                        values.Add(i);
                        values.Add(unmodifiedSequence[i - 1]);
                        values.Add(cTerminalLength);

                        if (ionSeriesIsEnabled(IonSeries.x))
                            for (int charge = min; charge <= max; ++charge)
                            {
                                if (i > 1)
                                    values.Add(Math.Round(fragmentation.x(sequenceLength - i + 1, charge), 3));
                                else
                                    values.Add("-");
                                if (waterLoss == true)
                                {
                                    if (cSTED && i > 1)
                                        values.Add(Math.Round(fragmentation.x(sequenceLength - i + 1, charge) - WATERMONOMASS / charge, 3));
                                    else values.Add("-");
                                }
                                if (ammoniumLoss == true)
                                {
                                    if (cRKQN && i > 1)
                                        values.Add(Math.Round(fragmentation.x(sequenceLength - i + 1, charge) - AMMONIUMMONOMASS / charge, 3));
                                    else values.Add("-");
                                }
                                if (phosphateLoss == true)
                                {
                                    if (i > 1)
                                    {
                                        for (int k = 1; k <= numPhosphate; k++)
                                        {
                                            if (k <= minCPhosphate)
                                            {
                                                values.Add(Math.Round(fragmentation.x(sequenceLength - i + 1, charge) - k * PHOSPHATEMONOMASS / charge, 3));
                                            }
                                            else
                                            {
                                                values.Add("-");
                                            }
                                        }
                                    }
                                    else values.Add("-");

                                }
                            }

                        if (ionSeriesIsEnabled(IonSeries.y))
                            for (int charge = min; charge <= max; ++charge)
                            {
                                values.Add(Math.Round(fragmentation.y(sequenceLength - i + 1, charge), 3));
                                if (waterLoss == true)
                                {
                                    if (cSTED) values.Add(Math.Round(fragmentation.y(sequenceLength - i + 1, charge) - WATERMONOMASS / charge, 3));
                                    else values.Add("-");
                                }
                                if (ammoniumLoss == true)
                                {
                                    if (cRKQN) values.Add(Math.Round(fragmentation.y(sequenceLength - i + 1, charge) - AMMONIUMMONOMASS / charge, 3));
                                    else values.Add("-");
                                }
                                if (phosphateLoss == true)
                                {
                                    for (int k = 1; k <= numPhosphate; k++)
                                    {
                                        if (k <= minCPhosphate)
                                        {
                                            values.Add(Math.Round(fragmentation.y(sequenceLength - i + 1, charge) - k * PHOSPHATEMONOMASS / charge, 3));
                                        }
                                        else
                                        {
                                            values.Add("-");
                                        }
                                    }
                                }
                            }

                        if (ionSeriesIsEnabled(IonSeries.z))
                            for (int charge = min; charge <= max; ++charge)
                            {
                                values.Add(Math.Round(fragmentation.z(sequenceLength - i + 1, charge), 3));
                                if (waterLoss == true)
                                {
                                    if (cSTED) values.Add(Math.Round(fragmentation.z(sequenceLength - i + 1, charge) - WATERMONOMASS / charge, 3));
                                    else values.Add("-");
                                }
                                if (ammoniumLoss == true)
                                {
                                    if (cRKQN) values.Add(Math.Round(fragmentation.z(sequenceLength - i + 1, charge) - AMMONIUMMONOMASS / charge, 3));
                                    else values.Add("-");
                                }
                                if (phosphateLoss == true)
                                {
                                    for (int k = 1; k <= numPhosphate; k++)
                                    {
                                        if (k <= minCPhosphate)
                                        {
                                            values.Add(Math.Round(fragmentation.z(sequenceLength - i + 1, charge) - k * PHOSPHATEMONOMASS / charge, 3));
                                        }
                                        else
                                        {
                                            values.Add("-");
                                        }
                                    }
                                }
                            }
                        if (ionSeriesIsEnabled(IonSeries.zRadical))
                            for (int charge = min; charge <= max; ++charge)
                            {
                                values.Add(Math.Round(fragmentation.zRadical(sequenceLength - i + 1, charge), 3));
                                if (waterLoss == true)
                                {
                                    if (cSTED) values.Add(Math.Round(fragmentation.zRadical(sequenceLength - i + 1, charge) - WATERMONOMASS / charge, 3));
                                    else values.Add("-");
                                }
                                if (ammoniumLoss == true)
                                {
                                    if (cRKQN) values.Add(Math.Round(fragmentation.zRadical(sequenceLength - i + 1, charge) - AMMONIUMMONOMASS / charge, 3));
                                    else values.Add("-");
                                }
                                if (phosphateLoss == true)
                                {
                                    for (int k = 1; k <= numPhosphate; k++)
                                    {
                                        if (k <= minCPhosphate)
                                        {
                                            values.Add(Math.Round(fragmentation.zRadical(sequenceLength - i + 1, charge) - k * PHOSPHATEMONOMASS / charge, 3));
                                        }
                                        else
                                        {
                                            values.Add("-");
                                        }
                                    }
                                }
                            }

                        row.SetValues(values.ToArray());

                    }//end for

                    //add sb_neutral loss table
                    #region add sb_neutral loss table
                    sb_neutral.Append("<html>");
                    sb_neutral.Append("<head>");
                    sb_neutral.Append("<title>neutralLossFragmentGridView2HTML</title>");
                    sb_neutral.Append("</head>");
                    sb_neutral.Append("<body>");
                    sb_neutral.Append("<br>");
                    sb_neutral.AppendLine("<" + "table border='2' cellpadding='1' cellspacing='1'>");
                    sb_neutral.AppendLine("<tr>");

                    for (int i = 0; i < neutralLossDataGridView.Columns.Count; i++)
                    {
                        sb_neutral.AppendLine("<th>" + neutralLossDataGridView.Columns[i].HeaderText + "</th>");
                    }

                    foreach (DataGridViewRow row in neutralLossDataGridView.Rows)
                    {
                        sb_neutral.AppendLine("<tr>");

                        #region basepeakthresholding is false
                        if (basePeakThresholding == false)
                        {
                            foreach (DataGridViewCell cell in row.Cells)
                            {
                                if (!(cell.Value is double))
                                {
                                    sb_neutral.AppendLine("<td>" + cell.FormattedValue + "</td>");
                                    continue;
                                }

                                double mz = (double)cell.Value;

                                int index = -1;
                                if (points != null)
                                    index = points.FullLowerBound(mz - 0.5);

                                if (index == -1 || points.FullList[index].X > (mz + 0.5))
                                {
                                    sb_neutral.AppendLine("<td>" + cell.FormattedValue + "</td>");
                                    //cell.Style.Font = new Font(annotationPanels.fragmentInfoGridView.Font, FontStyle.Regular);
                                    continue;
                                }
                                //cell.Style.Font = new Font(annotationPanels.fragmentInfoGridView.Font, FontStyle.Bold);
                                sb_neutral.AppendLine("<td><b>" + cell.FormattedValue + "</b></td>");
                            }
                        }
                        #endregion

                        else//basepeakthresholding is true
                        {
                            int columnIndex = 0;
                            foreach (DataGridViewCell cell in row.Cells)
                            {
                                if (neutralLossDataGridView.Columns[columnIndex].HeaderText.Contains("H2O") || neutralLossDataGridView.Columns[columnIndex].HeaderText.Contains("NH3") || neutralLossDataGridView.Columns[columnIndex].HeaderText.Contains("PHO"))
                                {
                                    if (!(cell.Value is double))
                                    {
                                        sb_neutral.AppendLine("<td>" + cell.FormattedValue + "</td>");
                                        columnIndex++;
                                        continue;
                                    }

                                    double mz = (double)cell.Value;

                                    int index = -1;
                                    if (points != null)
                                        index = points.FullLowerBound(mz - 0.5);

                                    if (index == -1 || points.FullList[index].X > (mz + 0.5) || points.FullList[index].Y < cutoff)
                                    {
                                        sb_neutral.AppendLine("<td>" + cell.FormattedValue + "</td>");
                                        columnIndex++;
                                        continue;
                                    }
                                    sb_neutral.AppendLine("<td><b>" + cell.FormattedValue + "</b></td>");
                                    columnIndex++;
                                }
                                else
                                {
                                    if (!(cell.Value is double))
                                    {
                                        sb_neutral.AppendLine("<td>" + cell.FormattedValue + "</td>");
                                        columnIndex++;
                                        continue;
                                    }

                                    double mz = (double)cell.Value;

                                    int index = -1;
                                    if (points != null)
                                        index = points.FullLowerBound(mz - 0.5);

                                    if (index == -1 || points.FullList[index].X > (mz + 0.5))
                                    {
                                        sb_neutral.AppendLine("<td>" + cell.FormattedValue + "</td>");
                                        columnIndex++;
                                        continue;
                                    }
                                    sb_neutral.AppendLine("<td><b>" + cell.FormattedValue + "</b></td>");
                                    columnIndex++;
                                }
                            }
                        }

                    }
                    sb_neutral.AppendLine("</tr>");
                    sb_neutral.AppendLine("</body>");
                    sb_neutral.AppendLine("</head>");
                    sb_neutral.AppendLine("</html>");
                    #endregion

                    #endregion
                } //end of else
                string file_neutral = "C:\\Temp\\neutralLossTable.html";
                Directory.CreateDirectory(Path.GetDirectoryName(file_neutral));
                TextWriter tw_neutral = new StreamWriter(file_neutral);
                tw_neutral.WriteLine(sb_neutral.ToString());
                tw_neutral.Flush();
                tw_neutral.Close();
                #endregion
            }
            else
                annotationPanels.fragmentInfoGridView.Rows.Clear();

            annotationPanels.fragmentInfoGridView.ResumeLayout();
        }
Esempio n. 13
0
        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);
        }
Esempio n. 14
0
        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
            }
        }
Esempio n. 15
0
        /// <summary>
        /// Get all annotation label text, for testing purposes
        /// </summary>
        public IEnumerable<string> GetAnnotationLabelStrings()
        {
            foreach (CurveItem item in CurveList)
            {
                var info = item.Tag as IMSGraphItemExtended;
                if (info == null || string.IsNullOrEmpty(info.ToString()))
                    continue;

                var points = item.Points as MSPointList;
                if (points == null)
                    continue;

                var listAnnotations = new GraphObjList();
                info.AddPreCurveAnnotations(this, null, points, listAnnotations);
                foreach (var annotation in listAnnotations)
                {
                    var textObj = annotation as TextObj;
                    if (textObj != null)
                        yield return textObj.Text;
                }

                foreach (var pt in points.FullList)
                {
                    var annotation = info.AnnotatePoint(pt);
                    if (annotation != null)
                        yield return annotation.Label;
                }
            }
        }
        public override void UpdateGraph(bool checkData)
        {
            _dotpLabels = new GraphObjList();

            SrmDocument document = GraphSummary.DocumentUIContainer.DocumentUI;
            var results = document.Settings.MeasuredResults;
            bool resultsAvailable = results != null;
            Clear();

            if (!resultsAvailable)
            {
                Title.Text = Resources.AreaReplicateGraphPane_UpdateGraph_No_results_available;
                EmptyGraph(document);
                return;
            }

            var selectedTreeNode = GraphSummary.StateProvider.SelectedNode as SrmTreeNode;
            if (selectedTreeNode == null || document.FindNode(selectedTreeNode.Path) == null)
            {
                EmptyGraph(document);
                return;
            }

            BarSettings.Type = BarType;
            Title.Text = null;

            DisplayTypeChrom displayType;
            if (Equals(PaneKey, PaneKey.PRECURSORS))
            {
                displayType = DisplayTypeChrom.precursors;
            }
            else if (Equals(PaneKey, PaneKey.PRODUCTS))
            {
                displayType = DisplayTypeChrom.products;
            }
            else
            {
                displayType = GraphChromatogram.GetDisplayType(document, selectedTreeNode);
            }

            DocNode selectedNode = selectedTreeNode.Model;
            DocNode parentNode = selectedNode;
            IdentityPath identityPath = selectedTreeNode.Path;
            bool optimizationPresent = results.Chromatograms.Contains(
                chrom => chrom.OptimizationFunction != null);

            // If the selected tree node is a transition, then its siblings are displayed.
            if (selectedTreeNode is TransitionTreeNode)
            {
                if (displayType == DisplayTypeChrom.single)
                {
                    BarSettings.Type = BarType.Cluster;
                }
                else
                {
                    SrmTreeNode parentTreeNode = selectedTreeNode.SrmParent;
                    parentNode = parentTreeNode.Model;
                    identityPath = parentTreeNode.Path;
                }
            }
            // If the selected node is a peptide with one child, then show the children,
            // unless chromatogram display type is total
            else if (selectedTreeNode is PeptideTreeNode)
            {
                var children = ((PeptideDocNode) selectedNode).TransitionGroups
                    .Where(PaneKey.IncludesTransitionGroup)
                    .ToArray();
                if (children.Length == 1 && displayType != DisplayTypeChrom.total)
                {
                    selectedNode = parentNode = children[0];
                    identityPath = new IdentityPath(identityPath, parentNode.Id);
                }
                else
                {
                    BarSettings.Type = BarType.Cluster;
                }
            }
            else if (!(selectedTreeNode is TransitionGroupTreeNode))
            {
                Title.Text = Resources.AreaReplicateGraphPane_UpdateGraph_Select_a_peptide_to_see_the_peak_area_graph;
                CanShowPeakAreaLegend = false;
                CanShowDotProduct = false;
                return;
            }

            var parentGroupNode = parentNode as TransitionGroupDocNode;

            // If a precursor is going to be displayed with display type single
            if (parentGroupNode != null && displayType == DisplayTypeChrom.single)
            {
                // If no optimization data, then show all the transitions
                if (!optimizationPresent)
                    displayType = DisplayTypeChrom.all;
                // Otherwise, do not stack the bars
                else
                    BarSettings.Type = BarType.Cluster;
            }
            int ratioIndex = AreaGraphData.RATIO_INDEX_NONE;
            var standardType = IsotopeLabelType.light;

            var areaView = AreaGraphController.AreaView;
            if (areaView == AreaNormalizeToView.area_ratio_view)
            {
                ratioIndex = GraphSummary.RatioIndex;
                standardType = document.Settings.PeptideSettings.Modifications.RatioInternalStandardTypes[ratioIndex];
            }
            else if (areaView == AreaNormalizeToView.area_global_standard_view)
            {
                if (document.Settings.HasGlobalStandardArea)
                    ratioIndex = ChromInfo.RATIO_INDEX_GLOBAL_STANDARDS;
                else
                    areaView = AreaNormalizeToView.none;
            }

            // Sets normalizeData to optimization, maximum_stack, maximum, total, or none
            AreaNormalizeToData normalizeData;
            if (optimizationPresent && displayType == DisplayTypeChrom.single &&
                areaView == AreaNormalizeToView.area_percent_view)
            {
                normalizeData = AreaNormalizeToData.optimization;
            }
            else if (areaView == AreaNormalizeToView.area_maximum_view)
            {
                normalizeData = BarSettings.Type == BarType.Stack
                                    ? AreaNormalizeToData.maximum_stack
                                    : AreaNormalizeToData.maximum;
            }
            else if (BarSettings.Type == BarType.PercentStack)
            {
                normalizeData = AreaNormalizeToData.total;
            }
            else
            {
                normalizeData = AreaNormalizeToData.none;
            }

            // Calculate graph data points
            // IsExpectedVisible depends on ExpectedVisible
            ExpectedVisible = AreaExpectedValue.none;
            if (parentGroupNode != null &&
                    displayType != DisplayTypeChrom.total &&
                    areaView != AreaNormalizeToView.area_ratio_view &&
                    !(optimizationPresent && displayType == DisplayTypeChrom.single))
            {
                var displayTrans = GraphChromatogram.GetDisplayTransitions(parentGroupNode, displayType).ToArray();
                bool isShowingMs = displayTrans.Any(nodeTran => nodeTran.IsMs1);
                bool isShowingMsMs = displayTrans.Any(nodeTran => !nodeTran.IsMs1);
                bool isFullScanMs = document.Settings.TransitionSettings.FullScan.IsEnabledMs && isShowingMs;
                if (isFullScanMs)
                {
                    if (!isShowingMsMs && parentGroupNode.HasIsotopeDist)
                        ExpectedVisible = AreaExpectedValue.isotope_dist;
                }
                else
                {
                    if (parentGroupNode.HasLibInfo)
                        ExpectedVisible = AreaExpectedValue.library;
                }
            }
            var expectedValue = IsExpectedVisible ? ExpectedVisible : AreaExpectedValue.none;
            var replicateGroupOp = GraphValues.ReplicateGroupOp.FromCurrentSettings(document.Settings);
            var graphData = new AreaGraphData(document,
                                              parentNode,
                                              displayType,
                                              replicateGroupOp,
                                              ratioIndex,
                                              normalizeData,
                                              expectedValue,
                                              PaneKey);

            var aggregateOp = replicateGroupOp.AggregateOp;
            // Avoid stacking CVs
            if (aggregateOp.Cv || aggregateOp.CvDecimal)
                BarSettings.Type = BarType.Cluster;

            int countNodes = graphData.DocNodes.Count;
            if (countNodes == 0)
                ExpectedVisible = AreaExpectedValue.none;
            CanShowDotProduct = ExpectedVisible != AreaExpectedValue.none &&
                                areaView != AreaNormalizeToView.area_percent_view;
            CanShowPeakAreaLegend = countNodes != 0;

            InitFromData(graphData);

            // Add data to the graph
            int selectedReplicateIndex = SelectedIndex;
            if (IsExpectedVisible)
            {
                if (GraphSummary.ActiveLibrary)
                    selectedReplicateIndex = 0;
            }

            double maxArea = -double.MaxValue;
            double sumArea = 0;

            // An array to keep track of height of all bars to determine
            // where each dot product annotation (if showing) should be placed
            var sumAreas = new double[graphData.ReplicateGroups.Count];

            // If only one bar to show, then use cluster instead of stack bar type, since nothing to stack
            // Important for mean error bar checking below
            if (BarSettings.Type == BarType.Stack && countNodes == 1 && graphData.PointPairLists[0].Count == 1)
                BarSettings.Type = BarType.Cluster;

            int colorOffset = 0;
            if(parentGroupNode != null)
            {
                // We want the product ion colors to stay the same whether they are displayed:
                // 1. In a single pane with the precursor ions (Transitions -> All)
                // 2. In a separate pane of the split graph (Transitions -> All AND Transitions -> Split Graph)
                // 3. In a single pane by themselves (Transition -> Products)
                // We will use an offset in the colors array for cases 2 and 3 so that we do not reuse the precursor ion colors.
                var nodeDisplayType = GraphChromatogram.GetDisplayType(document, selectedTreeNode);
                if (displayType == DisplayTypeChrom.products &&
                    (nodeDisplayType != DisplayTypeChrom.single ||
                    (nodeDisplayType == DisplayTypeChrom.single && !optimizationPresent)))
                {
                    colorOffset =
                        GraphChromatogram.GetDisplayTransitions(parentGroupNode, DisplayTypeChrom.precursors).Count();
                }
            }

            int iColor = 0, iCharge = -1;
            int? charge = null;
            int countLabelTypes = document.Settings.PeptideSettings.Modifications.CountLabelTypes;
            for (int i = 0; i < countNodes; i++)
            {
                var docNode = graphData.DocNodes[i];
                var pointPairLists = graphData.PointPairLists[i];
                int numSteps = pointPairLists.Count/2;
                for (int iStep = 0; iStep < pointPairLists.Count; iStep++)
                {
                    int step = iStep - numSteps;
                    var pointPairList = pointPairLists[iStep];
                    Color color;
                    var nodeGroup = docNode as TransitionGroupDocNode;
                    if (parentNode is PeptideDocNode)
                    {
                        int iColorGroup = GetColorIndex(nodeGroup, countLabelTypes, ref charge, ref iCharge);
                        color = COLORS_GROUPS[iColorGroup % COLORS_GROUPS.Length];
                    }
                    else if (displayType == DisplayTypeChrom.total)
                    {
                        color = COLORS_GROUPS[iColor%COLORS_GROUPS.Length];
                    }
                    else if (docNode.Equals(selectedNode) && step == 0)
                    {
                        color = ChromGraphItem.ColorSelected;
                    }
                    else
                    {
                        color = COLORS_TRANSITION[(iColor + colorOffset) % COLORS_TRANSITION.Length];
                    }
                    iColor++;
                    // If showing ratios, do not add the standard type to the graph,
                    // since it will always be empty, but make sure the colors still
                    // correspond with the other graphs.
                    if (nodeGroup != null && ratioIndex >= 0)
                    {
                        var labelType = nodeGroup.TransitionGroup.LabelType;
                        if (ReferenceEquals(labelType, standardType))
                            continue;
                    }

                    string label = graphData.DocNodeLabels[i];
                    if (step != 0)
                        label = string.Format(Resources.AreaReplicateGraphPane_UpdateGraph_Step__0_, step);
                    BarItem curveItem;
                    // Only use a MeanErrorBarItem if bars are not going to be stacked.
                    // TODO(nicksh): AreaGraphData.NormalizeTo does not know about MeanErrorBarItem
                    if (BarSettings.Type != BarType.Stack && BarSettings.Type != BarType.PercentStack && normalizeData == AreaNormalizeToData.none)
                    {
                        curveItem = new MeanErrorBarItem(label, pointPairList, color, Color.Black);
                    }
                    else
                    {
                        curveItem = new BarItem(label, pointPairList, color);
                    }

                    if (0 <= selectedReplicateIndex && selectedReplicateIndex < pointPairList.Count)
                    {
                        PointPair pointPair = pointPairList[selectedReplicateIndex];
                        if (!pointPair.IsInvalid)
                        {
                            sumArea += pointPair.Y;
                            maxArea = Math.Max(maxArea, pointPair.Y);
                        }
                    }

                    // Add area for this transition to each area entry
                    AddAreasToSums(pointPairList, sumAreas);

                    curveItem.Bar.Border.IsVisible = false;
                    curveItem.Bar.Fill.Brush = new SolidBrush(color);
                    curveItem.Tag = new IdentityPath(identityPath, docNode.Id);
                    CurveList.Add(curveItem);
                }
            }

            ParentGroupNode = parentGroupNode;
            SumAreas = sumAreas;

            // Draw a box around the currently selected replicate
            if (ShowSelection && maxArea >  -double.MaxValue)
            {
                double yValue;
                switch (BarSettings.Type)
                {
                    case BarType.Stack:
                        // The Math.Min(sumArea, .999) makes sure that if graph is in normalized view
                        // height of the selection rectangle does not exceed 1, so that top of the rectangle
                        // can be viewed when y-axis scale maximum is at 1
                        yValue = (areaView == AreaNormalizeToView.area_maximum_view ? Math.Min(sumArea, .999) : sumArea);
                        break;
                    case BarType.PercentStack:
                        yValue = 99.99;
                        break;
                    default:
                        // Scale the selection box to fit exactly the bar height
                        yValue = (areaView == AreaNormalizeToView.area_maximum_view ? Math.Min(maxArea, .999) : maxArea);
                        break;
                }
                GraphObjList.Add(new BoxObj(selectedReplicateIndex + .5, yValue, 0.99,
                                            yValue, Color.Black, Color.Empty)
                                     {
                                         IsClippedToChartRect = true,
                                     });
            }
            // Reset the scale when the parent node changes
            bool resetAxes = (_parentNode == null || !ReferenceEquals(_parentNode.Id, parentNode.Id));
            _parentNode = parentNode;

            UpdateAxes(resetAxes, aggregateOp, normalizeData, areaView, standardType);
        }
Esempio n. 17
0
		/// <summary>
		/// Default constructor for the <see cref="PaneBase"/> class.  Specifies the <see cref="Title"/> of
		/// the <see cref="PaneBase"/>, and the size of the <see cref="Rect"/>.
		/// </summary>
		public PaneBase( string title, RectangleF paneRect )
		{
			_rect = paneRect;

			_legend = new Legend();
				
			_baseDimension = Default.BaseDimension;
			_margin = new Margin();
			_titleGap = Default.TitleGap;

			_isFontsScaled = Default.IsFontsScaled;
			_isPenWidthScaled = Default.IsPenWidthScaled;
			_fill = new Fill( Default.FillColor );
			_border = new Border( Default.IsBorderVisible, Default.BorderColor,
				Default.BorderPenWidth );

			_title = new GapLabel( title, Default.FontFamily,
				Default.FontSize, Default.FontColor, Default.FontBold,
				Default.FontItalic, Default.FontUnderline );
			_title._fontSpec.Fill.IsVisible = false;
			_title._fontSpec.Border.IsVisible = false;

			_graphObjList = new GraphObjList();
			
			_tag = null;
		}
Esempio n. 18
0
		/// <summary>
		/// Constructor for deserializing objects
		/// </summary>
		/// <param name="info">A <see cref="SerializationInfo"/> instance that defines the serialized data
		/// </param>
		/// <param name="context">A <see cref="StreamingContext"/> instance that contains the serialized data
		/// </param>
		protected PaneBase( SerializationInfo info, StreamingContext context )
		{
			// The schema value is just a file version parameter.  You can use it to make future versions
			// backwards compatible as new member variables are added to classes
			int sch = info.GetInt32( "schema" );

			_rect = (RectangleF) info.GetValue( "rect", typeof(RectangleF) );
			_legend = (Legend) info.GetValue( "legend", typeof(Legend) );
			_title = (GapLabel) info.GetValue( "title", typeof(GapLabel) );
			//this.isShowTitle = info.GetBoolean( "isShowTitle" );
			_isFontsScaled = info.GetBoolean( "isFontsScaled" );
			_isPenWidthScaled = info.GetBoolean( "isPenWidthScaled" );
			//this.fontSpec = (FontSpec) info.GetValue( "fontSpec" , typeof(FontSpec) );
			_titleGap = info.GetSingle( "titleGap" );
			_fill = (Fill) info.GetValue( "fill", typeof(Fill) );
			_border = (Border) info.GetValue( "border", typeof(Border) );
			_baseDimension = info.GetSingle( "baseDimension" );
			_margin = (Margin)info.GetValue( "margin", typeof( Margin ) );
			_graphObjList = (GraphObjList) info.GetValue( "graphObjList", typeof(GraphObjList) );

			_tag = info.GetValue( "tag", typeof(object) );

		}
Esempio n. 19
0
        public override void Update (GraphItem item, pwiz.MSGraph.MSPointList points, GraphObjList annotations)
        {
            if (!Enabled)
                return;

            if (!(item is MassSpectrum))
                return; // throw exception?

            GraphObjList list = annotations;
            Peptide peptide;

            try
            {
                peptide = new Peptide(sequence,
                    pwiz.CLI.proteome.ModificationParsing.ModificationParsing_Auto,
                    pwiz.CLI.proteome.ModificationDelimiter.ModificationDelimiter_Brackets);
            }
            catch (Exception)
            {
                return;
            }

            var spectrum = (item as MassSpectrum).Element;

            if (ReferenceEquals(manualTolerance, null))
            {
                MZTolerance maxTolerance = new MZTolerance(0.5);
                foreach (var scan in spectrum.scanList.scans.Where(o => o.instrumentConfiguration != null))
                {
                    // assume the last analyzer of the instrument configuration is responsible for the resolution
                    if (scan.instrumentConfiguration.componentList.Count == 0)
                        continue;
                    var analyzer = scan.instrumentConfiguration.componentList.Where(o => o.type == ComponentType.ComponentType_Analyzer).Last().cvParamChild(CVID.MS_mass_analyzer_type);
                    if (analyzer.cvid == CVID.CVID_Unknown)
                        continue;

                    MZTolerance analyzerTolerance = null;
                    foreach (var kvp in mzToleranceByAnalyzer)
                        if (CV.cvIsA(analyzer.cvid, kvp.Key))
                        {
                            analyzerTolerance = kvp.Value;
                            break;
                        }

                    if (analyzerTolerance == null)
                        continue;

                    if (maxTolerance.units == analyzerTolerance.units)
                    {
                        if (maxTolerance.value < analyzerTolerance.value)
                            maxTolerance = analyzerTolerance;
                    }
                    else if (analyzerTolerance.units == MZTolerance.Units.PPM)
                        maxTolerance = analyzerTolerance;
                }
                tolerance = maxTolerance;
            }
            else
                tolerance = manualTolerance;

            if (ionSeriesIsEnabled(IonSeries.Auto))
                foreach (var precursor in spectrum.precursors)
                    foreach (var method in precursor.activation.cvParamChildren(CVID.MS_dissociation_method))
                    {
                        if (!ionSeriesByDissociationMethod.Contains(method.cvid))
                            ionSeries = IonSeries.All;
                        else
                            ionSeries |= ionSeriesByDissociationMethod[method.cvid];
                    }

            int nSeries = (ionSeriesIsEnabled(IonSeries.a) ? 1 : 0) +
                          (ionSeriesIsEnabled(IonSeries.b) ? 1 : 0) +
                          (ionSeriesIsEnabled(IonSeries.c) ? 1 : 0);
            int cSeries = (ionSeriesIsEnabled(IonSeries.x) ? 1 : 0) +
                          (ionSeriesIsEnabled(IonSeries.y) ? 1 : 0) +
                          (ionSeriesIsEnabled(IonSeries.z) ? 1 : 0) +
                          (ionSeriesIsEnabled(IonSeries.zRadical) ? 1 : 0);

            showLadders = showLadders && nSeries < 2 && cSeries < 2;

            string unmodifiedSequence = peptide.sequence;
            int sequenceLength = unmodifiedSequence.Length;
            Fragmentation fragmentation = peptide.fragmentation(fragmentMassType == 0 ? true : false, true);

            for (int i = 1; i <= sequenceLength; ++i)
            {
                if (ionSeriesIsEnabled(IonSeries.Immonium))
                    addFragment(list, points, "immonium-" + unmodifiedSequence[i - 1], 0, 1, immoniumIonByResidue[unmodifiedSequence[i - 1]]);

                for (int charge = min; charge <= max; ++charge)
                {
                    if (ionSeriesIsEnabled(IonSeries.a)) addFragment(list, points, "a", i, charge, fragmentation.a(i, charge));
                    if (ionSeriesIsEnabled(IonSeries.b)) addFragment(list, points, "b", i, charge, fragmentation.b(i, charge));
                    if (ionSeriesIsEnabled(IonSeries.y)) addFragment(list, points, "y", i, charge, fragmentation.y(i, charge));
                    if (ionSeriesIsEnabled(IonSeries.z)) addFragment(list, points, "z", i, charge, fragmentation.z(i, charge));
                    if (ionSeriesIsEnabled(IonSeries.zRadical)) addFragment(list, points, "z*", i, charge, fragmentation.zRadical(i, charge));

                    if (i < sequenceLength)
                    {
                        if (ionSeriesIsEnabled(IonSeries.c)) addFragment(list, points, "c", i, charge, fragmentation.c(i, charge));
                        if (ionSeriesIsEnabled(IonSeries.x)) addFragment(list, points, "x", i, charge, fragmentation.x(i, charge));
                    }
                }
            }

            if (showLadders || showFragmentationSummary)
            {
                string topSeries = ionSeriesIsEnabled(IonSeries.a) ? "a" : ionSeriesIsEnabled(IonSeries.b) ? "b" : ionSeriesIsEnabled(IonSeries.c) ? "c" : "";
                string bottomSeries = ionSeriesIsEnabled(IonSeries.x) ? "x" : ionSeriesIsEnabled(IonSeries.y) ? "y" : ionSeriesIsEnabled(IonSeries.z) ? "z" : ionSeriesIsEnabled(IonSeries.zRadical) ? "z*" : "";
                if (showLadders)
                    addIonSeries(list, points, peptide, fragmentation, topSeries, bottomSeries);
                if (showFragmentationSummary)
                    addFragmentationSummary(list, points, peptide, fragmentation, topSeries, bottomSeries);
            }

            // fill peptide info table
            annotationPanels.peptideInfoGridView.Rows.Clear();

            if (spectrum.precursors.Count > 0 &&
                spectrum.precursors[0].selectedIons.Count > 0 &&
                spectrum.precursors[0].selectedIons[0].hasCVParam(CVID.MS_selected_ion_m_z) &&
                spectrum.precursors[0].selectedIons[0].hasCVParam(CVID.MS_charge_state))
            {
                double selectedMz = (double) spectrum.precursors[0].selectedIons[0].cvParam(CVID.MS_selected_ion_m_z).value;
                int chargeState = (int) spectrum.precursors[0].selectedIons[0].cvParam(CVID.MS_charge_state).value;
                double calculatedMass = (precursorMassType == 0 ? peptide.monoisotopicMass(chargeState) : peptide.molecularWeight(chargeState)) * chargeState;
                double observedMass = selectedMz * chargeState;
                annotationPanels.peptideInfoGridView.Rows.Add("Calculated mass:", calculatedMass, "Mass error (daltons):", observedMass - calculatedMass);
                annotationPanels.peptideInfoGridView.Rows.Add("Observed mass:", observedMass, "Mass error (ppm):", ((observedMass - calculatedMass) / calculatedMass) * 1e6);
            }
            else
                annotationPanels.peptideInfoGridView.Rows.Add("Calculated neutral mass:", precursorMassType == 0 ? peptide.monoisotopicMass() : peptide.molecularWeight());

            annotationPanels.peptideInfoGridView.Columns[1].DefaultCellStyle.Format = "F4";
            foreach (DataGridViewRow row in annotationPanels.peptideInfoGridView.Rows)
                row.Height = row.InheritedStyle.Font.Height + 2;

            // show/hide/update fragment table
            if (!annotationPanels.showFragmentationTableCheckBox.Checked || ionSeries <= IonSeries.Auto)
            {
                annotationPanels.fragmentInfoGridView.Visible = false;
                annotationPanels.fragmentInfoGridView.Rows.Clear();
                return;
            }

            annotationPanels.fragmentInfoGridView.Visible = true;
            annotationPanels.fragmentInfoGridView.SuspendLayout();

            if (annotationPanels.fragmentInfoGridView.Columns.Count == 0)
            {
                #region Add columns for fragment types
                if (ionSeriesIsEnabled(IonSeries.a))
                    for (int charge = min; charge <= max; ++charge)
                        annotationPanels.fragmentInfoGridView.Columns.Add(
                            "a" + charge.ToString(),
                            "a" + (charge > 1 ? "(+" + charge.ToString() + ")" : ""));
                if (ionSeriesIsEnabled(IonSeries.b))
                    for (int charge = min; charge <= max; ++charge)
                        annotationPanels.fragmentInfoGridView.Columns.Add(
                            "b" + charge.ToString(),
                            "b" + (charge > 1 ? "(+" + charge.ToString() + ")" : ""));
                if (ionSeriesIsEnabled(IonSeries.c))
                    for (int charge = min; charge <= max; ++charge)
                        annotationPanels.fragmentInfoGridView.Columns.Add(
                            "c" + charge.ToString(),
                            "c" + (charge > 1 ? "(+" + charge.ToString() + ")" : ""));

                annotationPanels.fragmentInfoGridView.Columns.Add("N", "");
                annotationPanels.fragmentInfoGridView.Columns.Add("Sequence", "");
                annotationPanels.fragmentInfoGridView.Columns.Add("C", "");

                if (ionSeriesIsEnabled(IonSeries.x))
                    for (int charge = min; charge <= max; ++charge)
                        annotationPanels.fragmentInfoGridView.Columns.Add(
                            "x" + charge.ToString(),
                            "x" + (charge > 1 ? "(+" + charge.ToString() + ")" : ""));
                if (ionSeriesIsEnabled(IonSeries.y))
                    for (int charge = min; charge <= max; ++charge)
                        annotationPanels.fragmentInfoGridView.Columns.Add(
                            "y" + charge.ToString(),
                            "y" + (charge > 1 ? "(+" + charge.ToString() + ")" : ""));
                if (ionSeriesIsEnabled(IonSeries.z))
                    for (int charge = min; charge <= max; ++charge)
                        annotationPanels.fragmentInfoGridView.Columns.Add(
                            "z" + charge.ToString(),
                            "z" + (charge > 1 ? "(+" + charge.ToString() + ")" : ""));
                if (ionSeriesIsEnabled(IonSeries.zRadical))
                    for (int charge = min; charge <= max; ++charge)
                        annotationPanels.fragmentInfoGridView.Columns.Add(
                            "z*" + charge.ToString(),
                            "z*" + (charge > 1 ? "(+" + charge.ToString() + ")" : ""));
                #endregion

                foreach (DataGridViewColumn column in annotationPanels.fragmentInfoGridView.Columns)
                {
                    column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
                    if (column.Name != "N" && column.Name != "C" && column.Name != "Sequence")
                        column.DefaultCellStyle.Format = "F3";
                }
            }

            while (annotationPanels.fragmentInfoGridView.Rows.Count > sequenceLength)
                annotationPanels.fragmentInfoGridView.Rows.RemoveAt(annotationPanels.fragmentInfoGridView.Rows.Count - 1);
            if (sequenceLength - annotationPanels.fragmentInfoGridView.Rows.Count > 0)
                annotationPanels.fragmentInfoGridView.Rows.Add(sequenceLength - annotationPanels.fragmentInfoGridView.Rows.Count);
            for (int i = 1; i <= sequenceLength; ++i)
            {
                int cTerminalLength = sequenceLength - i + 1;
                var row = annotationPanels.fragmentInfoGridView.Rows[i - 1];
                var values = new List<object>(10);
                //var row = annotationPanels.fragmentInfoGridView.Rows.Add()];

                if (ionSeriesIsEnabled(IonSeries.a))
                    for (int charge = min; charge <= max; ++charge)
                        values.Add(fragmentation.a(i, charge));
                if (ionSeriesIsEnabled(IonSeries.b))
                    for (int charge = min; charge <= max; ++charge)
                        values.Add(fragmentation.b(i, charge));
                if (ionSeriesIsEnabled(IonSeries.c))
                    for (int charge = min; charge <= max; ++charge)
                        if (i < sequenceLength)
                            values.Add(fragmentation.c(i, charge));
                        else
                            values.Add("");

                values.Add(i);
                values.Add(unmodifiedSequence[i - 1]);
                values.Add(cTerminalLength);

                if (ionSeriesIsEnabled(IonSeries.x))
                    for (int charge = min; charge <= max; ++charge)
                        if (i > 1)
                            values.Add(fragmentation.x(cTerminalLength, charge));
                        else
                            values.Add("");
                if (ionSeriesIsEnabled(IonSeries.y))
                    for (int charge = min; charge <= max; ++charge)
                        values.Add(fragmentation.y(cTerminalLength, charge));
                if (ionSeriesIsEnabled(IonSeries.z))
                    for (int charge = min; charge <= max; ++charge)
                        values.Add(fragmentation.z(cTerminalLength, charge));
                if (ionSeriesIsEnabled(IonSeries.zRadical))
                    for (int charge = min; charge <= max; ++charge)
                        values.Add(fragmentation.zRadical(cTerminalLength, charge));
                row.SetValues(values.ToArray());
            }

            foreach (DataGridViewRow row in annotationPanels.fragmentInfoGridView.Rows)
            {
                row.Height = row.InheritedStyle.Font.Height + 2;

                foreach (DataGridViewCell cell in row.Cells)
                {
                    if (!(cell.Value is double))
                        continue;

                    double mz = (double) cell.Value;

                    if (findPointWithTolerance(points, mz, tolerance) > -1)
                        cell.Style.Font = new Font(annotationPanels.fragmentInfoGridView.Font, FontStyle.Bold);
                    else
                        cell.Style.Font = annotationPanels.fragmentInfoGridView.Font;
                }
            }

            annotationPanels.fragmentInfoGridView.ResumeLayout();
        }
Esempio n. 20
0
        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;
                }
            }
        }
Esempio n. 21
0
        public override void Update( GraphItem item, pwiz.MSGraph.MSPointList points, GraphObjList annotations )
        {
            if( !Enabled )
                return;

            if( !( item is MassSpectrum ) )
                return; // throw exception?

            GraphObjList list = annotations;
            Peptide peptide;

            try
            {
                peptide = new Peptide( currentSequence,
                    pwiz.CLI.proteome.ModificationParsing.ModificationParsing_Auto,
                    pwiz.CLI.proteome.ModificationDelimiter.ModificationDelimiter_Brackets );
            } catch( Exception )
            {
                return;
            }

            string unmodifiedSequence = peptide.sequence;
            int sequenceLength = unmodifiedSequence.Length;
            Fragmentation fragmentation = peptide.fragmentation( fragmentMassType == 0 ? true : false, true );
            // Keeps track of number of fragments predicted and matched in each ion series
            numFragmentsMatched.Clear();
            numFragmentsPredicted.Clear();
            for( int charge = min; charge <= max; ++charge )
            {
                for( int i = 1; i <= sequenceLength; ++i )
                {
                    if( a ) addFragment( list, points, "a", i, charge, fragmentation.a( i, charge ) );
                    if( b ) addFragment( list, points, "b", i, charge, fragmentation.b( i, charge ) );
                    if( y ) addFragment( list, points, "y", i, charge, fragmentation.y( i, charge ) );
                    if( z ) addFragment( list, points, "z", i, charge, fragmentation.z( i, charge ) );
                    if( zRadical ) addFragment( list, points, "z*", i, charge, fragmentation.zRadical( i, charge ) );

                    if( i < sequenceLength )
                    {
                        if( c ) addFragment( list, points, "c", i, charge, fragmentation.c( i, charge ) );
                        if( x ) addFragment( list, points, "x", i, charge, fragmentation.x( i, charge ) );
                    }
                }
            }

            if( showLadders )
            {
                string topSeries = a ? "a" : b ? "b" : c ? "c" : "";
                string bottomSeries = x ? "x" : y ? "y" : z ? "z" : zRadical ? "z*" : "";
                addIonSeries( list, points, peptide, fragmentation, topSeries, bottomSeries );
            }

            // fill peptide info table
            annotationPanels.peptideInfoGridView.Rows.Clear();

            var spectrum = ( item as MassSpectrum ).Element;            
            //if( spectrum.precursors.Count > 0 &&
            //    spectrum.precursors[0].selectedIons.Count > 0 &&
            //    spectrum.precursors[0].selectedIons[0].hasCVParam( pwiz.CLI.cv.CVID.MS_selected_ion_m_z ) &&
            //    spectrum.precursors[0].selectedIons[0].hasCVParam( pwiz.CLI.cv.CVID.MS_charge_state ) )
            //{
            //    double selectedMz = (double) spectrum.precursors[0].selectedIons[0].cvParam( pwiz.CLI.cv.CVID.MS_selected_ion_m_z ).value;
            //    int chargeState = (int) spectrum.precursors[0].selectedIons[0].cvParam( pwiz.CLI.cv.CVID.MS_charge_state ).value;
            //    double calculatedMass = ( precursorMassType == 0 ? peptide.monoisotopicMass( chargeState ) : peptide.molecularWeight( chargeState ) ) * chargeState;
            //    double observedMass = selectedMz * chargeState;
            //    annotationPanels.peptideInfoGridView.Rows.Add( "Calculated mass:", calculatedMass, "Mass error (daltons):", observedMass - calculatedMass );
            //    annotationPanels.peptideInfoGridView.Rows.Add( "Observed mass:", observedMass, "Mass error (ppm):", ( ( observedMass - calculatedMass ) / calculatedMass ) * 1e6 );
            //} else
            //    annotationPanels.peptideInfoGridView.Rows.Add( "Calculated neutral mass:", precursorMassType == 0 ? peptide.monoisotopicMass() : peptide.molecularWeight() );

            if (spectrum.precursors.Count > 0 &&
                spectrum.precursors[0].selectedIons.Count > 0 &&
                spectrum.precursors[0].selectedIons[0].hasCVParam(pwiz.CLI.cv.CVID.MS_selected_ion_m_z))
            {
                double selectedMz = (double)spectrum.precursors[0].selectedIons[0].cvParam(pwiz.CLI.cv.CVID.MS_selected_ion_m_z).value;
                
                // Add xcorr score
                ZedGraph.IPointList peaks = (item as MassSpectrum).Points;
                List<ScoringUtils.Peak> rawPeaks = new List<ScoringUtils.Peak>();
                for (int i = 0; i < peaks.Count; ++i)
                    rawPeaks.Add(new ScoringUtils.Peak(peaks[i].X, peaks[i].Y));
                // Remove the precursor and associated neutral loss peaks
                ScoringUtils.erasePrecursorIons(selectedMz, ref rawPeaks); //selectedMz = precursorMz

                if (spectrum.precursors[0].selectedIons[0].hasCVParam(pwiz.CLI.cv.CVID.MS_charge_state)) // known precursor charge state
                {
                    int chargeState = (int)spectrum.precursors[0].selectedIons[0].cvParam(pwiz.CLI.cv.CVID.MS_charge_state).value;
                    double calculatedMass = (precursorMassType == 0 ? peptide.monoisotopicMass(chargeState) : peptide.molecularWeight(chargeState)) * chargeState;
                    double observedMass = selectedMz * chargeState;
                    // compute XCorr
                    double precursorMH = (selectedMz * chargeState) - ((chargeState - 1) * 1.007276);
                    double xcorr = ScoringUtils.computeXCorr(rawPeaks, peptide, precursorMH);
                    annotationPanels.peptideInfoGridView.Rows.Add("Observed precursor charge:", chargeState, "XCorr:", xcorr);
                    annotationPanels.peptideInfoGridView.Rows.Add("Calculated mass:", calculatedMass, "Mass error (daltons):", observedMass - calculatedMass);
                    annotationPanels.peptideInfoGridView.Rows.Add("Observed mass:", observedMass, "Mass error (ppm):", ((observedMass - calculatedMass) / calculatedMass) * 1e6);

                    
                }
                else  // unknown precursor charge state, assume +2 or +3
                {
                    int[] assumedChargeStates = new int[2] { 2, 3 };
                    foreach (int chargeState in assumedChargeStates)
                    {
                        double calculatedMass = (precursorMassType == 0 ? peptide.monoisotopicMass(chargeState) : peptide.molecularWeight(chargeState)) * chargeState;
                        double observedMass = selectedMz * chargeState;
                        // compute XCorr
                        double precursorMH = (selectedMz * chargeState) - ((chargeState - 1) * 1.007276);
                        double xcorr = ScoringUtils.computeXCorr(rawPeaks, peptide, precursorMH);
                        annotationPanels.peptideInfoGridView.Rows.Add("Assumed precursor charge:", chargeState, "XCorr:", xcorr);
                        //annotationPanels.peptideInfoGridView.Rows.Add("Calculated mass:", calculatedMass, "Mass error (daltons):", observedMass - calculatedMass);
                        //annotationPanels.peptideInfoGridView.Rows.Add("Observed mass:", observedMass, "Mass error (ppm):", ((observedMass - calculatedMass) / calculatedMass) * 1e6);
                                                
                    }
                }
            }
            else
                annotationPanels.peptideInfoGridView.Rows.Add("Calculated neutral mass:", precursorMassType == 0 ? peptide.monoisotopicMass() : peptide.molecularWeight());
            
            // Adds number of fragments matched/predicted in each ion series
            foreach(var ionSeries in numFragmentsMatched.Keys)
                annotationPanels.peptideInfoGridView.Rows.Add( ionSeries+" (matched/predicted):", numFragmentsMatched[ionSeries].Count +"/" + numFragmentsPredicted[ionSeries].Count);

            annotationPanels.peptideInfoGridView.Columns[1].DefaultCellStyle.Format = "F4";
            foreach( DataGridViewRow row in annotationPanels.peptideInfoGridView.Rows )
                row.Height = row.InheritedStyle.Font.Height + 2;

            annotationPanels.fragmentInfoGridView.SuspendLayout();
            if( a || b || c || x || y || z || zRadical )
            {
                if( annotationPanels.fragmentInfoGridView.Columns.Count == 0 )
                {
                    #region Add columns for fragment types
                    if( a )
                        for( int charge = min; charge <= max; ++charge )
                            annotationPanels.fragmentInfoGridView.Columns.Add(
                                "a" + charge.ToString(),
                                "a" + ( charge > 1 ? "(+" + charge.ToString() + ")" : "" ) );
                    if( b )
                        for( int charge = min; charge <= max; ++charge )
                            annotationPanels.fragmentInfoGridView.Columns.Add(
                                "b" + charge.ToString(),
                                "b" + ( charge > 1 ? "(+" + charge.ToString() + ")" : "" ) );
                    if( c )
                        for( int charge = min; charge <= max; ++charge )
                            annotationPanels.fragmentInfoGridView.Columns.Add(
                                "c" + charge.ToString(),
                                "c" + ( charge > 1 ? "(+" + charge.ToString() + ")" : "" ) );

                    annotationPanels.fragmentInfoGridView.Columns.Add( "N", "" );
                    annotationPanels.fragmentInfoGridView.Columns.Add( "Sequence", "" );
                    annotationPanels.fragmentInfoGridView.Columns.Add( "C", "" );

                    if( x )
                        for( int charge = min; charge <= max; ++charge )
                            annotationPanels.fragmentInfoGridView.Columns.Add(
                                "x" + charge.ToString(),
                                "x" + ( charge > 1 ? "(+" + charge.ToString() + ")" : "" ) );
                    if( y )
                        for( int charge = min; charge <= max; ++charge )
                            annotationPanels.fragmentInfoGridView.Columns.Add(
                                "y" + charge.ToString(),
                                "y" + ( charge > 1 ? "(+" + charge.ToString() + ")" : "" ) );
                    if( z )
                        for( int charge = min; charge <= max; ++charge )
                            annotationPanels.fragmentInfoGridView.Columns.Add(
                                "z" + charge.ToString(),
                                "z" + ( charge > 1 ? "(+" + charge.ToString() + ")" : "" ) );
                    if( zRadical )
                        for( int charge = min; charge <= max; ++charge )
                            annotationPanels.fragmentInfoGridView.Columns.Add(
                                "z*" + charge.ToString(),
                                "z*" + ( charge > 1 ? "(+" + charge.ToString() + ")" : "" ) );
                #endregion

                    foreach( DataGridViewColumn column in annotationPanels.fragmentInfoGridView.Columns )
                    {
                        column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
                        if( column.Name != "N" && column.Name != "C" && column.Name != "Sequence" )
                            column.DefaultCellStyle.Format = "F3";
                    }
                }

                while( annotationPanels.fragmentInfoGridView.Rows.Count > sequenceLength )
                    annotationPanels.fragmentInfoGridView.Rows.RemoveAt( annotationPanels.fragmentInfoGridView.Rows.Count - 1 );
                if( sequenceLength - annotationPanels.fragmentInfoGridView.Rows.Count > 0 )
                    annotationPanels.fragmentInfoGridView.Rows.Add( sequenceLength - annotationPanels.fragmentInfoGridView.Rows.Count );
                for( int i = 1; i <= sequenceLength; ++i )
                {
                    int cTerminalLength = sequenceLength - i + 1;
                    var row = annotationPanels.fragmentInfoGridView.Rows[i - 1];
                    var values = new List<object>( 10 );
                    //var row = annotationPanels.fragmentInfoGridView.Rows.Add()];

                    if( a )
                        for( int charge = min; charge <= max; ++charge )
                            values.Add( fragmentation.a( i, charge ) );
                    if( b )
                        for( int charge = min; charge <= max; ++charge )
                            values.Add( fragmentation.b( i, charge ) );
                    if( c )
                        for( int charge = min; charge <= max; ++charge )
                            if( i < sequenceLength )
                                values.Add( fragmentation.c( i, charge ) );
                            else
                                values.Add( "" );

                    values.Add( i );
                    values.Add( unmodifiedSequence[i - 1] );
                    values.Add( cTerminalLength );

                    if( x )
                        for( int charge = min; charge <= max; ++charge )
                            if( i > 1 )
                                values.Add( fragmentation.x( cTerminalLength, charge ) );
                            else
                                values.Add( "" );
                    if( y )
                        for( int charge = min; charge <= max; ++charge )
                            values.Add( fragmentation.y( cTerminalLength, charge ) );
                    if( z )
                        for( int charge = min; charge <= max; ++charge )
                            values.Add( fragmentation.z( cTerminalLength, charge ) );
                    if( zRadical )
                        for( int charge = min; charge <= max; ++charge )
                            values.Add( fragmentation.zRadical( cTerminalLength, charge ) );
                    row.SetValues( values.ToArray() );
                }

                foreach( DataGridViewRow row in annotationPanels.fragmentInfoGridView.Rows )
                {
                    row.Height = row.InheritedStyle.Font.Height + 2;

                    foreach( DataGridViewCell cell in row.Cells )
                    {
                        if( !( cell.Value is double ) )
                            continue;

                        double mz = (double) cell.Value;

                        int index = -1;
                        if( points != null )
                            index = points.LowerBound( mz - 0.5 );

                        if( index == -1 || points.ScaledList[index].X > ( mz + 0.5 ) )
                            continue;
                        cell.Style.Font = new Font( annotationPanels.fragmentInfoGridView.Font, FontStyle.Bold );
                    }
                }
            }
            else
                annotationPanels.fragmentInfoGridView.Rows.Clear();

            annotationPanels.fragmentInfoGridView.ResumeLayout();
        }
Esempio n. 22
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;
            }
        }
Esempio n. 23
0
 public abstract void AddPreCurveAnnotations(MSGraphPane graphPane, Graphics g,
     MSPointList pointList, GraphObjList annotations);
Esempio n. 24
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;
                }
            }
        }
Esempio n. 25
0
        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
        }
Esempio n. 26
0
 public override void AddPreCurveAnnotations(MSGraphPane graphPane, Graphics g, MSPointList pointList, GraphObjList annotations)
 {
     // Do nothing
 }
Esempio n. 27
0
        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);
            }
        }
Esempio n. 28
0
		/// <summary>
		/// The Copy Constructor
		/// </summary>
		/// <param name="rhs">The <see cref="PaneBase"/> object from which to copy</param>
		public PaneBase( PaneBase rhs )
		{
			// copy over all the value types
			_isFontsScaled = rhs._isFontsScaled;
			_isPenWidthScaled = rhs._isPenWidthScaled;

			_titleGap = rhs._titleGap;
			_baseDimension = rhs._baseDimension;
			_margin = rhs._margin.Clone();
			_rect = rhs._rect;

			// Copy the reference types by cloning
			_fill = rhs._fill.Clone();
			_border = rhs._border.Clone();
			_title = rhs._title.Clone();

			_legend = rhs.Legend.Clone();
			_title = rhs._title.Clone();
			_graphObjList = rhs._graphObjList.Clone();
			
			if ( rhs._tag is ICloneable )
				_tag = ((ICloneable) rhs._tag).Clone();
			else
				_tag = rhs._tag;
		}
Esempio n. 29
0
        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);
                }
            }
        }
Esempio n. 30
0
 public override void AddAnnotations(MSGraphPane graphPane, Graphics g,
     MSPointList pointList, GraphObjList annotations)
 {
 }
Esempio n. 31
0
 /// <summary>
 /// The Copy Constructor
 /// </summary>
 /// <param name="rhs">The <see cref="GraphObjList"/> object from which to copy</param>
 public GraphObjList( GraphObjList rhs )
 {
     foreach ( GraphObj item in rhs )
         this.Add( (GraphObj) ((ICloneable)item).Clone() );
 }