/// <summary> /// Determines if the inputs match the specified mask. /// </summary> /// <param name="mask">Mask containing '1' (present) '0' (not present) and '-' (doesn't matter)</param> /// <returns>Whether inputs batch mask</returns> public bool CheckInputMask(string mask) { UiControls.Assert(InputNames.Length == mask.Length && mask.All(z => z == '0' || z == '1' || z == '-'), "Invalid quick calc check string."); for (int i = 0; i < InputNames.Length; i++) { char c = mask[i]; switch (c) { case '0': if (InputNames[i] != null) { return(false); } break; case '1': if (InputNames[i] == null) { return(false); } break; case '-': default: break; } } return(true); }
/// <summary> /// I wrote this when the program crashed after an hour. /// Intermediate results can now be saved to avoid losing data. /// </summary> private static ResultClusterer TryLoadIntermediateResult(Core core, Guid guid, int value, int repetition, ProgressReporter proggy) { string fileName = UiControls.GetTemporaryFile("." + value + "." + repetition + ".intermediate.dat", guid); if (!File.Exists(fileName)) { return(null); } LookupByGuidSerialiser guidS = core.GetLookups(); proggy.Enter("Loading saved results"); ResultClusterer result; try { result = XmlSettings.LoadOrDefault <ResultClusterer>(new FileDescriptor(fileName, SerialisationFormat.MSerialiserFastBinary), null, guidS, proggy); } catch { proggy.Leave(); // Result will probably be NULL rather than throwing an exception return(null); } UiControls.Assert(!guidS.HasLookupTableChanged, "Didn't expect the GUID lookup table to change when loading data."); proggy.Leave(); return(result); }
public override double QuickCalculate(IReadOnlyList <double> a, IReadOnlyList <double> b, object[] args) { UiControls.Assert(SupportsQuickCalculate, "Quick calculate called on a non quick-calculate script."); object[] inputs = { a, b, null, null, null, null, null, null, null, null }; return(Arr.Instance.RunScriptDouble(_script, inputs, args)); }
/// <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)); }
public ClustererScript(string script, string id, string name, string fileName) : base(id, name) { this._script = new RScript(script, INPUT_TABLE, fileName); UiControls.Assert(_script.IsInputPresent(0) || _script.IsInputPresent(1), "ClustererScript must take at least one of value matrix or distance matrix"); _usesDistanceMatrix = this._script.CheckInputMask("01"); Comment = "Clusters based on an R script."; }
/// <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); }
internal static ArgsClusterer Show(Form owner, Core core, ArgsClusterer def, bool readOnly, bool hideOptimise) { using (FrmEditConfigurationCluster frm = new FrmEditConfigurationCluster(core, def, readOnly, hideOptimise)) { if (UiControls.ShowWithDim(owner, frm) == DialogResult.OK) { UiControls.Assert(!readOnly, "Didn't expect an OK result from a readonly dialogue."); return(frm.GetSelection()); } return(null); } }
private void EndWait() { this._waitCounter--; UiControls.Assert(this._waitCounter >= 0, "EndWait called when no wait preceded."); if (this._waitCounter == 0) { this.toolStripStatusLabel2.Visible = false; this.UseWaitCursor = false; this._statusMain.BackColor = this.BackColor; this.toolStripProgressBar1.Visible = false; } }
protected override object InterpretArgs(object[] args) { int medianWindow = (int)args[0]; int medianRadius = (medianWindow - 1) / 2; if (medianRadius != 0) { UiControls.Assert((medianRadius * 2) == (medianWindow - 1), "Moving average window must be an odd number."); } return(medianRadius); }
void _listView_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) { if (this._suspendVirtual) { e.Item = new ListViewItem(new string[this._listView.Columns.Count]); return; } object tag = this._filteredList[e.ItemIndex]; e.Item = this.CreateNewListViewItem(tag); this.DoUpdate(e.Item, tag); UiControls.Assert(e.Item.SubItems.Count == this._listView.Columns.Count, "ListViewItem doesn't have the expected number of subitems."); }
/// <summary> /// /// </summary> private int FindMatch(List <List <Assignment> > uniqueCombinations, List <Assignment> pats) { for (int index = 0; index < uniqueCombinations.Count; index++) { var list = uniqueCombinations[index]; UiControls.Assert(list.Count == pats.Count, "FindMatch requires the lists to be of equal length."); if (IsEqual(pats, list)) { return(index); } } return(-1); }
/// <summary> /// Shows the form. /// </summary> /// <param name="autoSave">Controls whether to apply to core.DefaultStatistics</param> internal static ObsFilter.Condition Show(Form owner, Core core, ObsFilter.Condition defaults, bool readOnly) { using (FrmEditObsFilterCondition frm = new FrmEditObsFilterCondition(owner, core, defaults, readOnly)) { if (UiControls.ShowWithDim(owner, frm) == DialogResult.OK) { var r = frm.GetSelection(); UiControls.Assert(r != null, "Expected selection to be present if dialogue returned OK."); return(r); } return(null); } }
/// <summary> /// Shows the PeakFlag editor /// </summary> public static bool Show(Form owner, UserFlag flag, bool readOnly) { UiControls.Assert(flag != null, "flag must not be null"); using (FrmEditUserFlag frm = new FrmEditUserFlag(flag, readOnly)) { if (UiControls.ShowWithDim(owner, frm) == DialogResult.OK) { frm._binder1.Commit(); flag.Comment = frm._comment; return(true); } return(false); } }
/// <summary> /// Shows the form. /// </summary> /// <param name="autoSave">Controls whether to apply to core.DefaultStatistics</param> internal static PeakFilter.Condition Show(Form owner, Core core, PeakFilter.Condition defaults, bool readOnly) { using (FrmEditPeakFilterCondition frm = new FrmEditPeakFilterCondition(owner, core, defaults, readOnly)) { if (UiControls.ShowWithDim(owner, frm) == DialogResult.OK) { string err; var r = frm.GetSelection(out err); UiControls.Assert(r != null, err); return(r); } return(null); } }
/// <summary> /// /// </summary> private static bool IsEqual(List <Assignment> pats, List <Assignment> list) { for (int index = 0; index < pats.Count; index++) { Assignment v = pats[index]; Assignment t = list[index]; UiControls.Assert(v.Vector.Group == t.Vector.Group, "IsEqual expects the vector groups to match."); if (t.Cluster != v.Cluster) { return(false); } } return(true); }
/// <summary> /// (Private) Applies the inputs of an RScript object. /// </summary> private void ApplyInputs(RScript script, object[] inputs) { UiControls.Assert(inputs.Length == script.InputNames.Length, "Number of inputs requested by script must match number of inputs provided."); for (int i = 0; i < inputs.Length; i++) { string name = script.InputNames[i]; if (name != null) { var obj = inputs[i]; SymbolicExpression sym; if (obj is double[, ]) { sym = _r.CreateNumericMatrix((double[, ])obj); } else if (obj is IReadOnlyList <double> ) { sym = _r.CreateNumericVector((IReadOnlyList <double>)obj); } else if (obj is IEnumerable <double> ) { sym = _r.CreateNumericVector((IEnumerable <double>)obj); } else if (obj is int[]) { sym = _r.CreateIntegerVector((int[])obj); } else if (obj is int[, ]) { sym = _r.CreateIntegerMatrix((int[, ])obj); } else if (obj is IEnumerable <int> ) { sym = _r.CreateIntegerVector((IEnumerable <int>)obj); } else { throw new InvalidOperationException("Cannot create R object for obj: " + obj); } _r.SetSymbol(name, sym); } } }
/// <summary> /// Returns the minimum ([v] = -1) or maximum ([v] = 1) of vars. /// </summary> private static T GenericMax <T>(IEnumerable <T> vars, int v) where T : IComparable { bool assigned = false; T result = default(T); foreach (T var in vars) { if (!assigned || var.CompareTo(result) == v) { assigned = true; result = var; } } UiControls.Assert(assigned, "Maths.GenericMax: Expects at least one value."); return(result); }
/// <summary> /// /// </summary> private static Assignment GetMostDistantAssignment(IEnumerable <Cluster> clusters) { Assignment furthest = null; foreach (Cluster cluster in clusters) { foreach (var assignment in cluster.Assignments.List) { if (furthest == null || assignment.Score > furthest.Score) { furthest = assignment; } } } UiControls.Assert(furthest != null, "GetMostDistant: Failed to find furthest assignment."); return(furthest); }
/// <summary> /// (Private) Applies the arguments of an RScript object. /// </summary> private void ApplyArgs(RScript script, object[] args) { args = args ?? new object[0]; // Todo: Necessary for legacy only UiControls.Assert((args.Length != 0) == script.RequiredParameters.HasCustomisableParams, "No arguments provided when algorithm has customisable parameters, or arguments provided when the algorithm has no customisable parameters."); if (script.RequiredParameters.HasCustomisableParams) { var req = script.RequiredParameters; UiControls.Assert(req.Count == args.Length, "Argument count passed in doesn't match the count expected by the script"); for (int i = 0; i < req.Count; i++) { var p = req[i]; object v = args[i]; p.Type.SetSymbol(_r, p.Name, v); } } }
/// <summary> /// Returns the absolute minimum ([v] = -1) or maximum ([v] = 1) of vars. /// </summary> private static double AbsMax(IEnumerable <double> vars, int v) { bool assigned = false; double absResult = 0; double result = 0; foreach (double val in vars) { double absVal = Math.Abs(val); if (!assigned || absVal.CompareTo(absResult) == v) { assigned = true; absResult = absVal; result = val; } } UiControls.Assert(assigned, "Maths.GenericMax: Expects at least one value."); return(result); }
/// <summary> /// Calculate the median of matrix "S". /// Exclude the diagonal from the calculation. /// </summary> private static double ApMedian(double[,] s) { // Flatten the matrix and remove the diagnonal double[] flat = new double[s.Length - s.GetLength(0)]; int k = 0; for (int i = 0; i < s.GetLength(0); i++) { for (int j = 0; j < s.GetLength(1); j++) { if (i != j) { flat[k] = s[i, j]; k++; } } } UiControls.Assert(k == flat.Length, "ApMedian count mismatch. Maybe the matrix wasn't square."); return(Maths.Median(flat)); }
/// <summary> /// My interpretation of the local clustering distance metric as detailed by Qian et al. /// /// Jiang Qian, Marisa Dolled-Filhart, Jimmy Lin, Haiyuan Yu, and Mark Gerstein. /// Beyond synexpression relationships: local clustering of time-shifted and inverted /// gene expression profiles identifies new, biologically relevant interactions. Journal of /// molecular biology, 314(5):1053–1066, 2001. /// </summary> public static double Qian(double[] X, double[] y) { UiControls.Assert(X.Length == y.Length, "Qian metric, X and Y lengths differ"); X = Normalise(X); y = Normalise(y); int c = X.Length; // Score matrix M // Mij = Xi * Yj double[,] M = new double[c, c]; for (int i = 0; i < c; i++) { for (int j = 0; j < c; j++) { M[i, j] = X[i] * y[j]; } } // Sum matrices D/E // Eij = max( Mij * Ei-1j-1 , 0) double[,] D = new double[c, c]; double[,] E = new double[c, c]; for (int i = 0; i < c; i++) { for (int j = 0; j < c; j++) { double d; double e; if (i != 0 && j != 0) { d = D[i - 1, j - 1]; e = E[i - 1, j - 1]; } else { d = 0d; e = 0d; } D[i, j] = Math.Max(d - M[i, j], 0d); E[i, j] = Math.Max(e + M[i, j], 0d); } } // Match score s double s = E[0, 0]; for (int i = 0; i < c; i++) { s = Maths.AbsMax(s, E[i, c - 1]); s = Maths.AbsMax(s, E[c - 1, i]); s = Maths.AbsMax(s, D[c - 1, i]); s = Maths.AbsMax(s, D[c - 1, i]); } return(s); }
private void PerformSelectionActions() { // Series are tagged with the variables they represent // When multiple series are selected they all have the same variable so no worries about using the first one Peak peak = this._chart.SelectedItem.SelectedSeries != null ? (Peak)this._chart.SelectedItem.SelectedSeries.Tag : null; // Points are tagged with the observation IntensityInfo dataPoint; if (this._chart.SelectedItem.DataPoint != null) { if (this._chart.SelectedItem.DataPoint.Tag is IntensityInfo) { dataPoint = (IntensityInfo)this._chart.SelectedItem.DataPoint.Tag; } else if (this._chart.SelectedItem.DataPoint.Tag is IntensityInfo[]) { IntensityInfo[] dataPointArray = (IntensityInfo[])this._chart.SelectedItem.DataPoint.Tag; dataPoint = dataPointArray != null ? dataPointArray[this._chart.SelectedItem.YIndex] : default(IntensityInfo); } else { UiControls.Assert(false, "Unexpected data point format."); dataPoint = null; } } else { // Clear selection dataPoint = null; } if (this.SelectionChanged != null) { string name; if (this._chart.SelectedItem.Series.Length != 0) { // Select the first series names as all series are usually similar name = this._chart.SelectedItem.Series[0].Name; // Trim off everything after the | as this is just used so the chart doesn't complain if (name.Contains("|")) { name = name.Substring(0, name.LastIndexOf('|')).Trim(); } } else { name = null; } ChartSelectionEventArgs e = new ChartSelectionEventArgs(peak, dataPoint, name); this.SelectionChanged(this, e); } // Update text if (this._mnuSelectedPeak != null) { if (peak != null && this._chkShowPeak.Checked) { this._mnuSelectedPeak.Text = peak.DisplayName; this._mnuSelectedPeak.Image = UiControls.GetImage(((Visualisable)peak).Icon, true); this._mnuSelectedPeak.Visible = true; } else { this._mnuSelectedPeak.Visible = false; } if (dataPoint != null) { if (dataPoint.Rep.HasValue && this._chkShowReplicate.Checked) { this._mnuSelectedReplicate.Text = dataPoint.Rep.Value.ToString(); this._mnuSelectedReplicate.Visible = true; } else { this._mnuSelectedReplicate.Visible = false; } if (dataPoint.Time.HasValue && this._chkShowTime.Checked) { this._mnuSelectedTime.Text = dataPoint.Time.Value.ToString(); this._mnuSelectedTime.Visible = true; } else { this._mnuSelectedTime.Visible = false; } if (this._chkShowIntensity.Checked) { this._mnuSelectedIntensity.Text = dataPoint.Intensity.ToString(); this._mnuSelectedIntensity.Visible = true; } else { this._mnuSelectedIntensity.Visible = false; } if (dataPoint.Group != null && this._chkShowGroup.Checked) { this._mnuSelectedGroup.Text = dataPoint.Group.DisplayName; this._mnuSelectedGroup.Image = UiControls.CreateExperimentalGroupImage(true, dataPoint.Group, false); this._mnuSelectedGroup.Visible = true; } else { this._mnuSelectedGroup.Visible = false; } if (this._chkShowSeries.Checked && this._chart.SelectedItem.Series.Length != 0) { this._mnuSelectedSeries.Text = this._chart.SelectedItem.Series[0].Name; this._mnuSelectedSeries.Image = this._chart.SelectedItem.Series[0].DrawLegendKey(this._menuBar.ImageScalingSize.Width, this._menuBar.ImageScalingSize.Height); this._mnuSelectedSeries.Visible = true; } else { this._mnuSelectedSeries.Visible = false; } } else { this._mnuSelectedReplicate.Visible = false; this._mnuSelectedTime.Visible = false; this._mnuSelectedIntensity.Visible = false; this._mnuSelectedSeries.Visible = false; this._mnuSelectedGroup.Visible = false; } } // Perform derived-class-specific actions this.OnSelection(peak, dataPoint); }
/// <summary> /// Actual test running /// </summary> private static ClusterEvaluationPointer RunTest(Core core, ClusterEvaluationPointer origPointer, ClusterEvaluationConfiguration test, ProgressReporter proggy, bool paranoid, int index, int of) { UiControls.Assert(core.FileNames.Session != null, "Didn't expect the session filename to be null for cluster evaluation."); List <ClusterEvaluationParameterResult> results = new List <ClusterEvaluationParameterResult>(); // Iterate over parameters for (int valueIndex = 0; valueIndex < test.ParameterValues.Length; valueIndex++) { object value = test.ParameterValues[valueIndex]; List <ResultClusterer> repetitions = new List <ResultClusterer>(); // Iterate over repetitions for (int repetition = 0; repetition < test.NumberOfRepeats; repetition++) { proggy.Enter("Test " + index + "/" + of + ", parameter " + valueIndex + "/" + test.ParameterValues.Length + ", repetition " + repetition + "/" + test.NumberOfRepeats); // Create config string newName = AlgoParameterCollection.ParamToString(value) + " " + StringHelper.Circle(repetition + 1); object[] copyOfParameters = test.ClustererConfiguration.Parameters.ToArray(); copyOfParameters[test.ParameterIndex] = value; ArgsClusterer copyOfArgs = new ArgsClusterer( test.ClustererConfiguration.Id, test.ClustererConfiguration.SourceProvider, test.ClustererConfiguration.PeakFilter, test.ClustererConfiguration.Distance, test.ClustererConfiguration.ObsFilter, test.ClustererConfiguration.SplitGroups, test.ClustererConfiguration.Statistics, copyOfParameters, test.ClustererConfiguration.OverrideShortName) { OverrideDisplayName = newName, Comment = test.ClustererConfiguration.Comment }; var copyOfConfig = new ConfigurationClusterer() { Args = copyOfArgs }; // Try load previus result ResultClusterer result = null; if (paranoid) { result = TryLoadIntermediateResult(core, test.Guid, valueIndex, repetition, proggy); } if (result == null) { // DO CLUSTERING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! proggy.Enter("Clustering"); result = copyOfConfig.Cluster(core, 0, proggy); proggy.Leave(); if (paranoid) { SaveIntermediateResult(core, test.Guid, valueIndex, repetition, result, proggy); } } // Add result repetitions.Add(result); string name = AlgoParameterCollection.ParamToString(value); results.Add(new ClusterEvaluationParameterResult(name, test, valueIndex, repetitions)); proggy.Leave(); } } ClusterEvaluationResults final = new ClusterEvaluationResults(core, test, results); string folder = UiControls.GetOrCreateFixedFolder(UiControls.EInitialFolder.Evaluations); string sessionName = Path.GetFileNameWithoutExtension(core.FileNames.Session); string fileName = core.Options.ClusteringEvaluationResultsFileName; fileName = fileName.Replace("{SESSION}", sessionName); fileName = fileName.Replace("{RESULTS}", folder + "\\"); fileName = UiControls.GetNewFile(fileName); return(SaveResults(core, fileName, origPointer, final, proggy)); }
/// <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); } }