void WriteBasicYData(bool bWriteEndElement) { Altaxo.Data.DoubleColumn col = null; string colname; _writer.WriteStartElement("YData"); colname = WorksheetAnalysis.GetYMean_ColumnName(); col = _table.DataColumns[colname] as Altaxo.Data.DoubleColumn; if (null == col) { NotFound(colname); } WriteVector("YMean", col, _numberOfY); colname = WorksheetAnalysis.GetYScale_ColumnName(); col = _table.DataColumns[colname] as Altaxo.Data.DoubleColumn; if (null == col) { NotFound(colname); } WriteVector("YScale", col, _numberOfY); if (bWriteEndElement) { _writer.WriteEndElement(); // YData } }
public void FiveElements89Filled() { DoubleColumn d = new DoubleColumn(5); Assert.AreEqual(0, d.Count); d[8] = 77.0; d[9] = 88; Assert.AreEqual(10, d.Count); Assert.AreEqual(false, d.IsDirty); Assert.AreEqual(true, d.IsElementEmpty(7)); Assert.AreEqual(false, d.IsElementEmpty(8)); Assert.AreEqual(false, d.IsElementEmpty(9)); Assert.AreEqual(true, d.IsElementEmpty(10)); d[9] = double.NaN; Assert.AreEqual(9, d.Count, 9); Assert.AreEqual(true, d.IsElementEmpty(7)); Assert.AreEqual(false, d.IsElementEmpty(8)); Assert.AreEqual(true, d.IsElementEmpty(9)); Assert.AreEqual(true, d.IsElementEmpty(10)); d[8] = double.NaN; Assert.AreEqual(0, d.Count, 0); Assert.AreEqual(true, d.IsElementEmpty(7)); Assert.AreEqual(true, d.IsElementEmpty(8)); Assert.AreEqual(true, d.IsElementEmpty(9)); Assert.AreEqual(true, d.IsElementEmpty(10)); Assert.AreEqual(false, d.IsDirty); for (int i = 0; i < 11; i++) Assert.AreEqual(true, d.IsElementEmpty(i)); }
public override void Import( IMultivariateCalibrationModel calibrationSet, DataTable table) { PLS1CalibrationModel calib = (PLS1CalibrationModel)calibrationSet; for (int yn = 0; yn < calib.NumberOfY; yn++) { // store the x-loads - careful - they are horizontal in the matrix for (int i = 0; i < calib.XLoads[yn].Rows; i++) { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for (int j = 0; j < calib.XLoads[yn].Columns; j++) { col[j] = calib.XLoads[yn][i, j]; } table.DataColumns.Add(col, GetXLoad_ColumnName(yn, i), Altaxo.Data.ColumnKind.V, 0); } // now store the y-loads - careful - they are horizontal in the matrix for (int i = 0; i < calib.YLoads[yn].Rows; i++) { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for (int j = 0; j < calib.YLoads[yn].Columns; j++) { col[j] = calib.YLoads[yn][i, j]; } table.DataColumns.Add(col, GetYLoad_ColumnName(yn, i), Altaxo.Data.ColumnKind.V, 1); } // now store the weights - careful - they are horizontal in the matrix for (int i = 0; i < calib.XWeights[yn].Rows; i++) { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for (int j = 0; j < calib.XWeights[yn].Columns; j++) { col[j] = calib.XWeights[yn][i, j]; } table.DataColumns.Add(col, GetXWeight_ColumnName(yn, i), Altaxo.Data.ColumnKind.V, 0); } // now store the cross product vector - it is a horizontal vector { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for (int j = 0; j < calib.CrossProduct[yn].Columns; j++) { col[j] = calib.CrossProduct[yn][0, j]; } table.DataColumns.Add(col, GetCrossProduct_ColumnName(yn), Altaxo.Data.ColumnKind.V, 3); } } // for all y (constituents) }
public override void Import( IMultivariateCalibrationModel calibrationSet, DataTable table) { var calib = (PCRCalibrationModel)calibrationSet; int numFactors = calib.NumberOfFactors; int numberOfY = calib.NumberOfY; int numberOfPoints = calib.XLoads.RowCount; // store the x-loads - careful - they are horizontal for (int i = 0; i < numFactors; i++) { var col = new Altaxo.Data.DoubleColumn(); for (int j = 0; j < calib.XLoads.ColumnCount; j++) { col[j] = calib.XLoads[i, j]; } table.DataColumns.Add(col, GetXLoad_ColumnName(i), Altaxo.Data.ColumnKind.V, 0); } // now store the scores - careful - they are vertical in the matrix for (int i = 0; i < numFactors; i++) { var col = new Altaxo.Data.DoubleColumn(); for (int j = 0; j < calib.XScores.RowCount; j++) { col[j] = calib.XScores[j, i]; } table.DataColumns.Add(col, GetXScore_ColumnName(i), Altaxo.Data.ColumnKind.V, 0); } // now store the y-loads (this are the preprocessed y in this case for (int cn = 0; cn < numberOfY; cn++) { var col = new Altaxo.Data.DoubleColumn(); for (int i = 0; i < numberOfPoints; i++) { col[i] = calib.YLoads[i, cn]; } table.DataColumns.Add(col, GetYLoad_ColumnName(cn), Altaxo.Data.ColumnKind.V, 0); } // now store the cross product vector - it is a horizontal vector { var col = new Altaxo.Data.DoubleColumn(); for (int j = 0; j < numFactors; j++) { col[j] = calib.CrossProduct[j]; } table.DataColumns.Add(col, GetCrossProduct_ColumnName(), Altaxo.Data.ColumnKind.V, 3); } }
public void TenEmptyElements() { DoubleColumn d = new DoubleColumn(10); Assert.AreEqual(0, d.Count); Assert.AreEqual(false, d.IsDirty); for (int i = 0; i < 11; i++) Assert.AreEqual(true, d.IsElementEmpty(i)); }
public override void Import( IMultivariateCalibrationModel calibrationSet, DataTable table) { PCRCalibrationModel calib = (PCRCalibrationModel)calibrationSet; int numFactors = calib.NumberOfFactors; int numberOfY = calib.NumberOfY; int numberOfPoints = calib.XLoads.Rows; // store the x-loads - careful - they are horizontal for(int i=0;i<numFactors;i++) { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for(int j=0;j<calib.XLoads.Columns;j++) col[j] = calib.XLoads[i,j]; table.DataColumns.Add(col,GetXLoad_ColumnName(i),Altaxo.Data.ColumnKind.V,0); } // now store the scores - careful - they are vertical in the matrix for(int i=0;i<numFactors;i++) { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for(int j=0;j<calib.XScores.Rows;j++) col[j] = calib.XScores[j,i]; table.DataColumns.Add(col,GetXScore_ColumnName(i),Altaxo.Data.ColumnKind.V,0); } // now store the y-loads (this are the preprocessed y in this case for(int cn=0;cn<numberOfY;cn++) { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for(int i=0;i<numberOfPoints;i++) col[i] = calib.YLoads[i,cn]; table.DataColumns.Add(col,GetYLoad_ColumnName(cn),Altaxo.Data.ColumnKind.V,0); } // now store the cross product vector - it is a horizontal vector { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for(int j=0;j<numFactors;j++) col[j] = calib.CrossProduct[j]; table.DataColumns.Add(col,GetCrossProduct_ColumnName(),Altaxo.Data.ColumnKind.V,3); } }
public void ZeroElements() { DoubleColumn d = new DoubleColumn(); Assert.AreEqual(0, d.Count); Assert.AreEqual(false, d.IsDirty); Assert.AreEqual(true, d.IsElementEmpty(0)); Assert.AreEqual(true, d.IsElementEmpty(1)); }
public override void Import( IMultivariateCalibrationModel calibrationSet, DataTable table) { PLS1CalibrationModel calib = (PLS1CalibrationModel)calibrationSet; for(int yn=0;yn<calib.NumberOfY;yn++) { // store the x-loads - careful - they are horizontal in the matrix for(int i=0;i<calib.XLoads[yn].Rows;i++) { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for(int j=0;j<calib.XLoads[yn].Columns;j++) col[j] = calib.XLoads[yn][i,j]; table.DataColumns.Add(col,GetXLoad_ColumnName(yn,i),Altaxo.Data.ColumnKind.V,0); } // now store the y-loads - careful - they are horizontal in the matrix for(int i=0;i<calib.YLoads[yn].Rows;i++) { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for(int j=0;j<calib.YLoads[yn].Columns;j++) col[j] = calib.YLoads[yn][i,j]; table.DataColumns.Add(col,GetYLoad_ColumnName(yn,i),Altaxo.Data.ColumnKind.V,1); } // now store the weights - careful - they are horizontal in the matrix for(int i=0;i<calib.XWeights[yn].Rows;i++) { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for(int j=0;j<calib.XWeights[yn].Columns;j++) col[j] = calib.XWeights[yn][i,j]; table.DataColumns.Add(col,GetXWeight_ColumnName(yn,i),Altaxo.Data.ColumnKind.V,0); } // now store the cross product vector - it is a horizontal vector { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for(int j=0;j<calib.CrossProduct[yn].Columns;j++) col[j] = calib.CrossProduct[yn][0,j]; table.DataColumns.Add(col,GetCrossProduct_ColumnName(yn),Altaxo.Data.ColumnKind.V,3); } } // for all y (constituents) }
public override void Import( IMultivariateCalibrationModel calibrationSet, DataTable table) { var calib = (PLS2CalibrationModel)calibrationSet; // store the x-loads - careful - they are horizontal in the matrix for (int i = 0; i < calib.XLoads.RowCount; i++) { var col = new Altaxo.Data.DoubleColumn(); for (int j = 0; j < calib.XLoads.ColumnCount; j++) { col[j] = calib.XLoads[i, j]; } table.DataColumns.Add(col, GetXLoad_ColumnName(i), Altaxo.Data.ColumnKind.V, 0); } // now store the y-loads - careful - they are horizontal in the matrix for (int i = 0; i < calib.YLoads.RowCount; i++) { var col = new Altaxo.Data.DoubleColumn(); for (int j = 0; j < calib.YLoads.ColumnCount; j++) { col[j] = calib.YLoads[i, j]; } table.DataColumns.Add(col, GetYLoad_ColumnName(i), Altaxo.Data.ColumnKind.V, 1); } // now store the weights - careful - they are horizontal in the matrix for (int i = 0; i < calib.XWeights.RowCount; i++) { var col = new Altaxo.Data.DoubleColumn(); for (int j = 0; j < calib.XWeights.ColumnCount; j++) { col[j] = calib.XWeights[i, j]; } table.DataColumns.Add(col, GetXWeight_ColumnName(i), Altaxo.Data.ColumnKind.V, 0); } // now store the cross product vector - it is a horizontal vector { var col = new Altaxo.Data.DoubleColumn(); for (int j = 0; j < calib.CrossProduct.ColumnCount; j++) { col[j] = calib.CrossProduct[0, j]; } table.DataColumns.Add(col, GetCrossProduct_ColumnName(), Altaxo.Data.ColumnKind.V, 3); } }
void WriteVector(string name, Altaxo.Data.DoubleColumn col, int numberOfData) { _writer.WriteStartElement(name); for (int i = 0; i < numberOfData; i++) { _writer.WriteElementString("e", System.Xml.XmlConvert.ToString(col[i])); } _writer.WriteEndElement(); // name }
/// <summary> /// Merges two tables by fractional index. /// </summary> /// <param name="destinationTable">Table to merge into.</param> /// <param name="fractionalIndex">Array of fractional indices. Each item points into the slaveTable to the value that should be included in the master column at the item's index.</param> /// <param name="slaveTable">The table providing the data for merging into the master table.</param> /// <param name="slaveColumnsToMerge">Indices of that columns of the slave table that should be merged into the master table.</param> public static void MergeTable( this DataTable destinationTable, DoubleColumn fractionalIndex, DataTable slaveTable, IAscendingIntegerCollection slaveColumnsToMerge) { int destinationTableStartIdx = destinationTable.DataColumnCount; destinationTable.AddDataColumnsWithPropertiesFrom(slaveTable, slaveColumnsToMerge); for (int i = 0; i < slaveColumnsToMerge.Count; i++) { int slaveColIdx = slaveColumnsToMerge[i]; DataColumn newCol = destinationTable[destinationTableStartIdx + i]; SetColumnFromFractionalIndex(newCol, fractionalIndex, slaveTable[slaveColIdx]); } }
public static string Correlation(Altaxo.AltaxoDocument mainDocument, IWorksheetController dg) { int len = dg.SelectedDataColumns.Count; if (len == 0) { return("No column selected!"); // nothing selected } if (len > 2) { return("Too many columns selected!"); } if (!(dg.DataTable[dg.SelectedDataColumns[0]] is Altaxo.Data.DoubleColumn)) { return("First selected column is not numeric!"); } if (dg.SelectedDataColumns.Count == 2 && !(dg.DataTable[dg.SelectedDataColumns[1]] is Altaxo.Data.DoubleColumn)) { return("Second selected column is not numeric!"); } double[] arr1 = ((Altaxo.Data.DoubleColumn)dg.DataTable[dg.SelectedDataColumns[0]]).Array; double[] arr2 = arr1; if (dg.SelectedDataColumns.Count == 2) { arr2 = ((Altaxo.Data.DoubleColumn)dg.DataTable[dg.SelectedDataColumns[1]]).Array; } double[] result = new double[arr1.Length + arr2.Length - 1]; //Pfa235Convolution co = new Pfa235Convolution(arr1.Length); //co.Convolute(arr1, arr2, result, null, FourierDirection.Forward); Calc.Fourier.NativeFourierMethods.CorrelationNonCyclic(arr1, arr2, result); var col = new Altaxo.Data.DoubleColumn { Array = result }; dg.DataTable.DataColumns.Add(col, "Correlate"); return(null); }
public void TenElementsFirstFilled() { DoubleColumn d = new DoubleColumn(10); Assert.AreEqual(0, d.Count); d[0] = 77.0; Assert.AreEqual(1, d.Count); Assert.AreEqual(false, d.IsDirty); Assert.AreEqual(false, d.IsElementEmpty(0)); Assert.AreEqual(true, d.IsElementEmpty(1)); // now delete again element 0 d[0] = double.NaN; Assert.AreEqual(0, d.Count); Assert.AreEqual(false, d.IsDirty); for (int i = 0; i < 11; i++) Assert.AreEqual(true, d.IsElementEmpty(i)); Assert.AreEqual(false, d.IsDirty); }
public void TenEmptyColumns() { DataColumnCollection d = new DataColumnCollection(); DataColumn[] cols = new DataColumn[10]; for(int i=0;i<10;i++) { cols[i] = new DoubleColumn(); d.Add(cols[i]); } Assert.AreEqual(10, d.ColumnCount); Assert.AreEqual(0, d.RowCount); Assert.AreEqual(false, d.IsDirty); Assert.AreEqual(false, d.IsSuspended); Assert.AreEqual("A", d.GetColumnName(0)); Assert.AreEqual("A", d[0].Name); Assert.AreEqual("J", d.GetColumnName(9)); Assert.AreEqual("J", d[9].Name); // Test index to column resolution for(int i=0;i<10;i++) Assert.AreEqual(cols[i], d[i]); // test name to column resolution for(int i=0;i<10;i++) { char name = (char)('A'+i); Assert.AreEqual(cols[i], d[name.ToString()],"Column to name resolution of col " + name.ToString()); } // test column to number resolution for(int i=0;i<10;i++) Assert.AreEqual(i, d.GetColumnNumber(cols[i])); }
/// <summary> /// This function searches for patterns like aaa=bbb in the provided string. If it finds such a item, it creates a column named aaa /// and stores the value bbb at the same position in it as in the text column. /// </summary> /// <param name="strg">The string where to search for the patterns described above.</param> /// <param name="store">The column collection where to store the newly created columns of properties.</param> /// <param name="index">The index into the column where to store the property value.</param> public static void ExtractPropertiesFromString(string strg, Altaxo.Data.DataColumnCollection store, int index) { string pat; pat = @"(\S+)=(\S+)"; var r = new Regex(pat, RegexOptions.Compiled | RegexOptions.IgnoreCase); for (Match m = r.Match(strg); m.Success; m = m.NextMatch()) { string propname = m.Groups[1].ToString(); string propvalue = m.Groups[2].ToString(); // System.Diagnostics.Trace.WriteLine("Found the pair " + propname + " : " + propvalue); if (!store.ContainsColumn(propname)) { Altaxo.Data.DataColumn col; if (Altaxo.Serialization.DateTimeParsing.IsDateTime(propvalue)) { col = new Altaxo.Data.DateTimeColumn(); } else if (Altaxo.Serialization.NumberConversion.IsNumeric(propvalue)) { col = new Altaxo.Data.DoubleColumn(); } else { col = new Altaxo.Data.TextColumn(); } store.Add(col, propname); // add the column to the collection } // now the column is present we can store the value in it. store[propname][index] = new Altaxo.Data.AltaxoVariant(propvalue); } }
/// <summary> /// Imports a Origin OPJ file (tables only) into corresponding new tables in Altaxo. /// </summary> /// <param name="filename">The file name of the origin OPJ file.</param> /// <returns>Null if the import was successfull, or a error message.</returns> public static string Import(string filename) { OpjFile opj = new OpjFile(filename); opj.Parse(); // now create corresponding tables in Altaxo for (int nspread = 0; nspread < opj.numSpreads(); nspread++) { // Create a new table string tablename = Current.Project.DataTableCollection.FindNewTableName(opj.spreadName(nspread)); DataTable table = new DataTable(tablename); int numberOfColumns = opj.numCols(nspread); for (int ncol = 0; ncol < numberOfColumns; ncol++) { string colname = opj.colName(nspread, ncol); string coltype = opj.colType(nspread, ncol); int numberOfRows = opj.numRows(nspread, ncol); ColumnKind kind = coltype == "X" ? ColumnKind.X : ColumnKind.V; DoubleColumn column = new DoubleColumn(numberOfRows); column.CopyDataFrom(opj.Data(nspread, ncol), numberOfRows); colname = table.DataColumns.FindUniqueColumnName(colname); table.DataColumns.Add(column, colname, kind, 0); } table.Name = tablename; Current.Project.DataTableCollection.Add(table); Current.ProjectService.CreateNewWorksheet(table); } return null; }
/// <summary> /// Fills a provided table (should be empty) with the preprocessed spectra. The spectra are saved as columns (independently on their former orientation in the original worksheet). /// </summary> /// <param name="calibtable">The table containing the calibration model.</param> /// <param name="desttable">The table where to store the preprocessed spectra. Should be empty.</param> public void CalculatePreprocessedSpectra( Altaxo.Data.DataTable calibtable, Altaxo.Data.DataTable desttable) { var plsMemo = GetContentAsMultivariateContentMemento(calibtable); if (plsMemo == null) throw new ArgumentException("Table does not contain a PLSContentMemento"); IMatrix matrixX = GetRawSpectra(plsMemo); IMultivariateCalibrationModel calib = GetCalibrationModel(calibtable); // do spectral preprocessing plsMemo.SpectralPreprocessing.ProcessForPrediction(matrixX, calib.PreprocessingModel.XMean, calib.PreprocessingModel.XScale); // for the new table, save the spectra as column DoubleColumn xcol = new DoubleColumn(); for (int i = matrixX.Columns; i >= 0; i--) xcol[i] = calib.PreprocessingModel.XOfX[i]; desttable.DataColumns.Add(xcol, _XOfX_ColumnName, ColumnKind.X, 0); for (int n = 0; n < matrixX.Rows; n++) { DoubleColumn col = new DoubleColumn(); for (int i = matrixX.Columns - 1; i >= 0; i--) col[i] = matrixX[n, i]; desttable.DataColumns.Add(col, n.ToString(), ColumnKind.V, 0); } }
/// <summary> /// This predicts the selected columns/rows against a user choosen calibration model. /// The orientation of spectra is given by the parameter <c>spectrumIsRow</c>. /// </summary> /// <param name="srctable">Table holding the specta to predict values for.</param> /// <param name="selectedColumns">Columns selected in the source table.</param> /// <param name="selectedRows">Rows selected in the source table.</param> /// <param name="destTable">The table to store the prediction result.</param> /// <param name="modelTable">The table where the calibration model is stored.</param> /// <param name="numberOfFactors">Number of factors used to predict the values.</param> /// <param name="spectrumIsRow">If true, the spectra is horizontally oriented, else it is vertically oriented.</param> public virtual void PredictValues( DataTable srctable, IAscendingIntegerCollection selectedColumns, IAscendingIntegerCollection selectedRows, bool spectrumIsRow, int numberOfFactors, DataTable modelTable, DataTable destTable) { IMultivariateCalibrationModel calibModel = GetCalibrationModel(modelTable); // Export(modelTable, out calibModel); var memento = GetContentAsMultivariateContentMemento(modelTable); // Fill matrixX with spectra Altaxo.Collections.AscendingIntegerCollection spectralIndices; Altaxo.Collections.AscendingIntegerCollection measurementIndices; spectralIndices = new Altaxo.Collections.AscendingIntegerCollection(selectedColumns); measurementIndices = new Altaxo.Collections.AscendingIntegerCollection(selectedRows); RemoveNonNumericCells(srctable, measurementIndices, spectralIndices); // exchange selection if spectrum is column if (!spectrumIsRow) { Altaxo.Collections.AscendingIntegerCollection hlp; hlp = spectralIndices; spectralIndices = measurementIndices; measurementIndices = hlp; } // if there are more data than expected, we have to map the spectral indices if (spectralIndices.Count > calibModel.NumberOfX) { double[] xofx = GetXOfSpectra(srctable, spectrumIsRow, spectralIndices, measurementIndices); string errormsg; AscendingIntegerCollection map = MapSpectralX(calibModel.PreprocessingModel.XOfX, VectorMath.ToROVector(xofx), out errormsg); if (map == null) throw new ApplicationException("Can not map spectral data: " + errormsg); else { AscendingIntegerCollection newspectralindices = new AscendingIntegerCollection(); for (int i = 0; i < map.Count; i++) newspectralindices.Add(spectralIndices[map[i]]); spectralIndices = newspectralindices; } } IMatrix matrixX = GetRawSpectra(srctable, spectrumIsRow, spectralIndices, measurementIndices); MatrixMath.BEMatrix predictedY = new MatrixMath.BEMatrix(measurementIndices.Count, calibModel.NumberOfY); CalculatePredictedY(calibModel, memento.SpectralPreprocessing, matrixX, numberOfFactors, predictedY, null); // now save the predicted y in the destination table Altaxo.Data.DoubleColumn labelCol = new Altaxo.Data.DoubleColumn(); for (int i = 0; i < measurementIndices.Count; i++) { labelCol[i] = measurementIndices[i]; } destTable.DataColumns.Add(labelCol, "MeasurementLabel", Altaxo.Data.ColumnKind.Label, 0); for (int k = 0; k < predictedY.Columns; k++) { Altaxo.Data.DoubleColumn predictedYcol = new Altaxo.Data.DoubleColumn(); for (int i = 0; i < measurementIndices.Count; i++) { predictedYcol[i] = predictedY[i, k]; } destTable.DataColumns.Add(predictedYcol, "Predicted Y" + k.ToString(), Altaxo.Data.ColumnKind.V, 0); } }
/// <summary> /// Constructor /// </summary> /// <param name="column">The <see cref="DataColumn" /> to wrap.</param> /// <param name="selectedRows">The set of rows that are part of the vector. This collection is not cloned here, therefore it must not be subsequently changed!</param> public DoubleColumnSelectedRowsToVectorWrapper(Altaxo.Data.DoubleColumn column, IAscendingIntegerCollection selectedRows) { _column = column; _rows = selectedRows; }
public static void Interpolation(WorksheetController ctrl) { if(ctrl.SelectedDataColumns.Count==0) return; object paramobject = new InterpolationParameters(); if(!Current.Gui.ShowDialog(ref paramobject,"Interpolation")) return; InterpolationParameters parameters = (InterpolationParameters)paramobject; Altaxo.Data.DataColumn yCol = ctrl.Doc.DataColumns[ctrl.SelectedDataColumns[0]]; Altaxo.Data.DataColumn xCol = ctrl.Doc.DataColumns.FindXColumnOf(yCol); if(!(yCol is INumericColumn)) { Current.Gui.ErrorMessageBox("The selected column is not numeric!"); return; } if(!(xCol is INumericColumn)) { Current.Gui.ErrorMessageBox("The x-column of the selected column is not numeric!"); return; } int rows = Math.Min(xCol.Count,yCol.Count); IROVector yVec = DataColumnWrapper.ToROVector((INumericColumn)yCol,rows); IROVector xVec = DataColumnWrapper.ToROVector((INumericColumn)xCol,rows); parameters.InterpolationInstance.Interpolate(xVec,yVec); DoubleColumn xRes = new DoubleColumn(); DoubleColumn yRes = new DoubleColumn(); for(int i=0; i<parameters.NumberOfPoints;i++) { double r = i/(double)(parameters.NumberOfPoints-1); double x = parameters.XOrg*(1-r) + parameters.XEnd*(r); double y = ((IInterpolationFunction)parameters.InterpolationInstance).GetYOfX(x); xRes[i]=x; yRes[i]=y; } int newgroup = ctrl.DataTable.DataColumns.GetUnusedColumnGroupNumber(); ctrl.DataTable.DataColumns.Add(xRes,xCol.Name+".I",ColumnKind.X,newgroup); ctrl.DataTable.DataColumns.Add(yRes,yCol.Name+".I",ColumnKind.V,newgroup); }
/// <summary> /// Makes a PCA (a principal component analysis) of the table or the selected columns / rows and stores the results in a newly created table. /// </summary> /// <param name="mainDocument">The main document of the application.</param> /// <param name="srctable">The table where the data come from.</param> /// <param name="selectedColumns">The selected columns.</param> /// <param name="selectedRows">The selected rows.</param> /// <param name="bHorizontalOrientedSpectrum">True if a spectrum is a single row, False if a spectrum is a single column.</param> /// <param name="maxNumberOfFactors">The maximum number of factors to calculate.</param> /// <returns></returns> public static string PrincipalComponentAnalysis( Altaxo.AltaxoDocument mainDocument, Altaxo.Data.DataTable srctable, IAscendingIntegerCollection selectedColumns, IAscendingIntegerCollection selectedRows, bool bHorizontalOrientedSpectrum, int maxNumberOfFactors ) { bool bUseSelectedColumns = (null != selectedColumns && 0 != selectedColumns.Count); int prenumcols = bUseSelectedColumns ? selectedColumns.Count : srctable.DataColumns.ColumnCount; // check for the number of numeric columns int numcols = 0; for (int i = 0; i < prenumcols; i++) { int idx = bUseSelectedColumns ? selectedColumns[i] : i; if (srctable[i] is Altaxo.Data.INumericColumn) { numcols++; } } // check the number of rows bool bUseSelectedRows = (null != selectedRows && 0 != selectedRows.Count); int numrows; if (bUseSelectedRows) { numrows = selectedRows.Count; } else { numrows = 0; for (int i = 0; i < numcols; i++) { int idx = bUseSelectedColumns ? selectedColumns[i] : i; numrows = Math.Max(numrows, srctable[idx].Count); } } // check that both dimensions are at least 2 - otherwise PCA is not possible if (numrows < 2) { return("At least two rows are neccessary to do Principal Component Analysis!"); } if (numcols < 2) { return("At least two numeric columns are neccessary to do Principal Component Analysis!"); } // Create a matrix of appropriate dimensions and fill it MatrixMath.BEMatrix matrixX; if (bHorizontalOrientedSpectrum) { matrixX = new MatrixMath.BEMatrix(numrows, numcols); int ccol = 0; // current column in the matrix for (int i = 0; i < prenumcols; i++) { int colidx = bUseSelectedColumns ? selectedColumns[i] : i; Altaxo.Data.INumericColumn col = srctable[colidx] as Altaxo.Data.INumericColumn; if (null != col) { for (int j = 0; j < numrows; j++) { int rowidx = bUseSelectedRows ? selectedRows[j] : j; matrixX[j, ccol] = col[rowidx]; } ++ccol; } } } // end if it was a horizontal oriented spectrum else // if it is a vertical oriented spectrum { matrixX = new MatrixMath.BEMatrix(numcols, numrows); int ccol = 0; // current column in the matrix for (int i = 0; i < prenumcols; i++) { int colidx = bUseSelectedColumns ? selectedColumns[i] : i; Altaxo.Data.INumericColumn col = srctable[colidx] as Altaxo.Data.INumericColumn; if (null != col) { for (int j = 0; j < numrows; j++) { int rowidx = bUseSelectedRows ? selectedRows[j] : j; matrixX[ccol, j] = col[rowidx]; } ++ccol; } } } // if it was a vertical oriented spectrum // now do PCA with the matrix MatrixMath.REMatrix factors = new MatrixMath.REMatrix(0, 0); MatrixMath.BEMatrix loads = new MatrixMath.BEMatrix(0, 0); MatrixMath.BEMatrix residualVariances = new MatrixMath.BEMatrix(0, 0); MatrixMath.HorizontalVector meanX = new MatrixMath.HorizontalVector(matrixX.Columns); // first, center the matrix MatrixMath.ColumnsToZeroMean(matrixX, meanX); MatrixMath.NIPALS_HO(matrixX, maxNumberOfFactors, 1E-9, factors, loads, residualVariances); // now we have to create a new table where to place the calculated factors and loads // we will do that in a vertical oriented manner, i.e. even if the loads are // here in horizontal vectors: in our table they are stored in (vertical) columns Altaxo.Data.DataTable table = new Altaxo.Data.DataTable("PCA of " + srctable.Name); // Fill the Table table.Suspend(); // first of all store the meanscore { double meanScore = MatrixMath.LengthOf(meanX); MatrixMath.NormalizeRows(meanX); Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for (int i = 0; i < factors.Rows; i++) { col[i] = meanScore; } table.DataColumns.Add(col, "MeanFactor", Altaxo.Data.ColumnKind.V, 0); } // first store the factors for (int i = 0; i < factors.Columns; i++) { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for (int j = 0; j < factors.Rows; j++) { col[j] = factors[j, i]; } table.DataColumns.Add(col, "Factor" + i.ToString(), Altaxo.Data.ColumnKind.V, 1); } // now store the mean of the matrix { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for (int j = 0; j < meanX.Columns; j++) { col[j] = meanX[0, j]; } table.DataColumns.Add(col, "MeanLoad", Altaxo.Data.ColumnKind.V, 2); } // now store the loads - careful - they are horizontal in the matrix for (int i = 0; i < loads.Rows; i++) { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for (int j = 0; j < loads.Columns; j++) { col[j] = loads[i, j]; } table.DataColumns.Add(col, "Load" + i.ToString(), Altaxo.Data.ColumnKind.V, 3); } // now store the residual variances, they are vertical in the vector { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for (int i = 0; i < residualVariances.Rows; i++) { col[i] = residualVariances[i, 0]; } table.DataColumns.Add(col, "ResidualVariance", Altaxo.Data.ColumnKind.V, 4); } table.Resume(); mainDocument.DataTableCollection.Add(table); // create a new worksheet without any columns Current.ProjectService.CreateNewWorksheet(table); return(null); }
/// <summary> /// Multiplies selected columns to form a matrix. /// </summary> /// <param name="mainDocument"></param> /// <param name="srctable"></param> /// <param name="selectedColumns"></param> /// <returns>Null if successful, else the description of the error.</returns> /// <remarks>The user must select an even number of columns. All columns of the first half of the selection /// must have the same number of rows, and all columns of the second half of selection must also have the same /// number of rows. The first half of selected columns form a matrix of dimensions(firstrowcount,halfselected), and the second half /// of selected columns form a matrix of dimension(halfselected, secondrowcount). The resulting matrix has dimensions (firstrowcount,secondrowcount) and is /// stored in a separate worksheet.</remarks> public static string MultiplyColumnsToMatrix( Altaxo.AltaxoDocument mainDocument, Altaxo.Data.DataTable srctable, IAscendingIntegerCollection selectedColumns ) { // check that there are columns selected if(0==selectedColumns.Count) return "You must select at least two columns to multiply!"; // selected columns must contain an even number of columns if(0!=selectedColumns.Count%2) return "You selected an odd number of columns. Please select an even number of columns to multiply!"; // all selected columns must be numeric columns for(int i=0;i<selectedColumns.Count;i++) { if(!(srctable[selectedColumns[i]] is Altaxo.Data.INumericColumn)) return string.Format("The column[{0}] (name:{1}) is not a numeric column!",selectedColumns[i],srctable[selectedColumns[i]].Name); } int halfselect = selectedColumns.Count/2; // check that all columns from the first half of selected colums contain the same // number of rows int rowsfirsthalf=int.MinValue; for(int i=0;i<halfselect;i++) { int idx = selectedColumns[i]; if(rowsfirsthalf<0) rowsfirsthalf = srctable[idx].Count; else if(rowsfirsthalf != srctable[idx].Count) return "The first half of selected columns have not all the same length!"; } int rowssecondhalf=int.MinValue; for(int i=halfselect;i<selectedColumns.Count;i++) { int idx = selectedColumns[i]; if(rowssecondhalf<0) rowssecondhalf = srctable[idx].Count; else if(rowssecondhalf != srctable[idx].Count) return "The second half of selected columns have not all the same length!"; } // now create the matrices to multiply from the MatrixMath.REMatrix firstMat = new MatrixMath.REMatrix(rowsfirsthalf,halfselect); for(int i=0;i<halfselect;i++) { Altaxo.Data.INumericColumn col = (Altaxo.Data.INumericColumn)srctable[selectedColumns[i]]; for(int j=0;j<rowsfirsthalf;j++) firstMat[j,i] = col[j]; } MatrixMath.BEMatrix secondMat = new MatrixMath.BEMatrix(halfselect,rowssecondhalf); for(int i=0;i<halfselect;i++) { Altaxo.Data.INumericColumn col = (Altaxo.Data.INumericColumn)srctable[selectedColumns[i+halfselect]]; for(int j=0;j<rowssecondhalf;j++) secondMat[i,j] = col[j]; } // now multiply the two matrices MatrixMath.BEMatrix resultMat = new MatrixMath.BEMatrix(rowsfirsthalf,rowssecondhalf); MatrixMath.Multiply(firstMat,secondMat,resultMat); // and store the result in a new worksheet Altaxo.Data.DataTable table = new Altaxo.Data.DataTable("ResultMatrix of " + srctable.Name); table.Suspend(); // first store the factors for(int i=0;i<resultMat.Columns;i++) { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for(int j=0;j<resultMat.Rows;j++) col[j] = resultMat[j,i]; table.DataColumns.Add(col,i.ToString()); } table.Resume(); mainDocument.DataTableCollection.Add(table); // create a new worksheet without any columns Current.ProjectService.CreateNewWorksheet(table); return null; }
/// <summary> /// Get the matrix of x and y values (raw data). /// </summary> /// <param name="srctable">The table where the data come from.</param> /// <param name="selectedColumns">The selected columns.</param> /// <param name="selectedRows">The selected rows.</param> /// <param name="selectedPropertyColumns">The selected property column(s).</param> /// <param name="bHorizontalOrientedSpectrum">True if a spectrum is a single row, False if a spectrum is a single column.</param> /// <param name="matrixX">On return, gives the matrix of spectra (each spectra is a row in the matrix).</param> /// <param name="matrixY">On return, gives the matrix of y-values (each measurement is a row in the matrix).</param> /// <param name="plsContent">Holds information about the analysis results.</param> /// <param name="xOfX">On return, this is the vector of values corresponding to each spectral bin, i.e. wavelength values, frequencies etc.</param> /// <returns></returns> public static string GetXYMatrices( Altaxo.Data.DataTable srctable, IAscendingIntegerCollection selectedColumns, IAscendingIntegerCollection selectedRows, IAscendingIntegerCollection selectedPropertyColumns, bool bHorizontalOrientedSpectrum, MultivariateContentMemento plsContent, out IMatrix matrixX, out IMatrix matrixY, out IROVector xOfX ) { matrixX = null; matrixY = null; xOfX = null; plsContent.SpectrumIsRow = bHorizontalOrientedSpectrum; Altaxo.Data.DataColumn xColumnOfX = null; Altaxo.Data.DataColumn labelColumnOfX = new Altaxo.Data.DoubleColumn(); Altaxo.Data.DataColumnCollection concentration = bHorizontalOrientedSpectrum ? srctable.DataColumns : srctable.PropertyColumns; // we presume for now that the spectrum is horizontally, // if not we exchange the collections later AscendingIntegerCollection numericDataCols = new AscendingIntegerCollection(); AscendingIntegerCollection numericDataRows = new AscendingIntegerCollection(); AscendingIntegerCollection concentrationIndices = new AscendingIntegerCollection(); AscendingIntegerCollection spectralIndices = bHorizontalOrientedSpectrum ? numericDataCols : numericDataRows; AscendingIntegerCollection measurementIndices = bHorizontalOrientedSpectrum ? numericDataRows : numericDataCols; plsContent.ConcentrationIndices = concentrationIndices; plsContent.MeasurementIndices = measurementIndices; plsContent.SpectralIndices = spectralIndices; plsContent.SpectrumIsRow = bHorizontalOrientedSpectrum; plsContent.OriginalDataTableName = srctable.Name; bool bUseSelectedColumns = (null != selectedColumns && 0 != selectedColumns.Count); // this is the number of columns (for now), but it can be less than this in case // not all columns are numeric int prenumcols = bUseSelectedColumns ? selectedColumns.Count : srctable.DataColumns.ColumnCount; // check for the number of numeric columns int numcols = 0; for (int i = 0; i < prenumcols; i++) { int idx = bUseSelectedColumns ? selectedColumns[i] : i; if (srctable[idx] is Altaxo.Data.INumericColumn) { numericDataCols.Add(idx); numcols++; } } // check the number of rows bool bUseSelectedRows = (null != selectedRows && 0 != selectedRows.Count); int numrows; if (bUseSelectedRows) { numrows = selectedRows.Count; numericDataRows.Add(selectedRows); } else { numrows = 0; for (int i = 0; i < numcols; i++) { int idx = bUseSelectedColumns ? selectedColumns[i] : i; numrows = Math.Max(numrows, srctable[idx].Count); } numericDataRows.Add(ContiguousIntegerRange.FromStartAndCount(0, numrows)); } if (bHorizontalOrientedSpectrum) { if (numcols < 2) return "At least two numeric columns are neccessary to do Partial Least Squares (PLS) analysis!"; // check that the selected columns are in exactly two groups // the group which has more columns is then considered to have // the spectrum, the other group is the y-values int group0 = -1; int group1 = -1; int groupcount0 = 0; int groupcount1 = 0; for (int i = 0; i < numcols; i++) { int grp = srctable.DataColumns.GetColumnGroup(numericDataCols[i]); if (group0 < 0) { group0 = grp; groupcount0 = 1; } else if (group0 == grp) { groupcount0++; } else if (group1 < 0) { group1 = grp; groupcount1 = 1; } else if (group1 == grp) { groupcount1++; } else { return "The columns you selected must be members of two groups (y-values and spectrum), but actually there are more than two groups!"; } } // end for all columns if (groupcount1 <= 0) return "The columns you selected must be members of two groups (y-values and spectrum), but actually only one group was detected!"; if (groupcount1 < groupcount0) { int hlp; hlp = groupcount1; groupcount1 = groupcount0; groupcount0 = hlp; hlp = group1; group1 = group0; group0 = hlp; } // group0 is now the group of y-values (concentrations) // group1 is now the group of x-values (spectra) // we delete group0 from numericDataCols and add it to concentrationIndices for (int i = numcols - 1; i >= 0; i--) { int index = numericDataCols[i]; if (group0 == srctable.DataColumns.GetColumnGroup(index)) { numericDataCols.Remove(index); concentrationIndices.Add(index); } } // fill the corresponding X-Column of the spectra xColumnOfX = Altaxo.Data.DataColumn.CreateColumnOfSelectedRows( srctable.PropertyColumns.FindXColumnOfGroup(group1), spectralIndices); } else // vertically oriented spectrum -> one spectrum is one data column { // we have to exchange measurementIndices and // if PLS on columns, than we should have property columns selected // that designates the y-values // so count all property columns bool bUseSelectedPropCols = (null != selectedPropertyColumns && 0 != selectedPropertyColumns.Count); // this is the number of property columns (for now), but it can be less than this in case // not all columns are numeric int prenumpropcols = bUseSelectedPropCols ? selectedPropertyColumns.Count : srctable.PropCols.ColumnCount; // check for the number of numeric property columns for (int i = 0; i < prenumpropcols; i++) { int idx = bUseSelectedPropCols ? selectedPropertyColumns[i] : i; if (srctable.PropCols[idx] is Altaxo.Data.INumericColumn) { concentrationIndices.Add(idx); } } if (concentrationIndices.Count < 1) return "At least one numeric property column must exist to hold the y-values!"; // fill the corresponding X-Column of the spectra xColumnOfX = Altaxo.Data.DataColumn.CreateColumnOfSelectedRows( srctable.DataColumns.FindXColumnOf(srctable[measurementIndices[0]]), spectralIndices); } // else vertically oriented spectrum IVector xOfXRW = VectorMath.CreateExtensibleVector(xColumnOfX.Count); xOfX = xOfXRW; if (xColumnOfX is INumericColumn) { for (int i = 0; i < xOfX.Length; i++) xOfXRW[i] = ((INumericColumn)xColumnOfX)[i]; } else { for (int i = 0; i < xOfX.Length; i++) xOfXRW[i] = spectralIndices[i]; } // now fill the matrix // fill in the y-values matrixY = new MatrixMath.BEMatrix(measurementIndices.Count, concentrationIndices.Count); for (int i = 0; i < concentrationIndices.Count; i++) { Altaxo.Data.INumericColumn col = concentration[concentrationIndices[i]] as Altaxo.Data.INumericColumn; for (int j = 0; j < measurementIndices.Count; j++) { matrixY[j, i] = col[measurementIndices[j]]; } } // end fill in yvalues matrixX = new MatrixMath.BEMatrix(measurementIndices.Count, spectralIndices.Count); if (bHorizontalOrientedSpectrum) { for (int i = 0; i < spectralIndices.Count; i++) { labelColumnOfX[i] = spectralIndices[i]; Altaxo.Data.INumericColumn col = srctable[spectralIndices[i]] as Altaxo.Data.INumericColumn; for (int j = 0; j < measurementIndices.Count; j++) { matrixX[j, i] = col[measurementIndices[j]]; } } // end fill in x-values } else // vertical oriented spectrum { for (int i = 0; i < spectralIndices.Count; i++) { labelColumnOfX[i] = spectralIndices[i]; } for (int i = 0; i < measurementIndices.Count; i++) { Altaxo.Data.INumericColumn col = srctable[measurementIndices[i]] as Altaxo.Data.INumericColumn; for (int j = 0; j < spectralIndices.Count; j++) { matrixX[i, j] = col[spectralIndices[j]]; } } // end fill in x-values } return null; }
public virtual void StoreNumberOfFactors( int nNumberOfFactors, DataTable table) { // add a NumberOfFactors columm DoubleColumn xNumFactor = null; if (table.DataColumns.Contains(_NumberOfFactors_ColumnName)) xNumFactor = table[_NumberOfFactors_ColumnName] as DoubleColumn; if (null == xNumFactor) { xNumFactor = new Altaxo.Data.DoubleColumn(); table.DataColumns.Add(xNumFactor, _NumberOfFactors_ColumnName, Altaxo.Data.ColumnKind.X, _NumberOfFactors_ColumnGroup); } using (var suspendToken = xNumFactor.SuspendGetToken()) { for (int i = 0; i < nNumberOfFactors; i++) { xNumFactor[i] = i; } suspendToken.Resume(); } }
/// <summary> /// Imports a couple of JCAMP files into a table. The spectra are added as columns to the (one and only) table. If the x column /// of the rightmost column does not match the x-data of the spectra, a new x-column is also created. /// </summary> /// <param name="filenames">An array of filenames to import.</param> /// <param name="table">The table the spectra should be imported to.</param> /// <returns>Null if no error occurs, or an error description.</returns> public static string ImportJcampFiles(string[] filenames, Altaxo.Data.DataTable table) { DoubleColumn xcol = null; DoubleColumn xvalues, yvalues; var errorList = new System.Text.StringBuilder(); int lastColumnGroup = 0; if (table.DataColumns.ColumnCount > 0) { lastColumnGroup = table.DataColumns.GetColumnGroup(table.DataColumns.ColumnCount - 1); Altaxo.Data.DataColumn xColumnOfRightMost = table.DataColumns.FindXColumnOfGroup(lastColumnGroup); if (xColumnOfRightMost is Altaxo.Data.DoubleColumn) { xcol = (Altaxo.Data.DoubleColumn)xColumnOfRightMost; } } foreach (string filename in filenames) { var stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read); string error = ToDataTable(stream, out var localTable); stream.Close(); if (null != error) { errorList.Append(error); continue; } if (localTable.DataColumns.RowCount == 0) { continue; } xvalues = (DoubleColumn)localTable[0]; yvalues = (DoubleColumn)localTable[1]; // Add the necessary property columns for (int i = 0; i < localTable.PropCols.ColumnCount; i++) { string name = localTable.PropCols.GetColumnName(i); if (!table.PropCols.ContainsColumn(name)) { table.PropCols.Add((DataColumn)localTable.PropCols[i].Clone(), name, localTable.PropCols.GetColumnKind(i)); } } bool bMatchsXColumn = false; // first look if our default xcolumn matches the xvalues if (null != xcol) { bMatchsXColumn = ValuesMatch(xvalues, xcol); } // if no match, then consider all xcolumns from right to left, maybe some fits if (!bMatchsXColumn) { for (int ncol = table.DataColumns.ColumnCount - 1; ncol >= 0; ncol--) { if ((ColumnKind.X == table.DataColumns.GetColumnKind(ncol)) && (table.DataColumns[ncol] is DoubleColumn) && (ValuesMatch(xvalues, (DoubleColumn)table.DataColumns[ncol])) ) { xcol = (DoubleColumn)table.DataColumns[ncol]; lastColumnGroup = table.DataColumns.GetColumnGroup(xcol); bMatchsXColumn = true; break; } } } // create a new x column if the last one does not match if (!bMatchsXColumn) { xcol = new Altaxo.Data.DoubleColumn(); xcol.CopyDataFrom(xvalues); lastColumnGroup = table.DataColumns.GetUnusedColumnGroupNumber(); table.DataColumns.Add(xcol, "X", Altaxo.Data.ColumnKind.X, lastColumnGroup); } // now add the y-values var ycol = new Altaxo.Data.DoubleColumn(); ycol.CopyDataFrom(yvalues); table.DataColumns.Add(ycol, table.DataColumns.FindUniqueColumnName(System.IO.Path.GetFileNameWithoutExtension(filename)), Altaxo.Data.ColumnKind.V, lastColumnGroup); // add also a property column named "FilePath" if not existing so far if (!table.PropCols.ContainsColumn("FilePath")) { table.PropCols.Add(new Altaxo.Data.TextColumn(), "FilePath"); } // now set the file name property cell int yColumnNumber = table.DataColumns.GetColumnNumber(ycol); if (table.PropCols["FilePath"] is Altaxo.Data.TextColumn) { table.PropCols["FilePath"][yColumnNumber] = filename; } // set the other property columns for (int i = 0; i < localTable.PropCols.ColumnCount; i++) { string name = localTable.PropCols.GetColumnName(i); table.PropCols[name][yColumnNumber] = localTable.PropCols[i][1]; } } // foreache file return(errorList.Length == 0 ? null : errorList.ToString()); }
private static void AppendStatisticalData(DataColumnCollection destinationTable, Data.DoubleColumn colMean, Data.DoubleColumn colSd, Data.DoubleColumn colSe, Data.DoubleColumn colSum, Data.DoubleColumn colSumSqr, Data.DoubleColumn colN, Data.DoubleColumn fracOneSigma, Data.DoubleColumn fracTwoSigma, Data.DoubleColumn fracThreeSigma, DoubleColumn minimum, DoubleColumn maximum) { destinationTable.EnsureExistence(DefaultMeanColumnName, typeof(DoubleColumn), ColumnKind.V, 0).Append(colMean); destinationTable.EnsureExistence(DefaultStandardErrorColumnName, typeof(DoubleColumn), ColumnKind.Err, 0).Append(colSe); destinationTable.EnsureExistence(DefaultStandardDeviationColumnName, typeof(DoubleColumn), ColumnKind.V, 0).Append(colSd); destinationTable.EnsureExistence(DefaultSumColumnName, typeof(DoubleColumn), ColumnKind.V, 0).Append(colSum); destinationTable.EnsureExistence(DefaultSumSqrColumnName, typeof(DoubleColumn), ColumnKind.V, 0).Append(colSumSqr); destinationTable.EnsureExistence(DefaultNumberOfItemsColumnName, typeof(DoubleColumn), ColumnKind.V, 0).Append(colN); destinationTable.EnsureExistence(DefaultFractionInOneSigmaColumnName, typeof(DoubleColumn), ColumnKind.V, 0).Append(fracOneSigma); destinationTable.EnsureExistence(DefaultFractionInTwoSigmaColumnName, typeof(DoubleColumn), ColumnKind.V, 0).Append(fracTwoSigma); destinationTable.EnsureExistence(DefaultFractionInThreeSigmaColumnName, typeof(DoubleColumn), ColumnKind.V, 0).Append(fracThreeSigma); destinationTable.EnsureExistence(DefaultMinimumColumnName, typeof(DoubleColumn), ColumnKind.V, 0).Append(minimum); destinationTable.EnsureExistence(DefaultMaximumColumnName, typeof(DoubleColumn), ColumnKind.V, 0).Append(maximum); }
/// <summary> /// Imports a couple of SPC files into a table. The spectra are added as columns to the table. If the x column /// of the rightmost column does not match the x-data of the spectra, a new x-column is also created. /// </summary> /// <param name="filenames">An array of filenames to import.</param> /// <param name="table">The table the spectra should be imported to.</param> /// <returns>Null if no error occurs, or an error description.</returns> public static string ImportSpcFiles(string[] filenames, Altaxo.Data.DataTable table) { Altaxo.Data.DoubleColumn xcol = null; double[] xvalues, yvalues; System.Text.StringBuilder errorList = new System.Text.StringBuilder(); int lastColumnGroup = 0; if (table.DataColumns.ColumnCount > 0) { lastColumnGroup = table.DataColumns.GetColumnGroup(table.DataColumns.ColumnCount - 1); Altaxo.Data.DataColumn xColumnOfRightMost = table.DataColumns.FindXColumnOfGroup(lastColumnGroup); if (xColumnOfRightMost is Altaxo.Data.DoubleColumn) { xcol = (Altaxo.Data.DoubleColumn)xColumnOfRightMost; } } foreach (string filename in filenames) { string error = ToArrays(filename, out xvalues, out yvalues); if (null != error) { errorList.Append(error); continue; } bool bMatchsXColumn = false; // first look if our default xcolumn matches the xvalues if (null != xcol) { bMatchsXColumn = ValuesMatch(xvalues, xcol); } // if no match, then consider all xcolumns from right to left, maybe some fits if (!bMatchsXColumn) { for (int ncol = table.DataColumns.ColumnCount - 1; ncol >= 0; ncol--) { if ((ColumnKind.X == table.DataColumns.GetColumnKind(ncol)) && (table.DataColumns[ncol] is DoubleColumn) && (ValuesMatch(xvalues, (DoubleColumn)table.DataColumns[ncol])) ) { xcol = (DoubleColumn)table.DataColumns[ncol]; lastColumnGroup = table.DataColumns.GetColumnGroup(xcol); bMatchsXColumn = true; break; } } } // create a new x column if the last one does not match if (!bMatchsXColumn) { xcol = new Altaxo.Data.DoubleColumn(); xcol.CopyDataFrom(xvalues); lastColumnGroup = table.DataColumns.GetUnusedColumnGroupNumber(); table.DataColumns.Add(xcol, "SPC X values", Altaxo.Data.ColumnKind.X, lastColumnGroup); } // now add the y-values Altaxo.Data.DoubleColumn ycol = new Altaxo.Data.DoubleColumn(); ycol.CopyDataFrom(yvalues); table.DataColumns.Add(ycol, table.DataColumns.FindUniqueColumnName(System.IO.Path.GetFileNameWithoutExtension(filename)), Altaxo.Data.ColumnKind.V, lastColumnGroup); // add also a property column named "FilePath" if not existing so far if (!table.PropCols.ContainsColumn("FilePath")) { table.PropCols.Add(new Altaxo.Data.TextColumn(), "FilePath"); } // now set the file name property cell if (table.PropCols["FilePath"] is Altaxo.Data.TextColumn) { table.PropCols["FilePath"][table.DataColumns.GetColumnNumber(ycol)] = filename; } } // foreache file return(errorList.Length == 0 ? null : errorList.ToString()); }
public static DataColumn GetAltaxoColumnFromOriginDataFormat(COLDATAFORMAT originColDataFormat) { // create a column Altaxo.Data.DataColumn destCol = null; switch (originColDataFormat) { case COLDATAFORMAT.DF_BYTE: destCol = new Altaxo.Data.DoubleColumn(); break; case COLDATAFORMAT.DF_CHAR: destCol = new Altaxo.Data.DoubleColumn(); break; case COLDATAFORMAT.DF_COMPLEX: destCol = new Altaxo.Data.DoubleColumn(); break; case COLDATAFORMAT.DF_DATE: destCol = new Altaxo.Data.DateTimeColumn(); break; case COLDATAFORMAT.DF_DOUBLE: destCol = new Altaxo.Data.DoubleColumn(); break; case COLDATAFORMAT.DF_FLOAT: destCol = new Altaxo.Data.DoubleColumn(); break; case COLDATAFORMAT.DF_LONG: destCol = new Altaxo.Data.DoubleColumn(); break; case COLDATAFORMAT.DF_SHORT: destCol = new Altaxo.Data.DoubleColumn(); break; case COLDATAFORMAT.DF_TEXT: destCol = new Altaxo.Data.TextColumn(); break; case COLDATAFORMAT.DF_TEXT_NUMERIC: destCol = new Altaxo.Data.TextColumn(); break; case COLDATAFORMAT.DF_TIME: destCol = new Altaxo.Data.DateTimeColumn(); break; case COLDATAFORMAT.DF_ULONG: destCol = new Altaxo.Data.DoubleColumn(); break; case COLDATAFORMAT.DF_USHORT: destCol = new Altaxo.Data.DoubleColumn(); break; default: destCol = new Altaxo.Data.TextColumn(); break; } return(destCol); }
/// <summary> /// Retrieves the data columns from an Origin table. /// </summary> /// <param name="wks">The Origin worksheet to retrieve the data from.</param> /// <returns>The data columns with the data from the Origin worksheet.</returns> public static Altaxo.Data.DataColumnCollection GetDataColumns(this Origin.Worksheet wks) { var culture = Current.PropertyService.GetValue(Altaxo.Settings.CultureSettings.PropertyKeyDocumentCulture, Altaxo.Main.Services.RuntimePropertyKind.UserAndApplicationAndBuiltin).Culture; int nCols = wks.Cols; var result = new Altaxo.Data.DataColumnCollection(); for (int c = 0; c < nCols; c++) { var srcCol = wks.Columns[c]; Altaxo.Data.DataColumn destCol = GetAltaxoColumnFromOriginDataFormat(srcCol.DataFormat); int groupNumber = -1; var altaxoColumnKind = OriginToAltaxoColumnKind(srcCol.Type); if (altaxoColumnKind == Altaxo.Data.ColumnKind.X) { groupNumber++; } if (destCol is DoubleColumn) { var data = srcCol.GetData(Origin.ARRAYDATAFORMAT.ARRAY1D_NUMERIC, 0, -1, 0); (destCol as DoubleColumn).Array = (double[])data; } else if (destCol is DateTimeColumn) { var data = (double[])srcCol.GetData(Origin.ARRAYDATAFORMAT.ARRAY1D_NUMERIC, 0, -1, 0); const double refDateAsDouble = 2451910; // this is the number of days in julian calendar belonging to the date below... var refDate = DateTime.Parse("2001-01-01", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AssumeUniversal); for (int i = data.Length - 1; i >= 0; --i) { destCol[i] = refDate.AddDays(data[i] - refDateAsDouble); } } else if (destCol is TextColumn && srcCol.DataFormat == COLDATAFORMAT.DF_TEXT_NUMERIC) { var data = srcCol.GetData(Origin.ARRAYDATAFORMAT.ARRAY1D_VARIANT, 0, -1, 0); var destColNum = new Altaxo.Data.DoubleColumn(); object[] oarr; if (null != (oarr = data as object[])) { int numberOfNums = 0; int numberOfObjects = 0; for (int i = 0; i < oarr.Length; ++i) { if (oarr[i] is double) { destColNum[i] = (double)oarr[i]; ++numberOfNums; } if (oarr[i] != null) { destCol[i] = string.Format(culture, "{0}", oarr[i]); ++numberOfObjects; } } // if the column consist mostly of numerics, then exchange it with destcol if (numberOfNums >= 0.99 * numberOfObjects || numberOfNums >= numberOfObjects - 2) { destCol = destColNum; } } } else if (destCol is TextColumn) { var data = srcCol.GetData(Origin.ARRAYDATAFORMAT.ARRAY1D_TEXT, 0, -1, 0); string[] sarr; object[] oarr; if (null != (sarr = data as string[])) { (destCol as TextColumn).Array = sarr; } else if (null != (oarr = data as object[])) { for (int i = 0; i < oarr.Length; ++i) { if (null != oarr[i]) { destCol[i] = string.Format(culture, "{0}", oarr[i]); } else { destCol[i] = null; } } } } result.Add(destCol, (!string.IsNullOrEmpty(srcCol.LongName) ? srcCol.LongName : srcCol.Name), altaxoColumnKind, Math.Max(0, groupNumber)); } return(result); }
/// <summary> /// Calculate the cross PRESS values and stores the results in the provided table. /// </summary> /// <param name="xOfX">Vector of spectral wavelengths. Necessary to divide the spectras in different regions.</param> /// <param name="matrixX">Matrix of spectra (horizontal oriented).</param> /// <param name="matrixY">Matrix of concentrations.</param> /// <param name="plsOptions">Analysis options.</param> /// <param name="plsContent">Information about this analysis.</param> /// <param name="table">Table to store the results.</param> public virtual void CalculateCrossPRESS( IROVector xOfX, IMatrix matrixX, IMatrix matrixY, MultivariateAnalysisOptions plsOptions, MultivariateContentMemento plsContent, DataTable table ) { IROVector crossPRESSMatrix; Altaxo.Data.DoubleColumn crosspresscol = new Altaxo.Data.DoubleColumn(); double meanNumberOfExcludedSpectra = 0; if (plsOptions.CrossPRESSCalculation != CrossPRESSCalculationType.None) { // now a cross validation - this can take a long time for bigger matrices MultivariateRegression.GetCrossPRESS( xOfX, matrixX, matrixY, plsOptions.MaxNumberOfFactors, GetGroupingStrategy(plsOptions), plsContent.SpectralPreprocessing, this.CreateNewRegressionObject(), out crossPRESSMatrix); VectorMath.Copy(crossPRESSMatrix, DataColumnWrapper.ToVector(crosspresscol, crossPRESSMatrix.Length)); table.DataColumns.Add(crosspresscol, GetCrossPRESSValue_ColumnName(), Altaxo.Data.ColumnKind.V, 4); plsContent.MeanNumberOfMeasurementsInCrossPRESSCalculation = plsContent.NumberOfMeasurements - meanNumberOfExcludedSpectra; } else { table.DataColumns.Add(crosspresscol, GetCrossPRESSValue_ColumnName(), Altaxo.Data.ColumnKind.V, 4); } }
public virtual void StorePRESSData( IROVector PRESS, DataTable table) { StoreNumberOfFactors(PRESS.Length, table); Altaxo.Data.DoubleColumn presscol = new Altaxo.Data.DoubleColumn(); for (int i = 0; i < PRESS.Length; i++) presscol[i] = PRESS[i]; table.DataColumns.Add(presscol, GetPRESSValue_ColumnName(), Altaxo.Data.ColumnKind.V, 4); }
/// <summary> /// Calculates the leverage of the spectral data. /// </summary> /// <param name="table">Table where the calibration model is stored.</param> /// <param name="numberOfFactors">Number of factors used to calculate leverage.</param> public virtual void CalculateXLeverage( DataTable table, int numberOfFactors) { var plsMemo = GetContentAsMultivariateContentMemento(table); if (plsMemo == null) throw new ArgumentException("Table does not contain a PLSContentMemento"); IMultivariateCalibrationModel calib = this.GetCalibrationModel(table); IMatrix matrixX = GetRawSpectra(plsMemo); MultivariateRegression.PreprocessSpectraForPrediction(calib, plsMemo.SpectralPreprocessing, matrixX); MultivariateRegression regress = this.CreateNewRegressionObject(); regress.SetCalibrationModel(calib); IROMatrix xLeverage = regress.GetXLeverageFromRaw(matrixX, numberOfFactors); for (int i = 0; i < xLeverage.Columns; i++) { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); MatrixMath.SetColumn(xLeverage, i, DataColumnWrapper.ToVertMatrix(col, xLeverage.Rows), 0); table.DataColumns.Add( col, xLeverage.Columns == 1 ? GetXLeverage_ColumnName(numberOfFactors) : GetXLeverage_ColumnName(i, numberOfFactors), Altaxo.Data.ColumnKind.V, GetXLeverage_ColumnGroup()); } }
public virtual void StoreFRatioData( DataTable table, MultivariateContentMemento plsContent) { DoubleColumn pressColumn = null; DoubleColumn crossPRESSColumn = null; if (table.DataColumns.Contains(GetPRESSValue_ColumnName())) pressColumn = table[GetPRESSValue_ColumnName()] as DoubleColumn; if (table.DataColumns.Contains(GetCrossPRESSValue_ColumnName())) crossPRESSColumn = table[GetCrossPRESSValue_ColumnName()] as DoubleColumn; IROVector press; double meanNumberOfIncludedSpectra = plsContent.NumberOfMeasurements; if (crossPRESSColumn != null && crossPRESSColumn.Count > 0) { press = DataColumnWrapper.ToROVector(crossPRESSColumn); meanNumberOfIncludedSpectra = plsContent.MeanNumberOfMeasurementsInCrossPRESSCalculation; } else if (pressColumn != null && pressColumn.Count > 0) { press = DataColumnWrapper.ToROVector(pressColumn); meanNumberOfIncludedSpectra = plsContent.NumberOfMeasurements; } else return; // calculate the F-ratio and the F-Probability int numberOfSignificantFactors = press.Length; double pressMin = double.MaxValue; for (int i = 0; i < press.Length; i++) pressMin = Math.Min(pressMin, press[i]); DoubleColumn fratiocol = new DoubleColumn(); DoubleColumn fprobcol = new DoubleColumn(); for (int i = 0; i < press.Length; i++) { double fratio = press[i] / pressMin; double fprob = Calc.Probability.FDistribution.CDF(fratio, meanNumberOfIncludedSpectra, meanNumberOfIncludedSpectra); fratiocol[i] = fratio; fprobcol[i] = fprob; if (fprob < 0.75 && numberOfSignificantFactors > i) numberOfSignificantFactors = i; } plsContent.PreferredNumberOfFactors = numberOfSignificantFactors; table.DataColumns.Add(fratiocol, _FRatio_ColumnName, Altaxo.Data.ColumnKind.V, _FRatio_ColumnGroup); table.DataColumns.Add(fprobcol, _FProbability_ColumnName, Altaxo.Data.ColumnKind.V, _FProbability_ColumnGroup); }
/// <summary> /// Makes a PCA (a principal component analysis) of the table or the selected columns / rows and stores the results in a newly created table. /// </summary> /// <param name="mainDocument">The main document of the application.</param> /// <param name="srctable">The table where the data come from.</param> /// <param name="selectedColumns">The selected columns.</param> /// <param name="selectedRows">The selected rows.</param> /// <param name="bHorizontalOrientedSpectrum">True if a spectrum is a single row, False if a spectrum is a single column.</param> /// <param name="maxNumberOfFactors">The maximum number of factors to calculate.</param> /// <returns></returns> public static string PrincipalComponentAnalysis( Altaxo.AltaxoDocument mainDocument, Altaxo.Data.DataTable srctable, IAscendingIntegerCollection selectedColumns, IAscendingIntegerCollection selectedRows, bool bHorizontalOrientedSpectrum, int maxNumberOfFactors ) { bool bUseSelectedColumns = (null!=selectedColumns && 0!=selectedColumns.Count); int prenumcols = bUseSelectedColumns ? selectedColumns.Count : srctable.DataColumns.ColumnCount; // check for the number of numeric columns int numcols = 0; for(int i=0;i<prenumcols;i++) { int idx = bUseSelectedColumns ? selectedColumns[i] : i; if(srctable[i] is Altaxo.Data.INumericColumn) numcols++; } // check the number of rows bool bUseSelectedRows = (null!=selectedRows && 0!=selectedRows.Count); int numrows; if(bUseSelectedRows) numrows = selectedRows.Count; else { numrows = 0; for(int i=0;i<numcols;i++) { int idx = bUseSelectedColumns ? selectedColumns[i] : i; numrows = Math.Max(numrows,srctable[idx].Count); } } // check that both dimensions are at least 2 - otherwise PCA is not possible if(numrows<2) return "At least two rows are neccessary to do Principal Component Analysis!"; if(numcols<2) return "At least two numeric columns are neccessary to do Principal Component Analysis!"; // Create a matrix of appropriate dimensions and fill it MatrixMath.BEMatrix matrixX; if(bHorizontalOrientedSpectrum) { matrixX = new MatrixMath.BEMatrix(numrows,numcols); int ccol = 0; // current column in the matrix for(int i=0;i<prenumcols;i++) { int colidx = bUseSelectedColumns ? selectedColumns[i] : i; Altaxo.Data.INumericColumn col = srctable[colidx] as Altaxo.Data.INumericColumn; if(null!=col) { for(int j=0;j<numrows;j++) { int rowidx = bUseSelectedRows ? selectedRows[j] : j; matrixX[j,ccol] = col[rowidx]; } ++ccol; } } } // end if it was a horizontal oriented spectrum else // if it is a vertical oriented spectrum { matrixX = new MatrixMath.BEMatrix(numcols,numrows); int ccol = 0; // current column in the matrix for(int i=0;i<prenumcols;i++) { int colidx = bUseSelectedColumns ? selectedColumns[i] : i; Altaxo.Data.INumericColumn col = srctable[colidx] as Altaxo.Data.INumericColumn; if(null!=col) { for(int j=0;j<numrows;j++) { int rowidx = bUseSelectedRows ? selectedRows[j] : j; matrixX[ccol,j] = col[rowidx]; } ++ccol; } } } // if it was a vertical oriented spectrum // now do PCA with the matrix MatrixMath.REMatrix factors = new MatrixMath.REMatrix(0,0); MatrixMath.BEMatrix loads = new MatrixMath.BEMatrix(0,0); MatrixMath.BEMatrix residualVariances = new MatrixMath.BEMatrix(0,0); MatrixMath.HorizontalVector meanX = new MatrixMath.HorizontalVector(matrixX.Columns); // first, center the matrix MatrixMath.ColumnsToZeroMean(matrixX,meanX); MatrixMath.NIPALS_HO(matrixX,maxNumberOfFactors,1E-9,factors,loads,residualVariances); // now we have to create a new table where to place the calculated factors and loads // we will do that in a vertical oriented manner, i.e. even if the loads are // here in horizontal vectors: in our table they are stored in (vertical) columns Altaxo.Data.DataTable table = new Altaxo.Data.DataTable("PCA of " + srctable.Name); // Fill the Table table.Suspend(); // first of all store the meanscore { double meanScore = MatrixMath.LengthOf(meanX); MatrixMath.NormalizeRows(meanX); Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for(int i=0;i<factors.Rows;i++) col[i] = meanScore; table.DataColumns.Add(col,"MeanFactor",Altaxo.Data.ColumnKind.V,0); } // first store the factors for(int i=0;i<factors.Columns;i++) { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for(int j=0;j<factors.Rows;j++) col[j] = factors[j,i]; table.DataColumns.Add(col,"Factor"+i.ToString(),Altaxo.Data.ColumnKind.V,1); } // now store the mean of the matrix { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for(int j=0;j<meanX.Columns;j++) col[j] = meanX[0,j]; table.DataColumns.Add(col,"MeanLoad",Altaxo.Data.ColumnKind.V,2); } // now store the loads - careful - they are horizontal in the matrix for(int i=0;i<loads.Rows;i++) { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for(int j=0;j<loads.Columns;j++) col[j] = loads[i,j]; table.DataColumns.Add(col,"Load"+i.ToString(),Altaxo.Data.ColumnKind.V,3); } // now store the residual variances, they are vertical in the vector { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for(int i=0;i<residualVariances.Rows;i++) col[i] = residualVariances[i,0]; table.DataColumns.Add(col,"ResidualVariance",Altaxo.Data.ColumnKind.V,4); } table.Resume(); mainDocument.DataTableCollection.Add(table); // create a new worksheet without any columns Current.ProjectService.CreateNewWorksheet(table); return null; }
public void StoreOriginalY( DataTable table, MultivariateContentMemento plsContent ) { IMatrix matrixY = GetOriginalY(plsContent); IMultivariateCalibrationModel calib = GetCalibrationModel(table); // add a label column for the measurement number Altaxo.Data.DoubleColumn measurementLabel = new Altaxo.Data.DoubleColumn(); for (int i = 0; i < plsContent.MeasurementIndices.Count; i++) measurementLabel[i] = plsContent.MeasurementIndices[i]; table.DataColumns.Add(measurementLabel, _MeasurementLabel_ColumnName, Altaxo.Data.ColumnKind.Label, _MeasurementLabel_ColumnGroup); // now add the original Y-Columns for (int i = 0; i < matrixY.Columns; i++) { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for (int j = 0; j < matrixY.Rows; j++) col[j] = matrixY[j, i]; table.DataColumns.Add(col, _YOriginal_ColumnName + i.ToString(), Altaxo.Data.ColumnKind.X, 5 + i); } }
public static void Interpolation(IWorksheetController ctrl, InterpolationParameters parameters) { Dictionary<DataColumn, int> _columnToGroupNumber = new Dictionary<DataColumn, int>(); for (int nSel = 0; nSel < ctrl.SelectedDataColumns.Count; nSel++) { Altaxo.Data.DataColumn yCol = ctrl.DataTable.DataColumns[ctrl.SelectedDataColumns[nSel]]; Altaxo.Data.DataColumn xCol = ctrl.DataTable.DataColumns.FindXColumnOf(yCol); if (!(yCol is INumericColumn)) { Current.Gui.ErrorMessageBox("The selected column is not numeric!"); return; } if (!(xCol is INumericColumn)) { Current.Gui.ErrorMessageBox("The x-column of the selected column is not numeric!"); return; } DoubleColumn xRes = new DoubleColumn(); DoubleColumn yRes = new DoubleColumn(); int newgroup; if (!_columnToGroupNumber.TryGetValue(xCol, out newgroup)) { newgroup = ctrl.DataTable.DataColumns.GetUnusedColumnGroupNumber(); ctrl.DataTable.DataColumns.Add(xRes, xCol.Name + ".I", ColumnKind.X, newgroup); _columnToGroupNumber.Add(xCol, newgroup); } ctrl.DataTable.DataColumns.Add(yRes, yCol.Name + ".I", ColumnKind.V, newgroup); Interpolation(xCol, yCol, parameters, xRes, yRes); } }
public virtual void CalculatePredictedAndResidual( DataTable table, int whichY, int numberOfFactors, bool saveYPredicted, bool saveYResidual, bool saveXResidual) { var plsMemo = GetContentAsMultivariateContentMemento(table); if (plsMemo == null) throw new ArgumentException("Table does not contain a PLSContentMemento"); IMultivariateCalibrationModel calib = GetCalibrationModel(table); // Export(table,out calib); IMatrix matrixX = GetRawSpectra(plsMemo); MatrixMath.BEMatrix predictedY = new MatrixMath.BEMatrix(matrixX.Rows, calib.NumberOfY); MatrixMath.BEMatrix spectralResiduals = new MatrixMath.BEMatrix(matrixX.Rows, 1); CalculatePredictedY(calib, plsMemo.SpectralPreprocessing, matrixX, numberOfFactors, predictedY, spectralResiduals); if (saveYPredicted) { // insert a column with the proper name into the table and fill it string ycolname = GetYPredicted_ColumnName(whichY, numberOfFactors); Altaxo.Data.DoubleColumn ycolumn = new Altaxo.Data.DoubleColumn(); for (int i = 0; i < predictedY.Rows; i++) ycolumn[i] = predictedY[i, whichY]; table.DataColumns.Add(ycolumn, ycolname, Altaxo.Data.ColumnKind.V, GetYPredicted_ColumnGroup()); } // subract the original y data IMatrix matrixY = GetOriginalY(plsMemo); MatrixMath.SubtractColumn(predictedY, matrixY, whichY, predictedY); if (saveYResidual) { // insert a column with the proper name into the table and fill it string ycolname = GetYResidual_ColumnName(whichY, numberOfFactors); Altaxo.Data.DoubleColumn ycolumn = new Altaxo.Data.DoubleColumn(); for (int i = 0; i < predictedY.Rows; i++) ycolumn[i] = predictedY[i, whichY]; table.DataColumns.Add(ycolumn, ycolname, Altaxo.Data.ColumnKind.V, GetYResidual_ColumnGroup()); } if (saveXResidual) { // insert a column with the proper name into the table and fill it string ycolname = GetXResidual_ColumnName(whichY, numberOfFactors); Altaxo.Data.DoubleColumn ycolumn = new Altaxo.Data.DoubleColumn(); for (int i = 0; i < matrixX.Rows; i++) { ycolumn[i] = spectralResiduals[i, 0]; } table.DataColumns.Add(ycolumn, ycolname, Altaxo.Data.ColumnKind.V, GetXResidual_ColumnGroup()); } }
/// <summary> /// Multiplies selected columns to form a matrix. /// </summary> /// <param name="mainDocument"></param> /// <param name="srctable"></param> /// <param name="selectedColumns"></param> /// <returns>Null if successful, else the description of the error.</returns> /// <remarks>The user must select an even number of columns. All columns of the first half of the selection /// must have the same number of rows, and all columns of the second half of selection must also have the same /// number of rows. The first half of selected columns form a matrix of dimensions(firstrowcount,halfselected), and the second half /// of selected columns form a matrix of dimension(halfselected, secondrowcount). The resulting matrix has dimensions (firstrowcount,secondrowcount) and is /// stored in a separate worksheet.</remarks> public static string MultiplyColumnsToMatrix( Altaxo.AltaxoDocument mainDocument, Altaxo.Data.DataTable srctable, IAscendingIntegerCollection selectedColumns ) { // check that there are columns selected if (0 == selectedColumns.Count) { return("You must select at least two columns to multiply!"); } // selected columns must contain an even number of columns if (0 != selectedColumns.Count % 2) { return("You selected an odd number of columns. Please select an even number of columns to multiply!"); } // all selected columns must be numeric columns for (int i = 0; i < selectedColumns.Count; i++) { if (!(srctable[selectedColumns[i]] is Altaxo.Data.INumericColumn)) { return(string.Format("The column[{0}] (name:{1}) is not a numeric column!", selectedColumns[i], srctable[selectedColumns[i]].Name)); } } int halfselect = selectedColumns.Count / 2; // check that all columns from the first half of selected colums contain the same // number of rows int rowsfirsthalf = int.MinValue; for (int i = 0; i < halfselect; i++) { int idx = selectedColumns[i]; if (rowsfirsthalf < 0) { rowsfirsthalf = srctable[idx].Count; } else if (rowsfirsthalf != srctable[idx].Count) { return("The first half of selected columns have not all the same length!"); } } int rowssecondhalf = int.MinValue; for (int i = halfselect; i < selectedColumns.Count; i++) { int idx = selectedColumns[i]; if (rowssecondhalf < 0) { rowssecondhalf = srctable[idx].Count; } else if (rowssecondhalf != srctable[idx].Count) { return("The second half of selected columns have not all the same length!"); } } // now create the matrices to multiply from the MatrixMath.REMatrix firstMat = new MatrixMath.REMatrix(rowsfirsthalf, halfselect); for (int i = 0; i < halfselect; i++) { Altaxo.Data.INumericColumn col = (Altaxo.Data.INumericColumn)srctable[selectedColumns[i]]; for (int j = 0; j < rowsfirsthalf; j++) { firstMat[j, i] = col[j]; } } MatrixMath.BEMatrix secondMat = new MatrixMath.BEMatrix(halfselect, rowssecondhalf); for (int i = 0; i < halfselect; i++) { Altaxo.Data.INumericColumn col = (Altaxo.Data.INumericColumn)srctable[selectedColumns[i + halfselect]]; for (int j = 0; j < rowssecondhalf; j++) { secondMat[i, j] = col[j]; } } // now multiply the two matrices MatrixMath.BEMatrix resultMat = new MatrixMath.BEMatrix(rowsfirsthalf, rowssecondhalf); MatrixMath.Multiply(firstMat, secondMat, resultMat); // and store the result in a new worksheet Altaxo.Data.DataTable table = new Altaxo.Data.DataTable("ResultMatrix of " + srctable.Name); table.Suspend(); // first store the factors for (int i = 0; i < resultMat.Columns; i++) { Altaxo.Data.DoubleColumn col = new Altaxo.Data.DoubleColumn(); for (int j = 0; j < resultMat.Rows; j++) { col[j] = resultMat[j, i]; } table.DataColumns.Add(col, i.ToString()); } table.Resume(); mainDocument.DataTableCollection.Add(table); // create a new worksheet without any columns Current.ProjectService.CreateNewWorksheet(table); return(null); }
public void CalculateAndStorePredictionScores(DataTable table, int preferredNumberOfFactors) { IROMatrix predictionScores = this.CalculatePredictionScores(table, preferredNumberOfFactors); for (int i = 0; i < predictionScores.Columns; i++) { DoubleColumn col = new DoubleColumn(); for (int j = 0; j < predictionScores.Rows; j++) col[j] = predictionScores[j, i]; table.DataColumns.Add(col, GetPredictionScore_ColumnName(i, preferredNumberOfFactors), Altaxo.Data.ColumnKind.V, GetPredictionScore_ColumnGroup()); } }
public static void RealFourierTransform(RealFourierTransformOptions options) { var yCol = options.ColumnToTransform; int fftLen = yCol.Count; double[] resultCol = new double[fftLen]; for (int i = 0; i < resultCol.Length; ++i) resultCol[i] = yCol[i]; var transform = new Calc.Fourier.RealFourierTransform(fftLen); transform.Transform(resultCol, Calc.Fourier.FourierDirection.Forward); var wrapper = new Calc.Fourier.RealFFTResultWrapper(resultCol); DataTable outputTable = null; switch (options.OutputPlacement) { case RealFourierTransformOutputPlacement.CreateInNewWorksheet: outputTable = new DataTable(); outputTable.Name = "Real FFT results"; Current.Project.DataTableCollection.Add(outputTable); Current.ProjectService.OpenOrCreateWorksheetForTable(outputTable); break; case RealFourierTransformOutputPlacement.CreateInSameWorksheet: outputTable = DataTable.GetParentDataTableOf(yCol); if (null == outputTable) throw new ArgumentException("Provided y-column does not belong to a data table."); break; default: throw new ArgumentOutOfRangeException("Unkown enum value: " + options.OutputPlacement.ToString()); } // create the x-Column first var freqCol = new DoubleColumn(); freqCol.AssignVector = wrapper.FrequenciesFromXIncrement(options.XIncrementValue); int outputGroup = outputTable.DataColumns.GetUnusedColumnGroupNumber(); outputTable.DataColumns.Add(freqCol, "Frequency", ColumnKind.X, outputGroup); // now create the other output cols if (options.Output.HasFlag(RealFourierTransformOutput.Re)) { var col = new DoubleColumn(); col.AssignVector = wrapper.RealPart; outputTable.DataColumns.Add(col, "Re", ColumnKind.V, outputGroup); } if (options.Output.HasFlag(RealFourierTransformOutput.Im)) { var col = new DoubleColumn(); col.AssignVector = wrapper.ImaginaryPart; outputTable.DataColumns.Add(col, "Im", ColumnKind.V, outputGroup); } if (options.Output.HasFlag(RealFourierTransformOutput.Abs)) { var col = new DoubleColumn(); col.AssignVector = wrapper.Amplitude; outputTable.DataColumns.Add(col, "Abs", ColumnKind.V, outputGroup); } if (options.Output.HasFlag(RealFourierTransformOutput.Phase)) { var col = new DoubleColumn(); col.AssignVector = wrapper.Phase; outputTable.DataColumns.Add(col, "Phase", ColumnKind.V, outputGroup); } if (options.Output.HasFlag(RealFourierTransformOutput.Power)) { var col = new DoubleColumn(); col.AssignVector = wrapper.Amplitude; col.Data = col * col; outputTable.DataColumns.Add(col, "Power", ColumnKind.V, outputGroup); } }
/// <summary> /// Constructor /// </summary> /// <param name="column">The <see cref="DataColumn" /> to wrap.</param> /// <param name="nRows">The number of rows that are part of the vector. (Starting from index 0).</param> public DoubleColumnToVertMatrixWrapper(Altaxo.Data.DoubleColumn column, int nRows) { _column = column; _rows = nRows; }
/// <summary> /// Calculates statistics of selected columns. Creates a new table where the statistical data will be written to. /// </summary> /// <param name="srctable">Source table.</param> /// <param name="selectedColumns">Selected data columns in the source table.</param> /// <param name="selectedRows">Selected rows in the source table.</param> /// <param name="destinationTable">The table where the statistical results are written to.</param> public static void DoStatisticsOnRows( this DataColumnCollection srctable, IAscendingIntegerCollection selectedColumns, IAscendingIntegerCollection selectedRows, DataColumnCollection destinationTable ) { bool bUseSelectedColumns = (null != selectedColumns && 0 != selectedColumns.Count); int numcols = bUseSelectedColumns ? selectedColumns.Count : srctable.ColumnCount; if (numcols == 0) return; // nothing selected bool bUseSelectedRows = (null != selectedRows && 0 != selectedRows.Count); int numrows = bUseSelectedRows ? selectedRows.Count : srctable.RowCount; if (numrows == 0) return; Data.DoubleColumn cRows = new DoubleColumn(); // 1st column is the mean, and holds the sum during the calculation Data.DoubleColumn colMean = new Data.DoubleColumn(); // 2rd column is the standard deviation, and holds the square sum during calculation Data.DoubleColumn colSD = new Data.DoubleColumn(); // 3th column is the standard e (N) Data.DoubleColumn colSE = new Data.DoubleColumn(); // 4th column is the sum Data.DoubleColumn colSum = new Data.DoubleColumn(); // 5th column is the number of items for statistics Data.DoubleColumn colNN = new Data.DoubleColumn(); var colSumSqr = new Data.DoubleColumn(); var colFracOneSigma = new Data.DoubleColumn(); var colFracTwoSigma = new Data.DoubleColumn(); var colFracThreeSigma = new Data.DoubleColumn(); var colMinimum = new DoubleColumn(); var colMaximum = new DoubleColumn(); // first fill the cols c1, c2, c5 with zeros because we want to sum up for (int i = 0; i < numrows; i++) { colSum[i] = 0; colSumSqr[i] = 0; colNN[i] = 0; colMinimum[i] = double.PositiveInfinity; colMaximum[i] = double.NegativeInfinity; } for (int si = 0; si < numcols; si++) { Altaxo.Data.DataColumn col = bUseSelectedColumns ? srctable[selectedColumns[si]] : srctable[si]; if (!(col is Altaxo.Data.INumericColumn)) continue; // now do the statistics Data.INumericColumn ncol = (Data.INumericColumn)col; for (int i = 0; i < numrows; i++) { int row = bUseSelectedRows ? selectedRows[i] : i; cRows[i] = row; double val = ncol[row]; if (Double.IsNaN(val)) continue; colSum[i] += val; colSumSqr[i] += val * val; colNN[i] += 1; colMinimum[i] = Math.Min(colMinimum[i], val); colMaximum[i] = Math.Max(colMaximum[i], val); } } // for all selected columns // now calculate the statistics for (int i = 0; i < numrows; i++) { // now fill a new row in the worksheet double NN = colNN[i]; double sum = colSum[i]; double sumsqr = colSumSqr[i]; if (NN > 0) { double mean = sum / NN; double ymy0sqr = sumsqr - sum * sum / NN; if (ymy0sqr < 0) ymy0sqr = 0; // if this is lesser zero, it is a rounding error, so set it to zero double sd = NN > 1 ? Math.Sqrt(ymy0sqr / (NN - 1)) : 0; double se = sd / Math.Sqrt(NN); colMean[i] = mean; // mean colSD[i] = sd; colSE[i] = se; } else { colMinimum[i] = double.NaN; colMaximum[i] = double.NaN; } } // for all rows // calculate fractions for (int i = 0; i < numrows; i++) { int row = bUseSelectedRows ? selectedRows[i] : i; double mean = colMean[i]; double sd = colSD[i]; // calculate fractions double oneSigmaLo = mean - 1 * sd, oneSigmaHi = mean + 1 * sd; double twoSigmaLo = mean - 2 * sd, twoSigmaHi = mean + 2 * sd; double threeSigmaLo = mean - 3 * sd, threeSigmaHi = mean + 3 * sd; int cntOneSigma = 0, cntTwoSigma = 0, cntThreeSigma = 0; for (int si = 0; si < numcols; si++) { Altaxo.Data.DataColumn col = bUseSelectedColumns ? srctable[selectedColumns[si]] : srctable[si]; if (!(col is Altaxo.Data.INumericColumn)) continue; // now do the statistics Data.INumericColumn ncol = (Data.INumericColumn)col; double val = ncol[row]; if (Double.IsNaN(val)) continue; if (Altaxo.Calc.RMath.IsInIntervalCC(val, oneSigmaLo, oneSigmaHi)) ++cntOneSigma; if (Altaxo.Calc.RMath.IsInIntervalCC(val, twoSigmaLo, twoSigmaHi)) ++cntTwoSigma; if (Altaxo.Calc.RMath.IsInIntervalCC(val, threeSigmaLo, threeSigmaHi)) ++cntThreeSigma; } colFracOneSigma[i] = cntOneSigma / (double)colNN[i]; colFracTwoSigma[i] = cntTwoSigma / (double)colNN[i]; colFracThreeSigma[i] = cntThreeSigma / (double)colNN[i]; } destinationTable.EnsureExistence(DefaultRowNumberColumnName, typeof(DoubleColumn), ColumnKind.X, 0).Append(cRows); AppendStatisticalData(destinationTable, colMean, colSD, colSE, colSum, colSumSqr, colNN, colFracOneSigma, colFracTwoSigma, colFracThreeSigma, colMinimum, colMaximum); }
public virtual void StorePreprocessedData( IROVector meanX, IROVector scaleX, IROVector meanY, IROVector scaleY, DataTable table) { // Store X-Mean and X-Scale Altaxo.Data.DoubleColumn colXMean = new Altaxo.Data.DoubleColumn(); Altaxo.Data.DoubleColumn colXScale = new Altaxo.Data.DoubleColumn(); for (int i = 0; i < meanX.Length; i++) { colXMean[i] = meanX[i]; colXScale[i] = scaleX[i]; } table.DataColumns.Add(colXMean, _XMean_ColumnName, Altaxo.Data.ColumnKind.V, 0); table.DataColumns.Add(colXScale, _XScale_ColumnName, Altaxo.Data.ColumnKind.V, 0); // store the y-mean and y-scale Altaxo.Data.DoubleColumn colYMean = new Altaxo.Data.DoubleColumn(); Altaxo.Data.DoubleColumn colYScale = new Altaxo.Data.DoubleColumn(); for (int i = 0; i < meanY.Length; i++) { colYMean[i] = meanY[i]; colYScale[i] = 1; } table.DataColumns.Add(colYMean, _YMean_ColumnName, Altaxo.Data.ColumnKind.V, 1); table.DataColumns.Add(colYScale, _YScale_ColumnName, Altaxo.Data.ColumnKind.V, 1); }
/// <summary> /// Calculates statistics of selected columns. Creates a new table where the statistical data will be written to. /// </summary> /// <param name="srctable">Source table.</param> /// <param name="selectedColumns">Selected data columns in the source table. If the argument is null, all columns will be used.</param> /// <param name="selectedRows">Selected rows in the source table. If the argument is null, all rows will be used.</param> /// <param name="destinationTable">The table where the statistical results are written to.</param> public static void DoStatisticsOnColumns( this DataColumnCollection srctable, IAscendingIntegerCollection selectedColumns, IAscendingIntegerCollection selectedRows, DataColumnCollection destinationTable ) { bool bUseSelectedColumns = (null != selectedColumns && 0 != selectedColumns.Count); int numcols = bUseSelectedColumns ? selectedColumns.Count : srctable.ColumnCount; bool bUseSelectedRows = (null != selectedRows && 0 != selectedRows.Count); if (numcols == 0) return; // nothing selected // add a text column and some double columns // note: statistics is only possible for numeric columns since // otherwise in one column doubles and i.e. dates are mixed, which is not possible // 1st column is the name of the column of which the statistics is made Data.TextColumn colCol = new Data.TextColumn(); // 2nd column is the mean Data.DoubleColumn colMean = new Data.DoubleColumn(); // 3rd column is the standard deviation Data.DoubleColumn colSd = new Data.DoubleColumn(); // 4th column is the standard e (N) Data.DoubleColumn colSe = new Data.DoubleColumn(); // 5th column is the sum Data.DoubleColumn colSum = new Data.DoubleColumn(); var colSumSqr = new Data.DoubleColumn(); // 6th column is the number of items for statistics Data.DoubleColumn colN = new Data.DoubleColumn(); var colFracOneSigma = new Data.DoubleColumn(); var colFracTwoSigma = new Data.DoubleColumn(); var colFracThreeSigma = new Data.DoubleColumn(); var colMinimum = new DoubleColumn(); // Minimum of the values var colMaximum = new DoubleColumn(); // Maximum of the values int currRow = 0; for (int si = 0; si < numcols; si++) { Altaxo.Data.DataColumn col = bUseSelectedColumns ? srctable[selectedColumns[si]] : srctable[si]; if (!(col is Altaxo.Data.INumericColumn)) continue; int rows = bUseSelectedRows ? selectedRows.Count : srctable.RowCount; if (rows == 0) continue; // now do the statistics Data.INumericColumn ncol = (Data.INumericColumn)col; double sum = 0; double sumsqr = 0; int NN = 0; double minimum = double.PositiveInfinity; double maximum = double.NegativeInfinity; for (int i = 0; i < rows; i++) { double val = bUseSelectedRows ? ncol[selectedRows[i]] : ncol[i]; if (Double.IsNaN(val)) continue; NN++; sum += val; sumsqr += (val * val); minimum = Math.Min(minimum, val); maximum = Math.Max(maximum, val); } // now fill a new row in the worksheet double mean = sum / NN; double ymy0sqr = sumsqr - sum * sum / NN; if (ymy0sqr < 0) ymy0sqr = 0; // if this is lesser zero, it is a rounding error, so set it to zero double sd = NN > 1 ? Math.Sqrt(ymy0sqr / (NN - 1)) : 0; double se = sd / Math.Sqrt(NN); // calculate fractions double oneSigmaLo = mean - 1 * sd, oneSigmaHi = mean + 1 * sd; double twoSigmaLo = mean - 2 * sd, twoSigmaHi = mean + 2 * sd; double threeSigmaLo = mean - 3 * sd, threeSigmaHi = mean + 3 * sd; int cntOneSigma = 0, cntTwoSigma = 0, cntThreeSigma = 0; for (int i = 0; i < rows; i++) { double val = bUseSelectedRows ? ncol[selectedRows[i]] : ncol[i]; if (Double.IsNaN(val)) continue; if (Altaxo.Calc.RMath.IsInIntervalCC(val, oneSigmaLo, oneSigmaHi)) ++cntOneSigma; if (Altaxo.Calc.RMath.IsInIntervalCC(val, twoSigmaLo, twoSigmaHi)) ++cntTwoSigma; if (Altaxo.Calc.RMath.IsInIntervalCC(val, threeSigmaLo, threeSigmaHi)) ++cntThreeSigma; } if (0 == NN) { minimum = maximum = double.NaN; } colCol[currRow] = col.Name; colMean[currRow] = mean; // mean colSd[currRow] = sd; colSe[currRow] = se; colSum[currRow] = sum; colSumSqr[currRow] = sumsqr; colN[currRow] = NN; colFracOneSigma[currRow] = cntOneSigma / (double)NN; colFracTwoSigma[currRow] = cntTwoSigma / (double)NN; colFracThreeSigma[currRow] = cntThreeSigma / (double)NN; colMinimum[currRow] = minimum; colMaximum[currRow] = maximum; currRow++; // for the next column } // for all selected columns if (currRow != 0) { destinationTable.EnsureExistence(DefaultColumnNameColumnName, typeof(TextColumn), ColumnKind.X, 0).Append(colCol); AppendStatisticalData(destinationTable, colMean, colSd, colSe, colSum, colSumSqr, colN, colFracOneSigma, colFracTwoSigma, colFracThreeSigma, colMinimum, colMaximum); } }
public virtual void StoreXOfX(IROVector xOfX, DataTable table) { DoubleColumn xColOfX = new DoubleColumn(); VectorMath.Copy(xOfX, DataColumnWrapper.ToVector(xColOfX, xOfX.Length)); table.DataColumns.Add(xColOfX, _XOfX_ColumnName, Altaxo.Data.ColumnKind.X, 0); }