--- source_files: - Common/DTS.Common.Serialization/TDAS/TDAS.File.Reader.BadCrcException.cs - Common/DTS.Common.Serialization/TDAS/TDAS.File.Reader.MissingFileException.cs - Common/DTS.Common.Serialization/TDAS/TDAS.File.Reader.TooManyFilesException.cs - Common/DTS.Common.Serialization/TDAS/TDAS.File.IChannelHeader.cs - Common/DTS.Common.Serialization/TDAS/TDAS.File.PersistentChannel.NotInitializedException.cs - Common/DTS.Common.Serialization/TDAS/TDAS.File.PersistentChannel.DataTooBigForArrayException.cs - Common/DTS.Common.Serialization/TDAS/TDAS.File.cs - Common/DTS.Common.Serialization/TDAS/TDAS.File.BinaryChannelHeader.cs - Common/DTS.Common.Serialization/TDAS/TDAS.File.Writer.cs - Common/DTS.Common.Serialization/TDAS/TLFBin.cs generated_at: "2026-04-16T03:38:54.525487+00:00" model: "Qwen/Qwen3-Coder-Next-FP8" schema_version: 1 sha256: "8202fee238e4de73" --- # TDAS Serialization Module Documentation ## 1. Purpose This module provides serialization and deserialization support for TDAS (Test Data Acquisition System) files, specifically handling `.tlf` (text-based metadata) and `.BIN` (binary channel data) file formats used by Diversified Technical Systems, Inc. It defines core types—including `File`, `Writer`, `Reader`, `PersistentChannel`, and supporting classes like `TDASBinaryChannelHeader`—to manage test metadata, channel headers, and raw data. The module enables structured export/import of test data with support for channel-specific metadata (e.g., acquisition rate, calibration levels, signal-to-noise ratio), CRC validation, and exception handling for common file-level and data-level errors. ## 2. Public Interface ### Exception Types All exception types are nested within `File` or `File.PersistentChannel` and extend `Exception` or `ApplicationException`. Each provides three constructors: parameterless, `string msg`, and `string msg, Exception innerEx`. - **`File.Reader.BadCrcException`** Thrown when a CRC validation failure occurs during file reading (e.g., corrupted binary channel data or header). - **`File.Reader.MissingFileException`** Thrown when an expected file (e.g., `.tlf` or `.BIN`) is not found during deserialization. - **`File.Reader.TooManyFilesException`** Thrown when the number of channel files exceeds an internal limit during deserialization. - **`File.PersistentChannel.NotInitializedException`** Thrown when attempting to access a property of `PersistentChannel` that has not yet been initialized (e.g., reading `Data` before it's loaded). - **`File.PersistentChannel.DataTooBigForArrayException`** Thrown when attempting to materialize a large dataset into an array that exceeds safe memory constraints. ### Core Types - **`File`** Main entry point for TDAS file operations. Extends `Serialization.File` and implements `IWritable`. - **`static string Extension => ".tlf"`** The file extension for the primary metadata file. - **`static string TestFileExtension => ".tlf"`** Alias for `Extension`; used for test metadata files. - **`static string ChannelFileExtension => ".BIN"`** File extension for binary channel data files. - **`static string CalculatedChannelFileExtension => ".cchn"`** File extension for calculated channel files. - **`IWriter Exporter`** Lazily-initialized writer instance for serializing `Test` objects. - **`IReader Importer`** Lazily-initialized reader instance for deserializing `Test` objects. - **`int GetChannelNumberFromChannelFileName(string channelFileName)`** Extracts the 3-digit channel number from a channel filename (e.g., `"test.tlf001.BIN"` → `1`). Throws if parsing fails. - **`File.TDASBinaryChannelHeader`** Implements `IChannelHeader` and encapsulates binary channel header fields. Used to serialize/deserialize header metadata and compute CRCs. - **Properties (get/set):** `AcquisitionRate`, `NumberOfPreT0DataPoints`, `NumberOfPostT0DataPoints`, `PreZeroLevelInCnts`, `PreCalLevelInCnts`, `SignalToNoiseRatioInDb`, `PostZeroLevelInCnts`, `PostCalLevelInCnts`, `DataZeroLevelInCnts`, `ScaleFactorMVPerCnt`, `ScaleFactorEUPerCnt`. - **`UInt32 Crc32 { get; }`** Computes CRC32 over all header fields (no EU string padding stripping). - **`UInt32 UnpaddedEuCrc32 { get; }`** Computes CRC32 with EU string padding stripped. - **`UInt32 UnpaddedEuStringPaddedEuLengthCrc32 { get; }`** Computes CRC32 with EU string stripped but EU length field included. - **`private UInt32 CalculateCrc32(bool stripEuPadding, bool bKeepEuLength)`** Internal CRC calculation using `Utils.Math_DoCRC16Step` on 16-bit word pairs of header data. - **`File.Writer`** Internal class implementing `IWriter` for writing `Test` objects to disk. - **`void Write(string pathname, string id, string dataFolder, Test test, ...)`** Writes a `Test` to disk: - Serializes metadata to `.tlf` using `TLF` class. - Creates backup copy of `.tlf` file. - Writes binary channel data to `.NNN.BIN` files (`.BIN` extension), where `NNN` is a 3-digit channel number. - Supports event callbacks (`beginEventHandler`, `tickEventHandler`, `errorEventHandler`, etc.). - Throws `NotSupportedException` for the 5-parameter overload. - **`void Initialize(...)`** Currently a no-op stub. - **`IChannelHeader`** Interface defining contract for channel header metadata (implemented by `TDASBinaryChannelHeader`). All properties are get/set; see `TDASBinaryChannelHeader` for descriptions. - **`TLFBin`** Helper class for serializing binary channel data with resampling and scaling. - **Properties (get/set):** `AcquisitionRate`, `PreTriggerDataPoints`, `PostTriggerDataPoints`, `PreZeroLevel`, `PreCalLevel`, `SignalToNoiseRatio`, `PostZeroLevel`, `PostCalLevel`, `SuperSampleRate`. - **`TLFBin(Test.Module.Channel channel, double superSampleRate)`** Constructor computes header fields and scaling parameters from `channel` and `superSampleRate`. - `PreCalLevel` is hardcoded to `0.7 * short.MaxValue` (10922). - `SignalToNoiseRatio` computed from `NoiseAsPercentageOfFullScale` and full-scale ADC range. - `PostZeroLevel` and `PostCalLevel` are currently unimplemented (set to `0`). - **`void Serialize(BinaryWriter bw, Test.Module.Channel channel)`** Writes binary data to `BinaryWriter`: - Writes header (11 fields: `SuperSampleRate`, `PreTriggerDataPoints`, ..., `ScaleFactorEUPerCnt`). - Writes resampled ADC values (16-bit signed) for each sample, with interpolation. - For digital inputs (`Bridge == DigitalInput`), writes 16-bit digital values based on `DigitalMode` and `DigitalMultiplier`. - For linearized sensors, constrains `newADC` to `short.MinValue`/`short.MaxValue` to avoid underflow. ## 3. Invariants - **File Naming Convention:** Channel binary files follow `.NNN.BIN`, where `NNN` is a 3-digit channel number (e.g., `001`, `002`, `901` for squib channels). Channel numbers are extracted via `GetChannelNumberFromChannelFileName`, which assumes the last 3 characters before `.BIN` are digits. - **CRC Computation:** CRC32 is computed over 16-bit words (little-endian) of header data. Padding is added if data length is odd. Uses `Utils.Math_DoCRC16Step` (not standard CRC32), and the result is returned as `UInt32`. - **Data Resampling:** `TLFBin.Serialize` resamples data to `SuperSampleRate` using linear interpolation. The resampling factor `rate = ceil(SuperSampleRate / AcquisitionRate)` is applied per sample. - **Digital Input Handling:** Digital channels output 16-bit values based on `DigitalMode` (e.g., `CCNC`, `TLH`) and thresholds (`breakPoint`). Values are determined per interpolated step. - **Linearization Constraints:** For linearized sensors, `newADC` is clamped to `short.MinValue`/`short.MaxValue` to prevent overflow/underflow during serialization (see `TLFBin.Serialize`). ## 4. Dependencies - **Internal Dependencies:** - `DTS.Common.Utilities.DotNetProgrammingConstructs.Property` (used in `File` for static extension properties). - `DTS.Common.Utilities.Logging.APILogger` (used in `File.Writer.Write` for error logging). - `DTS.Common.Constant` and `DTS.Common.Enums.Sensors.SensorConstants` (used in `TLFBin` constructor for `BridgeType.DigitalInput`). - `DTS.Common.Enums.DigitalInputModes` (used in `TLFBin.Serialize` for digital input mode handling). - `SliceRaw.File.Reader.GetDataScaler` (used in `TLFBin.Serialize` to obtain scaling parameters). - `Utils.Math_DoCRC16Step` (used in `TDASBinaryChannelHeader.CalculateCrc32`). - `Serialization.File`, `IWriter`, `IReader` (base types for `File`, `Writer`, and `Reader`). - **External Dependencies:** - `System`, `System.IO`, `System.Linq`, `System.Text`, `System.Collections.Generic` (standard .NET libraries). - `DTS.Serialization.Test` and its nested types (`Test.Module.Channel`, `Test.Module.AnalogInputChannel`, `Test.Module.Channel.PersistentChannelInfo`). - `FilteredData`, `BeginEventHandler`, `CancelEventHandler`, etc. (event delegates for progress/error callbacks). ## 5. Gotchas - **`TDASBinaryChannelHeader.CalculateCrc32` uses CRC16, not CRC32:** Despite the property names (`Crc32`, `UnpaddedEuCrc32`, etc.), the implementation computes a 16-bit CRC using `Math_DoCRC16Step` and returns it as `UInt32`. This is likely a historical naming inconsistency. - **`PreCalLevel` is hardcoded:** In `TLFBin` constructor, `PreCalLevel` is set to `0.7 * short.MaxValue` (10922) instead of a configurable value. The comment suggests this is a placeholder. - **`PostZeroLevel` and `PostCalLevel` are unimplemented:** Both are set to `0` in `TLFBin` constructor with `@TODO` comments indicating missing data sources. - **Digital input `breakPoint` logic is complex and mode-dependent:** Thresholds differ by `DigitalMode` (e.g., `CCNC` vs `TLH`) and input type (current vs voltage). Misconfiguration may lead to incorrect digital output values. - **`TLFBin.Serialize` may produce out-of-range values for linearized sensors:** Although `newADC` is clamped to `short.MinValue`/`short.MaxValue`, the comment notes this was added to fix underflow in bug #14496. Ensure scaling factors and sensor capacities are valid to avoid unexpected clamping. - **Channel number extraction is fragile:** `GetChannelNumberFromChannelFileName` assumes filenames end with `.BIN` or `.bin` and that the 3 characters before the extension are digits. Filenames like `_C001.BIN` are handled, but edge cases (e.g., `.BIN` in middle of name) may cause errors. - **`File.Writer.Write` has two overloads, only one implemented:** The 5-parameter overload throws `NotSupportedException`. Ensure callers use the 15-parameter version. - **No public `Reader` class defined in source:** While `File.Importer` returns `IReader`, the `Reader` class is not defined in the provided files. Its implementation is likely in `TDAS.File.Reader.cs` (referenced in comments but not included). - **Encoding assumptions:** `File.Writer.Write` uses `Encoding.Default` for `.tlf` serialization. This may cause portability issues across systems with different default encodings.