Files
DP44/enriched-qwen3-coder-next/Common/DTS.Common.Serialization/SliceRaw.md

299 lines
14 KiB
Markdown
Raw Normal View History

2026-04-17 14:55:32 -04:00
---
source_files:
- Common/DTS.Common.Serialization/SliceRaw/SliceRaw.File.IDasTimestampHeader.cs
- Common/DTS.Common.Serialization/SliceRaw/SliceRaw.File.Reader.BadCrcException.cs
- Common/DTS.Common.Serialization/SliceRaw/SliceRaw.File.Reader.MissingFileException.cs
- Common/DTS.Common.Serialization/SliceRaw/SliceRaw.File.Reader.TooManyFilesException.cs
- Common/DTS.Common.Serialization/SliceRaw/SliceRaw.File.PersistentChannel.NotInitializedException.cs
- Common/DTS.Common.Serialization/SliceRaw/SliceRaw.File.PersistentChannel.IsInitializingException.cs
- Common/DTS.Common.Serialization/SliceRaw/SliceRaw.File.PersistentChannel.DataTooBigForArrayException.cs
- Common/DTS.Common.Serialization/SliceRaw/SliceRaw.File.PersistentChannel.AlreadyInitializedException.cs
- Common/DTS.Common.Serialization/SliceRaw/SliceRaw.File.PersistentChannel.DependencyNotInitializedException.cs
- Common/DTS.Common.Serialization/SliceRaw/SliceRaw.File.BinaryDasTimestampHeader.cs
- Common/DTS.Common.Serialization/SliceRaw/SliceRaw.File.PersistentEuChannel.cs
- Common/DTS.Common.Serialization/SliceRaw/SliceRaw.File.IChannelHeader.cs
- Common/DTS.Common.Serialization/SliceRaw/ModifyChannel.cs
- Common/DTS.Common.Serialization/SliceRaw/SliceRaw.File.BinaryChannelHeader.cs
generated_at: "2026-04-16T03:38:20.120884+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "880f258a855611f2"
---
# SliceRaw Serialization Module Documentation
## 1. Purpose
This module provides serialization and deserialization support for binary channel data files used in the DTS SLICE data acquisition system. It defines core interfaces (`IDasTimestampHeader`, `IChannelHeader`) and concrete implementations (`BinaryDasTimestampHeader`, `BinaryChannelHeader`) for structured header metadata, along with supporting classes for reading files (`File.Reader`), managing persistent channel data (`File.PersistentChannel`), and converting raw ADC samples to engineering units (`File.PersistentEuChannel`). The module enables robust handling of binary `.chn` files containing time-series sample data, including calibration metadata, trigger information, and unit conversion parameters.
## 2. Public Interface
### Interfaces
#### `IDasTimestampHeader`
- `uint MagicKey { get; set; }`
Magic number identifying the binary file type.
- `uint HeaderVersionNumber { get; set; }`
Version number of the header format.
- `ulong OffsetOfSampleDataStart { get; set; }`
Byte offset from file start to the beginning of sample data.
- `ulong NumberOfSamples { get; set; }`
Total number of samples in the file.
- `uint NumberOfBitsPerSample { get; set; }`
Bit depth per sample (e.g., 16, 24, 32).
- `uint Crc32 { get; }`
CRC16 (despite property name) checksum of header fields.
#### `IChannelHeader`
- `uint MagicKey { get; set; }`
Magic number identifying the binary channel file type.
- `uint HeaderVersionNumber { get; set; }`
Version number of the channel header format.
- `ulong OffsetOfSampleDataStart { get; set; }`
Byte offset from file start to sample data.
- `ulong NumberOfSamples { get; set; }`
Total number of samples.
- `uint NumberOfBitsPerSample { get; set; }`
Bit depth per sample.
- `uint AreSamplesSigned { get; set; }`
Flag indicating if samples are signed integers.
- `double SampleRate { get; set; }`
Sample rate in Hz.
- `ushort NumberOfTriggers { get; set; }`
Number of triggers recorded.
- `ulong[] TriggerSampleNumbers { get; set; }`
Array of sample indices where triggers occurred.
- `int TriggerAdjustmentSamples { get; set; }`
Adjustment count for trigger backdating.
- `int PreTestZeroLevelCounts { get; set; }`
Zero-level ADC counts before testing.
- `int RemovedADC { get; set; }`
ADC offset removed during hardware zeroing.
- `double Excitation { get; set; }`
Excitation voltage applied to the channel.
- `int ZeroMvInADC { get; set; }`
ADC value when 0mV is injected.
- `int WindowAverageADC { get; set; }`
Average ADC over zero window.
- `int OriginalOffsetADC { get; set; }`
Initial ADC offset.
- `int PreTestDiagnosticsLevelCounts { get; set; }`
Diagnostics level counts before testing.
- `double PreTestNoisePercentageOfFullScale { get; set; }`
Pre-test noise as % of full scale.
- `int PostTestZeroLevelCounts { get; set; }`
Zero-level ADC counts after testing.
- `int PostTestDiagnosticsLevelCounts { get; set; }`
Diagnostics level counts after testing.
- `int DataZeroLevelCounts { get; set; }`
Zero-level ADC counts in data.
- `double ScaleFactorMv { get; set; }`
Scale factor in mV.
- `double MvPerEu { get; set; }`
Sensitivity in mV per engineering unit.
- `ushort EuFieldLengthWithTerminator { get; set; }`
Length of engineering unit string including null terminator.
- `char[] EngineeringUnit { get; set; }`
Engineering unit string (e.g., 'V', 'Pa').
- `char[] IsoCode { get; set; }`
ISO unit code.
- `uint Crc32 { get; }`
CRC16 checksum of header fields.
### Concrete Header Classes
#### `BinaryDasTimestampHeader`
- `static uint RequiredMagicKey => 0xF15363C2`
Required magic key for timestamp headers.
- `static uint CurrentVersionNumber => 0x01`
Current header version.
- `static List<uint> KnownHeaderVersionNumbers => new List<uint>(new uint[] { 0x01 })`
Supported header versions.
- Implements `IDasTimestampHeader` interface.
#### `BinaryChannelHeader`
- `static uint RequiredMagicKey => 0x2C36351F`
Required magic key for channel headers.
- `static uint CurrentVersionNumber => 0x04`
Current header version.
- `static List<uint> KnownHeaderVersionNumbers => new List<uint>(new uint[] { 0x01, 0x02, 0x03, 0x04 })`
Supported header versions.
- `uint UnpaddedEuStringPaddedEuLengthCrc32 { get; }`
CRC16 using unpadded EU string but padded EU length field.
- `uint UnpaddedEuCrc32 { get; }`
CRC16 using unpadded EU string and calculated length.
- Implements `IChannelHeader` interface.
### Exception Classes
#### `File.Reader.BadCrcException`
- `BadCrcException()`
Default constructor.
- `BadCrcException(string msg)`
Constructor with message.
- `BadCrcException(string msg, Exception innerEx)`
Constructor with message and inner exception.
#### `File.Reader.MissingFileException`
- `MissingFileException()`
Default constructor.
- `MissingFileException(string msg)`
Constructor with message.
- `MissingFileException(string msg, Exception innerEx)`
Constructor with message and inner exception.
#### `File.Reader.TooManyFilesException`
- `TooManyFilesException()`
Default constructor.
- `TooManyFilesException(string msg)`
Constructor with message.
- `TooManyFilesException(string msg, Exception innerEx)`
Constructor with message and inner exception.
#### `File.PersistentChannel.NotInitializedException`
- `NotInitializedException()`
Default constructor.
- `NotInitializedException(string msg)`
Constructor with message.
- `NotInitializedException(string msg, Exception innerEx)`
Constructor with message and inner exception.
#### `File.PersistentChannel.IsInitializingException`
- `IsInitializingException()`
Default constructor.
- `IsInitializingException(string msg)`
Constructor with message.
- `IsInitializingException(string msg, Exception innerEx)`
Constructor with message and inner exception.
#### `File.PersistentChannel.DataTooBigForArrayException`
- `DataTooBigForArrayException()`
Default constructor.
- `DataTooBigForArrayException(string msg)`
Constructor with message.
- `DataTooBigForArrayException(string msg, Exception innerEx)`
Constructor with message and inner exception.
#### `File.PersistentChannel.AlreadyInitializedException`
- `AlreadyInitializedException()`
Default constructor.
- `AlreadyInitializedException(string msg)`
Constructor with message.
- `AlreadyInitializedException(string msg, Exception innerEx)`
Constructor with message and inner exception.
#### `File.PersistentChannel.DependencyNotInitializedException`
- `DependencyNotInitializedException()`
Default constructor.
- `DependencyNotInitializedException(string msg)`
Constructor with message.
- `DependencyNotInitializedException(string msg, Exception innerEx)`
Constructor with message and inner exception.
### Other Public Types
#### `PersistentEuChannel`
- `PersistentEuChannel(PersistentChannel persistentChannel, DataScaler scaler)`
Wraps a `PersistentChannel` and converts raw samples to engineering units.
- `PersistentChannel BasePersistentChannel { get; set; }`
Underlying raw channel.
- `DataScaler EuDataScaler { get; set; }`
Converter from ADC to EU.
- `double this[ulong i] { get; }`
Read-only indexer returning EU value at index `i`.
- `long Length { get; }`
Number of samples (same as `BasePersistentChannel.Length`).
- `void Dispose()`
Disposes underlying channel.
#### `ModifyChannel` (WinForms UI)
- `File.PersistentChannel ChannelToModify { set; }`
Sets the channel to be modified via UI.
- Public UI form for editing channel header metadata.
## 3. Invariants
- **Magic Key Validation**:
`BinaryDasTimestampHeader` requires `MagicKey == 0xF15363C2`; `BinaryChannelHeader` requires `MagicKey == 0x2C36351F`. Headers with incorrect magic keys are invalid.
- **Header Versioning**:
`BinaryDasTimestampHeader` supports only version `0x01`.
`BinaryChannelHeader` supports versions `0x01` through `0x04`. Version-specific fields are conditionally included in CRC calculation based on `HeaderVersionNumber`.
- **CRC Calculation Invariants**:
- CRC is computed over a byte array built from header fields in a specific order.
- For `BinaryChannelHeader`, version-specific fields (`RemovedADC`, `Excitation`, `TriggerAdjustmentSamples`, etc.) are included only if `HeaderVersionNumber >=` corresponding version constant.
- EU string padding behavior affects CRC: three CRC variants exist (`Crc32`, `UnpaddedEuCrc32`, `UnpaddedEuStringPaddedEuLengthCrc32`) with different padding rules.
- Data arrays are padded to even byte count before CRC calculation.
- **PersistentChannel Initialization**:
- Properties may only be set once (`AlreadyInitializedException` thrown on reassignment).
- Accessing properties during initialization throws `IsInitializingException`.
- Accessing uninitialized properties throws `NotInitializedException`.
- Dependencies must be initialized first; otherwise `DependencyNotInitializedException` is thrown.
- **Array Size Limitation**:
Attempting to load data exceeding `int.MaxValue` bytes throws `DataTooBigForArrayException`.
## 4. Dependencies
### Internal Dependencies
- `DTS.Common.Utilities.Logging.APILogger`
Used for logging (commented out in CRC calculation code).
- `DTS.Common.Utilities.Logging.Exceptional`
Base class for header classes (indicated by `: Exceptional`).
- `DTS.Common.DAS.Concepts.DataScaler`
Used by `PersistentEuChannel` for unit conversion.
- `DTS.Common.Utils.Utils.Math_DoCRC16Step`
CRC calculation helper (despite property name, CRC16 is used, not CRC32).
### External Dependencies
- `System` (Core .NET types)
- `System.Collections.Generic`
- `System.Text`
- `System.Windows.Forms` (for `ModifyChannel` UI form)
- `DTS.Common.DAS.Concepts` (for `DataScaler`)
- `DTS.Common.Utilities.DotNetProgrammingConstructs` (for `Property<T>` wrapper)
### Inferred Usage
- `File.Reader` class (not shown in source but referenced in exception files) likely handles file I/O and header parsing.
- `File.PersistentChannel` (not shown) likely implements `IChannelHeader` and manages raw sample data.
- `ModifyChannel` form suggests integration with desktop UI for header editing.
## 5. Gotchas
- **CRC Name Mismatch**:
Properties named `Crc32` actually compute CRC16 (16-bit), not CRC32. This is evident from `Math_DoCRC16Step` usage and `ushort crc` variable.
- **EU String Padding Ambiguity**:
CRC calculation has three variants with different EU string padding rules:
- `Crc32`: Uses original EU string (with padding if odd length).
- `UnpaddedEuCrc32`: Strips leading/trailing whitespace before padding.
- `UnpaddedEuStringPaddedEuLengthCrc32`: Strips padding but uses original `EuFieldLengthWithTerminator` value (including potential +1 bug).
- **Header Version Field Inclusion**:
CRC calculation conditionally includes fields based on `HeaderVersionNumber`. For example:
- `RemovedADC` included only if `HeaderVersionNumber >= 2`
- `Excitation`, `TriggerAdjustmentSamples`, etc., included only if `HeaderVersionNumber >= 3`
- `WindowAverageADC` included only if `HeaderVersionNumber >= 4`
- **`EuFieldLengthWithTerminator` Bug Tolerance**:
CRC calculation accommodates a known bug where `EuFieldLengthWithTerminator` is stored as `actual_length + 1`. Logic checks if `EuFieldLengthWithTerminator > EngineeringUnit.Length + 1` to detect this.
- **`TriggerSampleNumbers` Array Handling**:
`ModifyChannel` UI only edits the first trigger sample (`TriggerSampleNumbers[0]`), ignoring additional triggers.
- **Read-Only `PersistentEuChannel` Indexer**:
Setting values via `PersistentEuChannel[i] = value` throws `NotSupportedException`, even though the indexer has a setter.
- **Partial Class Structure**:
Classes like `File`, `Reader`, and `PersistentChannel` are declared as `partial`, implying implementation is split across multiple files not included in this documentation set. Behavior of `File.Reader` and `File.PersistentChannel` cannot be fully inferred.
- **Missing File Exception Handling**:
`MissingFileException` is thrown when a file is not found, but exact conditions (e.g., during `File.Reader` construction) are not visible in source.
- **No Public Constructor Visibility**:
Constructors for `File.Reader` and `File.PersistentChannel` are not shown, making initialization patterns unclear.
- **No Documentation for `StampCrc()`**:
`ModifyChannel.btnWrite_Click` calls `_channel.StampCrc()`, but this method is not defined in the provided source.