Esempio n. 1
0
            private static PointPair CreatePointPair(int iGroup, ICollection <double> listValues, ref double maxY, ref double minY)
            {
                if (listValues.Count == 0)
                {
                    return(PointPairMissing(iGroup));
                }

                var statValues = new Statistics(listValues);

                PointPair pointPair;

                if (Settings.Default.ShowPeptideCV)
                {
                    double cvRatio = statValues.StdDev() / statValues.Mean();
                    if (!Settings.Default.PeakDecimalCv)
                    {
                        cvRatio *= 100;
                    }
                    pointPair = MeanErrorBarItem.MakePointPair(iGroup, cvRatio, 0);
                }
                else
                {
                    pointPair = MeanErrorBarItem.MakePointPair(iGroup, statValues.Mean(), statValues.StdDev());
                }
                maxY = Math.Max(maxY, MeanErrorBarItem.GetYTotal(pointPair));
                minY = Math.Min(minY, MeanErrorBarItem.GetYMin(pointPair));
                return(pointPair);
            }
Esempio n. 2
0
            public PointPair MakeBarValue(double xValue, IEnumerable <double> values)
            {
                var statValues = new Statistics(values);

                if (Cv)
                {
                    var cv = statValues.StdDev() / statValues.Mean();
                    return(MeanErrorBarItem.MakePointPair(xValue, CvDecimal ? cv : cv *100, 0));
                }
                return(MeanErrorBarItem.MakePointPair(xValue, statValues.Mean(), statValues.StdDev()));
            }
Esempio n. 3
0
 private void UpdateGraph()
 {
     if (!IsHandleCreated)
     {
         return;
     }
     zedGraphControl.GraphPane.GraphObjList.Clear();
     zedGraphControl.GraphPane.CurveList.Clear();
     _barGraph = null;
     _rows = null;
     var points = new PointPairList();
     var groupComparisonModel = FoldChangeBindingSource.GroupComparisonModel;
     var groupComparisonDef = groupComparisonModel.GroupComparisonDef;
     var document = groupComparisonModel.Document;
     var sequences = new List<Tuple<string, bool>>();
     foreach (var nodePep in document.Molecules)
         sequences.Add(new Tuple<string, bool>(nodePep.RawTextId, nodePep.IsProteomic));
     var uniquePrefixGenerator = new UniquePrefixGenerator(sequences, 3);
     var textLabels = new List<string>();
     var rows = _bindingListSource.OfType<RowItem>()
         .Select(rowItem => rowItem.Value)
         .OfType<FoldChangeBindingSource.FoldChangeRow>()
         .ToArray();
     bool showLabelType = rows.Select(row => row.IsotopeLabelType).Distinct().Count() > 1;
     bool showMsLevel = rows.Select(row => row.MsLevel).Distinct().Count() > 1;
     bool showGroup = rows.Select(row => row.Group).Distinct().Count() > 1;
     foreach (var row in rows)
     {
         var foldChangeResult = row.FoldChangeResult;
         double error = Math.Log(foldChangeResult.MaxFoldChange/foldChangeResult.FoldChange, 2.0);
         var point = MeanErrorBarItem.MakePointPair(points.Count, foldChangeResult.Log2FoldChange, error);
         points.Add(point);
         string label;
         if (null != row.Peptide)
         {
             label = uniquePrefixGenerator.GetUniquePrefix(row.Peptide.GetDocNode().RawTextId, row.Peptide.GetDocNode().IsProteomic);
         }
         else
         {
             label = row.Protein.Name;
         }
         if (showMsLevel && row.MsLevel.HasValue)
         {
             label += " MS" + row.MsLevel; // Not L10N;
         }
         if (showLabelType && row.IsotopeLabelType != null)
         {
             label += " (" + row.IsotopeLabelType.Title + ")"; // Not L10N
         }
         if (showGroup && !Equals(row.Group, default(GroupIdentifier)))
         {
             label += " " + row.Group; // Not L10N
         }
         textLabels.Add(label);
         if (IsSelected(row))
         {
             double y, height;
             if (foldChangeResult.Log2FoldChange >= 0)
             {
                 y = foldChangeResult.Log2FoldChange + error;
                 height = y;
             }
             else
             {
                 y = 0;
                 height = error - foldChangeResult.Log2FoldChange;
             }
             zedGraphControl.GraphPane.GraphObjList.Add(new BoxObj(point.X + .5, y, .99, height)
             {
                 ZOrder = ZOrder.E_BehindCurves,
                 IsClippedToChartRect = true
             });
         }
     }
     zedGraphControl.GraphPane.XAxis.Title.Text = groupComparisonDef.PerProtein ? GroupComparisonStrings.FoldChangeBarGraph_UpdateGraph_Protein : GroupComparisonStrings.FoldChangeBarGraph_UpdateGraph_Peptide;
     zedGraphControl.GraphPane.YAxis.Title.Text = GroupComparisonStrings.FoldChangeBarGraph_UpdateGraph_Log_2_Fold_Change;
     var barGraph = new MeanErrorBarItem(null, points, Color.Black, Color.Blue);
     zedGraphControl.GraphPane.CurveList.Add(barGraph);
     zedGraphControl.GraphPane.XAxis.Type = AxisType.Text;
     zedGraphControl.GraphPane.XAxis.Scale.TextLabels = textLabels.ToArray();
     _axisLabelScaler.ScaleAxisLabels();
     zedGraphControl.GraphPane.AxisChange();
     zedGraphControl.Invalidate();
     _barGraph = barGraph;
     _rows = rows;
 }
