예제 #1
0
        protected override void OnRun(Core core, ProgressReporter prog)
        {
            IntensityMatrix source = this.Args.SourceMatrix;

            double[,] results = null;

            for (int index = 0; index < source.NumRows; index++)
            {
                prog.SetProgress(index, source.NumRows);

                // Apply new trend
                // TODO: Should we be using core here?
                double[] r = this.CreateTrend(core.Observations, core.Conditions, core.Groups, source.Vectors[index]);   // obs

                if (results == null)
                {
                    results = new double[source.NumRows, r.Length];
                }

                ArrayHelper.CopyRow(r, results, index);
            }

            IntensityMatrix.RowHeader[]    rows = source.Rows;
            IntensityMatrix.ColumnHeader[] cols = core.Conditions.Select(z => new IntensityMatrix.ColumnHeader(z)).ToArray();
            IntensityMatrix result = new IntensityMatrix(rows, cols, results);

            this.SetResults(new ResultTrend(result));
        }
예제 #2
0
        /// <summary>
        ///
        /// </summary>
        protected override IEnumerable <Cluster> Cluster(IntensityMatrix vmatrix, DistanceMatrix UNUSED, ArgsClusterer args, ConfigurationClusterer tag, ProgressReporter prog)
        {
            // GET OPTIONS
            int k = (int)args.Parameters[0];

            // CREATE RANDOM CENTRES
            Random rnd = new Random();

            var            potentialCentres = new List <Vector>(vmatrix.Vectors);
            List <Cluster> clusters         = new List <Cluster>();

            for (int n = 0; n < k; n++)
            {
                int random = rnd.Next(potentialCentres.Count);

                Cluster p   = new Cluster((clusters.Count + 1).ToString(), tag);
                Vector  vec = potentialCentres[random];
                p.Exemplars.Add(vec.Values);

                potentialCentres.RemoveAt(random);

                clusters.Add(p);
            }

            // Assign to exemplars
            prog.Enter("Initialising assignments");
            LegacyClustererHelper.Assign(vmatrix, clusters, ECandidateMode.Exemplars, args.Distance, prog);
            prog.Leave();

            // Centre
            LegacyClustererHelper.PerformKMeansCentering(vmatrix, clusters, args.Distance, prog);

            return(clusters);
        }
예제 #3
0
        public Vector CreateTrend(Core core, Vector vector)
        {
            double[]        newValues = this.CreateTrend(vector.Observations, core.Conditions, core.Groups, vector.Values);
            IntensityMatrix temporary = new IntensityMatrix(new[] { vector.Peak }, core.Conditions.ToArray(), Vector.VectorToMatrix(newValues));

            return(temporary.Vectors[0]);
        }
예제 #4
0
파일: Arr.cs 프로젝트: mjr129/metaboclust
        /// <summary>
        /// Gets the overlapping time range for the specified [groups].
        /// </summary>

        private static Range GetOverlappingTimeRange(Core core, IntensityMatrix source, IEnumerable <GroupInfo> groups)
        {
            int min = int.MinValue; // sic
            int max = int.MaxValue;

            foreach (GroupInfo type in groups)
            {
                int minA = int.MaxValue;
                int maxA = int.MinValue;

                foreach (ObservationInfo cond in source.Columns.Select(z => z.Observation))
                {
                    if (cond.Group == type)
                    {
                        minA = Math.Min(minA, cond.Time);
                        maxA = Math.Max(maxA, cond.Time);
                    }
                }

                UiControls.Assert(minA != int.MaxValue && maxA != int.MinValue, "Failed to determine overlapping time range (type).");

                min = Math.Max(minA, min);
                max = Math.Min(maxA, max);
            }

            UiControls.Assert(min != int.MinValue && max != int.MaxValue, "Failed to determine overlapping time range (all).");

            return(new Range(min, max));
        }
