Files
2026-04-17 14:55:32 -04:00

17 KiB
Raw Permalink Blame History

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
Common/DTS.Common.Serialization/TSV/TSV.File.cs
Common/DTS.Common.Serialization/TSV/TSVTest.cs
Common/DTS.Common.Serialization/TSV/TSVSettingsWindow.cs
Common/DTS.Common.Serialization/TSV/TSV.File.Writer.cs
Common/DTS.Common.Serialization/TSV/TSVChannel.cs
Common/DTS.Common.Serialization/TSV/TSVSettingsWindow.Designer.cs
2026-04-16T03:37:39.731029+00:00 Qwen/Qwen3-Coder-Next-FP8 1 ac1bf0260831585c

TSV Serialization Module Documentation

1. Purpose

This module provides serialization support for test data in Tab-Separated Values (TSV) format. It defines the core types (File, TSVTest, TSVChannel) for representing test metadata and channel data in a structured TSV schema, along with a Writer class for exporting Test objects to disk. The module also includes a UI form (TSVSettingsWindow) for interactive configuration of TSV export parameters. It serves as the backend for exporting test data to human-readable TSV files, primarily for interoperability with external tools (e.g., Excel, TTC), and integrates with application settings to persist last-used field values.

2. Public Interface

DTS.Serialization.TSV.File

  • File()
    Constructor. Initializes a new instance of the File class, passing "TSV" to the base Serialization.File constructor.

  • static string Extension
    Returns the file extension for this format: ".tsv".

  • IWriter<Test> Exporter
    Gets the writer instance for this file type. Lazily initializes _Exporter using DefaultEncoding if not already created. Throws an Exception with inner exception if initialization fails.

DTS.Serialization.TSV.TSVTest

  • TSVTest(Test test, FilteredData[] euFiltered, FilteredData[] adc, FilteredData[] euUnfiltered, string path, double[] actualRangesEUFiltered, double[] actualRangesEUUnfiltered, double[] actualRAngesADC)
    Constructor. Populates the test metadata from the provided Test object and raw data arrays. Initializes _channels for each channel in test.Channels. Sets default values for several fields (e.g., TestNumber, TestDate, TestTime, SamplingRate, AAFilterCutoffDescription) and loads persisted settings (e.g., TSVPOCNameLastUsed) into corresponding fields.

  • string GetValue(TSVTest.Fields field)
    Returns the string value for the specified field. If the field has no value, returns "#NOVALUE".

  • void SetValue(TSVTest.Fields field, string value)
    Sets the value for the specified field in the global metadata. Additionally, propagates the value to all _channels and persists specific fields (POCName, POCPhoneAndEmail, DataType, LabName, TestObject, TestType) to Properties.Settings1.Default.

  • TSVChannel[] Channels
    Gets or sets the array of TSVChannel instances associated with this test.

  • Test Test
    Reference to the original Test object.

  • FilteredData[] DataFilteredEU, DataUnfilteredEU, DataADC
    References to the filtered engineering units, unfiltered engineering units, and raw ADC data arrays, respectively.

  • double[] ActualRangesEUFiltered, ActualRangesEUUnfiltered, ActualRangesADC
    Arrays of actual measurement ranges (in engineering units or ADC counts) for each channel.

DTS.Serialization.TSV.TSVChannel

  • string GetValue(TSVTest.Fields field)
    Returns the string value for the specified field. If the field has no value, returns "#NOVALUE".

  • void SetValue(TSVTest.Fields field, string value)
    Sets the value for the specified field. Includes special handling for DataType:

    • "Raw" → sets EngineeringUnits to "ADC", clears DigitalFilterType, computes BitResolution from ActualRangesADC, and sets FileName to .../TSV/Raw/{TestId}_{ChannelNumber}.TSV.
    • "Processed" → sets EngineeringUnits to _engineeringUnits, computes DigitalFilterType from filtered data, computes BitResolution from ActualRangesEUFiltered, and sets FileName to .../TSV/Processed/....
    • "Converted" → sets EngineeringUnits to _engineeringUnits, clears DigitalFilterType, computes BitResolution from ActualRangesEUUnfiltered, and sets FileName to .../TSV/Converted/....
  • string FileName
    Gets or sets the full path to the TSV file for this channel.

  • int ChannelNumber
    Returns 1 + _channelIndex.

  • void Serialize(TickEventHandler tickHandler)
    Writes the channels TSV file to FileName. Creates the directory if needed. Writes metadata fields (title + value) followed by time-value pairs (time in seconds, data value). Uses Truncate to limit time precision based on sample rate. Invokes tickHandler periodically (every 1000 samples) with progress percentage.

