/// <summary> /// Determines if column c has monotonically increasing values. /// </summary> /// <param name="c">Column to test.</param> /// <returns>True if the values are monotonically increasing.</returns> public static bool IsMonotonicallyIncreasing(this DateTimeColumn c) { if (c.Count == 0) { return(true); } DateTime prev = c[0]; for (int i = 0; i < c.Count; i++) { DateTime next = c[i]; if (next >= prev) { prev = next; continue; } else { return(false); } } return(true); }
/// <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> /// Gets the fractional index for merging of two tables. /// </summary> /// <param name="masterColumn">X-column of the master table.</param> /// <param name="slaveColumn">X-column of the slave table.</param> /// <returns>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.</returns> public static DoubleColumn GetFractionalIndex(DateTimeColumn masterColumn, DateTimeColumn slaveColumn) { int masterCount = masterColumn.Count; int slaveCount = slaveColumn.Count; var result = new DoubleColumn(); var dict = new SortedDictionary <DateTime, int>(); for (int i = slaveCount - 1; i >= 0; i--) { dict[slaveColumn[i]] = i; } var sortedSlaveValues = dict.Keys.ToArray(); var sortedSlaveIndices = dict.Values.ToArray(); for (int masterIdx = 0; masterIdx < masterCount; masterIdx++) { var masterValue = masterColumn[masterIdx]; int dictIdx = Array.BinarySearch(sortedSlaveValues, masterValue); if (dictIdx >= 0) { result[masterIdx] = sortedSlaveIndices[dictIdx]; continue; } // dictIdx was negative, we have to take the complement dictIdx = ~dictIdx; if (dictIdx >= sortedSlaveIndices.Length) { result[masterIdx] = double.NaN; continue; } else if (dictIdx == 0) { result[masterIdx] = double.NaN; continue; } else { int firstSlaveIdx = sortedSlaveIndices[dictIdx - 1]; int secondSlaveIdx = sortedSlaveIndices[dictIdx]; var firstSlaveValue = sortedSlaveValues[dictIdx - 1]; var secondSlaveValue = sortedSlaveValues[dictIdx]; var diff = (secondSlaveValue - firstSlaveValue); if (diff.Ticks == 0) { result[masterIdx] = firstSlaveIdx; continue; } else { result[masterIdx] = firstSlaveIdx + (secondSlaveIdx - firstSlaveIdx) * (masterValue - firstSlaveValue).Ticks / ((double)diff.Ticks); continue; } } } return(result); }
/// <summary> /// Gets the fractional index for merging of two tables. /// </summary> /// <param name="masterColumn">X-column of the master table.</param> /// <param name="slaveColumn">X-column of the slave table.</param> /// <returns>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.</returns> public static DoubleColumn GetFractionalIndex(DateTimeColumn masterColumn, DateTimeColumn slaveColumn) { int masterCount = masterColumn.Count; int slaveCount = slaveColumn.Count; var result = new DoubleColumn(); var dict = new SortedDictionary<DateTime, int>(); for (int i = slaveCount - 1; i >= 0; i--) dict[slaveColumn[i]] = i; var sortedSlaveValues = dict.Keys.ToArray(); var sortedSlaveIndices = dict.Values.ToArray(); for (int masterIdx = 0; masterIdx < masterCount; masterIdx++) { var masterValue = masterColumn[masterIdx]; int dictIdx = Array.BinarySearch(sortedSlaveValues, masterValue); if (dictIdx >= 0) { result[masterIdx] = sortedSlaveIndices[dictIdx]; continue; } // dictIdx was negative, we have to take the complement dictIdx = ~dictIdx; if (dictIdx >= sortedSlaveIndices.Length) { result[masterIdx] = double.NaN; continue; } else if (dictIdx == 0) { result[masterIdx] = double.NaN; continue; } else { int firstSlaveIdx = sortedSlaveIndices[dictIdx - 1]; int secondSlaveIdx = sortedSlaveIndices[dictIdx]; var firstSlaveValue = sortedSlaveValues[dictIdx - 1]; var secondSlaveValue = sortedSlaveValues[dictIdx]; var diff = (secondSlaveValue - firstSlaveValue); if (diff.Ticks == 0) { result[masterIdx] = firstSlaveIdx; continue; } else { result[masterIdx] = firstSlaveIdx + (secondSlaveIdx - firstSlaveIdx) * (masterValue - firstSlaveValue).Ticks / ((double)diff.Ticks); continue; } } } return result; }
public DateTimeColumn(DateTimeColumn from) { _count = from._count; _capacity = from._capacity; _data = null == from._data ? null : (DateTime[])from._data.Clone(); }
/// <summary> /// Imports an Ascii stream into a table. The import options have to be known already. /// </summary> /// <param name="dataTable">The table into which to import.</param> /// <param name="stream">The stream to read from.</param> /// <param name="streamOriginHint">Stream origin hint. If the stream was opened from a file, you should prepend <see cref=" FileUrlStart"/> to the file name.</param> /// <param name="importOptions">The Ascii import options. This parameter can be null, or the options can be not fully specified. In this case the method tries to determine the import options by analyzing the stream.</param> /// <exception cref="System.ArgumentNullException"> /// Argument importOptions is null /// or /// Argument table is null /// </exception> /// <exception cref="System.ArgumentException">Argument importOptions: importOptions must be fully specified, i.e. all elements of importOptions must be valid. Please run a document analysis in-before to get appropriate values.</exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// Unconsidered AsciiColumnType: + impopt.RecognizedStructure[i].ToString() /// or /// Unknown switch case: + impopt.HeaderLinesDestination.ToString() /// </exception> private static void InternalImportFromAsciiStream(this DataTable dataTable, Stream stream, string streamOriginHint, ref AsciiImportOptions importOptions) { if (null == importOptions || !importOptions.IsFullySpecified) { var analysisOptions = GetDefaultAsciiDocumentAnalysisOptions(dataTable); importOptions = AsciiDocumentAnalysis.Analyze(importOptions ?? new AsciiImportOptions(), stream, analysisOptions); } if (null == importOptions) throw new InvalidDataException("Import options could not be determined from the data stream. Possibly, the data stream is empty or it is not an Ascii data stream"); if (!importOptions.IsFullySpecified) throw new InvalidDataException("Import options could not be fully determined from the data stream. Possibly, the data stream is empty or it is not an Ascii data stream"); string sLine; stream.Position = 0; // rewind the stream to the beginning StreamReader sr = new StreamReader(stream, System.Text.Encoding.Default, true); DataColumnCollection newcols = new DataColumnCollection(); DataColumnCollection newpropcols = new DataColumnCollection(); // in case a structure is provided, allocate already the columsn if (null != importOptions.RecognizedStructure) { for (int i = 0; i < importOptions.RecognizedStructure.Count; i++) { switch (importOptions.RecognizedStructure[i].ColumnType) { case AsciiColumnType.Double: newcols.Add(new DoubleColumn()); break; case AsciiColumnType.Int64: newcols.Add(new DoubleColumn()); break; case AsciiColumnType.DateTime: newcols.Add(new DateTimeColumn()); break; case AsciiColumnType.Text: newcols.Add(new TextColumn()); break; case AsciiColumnType.DBNull: newcols.Add(new DBNullColumn()); break; default: throw new ArgumentOutOfRangeException("Unconsidered AsciiColumnType: " + importOptions.RecognizedStructure[i].ToString()); } } } // add also additional property columns if not enough there if (importOptions.NumberOfMainHeaderLines.HasValue && importOptions.NumberOfMainHeaderLines.Value > 0) // if there are more than one header line, allocate also property columns { int toAdd = importOptions.NumberOfMainHeaderLines.Value; for (int i = 0; i < toAdd; i++) newpropcols.Add(new Data.TextColumn()); } // if decimal separator statistics is provided by impopt, create a number format info object System.Globalization.NumberFormatInfo numberFormatInfo = importOptions.NumberFormatCulture.NumberFormat; System.Globalization.DateTimeFormatInfo dateTimeFormat = importOptions.DateTimeFormatCulture.DateTimeFormat; var notesHeader = new System.Text.StringBuilder(); notesHeader.Append("Imported"); if (!string.IsNullOrEmpty(streamOriginHint)) notesHeader.AppendFormat(" from {0}", streamOriginHint); notesHeader.AppendFormat(" at {0}", DateTime.Now); notesHeader.AppendLine(); // first of all, read the header if existent for (int i = 0; i < importOptions.NumberOfMainHeaderLines; i++) { sLine = sr.ReadLine(); if (null == sLine) break; var tokens = new List<string>(importOptions.SeparationStrategy.GetTokens(sLine)); if (i == importOptions.IndexOfCaptionLine) // is it the column name line { for (int k = 0; k < tokens.Count; ++k) { var ttoken = tokens[k].Trim(); if (!string.IsNullOrEmpty(ttoken)) { string newcolname = newcols.FindUniqueColumnName(ttoken); newcols.SetColumnName(k, newcolname); } } continue; } switch (importOptions.HeaderLinesDestination) { case AsciiHeaderLinesDestination.Ignore: break; case AsciiHeaderLinesDestination.ImportToNotes: AppendLineToTableNotes(notesHeader, sLine); break; case AsciiHeaderLinesDestination.ImportToProperties: FillPropertyColumnWithTokens(newpropcols[i], tokens); break; case AsciiHeaderLinesDestination.ImportToPropertiesOrNotes: if (tokens.Count == importOptions.RecognizedStructure.Count) FillPropertyColumnWithTokens(newpropcols[i], tokens); else AppendLineToTableNotes(notesHeader, sLine); break; case AsciiHeaderLinesDestination.ImportToPropertiesAndNotes: FillPropertyColumnWithTokens(newpropcols[i], tokens); AppendLineToTableNotes(notesHeader, sLine); break; default: throw new ArgumentOutOfRangeException("Unknown switch case: " + importOptions.HeaderLinesDestination.ToString()); } } // now the data lines for (int i = 0; true; i++) { sLine = sr.ReadLine(); if (null == sLine) break; int maxcolumns = newcols.ColumnCount; int k = -1; foreach (string token in importOptions.SeparationStrategy.GetTokens(sLine)) { k++; if (k >= maxcolumns) break; if (string.IsNullOrEmpty(token)) continue; if (newcols[k] is DoubleColumn) { double val; if (double.TryParse(token, System.Globalization.NumberStyles.Any, numberFormatInfo, out val)) ((DoubleColumn)newcols[k])[i] = val; } else if (newcols[k] is DateTimeColumn) { DateTime val; if (DateTime.TryParse(token, dateTimeFormat, System.Globalization.DateTimeStyles.NoCurrentDateDefault, out val)) ((DateTimeColumn)newcols[k])[i] = val; } else if (newcols[k] is TextColumn) { ((TextColumn)newcols[k])[i] = token.Trim(); } else if (null == newcols[k] || newcols[k] is DBNullColumn) { bool bConverted = false; double val = Double.NaN; DateTime valDateTime = DateTime.MinValue; try { val = System.Convert.ToDouble(token); bConverted = true; } catch { } if (bConverted) { DoubleColumn newc = new DoubleColumn(); newc[i] = val; newcols.Replace(k, newc); } else { try { valDateTime = System.Convert.ToDateTime(token); bConverted = true; } catch { } if (bConverted) { DateTimeColumn newc = new DateTimeColumn(); newc[i] = valDateTime; newcols.Replace(k, newc); } else { TextColumn newc = new TextColumn(); newc[i] = token; newcols.Replace(k, newc); } } // end outer if null==newcol } } // end of for all cols } // end of for all lines // insert the new columns or replace the old ones using (var suspendToken = dataTable.SuspendGetToken()) { bool tableWasEmptyBefore = dataTable.DataColumns.ColumnCount == 0; for (int i = 0; i < newcols.ColumnCount; i++) { if (newcols[i] is DBNullColumn) // if the type is undefined, use a new DoubleColumn dataTable.DataColumns.CopyOrReplaceOrAdd(i, new DoubleColumn(), newcols.GetColumnName(i)); else dataTable.DataColumns.CopyOrReplaceOrAdd(i, newcols[i], newcols.GetColumnName(i)); // set the first column as x-column if the table was empty before, and there are more than one column if (i == 0 && tableWasEmptyBefore && newcols.ColumnCount > 1) dataTable.DataColumns.SetColumnKind(0, ColumnKind.X); } // end for loop // add the property columns for (int i = 0, j = 0; i < newpropcols.ColumnCount; i++) { if (newpropcols[i].Count == 0) continue; dataTable.PropCols.CopyOrReplaceOrAdd(j, newpropcols[i], newpropcols.GetColumnName(i)); ++j; } dataTable.Notes.Write(notesHeader.ToString()); suspendToken.Dispose(); } } // end of function ImportAscii
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; }
public DateTimeColumn(DateTimeColumn from) { this.m_Count = from.m_Count; this.m_Capacity = from.m_Capacity; this.m_Array = null == from.m_Array ? null : (DateTime[])from.m_Array.Clone(); }
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> /// 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+)"; Regex 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); } }
public DateTimeColumn(DateTimeColumn from) { this._count = from._count; this._capacity = from._capacity; this._data = null == from._data ? null : (DateTime[])from._data.Clone(); }