/// <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 ExpandCyclingVariableColumnDataSource; if (null != from) { using (var token = SuspendGetToken()) { ExpandCyclingVariableColumnOptions 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); ExpandCyclingVariableColumnOptions = dataSourceOptions; ImportOptions = importOptions; InputData = inputData; return(true); } } return(false); }
public static void ShowExpandCyclingVariableColumnDialog(this DataTable srcTable, IAscendingIntegerCollection selectedDataRows, IAscendingIntegerCollection selectedDataColumns) { DataTableMultipleColumnProxy proxy = null; ExpandCyclingVariableColumnOptions options = null; try { proxy = new DataTableMultipleColumnProxy(ExpandCyclingVariableColumnDataAndOptions.ColumnsParticipatingIdentifier, srcTable, selectedDataRows, selectedDataColumns); proxy.EnsureExistenceOfIdentifier(ExpandCyclingVariableColumnDataAndOptions.ColumnWithCyclingVariableIdentifier, 1); proxy.EnsureExistenceOfIdentifier(ExpandCyclingVariableColumnDataAndOptions.ColumnsToAverageIdentifier); options = new ExpandCyclingVariableColumnOptions(); } catch (Exception ex) { Current.Gui.ErrorMessageBox(string.Format("{0}\r\nDetails:\r\n{1}", ex.Message, ex.ToString()), "Error in preparation of 'Expand Cycling Variable'"); return; } var dataAndOptions = new ExpandCyclingVariableColumnDataAndOptions(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 = ExpandCyclingVariableColumn(dataAndOptions.Data, dataAndOptions.Options, destTable); } catch (Exception ex) { error = ex.ToString(); } if (null != error) { Current.Gui.ErrorMessageBox(error); } destTable.Name = srcTable.Name + "_Expanded"; // Create a DataSource var dataSource = new ExpandCyclingVariableColumnDataSource(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="ExpandCyclingVariableColumnDataSource"/> 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 ExpandCyclingVariableColumnDataSource(DataTableMultipleColumnProxy inputData, ExpandCyclingVariableColumnOptions dataSourceOptions, IDataSourceImportOptions importOptions) { if (null == inputData) { throw new ArgumentNullException("inputData"); } if (null == dataSourceOptions) { throw new ArgumentNullException("dataSourceOptions"); } if (null == importOptions) { throw new ArgumentNullException("importOptions"); } using (var token = SuspendGetToken()) { ExpandCyclingVariableColumnOptions = dataSourceOptions; ImportOptions = importOptions; InputData = inputData; } }
public ExpandCyclingVariableColumnOptions(ExpandCyclingVariableColumnOptions from) { CopyFrom(from); }
public ExpandCyclingVariableColumnDataAndOptions(DataTableMultipleColumnProxy data, ExpandCyclingVariableColumnOptions options) { Data = data; Options = options; }
/// <summary> /// Average the columns to average for each repetition period. /// </summary> /// <param name="srcTable">Source table of the ExpandCyclingVariableColumn action</param> /// <param name="columnsToAverageOverRepeatPeriod">The columns for which the data should be averaged over one repeat period.</param> /// <param name="options">Options containing the column numbers of the columns to average.</param> /// <param name="repeatRanges">Designates the start and the end of each repetition period.</param> /// <returns>Array of data columns which contain the averaged columns. Inside a column the row index designates the index of the range.</returns> private static DataColumn[] AverageColumns(DataTable srcTable, IEnumerable<DataColumn> columnsToAverageOverRepeatPeriod, ExpandCyclingVariableColumnOptions options, IList<ContiguousIntegerRange> repeatRanges) { // make the averaged property columns var propColsTemp = new DataColumn[columnsToAverageOverRepeatPeriod.Count()]; int nDestCol = -1; foreach (var srcCol in columnsToAverageOverRepeatPeriod) { nDestCol++; var destCol = (DataColumn)srcCol.Clone(); destCol.Clear(); var statistic = new Altaxo.Calc.Regression.QuickStatistics(); int nDestRow = -1; foreach (var range in repeatRanges) { ++nDestRow; foreach (var idx in range) statistic.Add(srcCol[idx] - srcCol[range.Start]); destCol[nDestRow] = statistic.Mean + srcCol[range.Start]; // Trick: we store the averaged values temporarily in index 0 of the property column } propColsTemp[nDestCol] = destCol; } return propColsTemp; }
/// <summary> /// Creates a property column for each averaged column of the source table. /// </summary> /// <param name="srcTable">Source table of the ExpandCyclingVariableColumn action</param> /// <param name="columnsToAverageOverRepeatPeriod">The columns for which the data should be averaged over one repeat period.</param> /// <param name="options">Options containing the column numbers of the columns to average.</param> /// <param name="destTable">Destination table where to create the property columns.</param> /// <returns>Indices of the newly created property columns. The indices have the same order as the columns to average.</returns> private static int[] CreatePropColsForAveragedColumns(DataTable srcTable, IEnumerable<DataColumn> columnsToAverageOverRepeatPeriod, ExpandCyclingVariableColumnOptions options, DataTable destTable) { var propColsIdx = new int[columnsToAverageOverRepeatPeriod.Count()]; int nDestCol = -1; foreach (var srcCol in columnsToAverageOverRepeatPeriod) { ++nDestCol; var destCol = destTable.PropCols.EnsureExistence(srcTable.DataColumns.GetColumnName(srcCol), srcCol.GetType(), srcTable.DataColumns.GetColumnKind(srcCol), srcTable.DataColumns.GetColumnGroup(srcCol)); propColsIdx[nDestCol] = destTable.PropCols.GetColumnNumber(destCol); } return propColsIdx; }
/// <summary> /// Expand 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 expanding.</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 ExpandCyclingVariableColumn(DataTableMultipleColumnProxy inputData, ExpandCyclingVariableColumnOptions options, DataTable destTable) { var srcTable = inputData.DataTable; try { ExpandCyclingVariableColumnDataAndOptions.EnsureCoherence(inputData, true); } catch (Exception ex) { return ex.Message; } destTable.DataColumns.RemoveColumnsAll(); destTable.PropCols.RemoveColumnsAll(); DataColumn srcCycCol = inputData.GetDataColumnOrNull(ExpandCyclingVariableColumnDataAndOptions.ColumnWithCyclingVariableIdentifier); var repeatRanges = DecomposeIntoRepeatUnits(srcCycCol); // check if there is at least one averaged column var columnsToAverageOverRepeatPeriod = inputData.GetDataColumns(ExpandCyclingVariableColumnDataAndOptions.ColumnsToAverageIdentifier); if (options.DestinationX == ExpandCyclingVariableColumnOptions.DestinationXColumn.FirstAveragedColumn && columnsToAverageOverRepeatPeriod.Count == 0) throw new ArgumentException("In order to let the first averaged column being the x-column, a column to average is needed, but the options didn't provide such column!"); // get the other columns to process var srcColumnsToProcess = new List<DataColumn>(inputData.GetDataColumns(ExpandCyclingVariableColumnDataAndOptions.ColumnsParticipatingIdentifier)); // subtract cyclic variable column and average columns srcColumnsToProcess.Remove(srcCycCol); foreach (var col in columnsToAverageOverRepeatPeriod) srcColumnsToProcess.Remove(col); // --- Create and calculate the averaged columns, for now only temporarily --- var propColsTemp = AverageColumns(srcTable, columnsToAverageOverRepeatPeriod, options, repeatRanges); // --- avgValueOrder designates the ordering of the first averaged column and therefore of the sorting of the ranges and of the first averaged column int[] avgValueOrder = Sorting.CreateIdentityIndices(repeatRanges.Count); // --- prepare the sorting of columns by first averaged column --- var rangeOrderSorting = options.DestinationX == ExpandCyclingVariableColumnOptions.DestinationXColumn.CyclingVariable ? options.DestinationColumnSorting : options.DestinationRowSorting; if (propColsTemp.Length > 0 && rangeOrderSorting != ExpandCyclingVariableColumnOptions.OutputSorting.None) { avgValueOrder = Sorting.HeapSortVirtually(propColsTemp[0], avgValueOrder); if (rangeOrderSorting == ExpandCyclingVariableColumnOptions.OutputSorting.Descending) Sorting.ReverseArray(avgValueOrder); } // prepare the sorting of the cycling values var cycValueSorting = options.DestinationX == ExpandCyclingVariableColumnOptions.DestinationXColumn.CyclingVariable ? options.DestinationRowSorting : options.DestinationColumnSorting; // create a dictionary with the cycling values (unique) and the corresponding ordering index var cycValueOrder = GetUniqueValues(srcCycCol, cycValueSorting == ExpandCyclingVariableColumnOptions.OutputSorting.Descending); if (options.DestinationX == ExpandCyclingVariableColumnOptions.DestinationXColumn.CyclingVariable) { int[] propColsIdx = CreatePropColsForAveragedColumns(srcTable, columnsToAverageOverRepeatPeriod, options, destTable); // --- Fill the x column, take the row sorting into account --- var destXCol = destTable.DataColumns.EnsureExistence(srcTable.DataColumns.GetColumnName(srcCycCol), srcCycCol.GetType(), ColumnKind.X, srcTable.DataColumns.GetColumnGroup(srcCycCol)); foreach (var entry in cycValueOrder) destXCol[entry.Value] = entry.Key; if (options.DestinationOutput == ExpandCyclingVariableColumnOptions.OutputFormat.GroupOneColumn) { // foreach sourceColumnToProcess create as many destination columns as there are cycling ranges available foreach (var srcCol in srcColumnsToProcess) { int nCreatedCol = -1; var destColumnsToSort = new AscendingIntegerCollection(); foreach (int rangeIndex in avgValueOrder) { var range = repeatRanges[rangeIndex]; ++nCreatedCol; var destCol = destTable.DataColumns.EnsureExistence(srcTable.DataColumns.GetColumnName(srcCol) + "." + nCreatedCol.ToString(), srcCol.GetType(), srcTable.DataColumns.GetColumnKind(srcCol), srcTable.DataColumns.GetColumnGroup(srcCol)); var nDestCol = destTable.DataColumns.GetColumnNumber(destCol); destColumnsToSort.Add(nDestCol); foreach (var nSrcRow in range) { int nDestRow = cycValueOrder[srcCycCol[nSrcRow]]; destCol[nDestRow] = srcCol[nSrcRow]; } // fill also property columns for (int nPropCol = 0; nPropCol < propColsTemp.Length; nPropCol++) { destTable.PropCols[propColsIdx[nPropCol]][nDestCol] = propColsTemp[nPropCol][rangeIndex]; } } } // repeat for each source colum to process } else if (options.DestinationOutput == ExpandCyclingVariableColumnOptions.OutputFormat.GroupAllColumns) { int nCreatedCol = -1; // running number of processed range for column creation (Naming) foreach (int rangeIndex in avgValueOrder) { var range = repeatRanges[rangeIndex]; ++nCreatedCol; foreach (var srcCol in srcColumnsToProcess) { var destCol = destTable.DataColumns.EnsureExistence(srcTable.DataColumns.GetColumnName(srcCol) + "." + nCreatedCol.ToString(), srcCol.GetType(), srcTable.DataColumns.GetColumnKind(srcCol), srcTable.DataColumns.GetColumnGroup(srcCol)); var nDestCol = destTable.DataColumns.GetColumnNumber(destCol); foreach (var nSrcRow in range) { int nDestRow = cycValueOrder[srcCycCol[nSrcRow]]; destCol[nDestRow] = srcCol[nSrcRow]; } // fill also property columns for (int nPropCol = 0; nPropCol < propColsTemp.Length; nPropCol++) { destTable.PropCols[propColsIdx[nPropCol]][nDestCol] = propColsTemp[nPropCol][rangeIndex]; } } } } else { throw new NotImplementedException("The option for destination output is unknown: " + options.DestinationOutput.ToString()); } } else if (options.DestinationX == ExpandCyclingVariableColumnOptions.DestinationXColumn.FirstAveragedColumn) { // now the first x column contains the values of the averaged column // the rest of the data columns is repeated as many times as there are members in each repeat range DataColumn srcXCol = columnsToAverageOverRepeatPeriod[0]; var destXCol = destTable.DataColumns.EnsureExistence(srcTable.DataColumns.GetColumnName(srcXCol), srcXCol.GetType(), ColumnKind.X, srcTable.DataColumns.GetColumnGroup(srcXCol)); // Fill with destination X for (int nDestRow = 0; nDestRow < repeatRanges.Count; nDestRow++) destXCol[nDestRow] = propColsTemp[0][avgValueOrder[nDestRow]]; // the only property column that is now usefull is that with the repeated values var destPropCol = destTable.PropCols.EnsureExistence(srcTable.DataColumns.GetColumnName(srcCycCol), srcCycCol.GetType(), srcTable.DataColumns.GetColumnKind(srcCycCol), srcTable.DataColumns.GetColumnGroup(srcCycCol)); if (options.DestinationOutput == ExpandCyclingVariableColumnOptions.OutputFormat.GroupOneColumn) { foreach (var srcCol in srcColumnsToProcess) { int nCurrNumber = -1; IEnumerable<AltaxoVariant> cycValues = cycValueOrder.Keys; if (options.DestinationColumnSorting == ExpandCyclingVariableColumnOptions.OutputSorting.Descending) cycValues = cycValueOrder.Keys.Reverse(); foreach (var cycValue in cycValues) { ++nCurrNumber; var destCol = destTable.DataColumns.EnsureExistence(srcTable.DataColumns.GetColumnName(srcCol) + "." + nCurrNumber.ToString(), srcCol.GetType(), srcTable.DataColumns.GetColumnKind(srcCol), srcTable.DataColumns.GetColumnGroup(srcCol)); var nDestCol = destTable.DataColumns.GetColumnNumber(destCol); int nDestRow = -1; foreach (int rangeIndex in avgValueOrder) { var range = repeatRanges[rangeIndex]; ++nDestRow; int nSrcRow = FindSrcXRow(srcCycCol, cycValue, range); if (nSrcRow >= 0) destCol[nDestRow] = srcCol[nSrcRow]; } // fill also property column destPropCol[nDestCol] = cycValue; } } } else if (options.DestinationOutput == ExpandCyclingVariableColumnOptions.OutputFormat.GroupAllColumns) { IEnumerable<AltaxoVariant> positionsKeys = cycValueOrder.Keys; if (options.DestinationColumnSorting == ExpandCyclingVariableColumnOptions.OutputSorting.Descending) positionsKeys = cycValueOrder.Keys.Reverse(); int nCurrNumber = -1; foreach (var xVal in positionsKeys) { ++nCurrNumber; foreach (var srcCol in srcColumnsToProcess) { var destCol = destTable.DataColumns.EnsureExistence(srcTable.DataColumns.GetColumnName(srcCol) + "." + nCurrNumber.ToString(), srcCol.GetType(), srcTable.DataColumns.GetColumnKind(srcCol), srcTable.DataColumns.GetColumnGroup(srcCol)); var nDestCol = destTable.DataColumns.GetColumnNumber(destCol); int nDestRow = -1; foreach (int rangeIndex in avgValueOrder) { var range = repeatRanges[rangeIndex]; ++nDestRow; int nSrcRow = FindSrcXRow(srcCycCol, xVal, range); if (nSrcRow >= 0) destCol[nDestRow] = srcCol[nSrcRow]; } // fill also property column destPropCol[nDestCol] = xVal; } } } else { throw new NotImplementedException("The option for destination output is unknown: " + options.DestinationOutput.ToString()); } } return null; }
public static void ShowExpandCyclingVariableColumnDialog(this DataTable srcTable, IAscendingIntegerCollection selectedDataRows, IAscendingIntegerCollection selectedDataColumns) { DataTableMultipleColumnProxy proxy = null; ExpandCyclingVariableColumnOptions options = null; try { proxy = new DataTableMultipleColumnProxy(ExpandCyclingVariableColumnDataAndOptions.ColumnsParticipatingIdentifier, srcTable, selectedDataRows, selectedDataColumns); proxy.EnsureExistenceOfIdentifier(ExpandCyclingVariableColumnDataAndOptions.ColumnWithCyclingVariableIdentifier, 1); proxy.EnsureExistenceOfIdentifier(ExpandCyclingVariableColumnDataAndOptions.ColumnsToAverageIdentifier); options = new ExpandCyclingVariableColumnOptions(); } catch (Exception ex) { Current.Gui.ErrorMessageBox(string.Format("{0}\r\nDetails:\r\n{1}", ex.Message, ex.ToString()), "Error in preparation of 'Expand Cycling Variable'"); return; } var dataAndOptions = new ExpandCyclingVariableColumnDataAndOptions(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 = ExpandCyclingVariableColumn(dataAndOptions.Data, dataAndOptions.Options, destTable); } catch (Exception ex) { error = ex.ToString(); } if (null != error) Current.Gui.ErrorMessageBox(error); destTable.Name = srcTable.Name + "_Expanded"; // Create a DataSource ExpandCyclingVariableColumnDataSource dataSource = new ExpandCyclingVariableColumnDataSource(proxy, options, new Altaxo.Data.DataSourceImportOptions()); destTable.DataSource = dataSource; Current.Project.DataTableCollection.Add(destTable); Current.ProjectService.ShowDocumentView(destTable); } }
/// <summary> /// Initializes a new instance of the <see cref="ExpandCyclingVariableColumnDataSource"/> 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 ExpandCyclingVariableColumnDataSource(DataTableMultipleColumnProxy inputData, ExpandCyclingVariableColumnOptions dataSourceOptions, IDataSourceImportOptions importOptions) { if (null == inputData) throw new ArgumentNullException("inputData"); if (null == dataSourceOptions) throw new ArgumentNullException("dataSourceOptions"); if (null == importOptions) throw new ArgumentNullException("importOptions"); using (var token = SuspendGetToken()) { this.ExpandCyclingVariableColumnOptions = dataSourceOptions; this.ImportOptions = importOptions; this.InputData = inputData; } }
/// <summary> /// Expand 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 expanding.</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 ExpandCyclingVariableColumn(DataTableMultipleColumnProxy inputData, ExpandCyclingVariableColumnOptions options, DataTable destTable) { var srcTable = inputData.DataTable; try { ExpandCyclingVariableColumnDataAndOptions.EnsureCoherence(inputData, true); } catch (Exception ex) { return(ex.Message); } destTable.DataColumns.RemoveColumnsAll(); destTable.PropCols.RemoveColumnsAll(); DataColumn srcCycCol = inputData.GetDataColumnOrNull(ExpandCyclingVariableColumnDataAndOptions.ColumnWithCyclingVariableIdentifier); var repeatRanges = DecomposeIntoRepeatUnits(srcCycCol); // check if there is at least one averaged column var columnsToAverageOverRepeatPeriod = inputData.GetDataColumns(ExpandCyclingVariableColumnDataAndOptions.ColumnsToAverageIdentifier); if (options.DestinationX == ExpandCyclingVariableColumnOptions.DestinationXColumn.FirstAveragedColumn && columnsToAverageOverRepeatPeriod.Count == 0) { throw new ArgumentException("In order to let the first averaged column being the x-column, a column to average is needed, but the options didn't provide such column!"); } // get the other columns to process var srcColumnsToProcess = new List <DataColumn>(inputData.GetDataColumns(ExpandCyclingVariableColumnDataAndOptions.ColumnsParticipatingIdentifier)); // subtract cyclic variable column and average columns srcColumnsToProcess.Remove(srcCycCol); foreach (var col in columnsToAverageOverRepeatPeriod) { srcColumnsToProcess.Remove(col); } // --- Create and calculate the averaged columns, for now only temporarily --- var propColsTemp = AverageColumns(srcTable, columnsToAverageOverRepeatPeriod, options, repeatRanges); // --- avgValueOrder designates the ordering of the first averaged column and therefore of the sorting of the ranges and of the first averaged column int[] avgValueOrder = Sorting.CreateIdentityIndices(repeatRanges.Count); // --- prepare the sorting of columns by first averaged column --- var rangeOrderSorting = options.DestinationX == ExpandCyclingVariableColumnOptions.DestinationXColumn.CyclingVariable ? options.DestinationColumnSorting : options.DestinationRowSorting; if (propColsTemp.Length > 0 && rangeOrderSorting != ExpandCyclingVariableColumnOptions.OutputSorting.None) { avgValueOrder = Sorting.HeapSortVirtually(propColsTemp[0], avgValueOrder); if (rangeOrderSorting == ExpandCyclingVariableColumnOptions.OutputSorting.Descending) { Sorting.ReverseArray(avgValueOrder); } } // prepare the sorting of the cycling values var cycValueSorting = options.DestinationX == ExpandCyclingVariableColumnOptions.DestinationXColumn.CyclingVariable ? options.DestinationRowSorting : options.DestinationColumnSorting; // create a dictionary with the cycling values (unique) and the corresponding ordering index var cycValueOrder = GetUniqueValues(srcCycCol, cycValueSorting == ExpandCyclingVariableColumnOptions.OutputSorting.Descending); if (options.DestinationX == ExpandCyclingVariableColumnOptions.DestinationXColumn.CyclingVariable) { int[] propColsIdx = CreatePropColsForAveragedColumns(srcTable, columnsToAverageOverRepeatPeriod, options, destTable); // --- Fill the x column, take the row sorting into account --- var destXCol = destTable.DataColumns.EnsureExistence(srcTable.DataColumns.GetColumnName(srcCycCol), srcCycCol.GetType(), ColumnKind.X, srcTable.DataColumns.GetColumnGroup(srcCycCol)); foreach (var entry in cycValueOrder) { destXCol[entry.Value] = entry.Key; } if (options.DestinationOutput == ExpandCyclingVariableColumnOptions.OutputFormat.GroupOneColumn) { // foreach sourceColumnToProcess create as many destination columns as there are cycling ranges available foreach (var srcCol in srcColumnsToProcess) { int nCreatedCol = -1; var destColumnsToSort = new AscendingIntegerCollection(); foreach (int rangeIndex in avgValueOrder) { var range = repeatRanges[rangeIndex]; ++nCreatedCol; var destCol = destTable.DataColumns.EnsureExistence(srcTable.DataColumns.GetColumnName(srcCol) + "." + nCreatedCol.ToString(), srcCol.GetType(), srcTable.DataColumns.GetColumnKind(srcCol), srcTable.DataColumns.GetColumnGroup(srcCol)); var nDestCol = destTable.DataColumns.GetColumnNumber(destCol); destColumnsToSort.Add(nDestCol); foreach (var nSrcRow in range) { int nDestRow = cycValueOrder[srcCycCol[nSrcRow]]; destCol[nDestRow] = srcCol[nSrcRow]; } // fill also property columns for (int nPropCol = 0; nPropCol < propColsTemp.Length; nPropCol++) { destTable.PropCols[propColsIdx[nPropCol]][nDestCol] = propColsTemp[nPropCol][rangeIndex]; } } } // repeat for each source colum to process } else if (options.DestinationOutput == ExpandCyclingVariableColumnOptions.OutputFormat.GroupAllColumns) { int nCreatedCol = -1; // running number of processed range for column creation (Naming) foreach (int rangeIndex in avgValueOrder) { var range = repeatRanges[rangeIndex]; ++nCreatedCol; foreach (var srcCol in srcColumnsToProcess) { var destCol = destTable.DataColumns.EnsureExistence(srcTable.DataColumns.GetColumnName(srcCol) + "." + nCreatedCol.ToString(), srcCol.GetType(), srcTable.DataColumns.GetColumnKind(srcCol), srcTable.DataColumns.GetColumnGroup(srcCol)); var nDestCol = destTable.DataColumns.GetColumnNumber(destCol); foreach (var nSrcRow in range) { int nDestRow = cycValueOrder[srcCycCol[nSrcRow]]; destCol[nDestRow] = srcCol[nSrcRow]; } // fill also property columns for (int nPropCol = 0; nPropCol < propColsTemp.Length; nPropCol++) { destTable.PropCols[propColsIdx[nPropCol]][nDestCol] = propColsTemp[nPropCol][rangeIndex]; } } } } else { throw new NotImplementedException("The option for destination output is unknown: " + options.DestinationOutput.ToString()); } } else if (options.DestinationX == ExpandCyclingVariableColumnOptions.DestinationXColumn.FirstAveragedColumn) { // now the first x column contains the values of the averaged column // the rest of the data columns is repeated as many times as there are members in each repeat range DataColumn srcXCol = columnsToAverageOverRepeatPeriod[0]; var destXCol = destTable.DataColumns.EnsureExistence(srcTable.DataColumns.GetColumnName(srcXCol), srcXCol.GetType(), ColumnKind.X, srcTable.DataColumns.GetColumnGroup(srcXCol)); // Fill with destination X for (int nDestRow = 0; nDestRow < repeatRanges.Count; nDestRow++) { destXCol[nDestRow] = propColsTemp[0][avgValueOrder[nDestRow]]; } // the only property column that is now usefull is that with the repeated values var destPropCol = destTable.PropCols.EnsureExistence(srcTable.DataColumns.GetColumnName(srcCycCol), srcCycCol.GetType(), srcTable.DataColumns.GetColumnKind(srcCycCol), srcTable.DataColumns.GetColumnGroup(srcCycCol)); if (options.DestinationOutput == ExpandCyclingVariableColumnOptions.OutputFormat.GroupOneColumn) { foreach (var srcCol in srcColumnsToProcess) { int nCurrNumber = -1; IEnumerable <AltaxoVariant> cycValues = cycValueOrder.Keys; if (options.DestinationColumnSorting == ExpandCyclingVariableColumnOptions.OutputSorting.Descending) { cycValues = cycValueOrder.Keys.Reverse(); } foreach (var cycValue in cycValues) { ++nCurrNumber; var destCol = destTable.DataColumns.EnsureExistence(srcTable.DataColumns.GetColumnName(srcCol) + "." + nCurrNumber.ToString(), srcCol.GetType(), srcTable.DataColumns.GetColumnKind(srcCol), srcTable.DataColumns.GetColumnGroup(srcCol)); var nDestCol = destTable.DataColumns.GetColumnNumber(destCol); int nDestRow = -1; foreach (int rangeIndex in avgValueOrder) { var range = repeatRanges[rangeIndex]; ++nDestRow; int nSrcRow = FindSrcXRow(srcCycCol, cycValue, range); if (nSrcRow >= 0) { destCol[nDestRow] = srcCol[nSrcRow]; } } // fill also property column destPropCol[nDestCol] = cycValue; } } } else if (options.DestinationOutput == ExpandCyclingVariableColumnOptions.OutputFormat.GroupAllColumns) { IEnumerable <AltaxoVariant> positionsKeys = cycValueOrder.Keys; if (options.DestinationColumnSorting == ExpandCyclingVariableColumnOptions.OutputSorting.Descending) { positionsKeys = cycValueOrder.Keys.Reverse(); } int nCurrNumber = -1; foreach (var xVal in positionsKeys) { ++nCurrNumber; foreach (var srcCol in srcColumnsToProcess) { var destCol = destTable.DataColumns.EnsureExistence(srcTable.DataColumns.GetColumnName(srcCol) + "." + nCurrNumber.ToString(), srcCol.GetType(), srcTable.DataColumns.GetColumnKind(srcCol), srcTable.DataColumns.GetColumnGroup(srcCol)); var nDestCol = destTable.DataColumns.GetColumnNumber(destCol); int nDestRow = -1; foreach (int rangeIndex in avgValueOrder) { var range = repeatRanges[rangeIndex]; ++nDestRow; int nSrcRow = FindSrcXRow(srcCycCol, xVal, range); if (nSrcRow >= 0) { destCol[nDestRow] = srcCol[nSrcRow]; } } // fill also property column destPropCol[nDestCol] = xVal; } } } else { throw new NotImplementedException("The option for destination output is unknown: " + options.DestinationOutput.ToString()); } } return(null); }
/// <summary> /// Average the columns to average for each repetition period. /// </summary> /// <param name="srcTable">Source table of the ExpandCyclingVariableColumn action</param> /// <param name="columnsToAverageOverRepeatPeriod">The columns for which the data should be averaged over one repeat period.</param> /// <param name="options">Options containing the column numbers of the columns to average.</param> /// <param name="repeatRanges">Designates the start and the end of each repetition period.</param> /// <returns>Array of data columns which contain the averaged columns. Inside a column the row index designates the index of the range.</returns> private static DataColumn[] AverageColumns(DataTable srcTable, IEnumerable <DataColumn> columnsToAverageOverRepeatPeriod, ExpandCyclingVariableColumnOptions options, IList <ContiguousIntegerRange> repeatRanges) { // make the averaged property columns var propColsTemp = new DataColumn[columnsToAverageOverRepeatPeriod.Count()]; int nDestCol = -1; foreach (var srcCol in columnsToAverageOverRepeatPeriod) { nDestCol++; var destCol = (DataColumn)srcCol.Clone(); destCol.Clear(); var statistic = new Altaxo.Calc.Regression.QuickStatistics(); int nDestRow = -1; foreach (var range in repeatRanges) { ++nDestRow; foreach (var idx in range) { statistic.Add(srcCol[idx] - srcCol[range.Start]); } destCol[nDestRow] = statistic.Mean + srcCol[range.Start]; // Trick: we store the averaged values temporarily in index 0 of the property column } propColsTemp[nDestCol] = destCol; } return(propColsTemp); }
/// <summary> /// Creates a property column for each averaged column of the source table. /// </summary> /// <param name="srcTable">Source table of the ExpandCyclingVariableColumn action</param> /// <param name="columnsToAverageOverRepeatPeriod">The columns for which the data should be averaged over one repeat period.</param> /// <param name="options">Options containing the column numbers of the columns to average.</param> /// <param name="destTable">Destination table where to create the property columns.</param> /// <returns>Indices of the newly created property columns. The indices have the same order as the columns to average.</returns> private static int[] CreatePropColsForAveragedColumns(DataTable srcTable, IEnumerable <DataColumn> columnsToAverageOverRepeatPeriod, ExpandCyclingVariableColumnOptions options, DataTable destTable) { var propColsIdx = new int[columnsToAverageOverRepeatPeriod.Count()]; int nDestCol = -1; foreach (var srcCol in columnsToAverageOverRepeatPeriod) { ++nDestCol; var destCol = destTable.PropCols.EnsureExistence(srcTable.DataColumns.GetColumnName(srcCol), srcCol.GetType(), srcTable.DataColumns.GetColumnKind(srcCol), srcTable.DataColumns.GetColumnGroup(srcCol)); propColsIdx[nDestCol] = destTable.PropCols.GetColumnNumber(destCol); } return(propColsIdx); }