DTS.Serialization.TSV.TSVSettingsWindow

  • TSVSettingsWindow(TSVTest test)
    Constructor. Populates two grids:

    • c1GridGlobal: Displays editable rows for non-hidden TSVTest.Fields (excludes AAFilterCutoffDescription, BitResolution, ChannelErrors, DataType, DigitalFilterType, EngineeringUnits, SensorAxis, SensorLocation, SensorMakeModelSerial, SensorMountType). Values come from test.GetValue(field).
    • c1GridChannels: Displays channel-specific data with columns for ChannelNumber, FileName, and all non-hidden fields.
      Initializes grid styles from Properties.Settings1.Default.
  • button1_Click
    Sets DialogResult = DialogResult.OK and closes the window.

  • c1GridGlobal_AfterEdit
    Updates _test with the new value for the edited global field. Propagates the change to all channels and updates the corresponding c1GridChannels rows.

  • c1GridChannels_AfterEdit
    Updates the specific TSVChannel instance with the new value for the edited field.

DTS.Serialization.TSV.File.Writer

  • internal Writer(File fileType, int encoding)
    Constructor. Initializes the writer with the associated File instance and encoding.

  • ExportMode CurrentExportMode
    Gets/sets the export mode (FtssExcel, Ttc, or Standard). Default: FtssExcel.

  • List<FilteredData> FilteredChannelData
    Gets/sets the list of filtered channel data to use during export.

  • void Write(string pathname, string id, Test test, bool bFiltering, bool includeGroupNameInISOExport, double minStartTime, int dataCollectionLength)
    Throws NotSupportedException with message "TSV::File::Writer Write(pathname, id, test, bFiltering) not supported".

  • void Write(string pathname, string id, string dataFolder, Test test, bool bFiltering, bool includeGroupNameInISOExport, FilteredData fd, Test.Module.Channel tmChannel, int channelNumber, BeginEventHandler beginEventHandler, CancelEventHandler cancelEventHandler, EndEventHandler endEventHandler, TickEventHandler tickEventHandler, ErrorEventHandler errorEventHandler, CancelRequested cancelRequested, double minStartTime, int dataCollectionLength)
    Writes TSV files for all channels in MyTSVTest.Channels by calling channel.Serialize(tickEventHandler) for each. Logs exceptions via APILogger. Invokes event handlers (beginEventHandler, tickEventHandler, endEventHandler, errorEventHandler) to report progress and errors.

  • void Initialize(...)
    Empty implementation.

  • double Start, double Stop, ushort SubSampleInterval, bool Filtered
    Public properties with no visible usage in the provided source.

3. Invariants

  • TSVTest._values and TSVChannel._values
    Both use Dictionary<Fields, string> to store field values. GetValue ensures every field has a value by inserting "#NOVALUE" on first access.

  • TSVChannel.FileName is always set during construction
    Based on path, Test.Id, and ChannelNumber, initially pointing to .../TSV/Processed/....

  • TSVChannel.SetValue(Fields.DataType, ...) triggers recomputation of FileName, EngineeringUnits, DigitalFilterType, and BitResolution
    The new values depend on the DataType ("Raw", "Processed", or "Converted") and the corresponding data/range arrays in _parentTest.

  • TSVTest.SetValue propagates changes to all channels
    When a field is set globally, SetValue calls channel.SetValue(field, value) for every channel.

  • TSVTest fields TestNumber, TestDate, TestTime, SamplingRate, AAFilterCutoffDescription are set during construction
    Derived from the Test object and its first module.

  • TSVChannel.ChannelNumber is 1-indexed
    Computed as 1 + _channelIndex.

  • TSVChannel.Serialize writes time-value pairs
    Time is computed as dStartTime + i / SampleRateHz, truncated to a precision based on SampleRateHz. Data source depends on DataType.