예제 #5
0
        /// <summary>
        /// Generates a new vector with a unique IntensityMatrix.
        /// For transient plots, etc. since its not efficient to create a new matrix for every peak.
        /// </summary>
        public Vector(double[] values, IntensityMatrix.RowHeader row, IntensityMatrix.ColumnHeader[] cols)
        {
            double[,] valuesAsMatrix = VectorToMatrix(values);

            Source   = new IntensityMatrix(new[] { row }, cols, valuesAsMatrix);
            RowIndex = 0;
        }
        private bool HasReplicates(IMatrixProvider src)
        {
            if (src == null)
            {
                return(false);
            }

            IntensityMatrix matrix = src.Provide;

            if (matrix == null)
            {
                return(false);
            }

            for (int i = 0; i < matrix.NumCols; ++i)
            {
                for (int j = 0; j < i; ++j)
                {
                    var a = matrix.Columns[i].Observation;
                    var b = matrix.Columns[j].Observation;

                    if (a.IsReplicateOf(b))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
예제 #7
0
        /// <summary>
        /// Returns the distance matrix for a set of peaks.
        /// </summary>
        public static DistanceMatrix Create(Core core, IntensityMatrix valueMatrix, ConfigurationMetric metric, ProgressReporter prog)
        {
            int n = valueMatrix.NumRows;

            int bytesRequired = (n * n) * 8;
            int mbRequired    = bytesRequired / (1024 * 1024);
            int limit         = core.Options.ObjectSizeLimit * 1024 * 1024;

            if (bytesRequired > limit)
            {
                // It ain't gonna happen. I'm not creating a distance matrix over 500Mb
                throw new InvalidOperationException("n = " + n + " input vectors. n * n = " + (n * n) + " elements in the distance matrix. 8 bytes per element gives " + (n * n * 8) + " bytes, or " + mbRequired + " megabytes. ObjectSizeLimit is " + core.Options.ObjectSizeLimit + " Mb. Reduce the number of input vectors by filtering the data, or change the limit from the preferences menu. Some algorithms also have the option to disable the distance matrix.");
            }

            double[,] s = new double[n, n];
            prog.Enter("Calculating distance matrix");

            for (int i = 0; i < n; i++)
            {
                prog.SetProgress(i, n);

                for (int j = 0; j < n; j++)
                {
                    s[i, j] = metric.Calculate(valueMatrix.Vectors[i], valueMatrix.Vectors[j]);
                }
            }

            prog.Leave();

            return(new DistanceMatrix(s, valueMatrix));
        }
        /// <summary>
        /// d-k-means++
        /// Ignores insignificant variables.
        /// Returns new clusters (these won't be added to the core so make sure to do so)
        /// </summary>
        private static List <Cluster> AutogenerateClusters(IntensityMatrix vmatrix, List <Cluster> seed, double?stoppingDistance, int?stoppingCount, ConfigurationMetric metric, ConfigurationClusterer tag, ProgressReporter prog)
        {
            // Make a log of whatever limits have been set
            if (!stoppingCount.HasValue && !stoppingDistance.HasValue)
            {
                throw new InvalidOperationException("No stopping condition set.");
            }

            // Assign all variables to nearest
            List <Cluster> result = new List <Cluster>(seed);

            // Get the actual limits
            int    iterations = 0;
            int    count      = (stoppingCount - seed.Count) ?? Int32.MaxValue;
            double distance   = stoppingDistance ?? Double.MinValue;

            // Get the most distant variable
            prog.Enter("Initialising assignments");
            LegacyClustererHelper.Assign(vmatrix, result, ECandidateMode.Exemplars, metric, prog);
            Assignment mostDistant = GetMostDistantAssignment(result);

            prog.Leave();

            // Continue until our limits are breached
            while ((count > 0) && (mostDistant.Score > distance))
            {
                // Check we haven't got unreasonable limits
                iterations++;

                prog.Enter("Centre generation (iteration " + iterations + ")");

                if (iterations > 1000)
                {
                    throw new InvalidOperationException("Too many iterations - exiting.");
                }

                // Create a new cluster with the most distant variable as its exemplar
                var newCluster = new Cluster((result.Count + 1).ToString(), tag);
                result.Add(newCluster);
                newCluster.Exemplars.Add(mostDistant.Vector.Values);  // todo: check to prevent multiple assignment?

                // Make the assignments based on the closest exemplars
                LegacyClustererHelper.Assign(vmatrix, result, ECandidateMode.Exemplars, metric, prog);

                // Basic check
                if (!newCluster.Assignments.Vectors.Contains(mostDistant.Vector))
                {
                    throw new InvalidOperationException("Problem creating new cluster from vector - " + mostDistant.Vector.ToString() + " doesn't like being in its own cluster. Check this vector for discrepancies.");
                }

                // Get the next most distant variable
                count       = count - 1;
                mostDistant = GetMostDistantAssignment(result);

                prog.Leave();
            }

            // Return the number of iterations
            return(result);
        }
예제 #9
0
        public Vector(IntensityMatrix source, int rowIndex)
        {
            if (rowIndex < 0 || rowIndex >= source.NumRows)
            {
                throw new InvalidOperationException($"Attempt to create a vector reference where the rowIndex {{{rowIndex}}} is outside the source dimensions: {{{source}}}.");
            }

            Source   = source;
            RowIndex = rowIndex;
        }
예제 #10
0
        /// <summary>IMPLEMENTS ClustererBase</summary>
        protected override IEnumerable <Cluster> Cluster(IntensityMatrix vmatrix, DistanceMatrix dmatrix, ArgsClusterer args, ConfigurationClusterer tag, ProgressReporter prog)
        {
            Cluster result = new Cluster("Com", tag);

            foreach (Vector vector in vmatrix.Vectors)
            {
                result.Assignments.Add(new Assignment(vector, result, double.NaN));
            }

            return(new Cluster[] { result });
        }
예제 #11
0
 /// <summary>
 /// The session's peaks
 /// </summary>
 public static DataSet <Vector> ForVectors(Core core, IntensityMatrix matrix)
 {
     return(new DataSet <Vector>()
     {
         Core = core,
         ListTitle = "Vectors",
         ListSource = matrix.Vectors,
         ItemTitle = z => z.ToString(),
         ItemDescription = z => z.Peak.Comment,
         Icon = Resources.IconPeak,
     });
 }
예제 #12
0
        /// <summary>
        /// Action completed - calculate statisstics
        /// </summary>
        internal void FinalizeResults(Core core, ConfigurationMetric metric, IntensityMatrix vmatrix, DistanceMatrix dmatrix, EClustererStatistics statistics, ProgressReporter prog)
        {
            UiControls.Assert(Assignments.IsEmpty(), "FinalizeResults on ClusterResults already called.");

            // Get ALL the assignments
            foreach (Cluster cluster in RealClusters)
            {
                Assignments.AddRange(cluster.Assignments.List);
            }

            RecalculateStatistics(core, metric, vmatrix, dmatrix, statistics, prog);
        }
        private void Check(object sender, EventArgs e)
        {
            ArgsTrend sel;

            try
            {
                sel = this.GetSelection();
            }
            catch
            {
                sel = null;
            }

            bool valid = sel != null;

            this._txtName.Watermark = sel != null ? sel.DefaultDisplayName : Texts.default_name;

            this._lnkError.Visible = false;

            if (sel != null)
            {
                StylisedPeak sPeak = new StylisedPeak(this._previewPeak);

                ConfigurationTrend temporary = new ConfigurationTrend()
                {
                    Args = sel
                };
                IntensityMatrix source = this._ecbSource.SelectedItem.Provide;

                if (this._previewPeak != null)
                {
                    try
                    {
                        sPeak.OverrideDefaultOptions = new StylisedPeakOptions(this._core)
                        {
                            SelectedTrend = temporary
                        };
                        this._chart1.Plot(sPeak);
                    }
                    catch (Exception ex)
                    {
                        this._lnkError.Visible       = true;
                        this._lnkError.Tag           = ex.ToString();
                        sPeak.OverrideDefaultOptions = null;
                        this._chart1.Plot(sPeak);
                    }
                }
            }

            this._btnOk.Enabled      = valid;
            this._tlpPreview.Visible = valid;
        }
예제 #14
0
        /// <summary>
        /// K-means centering.
        /// </summary>
        public static void PerformKMeansCentering(IntensityMatrix vmatrix, IReadOnlyList <Cluster> toChoose, ConfigurationMetric metric, ProgressReporter prog)
        {
            int n = 0;

            do
            {
                if (n != 0)
                {
                    prog.Leave();
                }

                prog.Enter("k-means (iteration " + (++n) + ")");
            } while (Assign(vmatrix, toChoose, ECandidateMode.Assignments, metric, prog));

            prog.Leave();
        }
예제 #15
0
        /// <summary>
        ///
        /// </summary>
        protected override IEnumerable <Cluster> Cluster(IntensityMatrix vmatrix, DistanceMatrix UNUSED, ArgsClusterer args, ConfigurationClusterer tag, ProgressReporter prog)
        {
            // Get parameters
            // COUNT LIMIT
            int countLimit = (int)tag.UntypedArgs.Parameters[0];
            // DISTANCE LIMIT
            double distanceLimit = (double)tag.UntypedArgs.Parameters[1];
            // SEED PEAK
            WeakReference <Peak> seedPeakRef = (WeakReference <Peak>)tag.UntypedArgs.Parameters[2];
            Peak seedPeak = seedPeakRef.GetTargetOrThrow();
            // SEED GROUP
            GroupInfo groupInfo = (GroupInfo)tag.UntypedArgs.Parameters[3];
            // DO-K-MEANS?
            bool doKMeans = (bool)tag.UntypedArgs.Parameters[4];

            // Create the seed cluster
            Cluster        seedCluster = new Cluster("1", tag);
            List <Cluster> seedList    = new List <Cluster> {
                seedCluster
            };
            int seedIndex = vmatrix.FindIndex(new IntensityMatrix.RowHeader(seedPeak, args.SplitGroups ? groupInfo : null));

            if (seedIndex == -1)
            {
                throw new InvalidOperationException($"The chosen peak {{{seedPeak}}} cannot be used a seed because it is not present in the value matrix. Please check that this peak has not been excluded by the filter condition {{{args.PeakFilter}}}.");
            }

            seedCluster.Exemplars.Add(vmatrix.Vectors[seedIndex]);

            // Autogenerate the clusters
            int?   nCountLimit    = (countLimit != Int32.MinValue) ? countLimit : (int?)null;
            double?nDistanceLimit = (distanceLimit != Double.MinValue) ? countLimit : (double?)null;

            List <Cluster> autoGenClusters = AutogenerateClusters(vmatrix, seedList, nDistanceLimit, nCountLimit, args.Distance, tag, prog);

            // Do k-means (if requested)
            if (doKMeans)
            {
                prog.Enter("k-means");
                LegacyClustererHelper.PerformKMeansCentering(vmatrix, autoGenClusters, args.Distance, prog);
                prog.Leave();
            }

            // Return full list
            return(autoGenClusters);
        }
예제 #16
0
        protected override IEnumerable <Cluster> Cluster(IntensityMatrix vmatrix, DistanceMatrix dmatrix, ArgsClusterer args, ConfigurationClusterer tag, ProgressReporter prog)
        {
            object[] inputs =
            {
                _script.IsInputPresent(0) ? vmatrix.Values : null,
                _script.IsInputPresent(1) ? dmatrix.Values : null
            };

            prog.Enter("Running script");
            prog.SetProgressMarquee();
            int[] clusters = Arr.Instance.RunScriptIntV(_script, inputs, args.Parameters).ToArray();
            prog.Leave();
            prog.Enter("Creating clusters");
            var result = CreateClustersFromIntegers(vmatrix, clusters, tag);

            prog.Leave();
            return(result);
        }
예제 #17
0
        /// <summary>
        /// Assigns peaks to clusters
        /// A single k-means iteration.
        /// </summary>
        public static bool Assign(IntensityMatrix vmatrix, IReadOnlyList <Cluster> toChoose, ECandidateMode source, ConfigurationMetric distanceMetric, ProgressReporter prog)
        {
            // Get the current cluster centres
            prog.SetProgress(0, vmatrix.NumRows);

            for (int index = 0; index < toChoose.Count; index++)
            {
                prog.SetProgress(index, toChoose.Count);
                toChoose[index].SetCentre(ECentreMode.Average, source);
            }

            // Clear the previous assignments
            Dictionary <Cluster, List <Vector> > previousAssignments = new Dictionary <Cluster, List <Vector> >();

            for (int index = 0; index < toChoose.Count; index++)
            {
                previousAssignments.Add(toChoose[index], toChoose[index].Assignments.Vectors.ToList());
                toChoose[index].Assignments.ClearAll();
            }

            // Detect changes so we know when the algorithm has converged
            bool somethingChanged = false;

            // Assign peaks to centres
            for (int index = 0; index < vmatrix.NumRows; index++)
            {
                Vector vec = vmatrix.Vectors[index];
                prog.SetProgress(index, vmatrix.NumRows);

                ClusterScore best = FindClosestCluster(vec.Values, toChoose, distanceMetric);

                // Something changed?
                if (!previousAssignments[best.Cluster].Contains(vec))
                {
                    somethingChanged = true;
                }

                // Create new assignment
                best.Cluster.Assignments.Add(new Assignment(vec, best.Cluster, best.Score));
            }

            return(somethingChanged);
        }
예제 #18
0
        protected override void OnRun(Core core, ProgressReporter prog)
        {
            // For each peak
            IntensityMatrix source = this.Args.SourceMatrix;

            double[,] results = new double[source.NumRows, source.NumCols];

            for (int peakIndex = 0; peakIndex < source.NumRows; peakIndex++)
            {
                prog.SetProgress(peakIndex, source.NumRows);
                Peak x   = source.Rows[peakIndex].Peak;
                var  row = this.Calculate(core, source.Vectors[peakIndex]);

                ArrayHelper.CopyRow(row, results, peakIndex);
            }

            IntensityMatrix imresult = new IntensityMatrix(source.Rows, source.Columns, results);

            this.SetResults(new ResultCorrection(imresult));
        }
예제 #19
0
        /// <summary>IMPLEMENTS ClustererBase</summary>
        protected override IEnumerable <Cluster> Cluster(IntensityMatrix vmatrix, DistanceMatrix dmatrix, ArgsClusterer args, ConfigurationClusterer tag, ProgressReporter prog)
        {
            Dictionary <Cluster, Cluster>          result   = new Dictionary <Cluster, Cluster>();
            WeakReference <ConfigurationClusterer> wrMethod = (WeakReference <ConfigurationClusterer>)args.Parameters[0];
            ConfigurationClusterer existing = wrMethod.GetTargetOrThrow();
            var existingResults             = existing.Results;

            foreach (Vector vector in vmatrix.Vectors)
            {
                Cluster existingCluster = existingResults.Assignments.FirstOrDefault(z => z.Peak == vector.Peak)?.Cluster;

                if (existingCluster != null)
                {
                    Cluster newCluster = result.GetOrCreate(existingCluster, xc => new Cluster(xc.ShortName, tag));

                    newCluster.Assignments.Add(new Assignment(vector, newCluster, double.NaN));
                }
            }

            return(result.Values);
        }
예제 #20
0
        /// <summary>
        ///
        /// </summary>
        protected override IEnumerable <Cluster> Cluster(IntensityMatrix vmatrix, DistanceMatrix dmatrix, ArgsClusterer args, ConfigurationClusterer tag, ProgressReporter prog)
        {
            Dictionary <Pathway, Cluster> d = new Dictionary <Pathway, Cluster>();
            List <Cluster> result           = new List <Cluster>();

            prog.Enter("Finding pathways");

            for (int index = 0; index < vmatrix.NumRows; index++)
            {
                Vector vec  = vmatrix.Vectors[index];
                Peak   peak = vec.Peak;
                prog.SetProgress(index, vmatrix.NumRows);

                foreach (Annotation c in peak.Annotations)
                {
                    foreach (Pathway p in c.Compound.Pathways)
                    {
                        Cluster pat;

                        if (!d.TryGetValue(p, out pat))
                        {
                            pat         = new Cluster(p.DefaultDisplayName, tag);
                            pat.States |= Session.Main.Cluster.EStates.Pathway;
                            result.Add(pat);
                            d.Add(p, pat);
                        }

                        if (!pat.Assignments.Peaks.Contains(peak))
                        {
                            pat.Assignments.Add(new Assignment(vec, pat, double.NaN));
                        }
                    }
                }
            }

            prog.Leave();

            return(result);
        }
예제 #21
0
        protected override IEnumerable <Cluster> Cluster(IntensityMatrix vmatrix, DistanceMatrix UNUSED, ArgsClusterer args, ConfigurationClusterer tag, ProgressReporter prog)
        {
            ConfigurationClusterer config     = ((WeakReference <ConfigurationClusterer>)args.Parameters[0]).GetTargetOrThrow();
            List <Cluster>         myClusters = new List <Cluster>();

            // Iterate existing clusters
            prog.Enter("Iterating existing");

            for (int index = 0; index < config.Results.Clusters.Length; index++)
            {
                Cluster cluster = config.Results.Clusters[index];
                prog.SetProgress(index, config.Results.Clusters.Length);

                if (!cluster.States.HasFlag(Session.Main.Cluster.EStates.Insignificants))
                {
                    // Get the centre
                    IReadOnlyList <double> centre = cluster.GetCentre(ECentreMode.Average, ECandidateMode.Assignments)[0];

                    // Reorder the centre to match our vmatrix
                    // centre = Reorder(centre, config.Results.VMatrix.Conditions, vmatrix.Conditions);

                    Cluster myCluster = new Cluster(cluster.DisplayName, tag);
                    myCluster.Exemplars.Add(centre);
                    myClusters.Add(myCluster);
                }
            }

            prog.Leave();

            prog.Enter("Assigning peaks");
            LegacyClustererHelper.Assign(vmatrix, myClusters, ECandidateMode.Exemplars, args.Distance, prog);
            prog.Leave();

            Cluster matchCluster = new Cluster("Matches", tag);

            matchCluster.States |= Session.Main.Cluster.EStates.Insignificants;

            return(myClusters);
        }
예제 #22
0
        /// <summary>
        /// INTENSITIES
        /// </summary>
        private void ExportData(string fileName, IntensityMatrix source)
        {
            // nPeaks x nObs
            Spreadsheet <double> ss = new Spreadsheet <double>(source.NumRows, source.NumCols);

            for (int nObs = 0; nObs < this._core.Observations.Count; ++nObs)
            {
                ss.ColNames[nObs] = this._uniqueTable.Name(this._core.Observations[nObs]);
            }

            for (int nPeak = 0; nPeak < this._core.Peaks.Count; ++nPeak)
            {
                Peak peak = this._core.Peaks[nPeak];
                ss.RowNames[nPeak] = this._uniqueTable.Name(peak);

                for (int nObs = 0; nObs < this._core.Observations.Count; ++nObs)
                {
                    ss[nPeak, nObs] = source.Values[nPeak, nObs];
                }
            }

            ss.SaveCsv(fileName);
        }
예제 #23
0
        protected override void OnRun(Core core, ProgressReporter prog)
        {
            IntensityMatrix source = this.Args.SourceMatrix;

            double max = double.MinValue;
            double min = double.MaxValue;

            Dictionary <Peak, double> results = new Dictionary <Peak, double>();

            for (int peakIndex = 0; peakIndex < source.Rows.Length; peakIndex++)
            {
                prog.SetProgress(peakIndex, source.Rows.Length);

                Peak   peak  = source.Rows[peakIndex].Peak;
                double value = this.Calculate(core, peak);
                max = Math.Max(max, value);
                min = Math.Min(min, value);

                results.Add(peak, value);
            }

            this.SetResults(new ResultStatistic(results, min, max));
        }
예제 #24
0
        protected static IEnumerable <Cluster> CreateClustersFromIntegers(IntensityMatrix vmatrix, IList <int> clusters, ConfigurationClusterer tag)
        {
            Dictionary <int, Cluster> pats = new Dictionary <int, Cluster>();
            List <Cluster>            r    = new List <Cluster>();

            for (int n = 0; n < vmatrix.NumRows; n++)
            {
                Vector p = vmatrix.Vectors[n];

                int     c = clusters != null ? clusters[n] : 0;
                Cluster pat;

                if (!pats.TryGetValue(c, out pat))
                {
                    pat = new Cluster((pats.Count + 1).ToString(), tag);
                    pats.Add(c, pat);
                    r.Add(pat);
                }

                pat.Assignments.Add(new Assignment(p, pat, double.NaN));
            }

            return(r);
        }
예제 #25
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);
            }
        }
        /// <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);
        }
