Files

175 lines
11 KiB
Markdown
Raw Permalink Normal View History

2026-04-17 14:55:32 -04:00
---
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<Test>`.
- **`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<Test> Exporter`**
Lazily-initialized writer instance for serializing `Test` objects.
- **`IReader<Test> 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<Test>` for writing `Test` objects to disk.
- **`void Write(string pathname, string id, string dataFolder, Test test, ...)`**
Writes a `Test` to disk:
- Serializes metadata to `<pathname>.tlf` using `TLF` class.
- Creates backup copy of `.tlf` file.
- Writes binary channel data to `<pathname>.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 `<base>.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<T>` (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<Test>`, `IReader<Test>` (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<Test>`, 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.