4. Dependencies

Dependencies of this module:

  • DTS.Common.Utilities.DotNetProgrammingConstructs.Property<T>
    Used in File.Writer for _CurrentExportMode and _FilteredChannelData.
  • DTS.Common.Utilities.Logging.APILogger
    Used in File.Writer.Write for logging exceptions.
  • DTS.Serialization.Test
    Referenced in TSVTest, TSVChannel, and File.Writer. Provides test metadata and channel data.
  • DTS.Serialization.FilteredData
    Used in TSVTest and TSVChannel to hold processed data arrays.
  • System.IO
    Used for file/directory operations (StreamWriter, Directory.CreateDirectory, Path.Combine).
  • System.Windows.Forms
    Used in TSVSettingsWindow and its designer.
  • C1.Win.C1FlexGrid
    Used for grid controls (c1GridGlobal, c1GridChannels).
  • Properties.Settings1.Default
    Used to persist and retrieve last-used values for several fields (TSVPOCNameLastUsed, etc.).
  • TSVStrings.ResourceManager
    Used to retrieve localized titles/descriptions for fields (e.g., "{field}_Title", "{field}_Description").

Dependencies on this module:

  • Serialization.File
    TSV.File inherits from Serialization.File.
  • IWritable<Test>
    Implemented by TSV.File.
  • IWriter<Test>
    Implemented by TSV.File.Writer.

