/// <summary> /// Exports to a single SPC spectrum from a single table column. /// </summary> /// <param name="filename">The name of the file where to export to.</param> /// <param name="table">The table from which to export.</param> /// <param name="columnnumber">The number of the table column that contains the data to export.</param> /// <param name="xcolumn">The x column that contains the x data.</param> /// <param name="selectedRows">The rows that where selected in the table, i.e. the rows which are exported. If this parameter is null /// or no rows are selected, then all data of a column will be exported.</param> /// <returns>Null if export was successfull, error description otherwise.</returns> public static string FromColumn( string filename, Altaxo.Data.DataTable table, int columnnumber, Altaxo.Data.INumericColumn xcolumn, IAscendingIntegerCollection selectedRows) { if (!(table.DataColumns[columnnumber] is Altaxo.Data.INumericColumn)) { return(string.Format("Table column[{0}] ({1}) is not a numeric column!", columnnumber, table.DataColumns[columnnumber].FullName)); } // test that all x and y cells have numeric values bool bUseSel = null != selectedRows && selectedRows.Count > 0; int spectrumlen = (bUseSel)? selectedRows.Count : table.DataColumns[columnnumber].Count; int i, j; for (j = 0; j < spectrumlen; j++) { i = bUseSel ? selectedRows[j] : j; if (xcolumn[i] == Double.NaN) { return(string.Format("X column at index {i} has no numeric value!", i)); } if (((Altaxo.Data.INumericColumn)table.DataColumns[columnnumber])[i] == Double.NaN) { return(string.Format("Table cell [{0},{1}] (column {2}) has no numeric value!", columnnumber, i, table.DataColumns[columnnumber].FullName)); } } // this first test was successfull, so start exporting now double[] xvalues = new double[spectrumlen]; double[] yvalues = new double[spectrumlen]; for (j = 0; j < spectrumlen; j++) { i = bUseSel ? selectedRows[j] : j; xvalues[j] = xcolumn[i]; yvalues[j] = ((Altaxo.Data.INumericColumn)table.DataColumns[columnnumber])[i]; } return(FromArrays(xvalues, yvalues, filename)); }
protected static string TwoDimFFT(Altaxo.AltaxoDocument mainDocument, GUI.WorksheetController dg, out double[] rePart, out double[] imPart) { int rows = dg.Doc.DataColumns.RowCount; int cols = dg.Doc.DataColumns.ColumnCount; // reserve two arrays (one for real part, which is filled with the table contents) // and the imaginary part - which is left zero here) rePart = new double[rows * cols]; imPart = new double[rows * cols]; // fill the real part with the table contents for (int i = 0; i < cols; i++) { Altaxo.Data.INumericColumn col = dg.Doc[i] as Altaxo.Data.INumericColumn; if (null == col) { return(string.Format("Can't apply fourier transform, since column number {0}, name:{1} is not numeric", i, dg.Doc[i].FullName)); } for (int j = 0; j < rows; j++) { rePart[i * rows + j] = col[j]; } } // test it can be done if (!Pfa235FFT.CanFactorized(cols)) { return(string.Format("Can't apply fourier transform, since the number of cols ({0}) are not appropriate for this kind of fourier transform.", cols)); } if (!Pfa235FFT.CanFactorized(rows)) { return(string.Format("Can't apply fourier transform, since the number of rows ({0}) are not appropriate for this kind of fourier transform.", rows)); } // fourier transform Pfa235FFT fft = new Pfa235FFT(cols, rows); fft.FFT(rePart, imPart, FourierDirection.Forward); // replace the real part by the amplitude for (int i = 0; i < rePart.Length; i++) { rePart[i] = Math.Sqrt(rePart[i] * rePart[i] + imPart[i] * imPart[i]); } return(null); }
/// <summary> /// Fits data provided as xcolumn and ycolumn with a polynomial base. /// </summary> /// <param name="order">The order of the fit (1:linear, 2:quadratic, etc.)</param> /// <param name="xcolumn">The column of x-values.</param> /// <param name="ycolumn">The column of y-values.</param> /// <returns>The fit.</returns> public static LinearFitBySvd Fit(int order, Altaxo.Data.DataColumn xcolumn, Altaxo.Data.DataColumn ycolumn) { if (!(xcolumn is Altaxo.Data.INumericColumn)) { throw new ArgumentException("The x-column must be numeric", "xcolumn"); } if (!(ycolumn is Altaxo.Data.INumericColumn)) { throw new ArgumentException("The y-column must be numeric", "ycolumn"); } int firstIndex = 0; int count = Math.Min(xcolumn.Count, ycolumn.Count); double[] xarr = new double[count]; double[] yarr = new double[count]; double[] earr = new double[count]; Altaxo.Data.INumericColumn xcol = (Altaxo.Data.INumericColumn)xcolumn; Altaxo.Data.INumericColumn ycol = (Altaxo.Data.INumericColumn)ycolumn; int numberOfDataPoints = 0; int endIndex = firstIndex + count; for (int i = firstIndex; i < endIndex; i++) { double x = xcol[i]; double y = ycol[i]; if (double.IsNaN(x) || double.IsNaN(y)) { continue; } xarr[numberOfDataPoints] = x; yarr[numberOfDataPoints] = y; earr[numberOfDataPoints] = 1; numberOfDataPoints++; } LinearFitBySvd fit = new LinearFitBySvd( xarr, yarr, earr, numberOfDataPoints, order + 1, new FunctionBaseEvaluator(EvaluatePolynomialBase), 1E-5); return(fit); }
/// <summary> /// Retrieves the data points of the current active plot. /// </summary> /// <param name="ctrl">The graph controller which controls the graph from which the points are to retrieve.</param> /// <param name="xarr">The array of the data point's x values.</param> /// <param name="yarr">The array of the data point's y values.</param> /// <param name="nPlotPoints">The number of plot points (may be smaller than the length of x and y arrays.</param> /// <returns>Null if all is ok, or error message if not.</returns> public static string GetActivePlotPoints(Altaxo.Graph.GUI.GraphController ctrl, ref double[] xarr, ref double[] yarr, out int nPlotPoints) { nPlotPoints = 0; ctrl.EnsureValidityOfCurrentLayerNumber(); ctrl.EnsureValidityOfCurrentPlotNumber(); IGPlotItem plotItem = ctrl.ActiveLayer.PlotItems.Flattened[ctrl.CurrentPlotNumber]; XYColumnPlotItem xyPlotItem = plotItem as XYColumnPlotItem; if (xyPlotItem == null) { return("No active plot!"); } XYColumnPlotData data = xyPlotItem.XYColumnPlotData; if (data == null) { return("Active plot item has no data"); } if (!(data.XColumn is Altaxo.Data.INumericColumn) || !(data.YColumn is Altaxo.Data.INumericColumn)) { return("X-Y values of plot data are not both numeric"); } Altaxo.Data.INumericColumn xcol = (Altaxo.Data.INumericColumn)data.XColumn; Altaxo.Data.INumericColumn ycol = (Altaxo.Data.INumericColumn)data.YColumn; int n = data.PlottablePoints; if (null == xarr || xarr.Length < n) { xarr = new double[n]; } if (null == yarr || yarr.Length < n) { yarr = new double[n]; } int end = data.PlotRangeEnd; int j = 0; for (int i = data.PlotRangeStart; i < end && j < n; i++) { double x = xcol[i]; double y = ycol[i]; if (double.IsNaN(x) || double.IsNaN(y)) { continue; } xarr[j] = x; yarr[j] = y; ++j; } nPlotPoints = j; return(null); }
/// <summary> /// With these function is is possible to change the data column used for the dependent variable. /// </summary> /// <param name="yCol">Data column representing the dependent variable.</param> public void SetDependentVariable(Altaxo.Data.INumericColumn yCol) { _fitEle.SetDependentVariable(0, yCol); }
/// <summary> /// Creates an instance of this class. This constructor needs either /// <paramref name="dataTable"/>, <paramref name="xCol"/> and <paramref name="yCol"/> to be valid, or all to be null. /// If all null, consider to use the other provided constructor. /// </summary> /// <param name="fitFunc">Fitting function.</param> /// <param name="parameter">Array of default parameters (length must match the expected number of parameter of fitFunc).</param> /// <param name="dataTable">The data table from which the provided <paramref name="xCol"/> and <paramref name="yCol"/> originate.</param> /// <param name="groupNumber">The group number of the columns <paramref name="xCol"/> and <paramref name="yCol"/>.</param> /// <param name="xCol">Data column of independent values.</param> /// <param name="yCol">Data column of dependent values.</param> /// <param name="start">First point to be used for fitting.</param> /// <param name="count">Number of points to be used for fitting.</param> public SimpleNonlinearFit(FitEvaluationFunction fitFunc, double[] parameter, Altaxo.Data.DataTable dataTable, int groupNumber, Altaxo.Data.INumericColumn xCol, Altaxo.Data.INumericColumn yCol, int start, int count) { _fitDoc = new NonlinearFitDocument(); if (null == dataTable && null == xCol && null == yCol) { _fitEle = new FitElement(Altaxo.Data.Selections.RangeOfRowIndices.FromStartAndCount(start, count)); } else { _fitEle = new FitElement(dataTable, groupNumber, Altaxo.Data.Selections.RangeOfRowIndices.FromStartAndCount(start, count), xCol, yCol); } _fitEle.FitFunction = new DummyFitFunc(fitFunc, parameter); _fitDoc.FitEnsemble.Add(_fitEle); _fitDoc.SetDefaultParametersForFitElement(0); }
/// <summary> /// Paint the density image in the layer. /// </summary> /// <param name="gfrx">The graphics context painting in.</param> /// <param name="gl">The layer painting in.</param> /// <param name="plotObject">The data to plot.</param> public void Paint(Graphics gfrx, IPlotArea gl, object plotObject) // plots the curve with the choosen style { if (!(plotObject is XYZMeshedColumnPlotData)) { return; // we cannot plot any other than a TwoDimMeshDataAssociation now } XYZMeshedColumnPlotData myPlotAssociation = (XYZMeshedColumnPlotData)plotObject; Altaxo.Data.INumericColumn xColumn = myPlotAssociation.XColumn as Altaxo.Data.INumericColumn; Altaxo.Data.INumericColumn yColumn = myPlotAssociation.YColumn as Altaxo.Data.INumericColumn; if (null == xColumn || null == yColumn) { return; // this plotitem is only for x and y double columns } //double layerWidth = gl.Size.Width; //double layerHeight = gl.Size.Height; int cols = myPlotAssociation.ColumnCount; int rows = myPlotAssociation.RowCount; if (cols <= 0 || rows <= 0) { return; // we cannot show a picture if one length is zero } // there is a need for rebuilding the bitmap only if the data are invalid for some reason if (!m_bCachedDataValid) { System.Diagnostics.Trace.WriteLine("DensityImagePlotStyle.Paint, calculate image data..."); // look if the image has the right dimensions if (null == m_Image || m_Image.Width != cols || m_Image.Height != rows) { if (null != m_Image) { m_Image.Dispose(); } // please notice: the horizontal direction of the image is related to the row index!!! (this will turn the image in relation to the table) // and the vertical direction of the image is related to the column index m_Image = new System.Drawing.Bitmap(rows, cols, System.Drawing.Imaging.PixelFormat.Format32bppArgb); } // now we can fill the image with our data NumericalBoundaries pb = m_ScalingStyle == ScalingStyle.Logarithmic ? (NumericalBoundaries) new PositiveFiniteNumericalBoundaries() : (NumericalBoundaries) new FiniteNumericalBoundaries(); myPlotAssociation.SetVBoundsFromTemplate(pb); // ensure that the right v-boundary type is set myPlotAssociation.MergeVBoundsInto(pb); double vmin = double.IsNaN(this.m_RangeFrom) ? pb.LowerBound : Math.Max(pb.LowerBound, this.m_RangeFrom); double vmax = double.IsNaN(this.m_RangeTo) ? pb.UpperBound : Math.Min(pb.UpperBound, this.m_RangeTo); double lowerBound = vmin; double upperBound = vmax; if (this.m_ScalingStyle == ScalingStyle.Logarithmic) { // Ensure that min and max >0 vmin = lowerBound = Math.Max(lowerBound, double.Epsilon); vmax = upperBound = Math.Max(lowerBound, upperBound); // lowerBound is ok, to ensure that upperBound>=lowerBound vmin = Math.Log(vmin); vmax = vmax > 0 ? Math.Log(vmax) : vmin; } // double vmid = (vmin+vmax)*0.5; double vscal = vmax <= vmin ? 1 : 255.0 / (vmax - vmin); int r, g, b; for (int i = 0; i < cols; i++) { Altaxo.Data.INumericColumn col = myPlotAssociation.DataColumns[i] as Altaxo.Data.INumericColumn; if (null == col) { continue; } for (int j = 0; j < rows; j++) { double val = col[j]; if (double.IsNaN(val)) { m_Image.SetPixel(j, cols - i - 1, m_ColorInvalid); // invalid pixels are transparent } else if (val < lowerBound) { m_Image.SetPixel(j, cols - i - 1, m_ColorBelow); // below the lower bound } else if (val > upperBound) { m_Image.SetPixel(j, cols - i - 1, m_ColorAbove); // above the upper bound } else // a valid value { double relval; // calculate a relative value between 0 and 255 from the borders and the scaling style if (this.m_ScalingStyle == ScalingStyle.Logarithmic) { relval = (Math.Log(val) - vmin) * vscal; } else // ScalingStyle is linear { relval = (val - vmin) * vscal; } r = ((int)(Math.Abs(relval))) % 256; g = ((int)(Math.Abs(relval + relval))) % 256; b = ((int)(Math.Abs(255 - relval))) % 256; m_Image.SetPixel(j, cols - i - 1, System.Drawing.Color.FromArgb(r, g, b)); } } // for all pixel of a column } // for all columns m_bCachedDataValid = true; // now the bitmap is valid } double x_rel_left = gl.XAxis.PhysicalVariantToNormal(xColumn[0]); double x_rel_right = gl.XAxis.PhysicalVariantToNormal(xColumn[rows - 1]); double y_rel_bottom = gl.YAxis.PhysicalVariantToNormal(yColumn[0]); double y_rel_top = gl.YAxis.PhysicalVariantToNormal(yColumn[cols - 1]); double xleft, xright, ytop, ybottom; if (gl.CoordinateSystem.LogicalToLayerCoordinates(new Logical3D(x_rel_left, y_rel_top), out xleft, out ytop) && gl.CoordinateSystem.LogicalToLayerCoordinates(new Logical3D(x_rel_right, y_rel_bottom), out xright, out ybottom)) { GraphicsState savedGraphicsState = gfrx.Save(); if (this.m_ClipToLayer) { gfrx.Clip = gl.CoordinateSystem.GetRegion(); } gfrx.DrawImage(m_Image, (float)xleft, (float)ytop, (float)(xright - xleft), (float)(ybottom - ytop)); gfrx.Restore(savedGraphicsState); } }