Esempio n. 4
0
        public override void UpdateGraph(bool selectionChanged)
        {
            Clear();

            TransitionGroupDocNode selectedGroup   = null;
            PeptideGroupDocNode    selectedProtein = null;
            var selectedTreeNode = GraphSummary.StateProvider.SelectedNode as SrmTreeNode;

            if (selectedTreeNode != null)
            {
                if (selectedTreeNode is TransitionTreeNode)
                {
                    selectedGroup = (TransitionGroupDocNode)selectedTreeNode.SrmParent.Model;
                }
                else if (selectedTreeNode is TransitionGroupTreeNode)
                {
                    selectedGroup = (TransitionGroupDocNode)selectedTreeNode.Model;
                }
                else
                {
                    var node = selectedTreeNode as PeptideTreeNode;
                    if (node != null)
                    {
                        var nodePep = node.DocNode;
                        selectedGroup = nodePep.TransitionGroups.FirstOrDefault();
                    }
                }
                var proteinTreeNode = selectedTreeNode.GetNodeOfType <PeptideGroupTreeNode>();
                if (proteinTreeNode != null)
                {
                    selectedProtein = proteinTreeNode.DocNode;
                }
            }

            SrmDocument document    = GraphSummary.DocumentUIContainer.DocumentUI;
            var         displayType = GraphChromatogram.GetDisplayType(document, selectedTreeNode);

            _graphData = CreateGraphData(document, selectedProtein, selectedGroup, displayType);

            int iColor      = 0;
            int colorOffset = 0;

            if (selectedGroup != null && displayType == DisplayTypeChrom.products)
            {
                // If we are only displaying product ions, we want to use an offset in the colors array
                // so that we do not re-use colors that would be used for any precursor ions.
                colorOffset =
                    GraphChromatogram.GetDisplayTransitions(selectedGroup, DisplayTypeChrom.precursors).Count();
            }

            foreach (var pointPairList in _graphData.PointPairLists)
            {
                Color color = displayType == DisplayTypeChrom.total
                    ? COLORS_GROUPS[iColor++ % COLORS_GROUPS.Count]
                    : COLORS_TRANSITION[(iColor++ + colorOffset) % COLORS_TRANSITION.Count];

                BarItem curveItem;
                if (HiLowMiddleErrorBarItem.IsHiLoMiddleErrorList(pointPairList))
                {
                    curveItem = new HiLowMiddleErrorBarItem(string.Empty, pointPairList, color, Color.Black);
                }
                else
                {
                    curveItem = new MeanErrorBarItem(string.Empty, pointPairList, color, Color.Black);
                }

                curveItem.Bar.Border.IsVisible = false;
                curveItem.Bar.Fill.Brush       = new SolidBrush(color);
                CurveList.Add(curveItem);
            }

            if (ShowSelection && SelectedIndex != -1)
            {
                double yValue = _graphData.SelectedMaxY;
                double yMin   = _graphData.SelectedMinY;
                double height = yValue - yMin;
                GraphObjList.Add(new BoxObj(SelectedIndex + .5, yValue, 0.99,
                                            height, Color.Black, Color.Empty)
                {
                    IsClippedToChartRect = true,
                });
            }

            UpdateAxes();
        }
