Example #1
0
        /// <summary>
        /// Does Arian's PCA-ANOVA idea.
        /// </summary>
        public double PcaAnova(IntensityMatrix source, Peak peak, Core core, List <GroupInfo> types, List <int> replicates)
        {
            Range times = GetOverlappingTimeRange(core, source, types);

            // Create a matrix thusly:
            // Control Replicate 1: <day1> <day2> <day3> ...
            // Control Replicate 2: <day1> <day2> <day3> ...
            // Control Replicate 3: <day1> <day2> <day3> ...
            // Drought Replicate 1: <day1> <day2> <day3> ...
            // Drought Replicate 2: <day1> <day2> <day3> ...
            // ...

            // Create and clear the matrix
            int rowCount = types.Count * replicates.Count;
            int colCount = times.Count;

            double[,] matrix = new double[rowCount, colCount];

            for (int r = 0; r < rowCount; r++)
            {
                for (int c = 0; c < colCount; c++)
                {
                    matrix[r, c] = double.NaN;
                }
            }

            // Create the group vector
            double[] groups = new double[rowCount];

            for (int r = 0; r < rowCount; r++)
            {
                groups[r] = types[r / replicates.Count].Order;
            }

            IReadOnlyList <double> raw = source.Find(peak).Values;  // TODO: Dirty

            // Fill out the values we know
            for (int i = 0; i < core.Observations.Count; i++)
            {
                ObservationInfo o         = core.Observations[i];
                int             typeIndex = types.IndexOf(o.Group);
                int             repIndex  = replicates.IndexOf(o.Rep);

                if (times.Contains(o.Time) && typeIndex != -1 && repIndex != -1)
                {
                    int timeIndex = o.Time - times.Min;

                    int row = typeIndex * replicates.Count + repIndex;
                    UiControls.Assert(double.IsNaN(matrix[row, timeIndex]), "Duplicate day/time/rep observations in dataset are not allowed.");
                    matrix[row, timeIndex] = raw[i];
                }
            }

            // Guess missing values
            for (int r = 0; r < rowCount; r++)
            {
                for (int c = 0; c < colCount; c++)
                {
                    if (double.IsNaN(matrix[r, c]))
                    {
                        // Missing values - average other values for this point
                        int repIndex  = r % replicates.Count;
                        int typeStart = r - repIndex;

                        double total = 0;
                        int    count = 0;

                        for (int rep = 0; rep < replicates.Count; rep++)
                        {
                            int newRow = typeStart + rep;

                            if (!double.IsNaN(matrix[newRow, c]))
                            {
                                total += matrix[newRow, c];
                                count += 1;
                            }
                        }

                        matrix[r, c] = total / count;
                    }
                }
            }

            // Now do that R stuff...

            var rMatrix = _r.CreateNumericMatrix(matrix);
            var rVector = _r.CreateNumericVector(groups);

            _r.SetSymbol("a", rMatrix);
            _r.SetSymbol("g", rVector);

            //R.Evaluate("write.csv(a, file = \"E:/MJR/Project/05. PEAS/AbstressData/Leaf/Positive/CCor/LP1131.cs.csv\")");

            try
            {
                double result = _r.Evaluate(
                    @"p = prcomp(a)
f = data.frame(y = p$x[,1], group = factor(g))
fit = lm(y ~ group, f)
an = anova(fit)
pval = an$""Pr(>F)""[1]").AsNumeric()[0];

                return(result);
            }
            catch (Exception ex)
            {
                throw new Exception("Something went wrong calculating PCA-ANOVA statistics. See inner exception for details. (Note that this error can occur if only 1 replicate is specified and PCA-ANOVA is calculated with missing values - make sure the replicates are specified correctly.)", ex);
            }
        }
        /// <summary>
        /// Generates the preview image.
        /// </summary>
        /// <param name="sel">Correction to generate the preview for</param>
        private void GeneratePreview(ArgsCorrection sel)
        {
            // No error unless otherwise
            this._lnkError.Visible = false;

            // No selection, no preview
            if (sel == null)
            {
                this.SetPreviewError("Nothing to preview", null);
                return;
            }

            // No peak, no preview
            if (this._selectedPeak == null)
            {
                this.SetPreviewError("No peak selected", null);
                return;
            }

            // Title
            this._lblPreviewTitle.Text = "Preview (" + this._selectedPeak.DisplayName + ")";

            // Get source matrix
            IntensityMatrix source = sel.SourceProvider?.Provide;

            if (source == null)
            {
                this.SetPreviewError(StrRes.NoPreview, StrRes.MissingSourceDetails(sel));
                return;
            }

            // Get vectors
            Vector original = source.Find(this._selectedPeak);
            Vector trend;
            Vector corrected;

            ConfigurationCorrection temp = new ConfigurationCorrection()
            {
                Args = sel
            };

            try
            {
                IReadOnlyList <ObservationInfo> order;
                double[] trendData = temp.ExtractTrend(this._core, original.Values, out order);
                trend     = (trendData != null) ? new Vector(trendData, original.Header, order.Select(z => new IntensityMatrix.ColumnHeader(z)).ToArray()) : null;
                corrected = new Vector(temp.Calculate(this._core, original.Values), original.Header, original.ColHeaders);
            }
            catch (Exception ex)
            {
                this._chartOrig.Plot(null);
                this._chartChanged.Plot(null);
                this._lnkError.Text    = StrRes.PreviewError;
                this._lnkError.Tag     = ex.ToString();
                this._lnkError.Visible = true;
                return;
            }

            // Special flag for batch ordering
            bool isBatchMode;

            if (sel.IsUsingTrend)
            {
                isBatchMode = sel.Mode == ECorrectionMode.Batch;
            }
            else
            {
                isBatchMode = false;
            }

            // Create displays
            StylisedPeak oldDisplay = new StylisedPeak(this._selectedPeak)
            {
                OverrideDefaultOptions = new StylisedPeakOptions(this._core)
                {
                    ShowAcqisition       = isBatchMode,
                    ViewBatches          = this._vBatches,
                    ViewGroups           = this._vTypes,
                    ConditionsSideBySide = true,
                    ShowPoints           = true,
                    ShowTrend            = sel.IsUsingTrend,
                    ShowRanges           = false,
                },

                ForceTrend = trend
            };

            StylisedPeak newDisplay = new StylisedPeak(this._selectedPeak)
            {
                OverrideDefaultOptions = oldDisplay.OverrideDefaultOptions.Clone(),
                ForceObservations      = corrected
            };

            newDisplay.OverrideDefaultOptions.ShowTrend = false;

            // Draw it!
            this._chartOrig.Plot(oldDisplay);
            this._chartChanged.Plot(newDisplay);
        }
Example #3
0
        public void Plot(StylisedPeak stylisedPeak)
        {
            // Get observations
            Vector vector;

            if (stylisedPeak.ForceObservations != null)
            {
                vector = stylisedPeak.ForceObservations;
            }
            else
            {
                IntensityMatrix matrix = this._core.Options.SelectedMatrix;

                if (matrix == null)
                {
                    vector = null;
                }
                else
                {
                    vector = matrix.Find(stylisedPeak.Peak);
                }
            }

            Debug.WriteLine("PeakPlot: " + stylisedPeak);
            Dictionary <string, MCharting.Series> seriesNames = new Dictionary <string, MCharting.Series>();
            Peak peak = stylisedPeak?.Peak;

            // Clear plot
            MCharting.Plot plot = this.PrepareNewPlot(stylisedPeak != null && !stylisedPeak.IsPreview, peak, vector?.Source);

            try // <- CompletNewPlot
            {
                // Get selection
                this.SelectedPeak = peak;
                this.SetCaption("Plot of {0}.", peak);

                if (peak == null)
                {
                    return;
                }

                // Get options
                StylisedPeakOptions opts = stylisedPeak.OverrideDefaultOptions ?? new StylisedPeakOptions(this._core);

                // Get order data
                ObservationInfo[] obsOrder = this._core.Observations.ToArray();

                // Group legends
                IEnumerable <GroupInfoBase> order = opts.ShowAcqisition ? (IEnumerable <GroupInfoBase>)opts.ViewBatches : (IEnumerable <GroupInfoBase>)opts.ViewGroups;
                Dictionary <GroupInfoBase, MCharting.Series> groupLegends = this.DrawLegend(plot, order);

                if (vector == null)
                {
                    return;
                }

                // Show acquisition and batches?
                if (opts.ShowAcqisition)
                {
                    // --- RAW DATA (points) ---
                    MCharting.Series legendEntry = new MCharting.Series();
                    legendEntry.Name             = "Observations";
                    legendEntry.Style.DrawPoints = new SolidBrush(Color.Black);
                    plot.LegendEntries.Add(legendEntry);

                    this.AddToPlot(plot, peak, seriesNames, vector, "Raw data", opts, EPlot.ByBatch, groupLegends, legendEntry);

                    // --- TREND (thick line) ---
                    if (stylisedPeak.ForceTrend != null)
                    {
                        MCharting.Series legendEntry2 = new MCharting.Series();
                        legendEntry2.Name                  = "Trend";
                        legendEntry2.Style.DrawLines       = new Pen(Color.Black, this._core.Options.LineWidth);
                        legendEntry2.Style.DrawLines.Width = 4;
                        plot.LegendEntries.Add(legendEntry2);

                        this.AddToPlot(plot, peak, seriesNames, stylisedPeak.ForceTrend, "Trend data", opts, EPlot.ByBatch | EPlot.DrawLine | EPlot.DrawBold, groupLegends, legendEntry2);
                    }

                    this.DrawLabels(plot, opts.ConditionsSideBySide, order, opts.DrawExperimentalGroupAxisLabels);
                    return;
                }

                // Sort data
                ConfigurationTrend trend = opts.SelectedTrend;
                Vector             avg   = stylisedPeak.ForceTrend ?? trend.CreateTrend(this._core, vector);
                Vector             min   = MinSmoother.CreateTrend(this._core, vector);
                Vector             max   = MaxSmoother.CreateTrend(this._core, vector);

                // --- PLOT MEAN & SD (lines across)
                if (opts.ShowVariableMean)
                {
                    this.AddMeanAndSdLines(plot, opts, vector.Values, peak, groupLegends);
                }

                // --- RANGE (shaded area) ---
                if (opts.ShowRanges)
                {
                    this.AddUpperAndLowerShade(plot, opts, seriesNames, peak, min, max, groupLegends);
                }

                // --- RAW DATA (points) ---
                if (opts.ShowPoints && !stylisedPeak.IsPreview)
                {
                    MCharting.Series legendEntry = new MCharting.Series();
                    legendEntry.Name             = "Observations";
                    legendEntry.Style.DrawPoints = new SolidBrush(Color.Black);
                    plot.LegendEntries.Add(legendEntry);

                    this.AddToPlot(plot, peak, seriesNames, vector, "Raw data", opts, EPlot.None, groupLegends, legendEntry);
                }

                // --- RANGE (lines) ---
                if (opts.ShowMinMax)
                {
                    MCharting.Series legendEntry = new MCharting.Series();
                    legendEntry.Name            = "Range min/max";
                    legendEntry.Style.DrawLines = new Pen(Color.Gray, this._core.Options.LineWidth);
                    plot.LegendEntries.Add(legendEntry);

                    this.AddToPlot(plot, peak, seriesNames, min, "Min value", opts, EPlot.DrawLine, groupLegends, legendEntry);
                    this.AddToPlot(plot, peak, seriesNames, max, "Max value", opts, EPlot.DrawLine, groupLegends, legendEntry);
                }

                // --- TREND (thick line) ---
                if (opts.ShowTrend)
                {
                    MCharting.Series legendEntry = new MCharting.Series();
                    legendEntry.Name                  = "Trend";
                    legendEntry.Style.DrawLines       = new Pen(Color.Black, this._core.Options.LineWidth);
                    legendEntry.Style.DrawLines.Width = this._core.Options.LineWidth * 4;
                    plot.LegendEntries.Add(legendEntry);

                    this.AddToPlot(plot, peak, seriesNames, avg, "Trend data", opts, EPlot.DrawLine | EPlot.DrawBold, groupLegends, legendEntry);
                }

                // --- LABELS ---
                this.DrawLabels(plot, opts.ConditionsSideBySide, order, opts.DrawExperimentalGroupAxisLabels);
            }
            finally
            {
                this.CompleteNewPlot(plot);
            }
        }