14 KiB
source_files, generated_at, model, schema_version, sha256
| source_files | generated_at | model | schema_version | sha256 | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
2026-04-16T03:38:20.120884+00:00 | Qwen/Qwen3-Coder-Next-FP8 | 1 | 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
IDasTimestampHeaderinterface.
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
IChannelHeaderinterface.
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 aPersistentChanneland 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 indexi.long Length { get; }
Number of samples (same asBasePersistentChannel.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:
BinaryDasTimestampHeaderrequiresMagicKey == 0xF15363C2;BinaryChannelHeaderrequiresMagicKey == 0x2C36351F. Headers with incorrect magic keys are invalid. -
Header Versioning:
BinaryDasTimestampHeadersupports only version0x01.
BinaryChannelHeadersupports versions0x01through0x04. Version-specific fields are conditionally included in CRC calculation based onHeaderVersionNumber. -
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 ifHeaderVersionNumber >=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 (
AlreadyInitializedExceptionthrown on reassignment). - Accessing properties during initialization throws
IsInitializingException. - Accessing uninitialized properties throws
NotInitializedException. - Dependencies must be initialized first; otherwise
DependencyNotInitializedExceptionis thrown.
- Properties may only be set once (
-
Array Size Limitation:
Attempting to load data exceedingint.MaxValuebytes throwsDataTooBigForArrayException.
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 byPersistentEuChannelfor 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.GenericSystem.TextSystem.Windows.Forms(forModifyChannelUI form)DTS.Common.DAS.Concepts(forDataScaler)DTS.Common.Utilities.DotNetProgrammingConstructs(forProperty<T>wrapper)
Inferred Usage
File.Readerclass (not shown in source but referenced in exception files) likely handles file I/O and header parsing.File.PersistentChannel(not shown) likely implementsIChannelHeaderand manages raw sample data.ModifyChannelform suggests integration with desktop UI for header editing.
5. Gotchas
-
CRC Name Mismatch:
Properties namedCrc32actually compute CRC16 (16-bit), not CRC32. This is evident fromMath_DoCRC16Stepusage andushort crcvariable. -
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 originalEuFieldLengthWithTerminatorvalue (including potential +1 bug).
-
Header Version Field Inclusion:
CRC calculation conditionally includes fields based onHeaderVersionNumber. For example:RemovedADCincluded only ifHeaderVersionNumber >= 2Excitation,TriggerAdjustmentSamples, etc., included only ifHeaderVersionNumber >= 3WindowAverageADCincluded only ifHeaderVersionNumber >= 4
-
EuFieldLengthWithTerminatorBug Tolerance:
CRC calculation accommodates a known bug whereEuFieldLengthWithTerminatoris stored asactual_length + 1. Logic checks ifEuFieldLengthWithTerminator > EngineeringUnit.Length + 1to detect this. -
TriggerSampleNumbersArray Handling:
ModifyChannelUI only edits the first trigger sample (TriggerSampleNumbers[0]), ignoring additional triggers. -
Read-Only
PersistentEuChannelIndexer:
Setting values viaPersistentEuChannel[i] = valuethrowsNotSupportedException, even though the indexer has a setter. -
Partial Class Structure:
Classes likeFile,Reader, andPersistentChannelare declared aspartial, implying implementation is split across multiple files not included in this documentation set. Behavior ofFile.ReaderandFile.PersistentChannelcannot be fully inferred. -
Missing File Exception Handling:
MissingFileExceptionis thrown when a file is not found, but exact conditions (e.g., duringFile.Readerconstruction) are not visible in source. -
No Public Constructor Visibility:
Constructors forFile.ReaderandFile.PersistentChannelare not shown, making initialization patterns unclear. -
No Documentation for
StampCrc():
ModifyChannel.btnWrite_Clickcalls_channel.StampCrc(), but this method is not defined in the provided source.