Esempio n. 5
0
 protected static PointPair PointPairMissing(int iGroup)
 {
     return(MeanErrorBarItem.MakePointPair(iGroup, PointPairBase.Missing, PointPairBase.Missing));
 }
        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. 7
0
        public override void UpdateGraph(bool selectionChanged)
        {
            SrmDocument document         = GraphSummary.DocumentUIContainer.DocumentUI;
            var         results          = document.Settings.MeasuredResults;
            bool        resultsAvailable = results != null;

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

            var selectedTreeNode = GraphSummary.StateProvider.SelectedNode as SrmTreeNode ??
                                   GraphSummary.StateProvider.SelectedNodes.OfType <SrmTreeNode>().FirstOrDefault();

            if (selectedTreeNode == null || document.FindNode(selectedTreeNode.Path) == null)
            {
                EmptyGraph(document);
                return;
            }

            Title.Text = null;

            DisplayTypeChrom displayType  = GraphChromatogram.GetDisplayType(document, selectedTreeNode);
            DocNode          selectedNode = selectedTreeNode.Model;
            IdentityPath     selectedPath = selectedTreeNode.Path;
            DocNode          parentNode   = selectedNode;
            IdentityPath     parentPath   = selectedTreeNode.Path;

            // If the selected tree node is a transition, then its siblings are displayed.
            if (selectedTreeNode is TransitionTreeNode)
            {
                if (displayType != DisplayTypeChrom.single)
                {
                    SrmTreeNode parentTreeNode = selectedTreeNode.SrmParent;
                    parentNode   = parentTreeNode.Model;
                    selectedPath = 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 = ((DocNodeParent)selectedNode).Children;
                if (children.Count == 1 && displayType != DisplayTypeChrom.total)
                {
                    selectedNode = parentNode = children[0];
                    selectedPath = new IdentityPath(parentPath, children[0].Id);
                }
            }
            else if (!(selectedTreeNode is PeptideGroupTreeNode) && !(selectedTreeNode is TransitionGroupTreeNode))
            {
                Title.Text      = Resources.RTReplicateGraphPane_UpdateGraph_Select_a_peptide_to_see_the_retention_time_graph;
                CanShowRTLegend = false;
                return;
            }

            // If a precursor is going to be displayed with display type single
            if (parentNode is TransitionGroupDocNode && displayType == DisplayTypeChrom.single)
            {
                // If no optimization data, then show all the transitions
                if (!results.Chromatograms.Contains(chrom => chrom.OptimizationFunction != null))
                {
                    displayType = DisplayTypeChrom.all;
                }
            }
            var rtTransformOp = GraphSummary.StateProvider.GetRetentionTimeTransformOperation();
            var rtValue       = RTPeptideGraphPane.RTValue;

            GraphValues.ReplicateGroupOp replicateGroupOp;
            if (rtValue == RTPeptideValue.All)
            {
                replicateGroupOp = GraphValues.ReplicateGroupOp.FromCurrentSettings(document.Settings, GraphValues.AggregateOp.MEAN);
            }
            else
            {
                replicateGroupOp = GraphValues.ReplicateGroupOp.FromCurrentSettings(document.Settings);
            }
            var retentionTimeValue = new GraphValues.RetentionTimeTransform(rtValue, rtTransformOp, replicateGroupOp.AggregateOp);

            YAxis.Title.Text = retentionTimeValue.GetAxisTitle();

            var peptidePaths = GetSelectedPeptides().GetUniquePeptidePaths().ToList();

            // if PeptideGroupTreeNode is selected but has only one child isMultiSelect should still be true
            IsMultiSelect = peptidePaths.Count > 1 ||
                            (peptidePaths.Count == 1 &&
                             GraphSummary.StateProvider.SelectedNodes.FirstOrDefault() is PeptideGroupTreeNode);

            GraphData graphData = new RTGraphData(document,
                                                  IsMultiSelect
                ? peptidePaths
                : new[] { selectedPath }.AsEnumerable(), displayType, retentionTimeValue, replicateGroupOp);

            CanShowRTLegend = graphData.DocNodes.Count != 0;
            InitFromData(graphData);

            int    selectedReplicateIndex = SelectedIndex;
            double minRetentionTime = double.MaxValue;
            double maxRetentionTime = -double.MaxValue;
            int    iColor = 0, iCharge = -1;
            var    charge = Adduct.EMPTY;
            int    countLabelTypes        = document.Settings.PeptideSettings.Modifications.CountLabelTypes;
            int    colorOffset            = 0;
            var    transitionGroupDocNode = parentNode as TransitionGroupDocNode;

            if (transitionGroupDocNode != null && displayType == DisplayTypeChrom.products)
            {
                // If we are only displaying product ions, we want to use an offset in the colors array
                // so that we do not re-use colors that would be used for any precursor ions.
                colorOffset =
                    GraphChromatogram.GetDisplayTransitions(transitionGroupDocNode, DisplayTypeChrom.precursors).Count();
            }
            for (int i = 0; i < graphData.DocNodes.Count; i++)
            {
                var docNode        = graphData.DocNodes[i];
                var identityPath   = graphData.DocNodePaths[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   isSelected = false;
                    var   nodeGroup  = docNode as TransitionGroupDocNode;
                    if (IsMultiSelect)
                    {
                        var peptides = peptidePaths.Select(path => document.FindNode(path))
                                       .Cast <PeptideDocNode>().ToArray();
                        var peptideDocNode = peptides.FirstOrDefault(
                            peptide => 0 <= peptide.FindNodeIndex(docNode.Id));
                        if (peptideDocNode == null)
                        {
                            continue;
                        }
                        color = GraphSummary.StateProvider.GetPeptideGraphInfo(peptideDocNode).Color;
                        if (identityPath.Equals(selectedTreeNode.Path) && step == 0)
                        {
                            color      = ChromGraphItem.ColorSelected;
                            isSelected = true;
                        }
                    }
                    else if (parentNode is PeptideDocNode)
                    {
                        // Resharper code inspection v9.0 on TC gets this one wrong
                        // ReSharper disable ExpressionIsAlwaysNull
                        int iColorGroup = GetColorIndex(nodeGroup, countLabelTypes, ref charge, ref iCharge);
                        // ReSharper restore ExpressionIsAlwaysNull
                        color = COLORS_GROUPS[iColorGroup % COLORS_GROUPS.Count];
                    }
                    else if (displayType == DisplayTypeChrom.total)
                    {
                        color = COLORS_GROUPS[iColor % COLORS_GROUPS.Count];
                    }
                    else if (ReferenceEquals(docNode, selectedNode) && step == 0)
                    {
                        color      = ChromGraphItem.ColorSelected;
                        isSelected = true;
                    }
                    else
                    {
                        color = COLORS_TRANSITION[(iColor + colorOffset) % COLORS_TRANSITION.Count];
                    }
                    iColor++;

                    string label = graphData.DocNodeLabels[i];
                    if (step != 0)
                    {
                        label = string.Format(Resources.RTReplicateGraphPane_UpdateGraph_Step__0__, step);
                    }

                    CurveItem curveItem;
                    if (IsMultiSelect)
                    {
                        if (rtValue != RTPeptideValue.All)
                        {
                            curveItem = CreateLineItem(label, pointPairList, color);
                        }
                        else
                        {
                            curveItem = CreateMultiSelectBarItem(label, pointPairList, color);
                        }
                    }
                    else if (HiLowMiddleErrorBarItem.IsHiLoMiddleErrorList(pointPairList))
                    {
                        curveItem        = new HiLowMiddleErrorBarItem(label, pointPairList, color, Color.Black);
                        BarSettings.Type = BarType.Cluster;
                    }
                    else if (rtValue == RTPeptideValue.All)
                    {
                        curveItem        = new MeanErrorBarItem(label, pointPairList, color, Color.Black);
                        BarSettings.Type = BarType.Cluster;
                    }
                    else
                    {
                        curveItem = CreateLineItem(label, pointPairList, color);
                    }

                    if (curveItem != null)
                    {
                        curveItem.Tag = identityPath;

                        var barItem = curveItem as BarItem;
                        if (barItem != null)
                        {
                            barItem.Bar.Border.IsVisible = false;
                            barItem.Bar.Fill.Brush       = GetBrushForNode(docNode, color);
                            if (!isSelected)
                            {
                                barItem.SortedOverlayPriority = 1;
                            }
                        }
                        CurveList.Add(curveItem);

                        if (selectedReplicateIndex != -1 && selectedReplicateIndex < pointPairList.Count)
                        {
                            PointPair pointPair = pointPairList[selectedReplicateIndex];
                            if (!pointPair.IsInvalid)
                            {
                                minRetentionTime = Math.Min(minRetentionTime, pointPair.Z);
                                maxRetentionTime = Math.Max(maxRetentionTime, pointPair.Y);
                            }
                        }
                    }
                }
            }
            // Draw a box around the currently selected replicate
            if (ShowSelection && minRetentionTime != double.MaxValue)
            {
                AddSelection(selectedReplicateIndex, maxRetentionTime, minRetentionTime);
            }
            // Reset the scale when the parent node changes
            if (_parentNode == null || !ReferenceEquals(_parentNode.Id, parentNode.Id))
            {
                XAxis.Scale.MaxAuto = XAxis.Scale.MinAuto = true;
                YAxis.Scale.MaxAuto = YAxis.Scale.MinAuto = true;
            }
            _parentNode      = parentNode;
            Legend.IsVisible = !IsMultiSelect && Settings.Default.ShowRetentionTimesLegend;
            GraphSummary.GraphControl.Invalidate();
            AxisChange();
        }
Esempio n. 8
0
 public LineErrorBarItem(String label,
                         double[] xValues, double[] yValues, double[] errorValues,
                         Color color, Color errorColor)
     : this(label, MeanErrorBarItem.MakePointPairList(xValues, yValues, errorValues), color, errorColor)
 {
 }
Esempio n. 9
0
        public override void UpdateGraph(bool checkData)
        {
            SrmDocument document         = GraphSummary.DocumentUIContainer.DocumentUI;
            var         results          = document.Settings.MeasuredResults;
            bool        resultsAvailable = results != null;

            Clear();
            if (!resultsAvailable)
            {
                Title.Text = Resources.RTReplicateGraphPane_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;
            }

            Title.Text = null;

            DisplayTypeChrom displayType  = GraphChromatogram.GetDisplayType(document, selectedTreeNode);
            DocNode          selectedNode = selectedTreeNode.Model;
            DocNode          parentNode   = selectedNode;
            IdentityPath     identityPath = selectedTreeNode.Path;

            // If the selected tree node is a transition, then its siblings are displayed.
            if (selectedTreeNode is TransitionTreeNode)
            {
                if (displayType != DisplayTypeChrom.single)
                {
                    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 = ((DocNodeParent)selectedNode).Children;
                if (children.Count == 1 && displayType != DisplayTypeChrom.total)
                {
                    selectedNode = parentNode = children[0];
                    identityPath = new IdentityPath(identityPath, parentNode.Id);
                }
            }
            else if (!(selectedTreeNode is TransitionGroupTreeNode))
            {
                Title.Text      = Resources.RTReplicateGraphPane_UpdateGraph_Select_a_peptide_to_see_the_retention_time_graph;
                CanShowRTLegend = false;
                return;
            }

            // If a precursor is going to be displayed with display type single
            if (parentNode is TransitionGroupDocNode && displayType == DisplayTypeChrom.single)
            {
                // If no optimization data, then show all the transitions
                if (!results.Chromatograms.Contains(chrom => chrom.OptimizationFunction != null))
                {
                    displayType = DisplayTypeChrom.all;
                }
            }
            var rtTransformOp = GraphSummary.StateProvider.GetRetentionTimeTransformOperation();
            var rtValue       = RTPeptideGraphPane.RTValue;

            GraphValues.ReplicateGroupOp replicateGroupOp;
            if (rtValue == RTPeptideValue.All)
            {
                replicateGroupOp = GraphValues.ReplicateGroupOp.FromCurrentSettings(document.Settings, GraphValues.AggregateOp.MEAN);
            }
            else
            {
                replicateGroupOp = GraphValues.ReplicateGroupOp.FromCurrentSettings(document.Settings);
            }
            var retentionTimeValue = new GraphValues.RetentionTimeTransform(rtValue, rtTransformOp, replicateGroupOp.AggregateOp);

            YAxis.Title.Text = retentionTimeValue.GetAxisTitle();
            GraphData graphData = new RTGraphData(document, parentNode, displayType, retentionTimeValue, replicateGroupOp);

            CanShowRTLegend = graphData.DocNodes.Count != 0;
            InitFromData(graphData);

            int    selectedReplicateIndex = SelectedIndex;
            double minRetentionTime = double.MaxValue;
            double maxRetentionTime = -double.MaxValue;
            int    iColor = 0, iCharge = -1;
            int?   charge = null;
            int    countLabelTypes        = document.Settings.PeptideSettings.Modifications.CountLabelTypes;
            int    colorOffset            = 0;
            var    transitionGroupDocNode = parentNode as TransitionGroupDocNode;

            if (transitionGroupDocNode != null && displayType == DisplayTypeChrom.products)
            {
                // If we are only displaying product ions, we want to use an offset in the colors array
                // so that we do not re-use colors that would be used for any precursor ions.
                colorOffset =
                    GraphChromatogram.GetDisplayTransitions(transitionGroupDocNode, DisplayTypeChrom.precursors).Count();
            }
            for (int i = 0; i < graphData.DocNodes.Count; 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)
                    {
                        // Resharper code inspection v9.0 on TC gets this one wrong
                        // ReSharper disable ExpressionIsAlwaysNull
                        int iColorGroup = GetColorIndex(nodeGroup, countLabelTypes, ref charge, ref iCharge);
                        // ReSharper restore ExpressionIsAlwaysNull
                        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++;

                    string label = graphData.DocNodeLabels[i];
                    if (step != 0)
                    {
                        label = string.Format(Resources.RTReplicateGraphPane_UpdateGraph_Step__0__, step);
                    }
                    BarItem curveItem;
                    if (HiLowMiddleErrorBarItem.IsHiLoMiddleErrorList(pointPairList))
                    {
                        curveItem = new HiLowMiddleErrorBarItem(label, pointPairList, color, Color.Black);
                    }
                    else
                    {
                        curveItem = new MeanErrorBarItem(label, pointPairList, color, Color.Black);
                    }
                    if (selectedReplicateIndex != -1 && selectedReplicateIndex < pointPairList.Count)
                    {
                        PointPair pointPair = pointPairList[selectedReplicateIndex];
                        if (!pointPair.IsInvalid)
                        {
                            minRetentionTime = Math.Min(minRetentionTime, pointPair.Z);
                            maxRetentionTime = Math.Max(maxRetentionTime, pointPair.Y);
                        }
                    }
                    curveItem.Bar.Border.IsVisible = false;
                    curveItem.Bar.Fill.Brush       = new SolidBrush(color);
                    curveItem.Tag = new IdentityPath(identityPath, docNode.Id);
                    CurveList.Add(curveItem);
                }
            }
            // Draw a box around the currently selected replicate
            if (ShowSelection && minRetentionTime != double.MaxValue)
            {
                GraphObjList.Add(new BoxObj(selectedReplicateIndex + .5, maxRetentionTime, 1,
                                            maxRetentionTime - minRetentionTime, Color.Black, Color.Empty)
                {
                    IsClippedToChartRect = true,
                });
            }
            // Reset the scale when the parent node changes
            if (_parentNode == null || !ReferenceEquals(_parentNode.Id, parentNode.Id))
            {
                XAxis.Scale.MaxAuto = XAxis.Scale.MinAuto = true;
                YAxis.Scale.MaxAuto = YAxis.Scale.MinAuto = true;
            }
            _parentNode      = parentNode;
            Legend.IsVisible = Settings.Default.ShowRetentionTimesLegend;
            AxisChange();
        }
        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);
        }
        public override void UpdateGraph(bool checkData)
        {
            Clear();

            TransitionGroupDocNode selectedGroup = null;
            PeptideGroupDocNode selectedProtein = null;
            var selectedTreeNode = GraphSummary.StateProvider.SelectedNode as SrmTreeNode;
            if (selectedTreeNode != null)
            {
                if (selectedTreeNode is TransitionTreeNode)
                    selectedGroup = (TransitionGroupDocNode)selectedTreeNode.SrmParent.Model;
                else if (selectedTreeNode is TransitionGroupTreeNode)
                    selectedGroup = (TransitionGroupDocNode)selectedTreeNode.Model;
                else
                {
                    var node = selectedTreeNode as PeptideTreeNode;
                    if (node != null)
                    {
                        var nodePep = node.DocNode;
                        selectedGroup = nodePep.TransitionGroups.FirstOrDefault();
                    }
                }
                var proteinTreeNode = selectedTreeNode.GetNodeOfType<PeptideGroupTreeNode>();
                if (proteinTreeNode != null)
                    selectedProtein = proteinTreeNode.DocNode;
            }

            SrmDocument document = GraphSummary.DocumentUIContainer.DocumentUI;
            var displayType = GraphChromatogram.GetDisplayType(document, selectedTreeNode);

            _graphData = CreateGraphData(document, selectedProtein, selectedGroup, displayType);

            int iColor = 0;
            int colorOffset = 0;
            if(selectedGroup != null && displayType == DisplayTypeChrom.products)
            {
                // If we are only displaying product ions, we want to use an offset in the colors array
                // so that we do not re-use colors that would be used for any precursor ions.
                colorOffset =
                   GraphChromatogram.GetDisplayTransitions(selectedGroup, DisplayTypeChrom.precursors).Count();
            }

            foreach (var pointPairList in _graphData.PointPairLists)
            {
                Color color = displayType == DisplayTypeChrom.total
                    ? COLORS_GROUPS[iColor++ % COLORS_GROUPS.Length]
                    : COLORS_TRANSITION[(iColor++ + colorOffset)% COLORS_TRANSITION.Length];

                BarItem curveItem;
                if (HiLowMiddleErrorBarItem.IsHiLoMiddleErrorList(pointPairList))
                    curveItem = new HiLowMiddleErrorBarItem(string.Empty, pointPairList, color, Color.Black);
                else
                    curveItem = new MeanErrorBarItem(string.Empty, pointPairList, color, Color.Black);

                curveItem.Bar.Border.IsVisible = false;
                curveItem.Bar.Fill.Brush = new SolidBrush(color);
                CurveList.Add(curveItem);
            }

            if (ShowSelection && SelectedIndex != -1)
            {
                double yValue = _graphData.SelectedMaxY;
                double yMin = _graphData.SelectedMinY;
                GraphObjList.Add(new BoxObj(SelectedIndex + .5, yValue, 0.99,
                                            yValue - yMin, Color.Black, Color.Empty)
                {
                    IsClippedToChartRect = true,
                });
            }

            UpdateAxes();
        }
        public override void UpdateGraph(bool selectionChanged)
        {
            CurveList.Clear();
            GraphObjList.Clear();
            SrmDocument document         = GraphSummary.DocumentUIContainer.DocumentUI;
            var         selectedTreeNode = GraphSummary.StateProvider.SelectedNode as SrmTreeNode;

            if (selectedTreeNode == null || document.FindNode(selectedTreeNode.Path) == null)
            {
                Title.Text = Helpers.PeptideToMoleculeTextMapper.Translate(Resources.MassErrorReplicateGraphPane_UpdateGraph_Select_a_peptide_to_see_the_mass_error_graph, document.DocumentType);
                EmptyGraph(document);
                return;
            }
            if (!document.Settings.HasResults)
            {
                Title.Text = Resources.AreaReplicateGraphPane_UpdateGraph_No_results_available;
                EmptyGraph(document);
                return;
            }
            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);
            }
            Title.Text = null;
            var aggregateOp = GraphValues.AggregateOp.FromCurrentSettings();

            YAxis.Title.Text = aggregateOp.Cv
                ? aggregateOp.AnnotateTitle(Resources.MassErrorReplicateGraphPane_UpdateGraph_Mass_Error_No_Ppm)
                : Resources.MassErrorReplicateGraphPane_UpdateGraph_Mass_Error;
            DocNode      selectedNode = selectedTreeNode.Model;
            DocNode      parentNode   = selectedNode;
            IdentityPath identityPath = selectedTreeNode.Path;

            // If the selected tree node is a transition, then its siblings are displayed.
            if (selectedTreeNode is TransitionTreeNode)
            {
                if (displayType != DisplayTypeChrom.single)
                {
                    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 if (!(selectedTreeNode is TransitionGroupTreeNode))
            {
                Title.Text = Helpers.PeptideToMoleculeTextMapper.Translate(Resources.MassErrorReplicateGraphPane_UpdateGraph_Select_a_peptide_to_see_the_mass_error_graph, document.DocumentType);
                EmptyGraph(document);
                CanShowMassErrorLegend = false;
                return;
            }
            // If a precursor is going to be displayed with display type single
            if (parentNode is TransitionGroupDocNode && displayType == DisplayTypeChrom.single)
            {
                // If no optimization data, then show all the transitions
                displayType = DisplayTypeChrom.all;
            }

            var       replicateGroupOp = ReplicateGroupOp.FromCurrentSettings(document.Settings);
            GraphData graphData        = new MassErrorGraphData(document,
                                                                identityPath,
                                                                displayType,
                                                                replicateGroupOp,
                                                                PaneKey);

            CanShowMassErrorLegend = graphData.DocNodes.Count != 0;
            InitFromData(graphData);

            int    selectedReplicateIndex = SelectedIndex;
            double minRetentionTime       = double.MaxValue;
            double maxRetentionTime       = double.MinValue;

            int iColor = 0, iCharge = -1;
            var charge                 = Adduct.EMPTY;
            int countLabelTypes        = document.Settings.PeptideSettings.Modifications.CountLabelTypes;
            int colorOffset            = 0;
            var transitionGroupDocNode = parentNode as TransitionGroupDocNode;

            if (transitionGroupDocNode != null && displayType == DisplayTypeChrom.products)
            {
                // If we are only displaying product ions, we want to use an offset in the colors array
                // so that we do not re-use colors that would be used for any precursor ions.
                colorOffset =
                    GraphChromatogram.GetDisplayTransitions(transitionGroupDocNode, DisplayTypeChrom.precursors).Count();
            }
            for (int i = 0; i < graphData.DocNodes.Count; 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;
                    // ReSharper disable ExpressionIsAlwaysNull
                    var nodeGroup = docNode as TransitionGroupDocNode;
                    if (parentNode is PeptideDocNode)
                    {
                        int iColorGroup = GetColorIndex(nodeGroup, countLabelTypes, ref charge, ref iCharge);
                        color = COLORS_GROUPS[iColorGroup % COLORS_GROUPS.Count];
                    }
                    else if (displayType == DisplayTypeChrom.total)
                    {
                        color = COLORS_GROUPS[iColor % COLORS_GROUPS.Count];
                    }
                    else if (docNode.Equals(selectedNode) && step == 0)
                    {
                        color = ChromGraphItem.ColorSelected;
                    }
                    else
                    {
                        color = COLORS_TRANSITION[(iColor + colorOffset) % COLORS_TRANSITION.Count];
                    }
                    // ReSharper restore ExpressionIsAlwaysNull
                    iColor++;

                    string label = graphData.DocNodeLabels[i];
                    if (step != 0)
                    {
                        label = string.Format(Resources.RTReplicateGraphPane_UpdateGraph_Step__0__, step);
                    }
                    BarItem curveItem = new MeanErrorBarItem(label, pointPairList, color, Color.Black);

                    if (selectedReplicateIndex != -1 && selectedReplicateIndex < pointPairList.Count)
                    {
                        PointPair pointPair = pointPairList[selectedReplicateIndex];
                        if (!pointPair.IsInvalid)
                        {
                            minRetentionTime = Math.Min(minRetentionTime, pointPair.Y);
                            maxRetentionTime = Math.Max(maxRetentionTime, pointPair.Y);
                        }
                    }

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

            // Draw a box around the currently selected replicate
            if (ShowSelection && minRetentionTime != double.MaxValue)
            {
                maxRetentionTime = Math.Max(maxRetentionTime, 0);
                minRetentionTime = Math.Min(minRetentionTime, 0);
                GraphObjList.Add(new BoxObj(selectedReplicateIndex + .5, maxRetentionTime, 1,
                                            maxRetentionTime - minRetentionTime, Color.Black, Color.Empty)
                {
                    IsClippedToChartRect = true,
                });
            }

            XAxis.Scale.MinAuto = XAxis.Scale.MaxAuto = selectionChanged;
            YAxis.Scale.MinAuto = YAxis.Scale.MaxAuto = true;
            if (Settings.Default.MinMassError != 0)
            {
                YAxis.Scale.Min = Settings.Default.MinMassError;
            }
            if (Settings.Default.MaxMassError != 0)
            {
                YAxis.Scale.Max = Settings.Default.MaxMassError;
            }
            Legend.IsVisible = Settings.Default.ShowMassErrorLegend;
            AxisChange();
        }