예제 #27
0
 public ResultCorrection(IntensityMatrix result)
 {
     Matrix = result;
 }
예제 #28
0
파일: Arr.cs 프로젝트: mjr129/metaboclust
        /// <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);
            }
        }
예제 #29
0
        /// <summary>
        /// ACTION!
        /// </summary>
        protected override IEnumerable <Cluster> Cluster(IntensityMatrix vm, DistanceMatrix dm, ArgsClusterer args, ConfigurationClusterer tag, ProgressReporter prog)
        {
            // Construct similarity matrix
            int N = vm.NumRows;

            double[,] s; // = new double[N, N];
            double[,] r  = new double[N, N];
            double[,] a  = new double[N, N];
            double[,] rn = new double[N, N];
            double[,] an = new double[N, N];

            // CALCULATE SIMILARITIES "S"
            s = dm.Values;

            // CALCULATE PREFERENCES "diag(S)"
            double median = ApMedian(s);

            for (int i = 0; i < N; i++)
            {
                s[i, i] = median;
            }

            // SET LAMBDA (change rate)
            const double lambda = 0.5;

            prog.SetProgress(-1);

            // CALCULATE NEXT R AND NEXT A
            for (int iter = 0; iter < 100; iter++)
            {
                prog.Enter("Affinity Propagation Iteration " + iter);

                // CALCULATE R
                // r[i,k] =   s[i,k]
                //          - max( a[i,kp] + s[i,kp] )
                for (int i = 0; i < N; i++)
                {
                    for (int k = 0; k < N; k++)
                    {
                        double v = double.MinValue;

                        for (int kp = 0; kp < N; kp++)
                        {
                            if (kp != k)
                            {
                                v = Math.Max(v, a[i, kp] + s[i, kp]);
                            }
                        }

                        rn[i, k] = s[i, k] - v;
                    }
                }

                for (int i = 0; i < N; i++)
                {
                    for (int k = 0; k < N; k++)
                    {
                        r[i, k] = r[i, k] * lambda + rn[i, k] * (1 - lambda);
                    }
                }

                // CALCULATE A
                // a[i, k] = min(0, r(k,k)
                //                 + sum( max ( 0,
                //                        r(ip, k)
                // a[k, k] = sum( max( 0, r(ip, k ) )
                for (int i = 0; i < N; i++)
                {
                    for (int k = 0; k < N; k++)
                    {
                        if (i != k)
                        {
                            double v = 0;

                            for (int ip = 0; ip < N; ip++)
                            {
                                if (ip != i && ip != k)
                                {
                                    v += Math.Max(0, r[ip, k]);
                                }
                            }

                            an[i, k] = Math.Min(0, r[k, k] + v);
                        }
                        else
                        {
                            double v = 0;

                            for (int ip = 0; ip < N; ip++)
                            {
                                if (ip != i && ip != k)
                                {
                                    v += Math.Max(0, r[ip, k]);
                                }
                            }

                            an[k, k] = v;
                        }
                    }
                }

                for (int i = 0; i < N; i++)
                {
                    for (int k = 0; k < N; k++)
                    {
                        a[i, k] = a[i, k] * lambda + an[i, k] * (1 - lambda);
                    }
                }

                prog.Leave();
            }

            // CALCULATE EXEMPLARS "E"
            // the value of k that maximizes a(i,k) + r(i,k)
            int[]    exemplars = new int[N];
            double[] scores    = new double[N];

            for (int i = 0; i < N; i++)
            {
                double maxVal = double.MinValue;
                int    maxK   = -1;

                for (int k = 0; k < N; k++)
                {
                    double val = a[i, k] + r[i, k];

                    if (val > maxVal)
                    {
                        maxVal = val;
                        maxK   = k;
                    }
                }

                exemplars[i] = maxK;
                scores[i]    = maxVal; // HIGHER is better
            }

            // CONVERT TO CLUSTERS
            Dictionary <int, Cluster> dict = new Dictionary <int, Cluster>();

            for (int pInd = 0; pInd < vm.NumRows; pInd++)
            {
                Vector vec   = vm.Vectors[pInd];
                int    exe   = exemplars[pInd];
                Vector vecx  = vm.Vectors[exe];
                double score = scores[pInd]; // HIGHER is better

                Cluster clu = dict.GetOrCreate(exe, x => new Cluster(vecx.Peak.DisplayName, tag));

                clu.Assignments.Add(new Assignment(vec, clu, score));
            }

            return(dict.Values.OrderBy(z => z.DisplayName));
        }
