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)); }
/// <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); }
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]); }
/// <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)); }
/// <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); }
/// <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); }
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; }
/// <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 }); }
/// <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, }); }
/// <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; }
/// <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(); }
/// <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); }
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); }
/// <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); }
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)); }
/// <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); }
/// <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); }
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); }
/// <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); }
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)); }
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); }
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); }
public ResultCorrection(IntensityMatrix result) { Matrix = result; }
/// <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> /// 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)); }
/// <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); }