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.
-
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.
-
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.
-
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.
-
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