299 lines
14 KiB
Markdown
299 lines
14 KiB
Markdown
---
|
|
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. |