예제 #30
0
        /// <summary>
        ///
        /// </summary>
        protected override IEnumerable <Cluster> Cluster(IntensityMatrix vmatrix, DistanceMatrix dmatrix, ArgsClusterer args, ConfigurationClusterer tag, ProgressReporter prog)
        {
            ConfigurationClusterer    existing           = ((WeakReference <ConfigurationClusterer>)args.Parameters[0]).GetTarget();
            List <List <Assignment> > uniqueCombinations = new List <List <Assignment> >();
            List <Cluster>            newClusters        = new List <Cluster>();
            List <ObservationInfo[]>  observations       = new List <ObservationInfo[]>();

            var existingResults = existing.Results;

            prog.Enter("Finding unique matches");

            for (int row = 0; row < vmatrix.NumRows; row++)
            {
                Vector vector = vmatrix.Vectors[row];
                Peak   peak   = vector.Peak;
                prog.SetProgress(row, vmatrix.NumRows);

                List <Assignment> assignments = new List <Assignment>(existingResults.Assignments
                                                                      .Where(z => z.Peak == peak)
                                                                      .OrderBy(z => z.Vector.Group.Order));

                int     index = FindMatch(uniqueCombinations, assignments);
                Cluster pat;

                if (index == -1)
                {
                    uniqueCombinations.Add(assignments);

                    string name = StringHelper.ArrayToString <Assignment>(assignments, z => z.Vector.Group.DisplayShortName + "." + z.Cluster.ShortName, " / ");

                    pat = new Cluster(name, tag);

                    // Centre (merge centres)
                    IEnumerable <IReadOnlyList <double> > centres = assignments.Select(z => z.Cluster.Centres.First());
                    pat.Centres.Add(centres.SelectMany(z => z).ToArray());

                    // Vector (merge vectors)
                    if (assignments[0].Vector.Observations != null)
                    {
                        observations.Add(assignments.Select(z => z.Vector.Observations).SelectMany(z => z).ToArray());
                    }
                    else
                    {
                        observations.Add(null);
                    }

                    // Relations (all clusters)
                    pat.Related.AddRange(assignments.Select(z => z.Cluster).Unique());

                    foreach (Cluster pat2 in pat.Related)
                    {
                        if (!pat2.Related.Contains(pat))
                        {
                            pat2.Related.Add(pat);
                        }
                    }

                    index = newClusters.Count;
                    newClusters.Add(pat);
                }


                pat = newClusters[index];

                double[] values = assignments.Select(z => z.Vector.Values).SelectMany(z => z).ToArray();
                pat.Assignments.Add(new Assignment(vector, pat, assignments.Count));
            }

            prog.Leave();

            return(newClusters);
        }