5. Gotchas

  • File.Writer.Write(...) overload with 9 parameters is the only supported write path
    The 7-parameter overload throws NotSupportedException. The 16-parameter overload is the functional entry point.

  • TSVChannel.FileName is overwritten on DataType change
    Changing DataType via SetValue immediately updates FileName and other derived fields, which may be unexpected if called multiple times.

  • TSVChannel.Serialize uses Encoding.Default
    This may produce non-portable encodings depending on the system locale.

  • TSVChannel.Serialize truncates time values
    Precision is based on SampleRateHz (decimalplaces = ceil(log10(SampleRateHz))), which may cause rounding artifacts for high sample rates.

  • TSVTest.SetValue persists only 6 fields to settings
    Only POCName, POCPhoneAndEmail, DataType, LabName, TestObject, and TestType are persisted; others are not.

  • TSVChannel constructor assumes Test.Channels[i] is an AnalogInputChannel
    Casts to Test.Module.AnalogInputChannel without checking; may throw InvalidCastException if not.

  • TSVSettingsWindow hides 10 fields from the UI
    Fields like EngineeringUnits, SensorLocation, etc., are excluded from the global and channel grids, even though they are editable programmatically.

  • TSVTest constructor populates _channels only for test.Channels.Count channels
    Assumes euUnfiltered.Length >= test.Channels.Count; no bounds check beyond the loop condition.

  • TSVChannel.Serialize uses channel.ParentModule.StartRecordSampleNumber and TriggerSampleNumbers[0]
    May produce incorrect start times if trigger data is missing or malformed.

  • TSVChannel.Serialize assumes DataADC, DataUnfilteredEU, DataFilteredEU are non-null and indexed correctly
    No validation of array lengths or indices beyond the loop.

  • TSVSettingsWindow uses _bPopulating to suppress event recursion
    This flag prevents infinite loops during initialization but may mask issues if not managed carefully.

  • TSV.File.Writer has unused properties (Start, Stop, SubSampleInterval, Filtered)
    No logic in the provided source uses these; may be legacy or incomplete.

  • TSV.File.Exporter caches _Exporter
    Reuse of the same writer instance across multiple exports may cause issues if state (e.g., CurrentExportMode, FilteredChannelData) is not reset.

  • TSVStrings.ResourceManager is used but not defined in source
    Its availability and behavior are assumed; no fallback or error handling is visible.

  • TSVTest constructor sets SamplingRate and AAFilterCutoffDescription from test.Modules.First()
    Assumes at least one module exists; may throw InvalidOperationException if Modules is empty.

  • TSVChannel.Serialize writes time column first, then data column
    The TSV format is metadata rows (field\tvalue) followed by time-value pairs, which may not be compatible with all TSV parsers expecting a header row.

  • TSVChannel.Serialize writes #NOVALUE if a field is unset
    This literal string appears in the output file, which may be misinterpreted as data.

  • TSVChannel does not expose _engineeringUnits directly
    It is set once in the constructor and used in SetValue for DataType == "Processed" or "Converted", but not updated if changed later.

  • TSVSettingsWindow uses c1GridChannels.Cols.Add() to build columns dynamically
    Column order depends on Enum.GetValues order, which is not guaranteed stable across .NET versions unless explicitly sorted.

  • TSVTest constructor sets FileName for all channels to .../Processed/... initially
    This is overwritten if DataType is later changed via SetValue.

  • TSVChannel.Serialize uses channel.ParentModule.NumberOfSamples
    Assumes all channels have the same number of samples; no validation.

  • TSVChannel.Serialize uses channel cast from parentTest.Test.Channels[_channelIndex]
    Assumes the channel is an AnalogInputChannel; no fallback for digital channels.

  • TSVSettingsWindow does not validate user input
    No checks for invalid field values (e.g., DataType not in {"Raw", "Processed", "Converted"}).

  • TSVChannel does not expose FileName as a settable property in the constructor
    It is computed from path, Test.Id, and ChannelNumber; changing path later does not update FileName.

  • TSVTest constructor sets AAFilterCutoffDescription using test.Modules.First().AaFilterRateHz
    May be 0 or invalid if not set; no validation.

  • TSVChannel.Serialize writes #NOVALUE for unset fields in metadata rows
    This may cause issues for downstream parsers expecting only valid data.

  • TSVChannel.Serialize does not flush or dispose the StreamWriter explicitly beyond using
    using ensures disposal, but no explicit flush is done before closing.

  • TSVChannel.Serialize uses tickHandler(this, percent) with this as sender
    The TickEventHandler signature is not defined in the source; assumed to be void(object sender, double percent).

  • TSVChannel.Serialize uses percentageComplete + i * weight / channel.ParentModule.NumberOfSamples
    May produce inaccurate progress if channels have varying sample counts.

  • TSVChannel does not handle #NOVALUE in FileName
    If FileName is not set correctly, Serialize may throw DirectoryNotFoundException or IOException.

  • TSVSettingsWindow does not validate TSVChannel or TSVTest before editing
    No null checks for _test or _test.Channels.

  • TSVChannel does not validate channelIndex
    Assumes channelIndex < parentTest.Test.Channels.Count and channelIndex < data array lengths.

  • TSVChannel does not validate parentTest arrays
    Assumes ActualRangesADC, DataFilteredEU, etc., are non-null and indexed correctly.

  • TSVChannel does not validate parentTest.Test.Channels[channelIndex]
    Assumes it is an AnalogInputChannel.

  • TSVChannel does not validate parentTest.Test.Channels[channelIndex].ParentModule
    Assumes it is non-null and has valid SampleRateHz, NumberOfSamples, etc.

  • TSVChannel does not validate parentTest.Test.Channels[channelIndex].ParentModule.TriggerSampleNumbers
    Assumes it has at least one element if Count > 0.

  • TSVChannel does not validate parentTest.Test.Channels[channelIndex].ParentModule.StartRecordSampleNumber
    Assumes it is a valid sample number.

  • TSVChannel does not validate parentTest.Test.Channels[channelIndex].EngineeringUnits
    Trims trailing whitespace but does not validate content.

  • TSVChannel does not validate parentTest.ActualRangesADC[_channelIndex]
    Assumes it is a valid range.

  • TSVChannel does not validate parentTest.DataFilteredEU[_channelIndex].FilterDescription or FilterFrequencyHz
    Assumes they are non