/// <summary> /// Copies from another instance. /// </summary> /// <param name="obj">The object to copy from.</param> /// <returns><c>True</c> if anything could be copied from the object, otherwise <c>false</c>.</returns> public bool CopyFrom(object obj) { if (object.ReferenceEquals(this, obj)) { return(true); } var from = obj as ConvertXYVToMatrixDataSource; if (null != from) { using (var token = SuspendGetToken()) { ConvertXYVToMatrixOptions dataSourceOptions = null; DataTableMultipleColumnProxy inputData = null; IDataSourceImportOptions importOptions = null; CopyHelper.Copy(ref importOptions, from._importOptions); CopyHelper.Copy(ref dataSourceOptions, from._processOptions); CopyHelper.Copy(ref inputData, from._processData); DataSourceOptions = dataSourceOptions; ImportOptions = importOptions; InputData = inputData; return(true); } } return(false); }
public static void ShowActionDialog(this DataTable srcTable, IAscendingIntegerCollection selectedDataColumns) { DataTableMultipleColumnProxy proxy = null; ConvertXYVToMatrixOptions options = null; try { proxy = new DataTableMultipleColumnProxy(ConvertXYVToMatrixDataAndOptions.ColumnV, srcTable, null, selectedDataColumns); proxy.EnsureExistenceOfIdentifier(ConvertXYVToMatrixDataAndOptions.ColumnX, 1); proxy.EnsureExistenceOfIdentifier(ConvertXYVToMatrixDataAndOptions.ColumnY, 1); options = new ConvertXYVToMatrixOptions(); } catch (Exception ex) { Current.Gui.ErrorMessageBox(string.Format("{0}\r\nDetails:\r\n{1}", ex.Message, ex.ToString()), "Error in preparation of 'Convert X-Y-V values to matrix'"); return; } var dataAndOptions = new ConvertXYVToMatrixDataAndOptions(proxy, options); // in order to show the column names etc in the dialog, it is neccessary to set the source if (true == Current.Gui.ShowDialog(ref dataAndOptions, "Choose options", false)) { var destTable = new DataTable(); proxy = dataAndOptions.Data; options = dataAndOptions.Options; string error = null; try { error = ConvertXYVToMatrix(dataAndOptions.Data, dataAndOptions.Options, destTable); } catch (Exception ex) { error = ex.ToString(); } if (null != error) { Current.Gui.ErrorMessageBox(error); } destTable.Name = srcTable.Name + "_Decomposed"; // Create a DataSource var dataSource = new ConvertXYVToMatrixDataSource(proxy, options, new Altaxo.Data.DataSourceImportOptions()); destTable.DataSource = dataSource; Current.Project.DataTableCollection.Add(destTable); Current.IProjectService.ShowDocumentView(destTable); } }
/// <summary> /// Initializes a new instance of the <see cref="ConvertXYVToMatrixDataSource"/> class. /// </summary> /// <param name="inputData">The input data designates the original source of data (used then for the processing).</param> /// <param name="dataSourceOptions">The Fourier transformation options.</param> /// <param name="importOptions">The data source import options.</param> /// <exception cref="System.ArgumentNullException"> /// inputData /// or /// transformationOptions /// or /// importOptions /// </exception> public ConvertXYVToMatrixDataSource(DataTableMultipleColumnProxy inputData, ConvertXYVToMatrixOptions dataSourceOptions, IDataSourceImportOptions importOptions) { if (null == inputData) { throw new ArgumentNullException(nameof(inputData)); } if (null == dataSourceOptions) { throw new ArgumentNullException(nameof(dataSourceOptions)); } if (null == importOptions) { throw new ArgumentNullException(nameof(importOptions)); } using (var token = SuspendGetToken()) { DataSourceOptions = dataSourceOptions; ImportOptions = importOptions; InputData = inputData; } }
public ConvertXYVToMatrixDataAndOptions(DataTableMultipleColumnProxy data, ConvertXYVToMatrixOptions options) { Data = data; Options = options; }
public ConvertXYVToMatrixOptions(ConvertXYVToMatrixOptions from) { CopyFrom(from); }
/// <summary> /// Creates a matrix from three selected columns. This must be a x-column, a y-column, and a value column. /// </summary> /// <param name="ctrl">Controller where the columns are selected in.</param> /// <returns>Null if no error occurs, or an error message.</returns> public static string DoMakeActionWithoutDialog(this DataTable srcTable, IAscendingIntegerCollection selectedDataColumns) { DataColumn xcol = null, ycol = null, vcol = null; // for this command to work, there must be exactly 3 data columns selected int nCols = selectedDataColumns.Count; if (nCols >= 3) { for (int i = 0; i < nCols; i++) { if (srcTable.DataColumns.GetColumnKind(selectedDataColumns[i]) == ColumnKind.Y) { ycol = srcTable.DataColumns[selectedDataColumns[i]]; break; } } for (int i = 0; i < nCols; i++) { if (srcTable.DataColumns.GetColumnKind(selectedDataColumns[i]) == ColumnKind.X) { xcol = srcTable.DataColumns[selectedDataColumns[i]]; break; } } if (xcol == null || ycol == null) { return("The selected columns must be a x-column, a y-column, and one or more value columns"); } } else { return("You must select exactly a x-column, a y-column, and one or more value column"); } // use the last column that is a value column as v // and use the first column that is an x column as x for (int i = 0; i < nCols; i++) { vcol = srcTable.DataColumns[selectedDataColumns[i]]; if (object.ReferenceEquals(vcol, xcol) || object.ReferenceEquals(vcol, ycol)) { continue; } var proxy = new DataTableMultipleColumnProxy(srcTable, srcTable.DataColumns.GetColumnGroup(vcol)); proxy.EnsureExistenceOfIdentifier(ConvertXYVToMatrixDataAndOptions.ColumnX, 1); proxy.EnsureExistenceOfIdentifier(ConvertXYVToMatrixDataAndOptions.ColumnY, 1); proxy.EnsureExistenceOfIdentifier(ConvertXYVToMatrixDataAndOptions.ColumnV, 1); proxy.AddDataColumn(ConvertXYVToMatrixDataAndOptions.ColumnX, xcol); proxy.AddDataColumn(ConvertXYVToMatrixDataAndOptions.ColumnY, ycol); proxy.AddDataColumn(ConvertXYVToMatrixDataAndOptions.ColumnV, vcol); var newtablename = Current.Project.DataTableCollection.FindNewItemName(srcTable.Name + "-" + vcol.Name); var newTable = new DataTable(newtablename); Current.Project.DataTableCollection.Add(newTable); var options = new ConvertXYVToMatrixOptions(); ConvertXYVToMatrix(proxy, options, newTable); var dataSource = new ConvertXYVToMatrixDataSource(proxy, options, new Altaxo.Data.DataSourceImportOptions()); newTable.DataSource = dataSource; Current.IProjectService.ShowDocumentView(newTable); } return(null); }
/// <summary> /// Decompose the source columns according to the provided options. The source table and the settings are provided in the <paramref name="options"/> variable. /// The provided destination table is cleared from all data and property values before. /// </summary> /// <param name="inputData">The data containing the source table, the participating columns and the column with the cycling variable.</param> /// <param name="options">The settings for decomposing.</param> /// <param name="destTable">The destination table. Any data will be removed before filling with the new data.</param> /// <returns>Null if the method finishes successfully, or an error information.</returns> public static string ConvertXYVToMatrix(DataTableMultipleColumnProxy inputData, ConvertXYVToMatrixOptions options, DataTable destTable) { var srcTable = inputData.DataTable; try { ConvertXYVToMatrixDataAndOptions.EnsureCoherence(inputData, true); } catch (Exception ex) { return(ex.Message); } destTable.DataColumns.RemoveColumnsAll(); destTable.PropCols.RemoveColumnsAll(); DataColumn srcXCol = inputData.GetDataColumnOrNull(ConvertXYVToMatrixDataAndOptions.ColumnX); DataColumn srcYCol = inputData.GetDataColumnOrNull(ConvertXYVToMatrixDataAndOptions.ColumnY); // X-Values IReadOnlyList <AltaxoVariant> clusterValuesX; IReadOnlyList <int> clusterIndicesX; IReadOnlyList <double> clusterStdDevX = null; if (options.UseClusteringForX && options.NumberOfClustersX.HasValue && srcXCol is DoubleColumn srcXDbl) { (clusterValuesX, clusterStdDevX, clusterIndicesX) = ClusterValuesByKMeans(srcXDbl, options.NumberOfClustersX.Value, options.DestinationXColumnSorting, options.CreateStdDevX); } else { (clusterValuesX, clusterIndicesX) = ClusterValuesByEquality(srcXCol, options.DestinationXColumnSorting); } // Y-Values IReadOnlyList <AltaxoVariant> clusterValuesY; IReadOnlyList <int> clusterIndicesY; IReadOnlyList <double> clusterStdDevY = null; if (options.UseClusteringForY && options.NumberOfClustersY.HasValue && srcYCol is DoubleColumn srcYDbl) { (clusterValuesY, clusterStdDevY, clusterIndicesY) = ClusterValuesByKMeans(srcYDbl, options.NumberOfClustersY.Value, options.DestinationYColumnSorting, options.CreateStdDevY); } else { (clusterValuesY, clusterIndicesY) = ClusterValuesByEquality(srcYCol, options.DestinationYColumnSorting); } // get the other columns to process var srcColumnsToProcess = new List <DataColumn>(inputData.GetDataColumns(ConvertXYVToMatrixDataAndOptions.ColumnV)); // subtract the column containing the decompose values srcColumnsToProcess.Remove(srcXCol); srcColumnsToProcess.Remove(srcYCol); int xOffset = 1 + (clusterStdDevY != null ? 1 : 0); // the only property column that is now useful is that with the repeated values var destXCol = destTable.PropCols.EnsureExistence(srcTable.DataColumns.GetColumnName(srcXCol), srcXCol.GetType(), ColumnKind.X, 0); for (int i = 0; i < xOffset; ++i) { destXCol[0] = double.NaN; } for (int i = 0; i < clusterValuesX.Count; ++i) { destXCol[i + xOffset] = clusterValuesX[i]; // leave index 0 and maybe 1for the y-column } if (clusterStdDevX != null) { var stdXCol = destTable.PropCols.EnsureExistence(srcTable.DataColumns.GetColumnName(srcXCol) + "_StdDev", srcXCol.GetType(), ColumnKind.Err, 0); for (int i = 0; i < xOffset; ++i) { stdXCol[0] = double.NaN; } for (int i = 0; i < clusterStdDevX.Count; ++i) { stdXCol[i + xOffset] = clusterStdDevX[i]; // leave index 0 and maybe 1 for the y-column } } var destYCol = destTable.DataColumns.EnsureExistence(srcTable.DataColumns.GetColumnName(srcYCol), srcYCol.GetType(), ColumnKind.X, 0); for (int i = 0; i < clusterValuesY.Count; ++i) { destYCol[i] = clusterValuesY[i]; // leave index 0 for the y-column } if (clusterStdDevY != null) { var stdYCol = destTable.DataColumns.EnsureExistence(srcTable.DataColumns.GetColumnName(srcYCol) + "_StdDev", srcYCol.GetType(), ColumnKind.Err, 0); for (int i = 0; i < clusterStdDevY.Count; ++i) { stdYCol[i] = clusterStdDevY[i]; // leave index 0 for the y-column } } var srcVColumn = srcColumnsToProcess[0]; // Create as many columns as there are values in the destXColumn for (int i = 0; i < clusterValuesX.Count; ++i) { if (options.ColumnNaming == ConvertXYVToMatrixOptions.OutputNaming.ColAndIndex || string.IsNullOrEmpty(options.ColumnNameFormatString)) { destTable.DataColumns.EnsureExistence("Col" + i.ToString(), srcVColumn.GetType(), ColumnKind.V, 0); } else { destTable.DataColumns.EnsureExistence(string.Format(options.ColumnNameFormatString, clusterValuesX[i], i), srcVColumn.GetType(), ColumnKind.V, 0); } } var dict = new Dictionary <(int iX, int iY), (AltaxoVariant sum, int count)>(); for (int i = 0; i < srcVColumn.Count; ++i) { var iX = xOffset + clusterIndicesX[i]; var iY = clusterIndicesY[i]; if (destTable[iX].IsElementEmpty(iY)) { destTable[iX][iY] = srcVColumn[i]; } else { switch (options.ValueAveraging) { case ConvertXYVToMatrixOptions.OutputAveraging.NoneIgnoreUseLastValue: destTable[iX][iY] = srcVColumn[i]; break; case ConvertXYVToMatrixOptions.OutputAveraging.NoneThrowException: throw new Exception(string.Format("Multiple data present for X={0}, Y={1}, and average options has been set to throw an exception in this case!", srcXCol[i], srcYCol[i])); case ConvertXYVToMatrixOptions.OutputAveraging.AverageLinear: { if (!dict.ContainsKey((iX, iY))) { dict.Add((iX, iY), (srcVColumn[i], 1)); // if not found in the dictionary, then add the first value that was already in the table } var(sum, count) = dict[(iX, iY)];