Files
DP44/docs/ai/Common/DTS.Common.Serialization/DDAS (Chrysler).md
2026-04-17 14:55:32 -04:00

326 lines
15 KiB
Markdown

---
source_files:
- Common/DTS.Common.Serialization/DDAS (Chrysler)/ChannelDefinition.h
- Common/DTS.Common.Serialization/DDAS (Chrysler)/DDASTestDefinition.h
- Common/DTS.Common.Serialization/DDAS (Chrysler)/DataFloat.h
- Common/DTS.Common.Serialization/DDAS (Chrysler)/DDAS.File.cs
- Common/DTS.Common.Serialization/DDAS (Chrysler)/DDASTest.cs
- Common/DTS.Common.Serialization/DDAS (Chrysler)/DDAS.File.Writer.cs
- Common/DTS.Common.Serialization/DDAS (Chrysler)/TSVSettingsWindow.cs
- Common/DTS.Common.Serialization/DDAS (Chrysler)/TSVSettingsWindow.Designer.cs
- Common/DTS.Common.Serialization/DDAS (Chrysler)/DDASChannel.cs
generated_at: "2026-04-17T15:32:53.691261+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "403f99d261310d3b"
---
# DDAS Serialization Module Documentation
## 1. Purpose
This module provides serialization and deserialization support for the DDAS (DaimlerChrysler Data Acquisition System) file format, a proprietary binary format used for storing crash test data. It bridges legacy C++ structures (originally from DDAS testplan.h) with a modern C# serialization framework, enabling export of test data including channel configurations, transducer metadata, and floating-point sample data. The module handles multiple data types (Raw/ADC, Processed/Filtered, and Converted/Engineering Units) and produces `.ddas` or `.fpd` files compatible with downstream analysis tools.
---
## 2. Public Interface
### C# Classes
#### `DTS.Serialization.DDAS.File`
A partial class representing the DDAS file format, extending `Serialization.File` and implementing `IWritable<Test>`.
```csharp
public File() // Constructor, initializes with "DDAS" format identifier
public static string Extension // Returns ".ddas"
public IWriter<Test> Exporter // Lazy-initialized property returning a Writer instance
```
#### `DTS.Serialization.DDAS.File.Writer`
Nested class for serializing `Test` objects to DDAS format.
```csharp
internal Writer(File fileType, int encoding) // Constructor
public void Write(string pathname, string id, Test test, bool bFiltering, bool includeGroupNameInISOExport, double minStartTime, int dataCollectionLength) // Throws NotImplementedException
public void Write(string pathname, string id, string dataFolder, Test test, bool bFiltering, bool includeGroupNameInISOExport, FilteredData fd, Test.Module.Channel tmChannel, int channelNumber, BeginEventHandler beginEventHandler, CancelEventHandler cancelEventHandler, EndEventHandler endEventHandler, TickEventHandler tickEventHandler, ErrorEventHandler errorEventHandler, CancelRequested cancelRequested, double minStartTime, int dataCollectionLength) // Main write method
public void Initialize(...) // Empty initialization method
public string ExtensionPrefix { get; set; } // Defaults to empty string
public DDASTest MyTVTTest { get; set; } // Reference to DDASTest being written
private int DataSamplesPerTick // Returns 1000
private uint GetChannelTicks(Test.Module.Channel channel) // Calculates progress ticks
```
#### `DTS.Serialization.DDAS.DDASTest`
Represents a complete DDAS test with metadata and channel collection.
```csharp
public enum Fields { LabName, POCName, POCPhoneAndEmail, TestDate, TestTime, TestNumber, TestType, TestObject, DataType, SensorMakeModelSerial, SensorLocation, SensorAxis, SensorMountType, EngineeringUnits, ChannelErrors, SamplingRate, AAFilterCutoffDescription, BitResolution, DigitalFilterType, Notes }
public string GetValue(Fields field) // Returns "#NOVALUE" if not set
public void SetValue(Fields field, string value) // Sets value and propagates to all channels
public DDASChannel[] Channels { get; set; } // Array of channel objects
public Test Test { get; } // Reference to underlying Test object
public FilteredData[] DataUnfilteredEU { get; } // Unfiltered engineering unit data
public FilteredData[] DataADC { get; } // ADC/raw data
public double[] ActualRangesEUFiltered { get; } // Filtered EU ranges
public double[] ActualRangesEUUnfiltered { get; } // Unfiltered EU ranges
public double[] ActualRangesADC { get; } // ADC ranges
public bool FlatFolders { get; } // Folder structure option
public DDASTest(Test test, FilteredData[] adc, FilteredData[] euUnfiltered, string path, double[] actualRangesEUFiltered, double[] actualRangesEUUnfiltered, double[] actualRAngesADC, bool flatFolders) // Constructor
```
#### `DTS.Serialization.DDAS.DDASChannel`
Handles serialization of individual channel data to binary DDAS format.
```csharp
public string GetValue(DDASTest.Fields field) // Returns "#NOVALUE" if not set
public void SetValue(DDASTest.Fields field, string value) // Sets value; handles DataType side effects
public string FileName { get; set; } // Output file path
public int ChannelNumber { get; } // Returns 1 + _channelIndex
public void Serialize(TickEventHandler tickHandler) // Writes binary DDAS file
public DDASChannel(DDASTest parentTest, int channelIndex, string path) // Constructor
```
#### `DTS.Serialization.TSV.TSVSettingsWindow`
Windows Forms dialog for configuring TSV export settings.
```csharp
public TSVSettingsWindow(TSVTest test) // Constructor, populates grids from test data
```
### C++ Structures
#### `CHANNEL` (ChannelDefinition.h)
```c
typedef struct tagCHANNEL {
short Size; // Size of this object
short Flags; // Channel Flags
char Name[64]; // Channel Name
char Sign[8]; // Sign +, -, or blank
char Axis[8]; // X,Y,Z,FX,MX,AX,...
float FilterFreq; // Channel Filter Class (in Hz)
float SetGain; // Gain setting (1 - n)
float ActGain; // Actual (measured?) gain setting
float Rcal; // Shunt cal resistance
float Excitation; // Excitation Voltage (when programable)
byte byteSpares[4]; // Spare bytes (was Cal Date)
TRANSDUCER Transducer; // "Snapshot" of transducer values
} CHANNEL;
typedef CHANNEL *PCHANNEL;
typedef CHANNEL *PCHAN;
```
#### `FILEINFOBLOCK` (DDASTestDefinition.h)
```c
typedef struct tagFILEINFOBLOCK {
UINT Size; // Block Size (including nSize)
char FileTypeName[12]; // Software Type Name
char FileTypeVers[12]; // File Version Name
UINT FileTypeFlags; // Hardware Type in upper 16 bits, File Type in lower 16 bits
char CreatedByName[16]; // Created by T-number
char UpdatedByName[16]; // Updated by T-number
} FILEINFOBLOCK;
```
#### `TESTINFO` (DataFloat.h)
```c
typedef struct tagTESTINFO {
unsigned long Size; // Block Size (including Size)
unsigned long DeviceID; // DAQ device ID
long ChannelNo; // Channel number (1-32)
long SampleRate; // Samples per second
long TotalSamples; // Total samples in data record
long PreEventSamples; // Samples before event
short ChanNumInSys; // Channel Number (1-128) in system
short NumPreCalPts; // Number of preCal points
short NumPostCalPts; // Number of postCal points
char TestCreation[128]; // Test path and date
char TimeAxisTitle[32]; // Time axis title
byte SpareBytes[2]; // 2 bytes of spare (for 4 byte alignment)
} TESTINFO;
```
#### `ACQUISITIONBLOCK` (DDASTestDefinition.h)
```c
typedef struct tagACQUISITIONBLOCK {
long nSize; // Block Size (including nSize)
long nRecordMode; // Enumerated constant data mode
long SampleRate; // Samples per second
long TotalSamples; // Total samples in record
long PreEventSamples; // Pre-Event samples (Rec Mode only!)
long TapeModeChannels; // No of Channels (Tape Mode only!)
long nTrigBlock; // Number of trigger entries (can be 0)
} ACQUISITIONBLOCK;
```
#### `TRIGCHANDEF` and `TRIGCHANBLOCK` (DDASTestDefinition.h)
```c
typedef struct tagTRIGCHANDEF {
BYTE ChanNo; // Channel number to use as trigger
BYTE LevelPct; // Trig level in % full scale (0=off)
} TRIGCHANDEF;
#define MAXTRIGCHANS 4
#define TRIGCHANDSBL 0x80
typedef struct tagTRIGCHANBLOCK {
unsigned short SizeBlock;
unsigned short NumTrigs;
TRIGCHANDEF TrigChan[MAXTRIGCHANS];
} TRIGCHANBLOCK;
```
### C++ Class: `CDataFloat` (DataFloat.h)
```c
CDataFloat(unsigned int nSize);
CDataFloat();
virtual ~CDataFloat();
int GetChannelNumberInBox();
bool VerifyAndCoerceAxis(bool bNegativeSign, const char* szAxis, BOOL bVerbose);
void SetEngrgUnits(char *szNewEngrgUnits);
void SetChannelName(char* szNewChannelName);
int CalcSampIn3mSecInt();
int ConvertTimeToIndex(float fTime);
float ConvertIndexToTime(int nIndex);
const CString GetFileName();
int AppendArrayFloat(CArray<float, float&>* srcArray);
CArray<float, float&>* GetDataArray();
bool GetTimeAtValue(float fValue, float *pTvalue);
bool GetDataPeaks(int nPkType, int nVerbose, float* pTStart, float* pTEnd, float* pTMin, float* pDMin, float* pTMax, float* pDMax);
bool GetDataPeaks(int nPkType, int nVerbose, float* pTMin, float* pDMin, float* pTMax, float* pDMax);
bool GetDataPeaks(int nPkType, int nVerbose, int *pXMin, float *pTMin, float *pDMin, int *pXMax, float *pTMax, float *pDMax);
int GetChannelNumber();
float GetStartTime(bool bmSec);
float GetStartTimeData(bool bmSec);
float GetStopTime(bool bmSec);
float GetStopTimeData(bool bmSec);
const char* GetFileExt();
const char* GetFileTitle();
long GetSampleRate();
const char* GetFilePathAndName();
int SetFilePathAndName(char* szNewFileSpec);
int ClearAll(long NewNumberElements);
TESTINFO* GetTestInfo();
FILEINFOBLOCK* GetFileInfo();
CHANNEL* GetChannel();
float GetFilterClass();
int GetEventOffset();
CString GetDataSetName(CString &csName);
FILEHEADER* GetFileHeader();
bool WriteToFile(const char *lpFilename, bool bPrint);
bool ReadFromFile(const char *lpFilename);
float* GetDataBuffer();
bool SetSize(long lNumberElements);
long GetSize();
bool GetDataNext(float* fData);
bool StoreDataNext(float fData);
bool SetIndexToStart();
void operator=(const CDataFloat &src);
```
### Macros and Constants
```c
// Channel state macros (ChannelDefinition.h)
#define ISCHANACTIVE(pChan) (pChan->Flags&(1<<CHANFLAG_ACTIVE)?1:0)
#define SETCHANACTIVE(pChan) (pChan->Flags|=(1<<CHANFLAG_ACTIVE))
#define CLRCHANACTIVE(pChan) (pChan->Flags&=(~(1<<CHANFLAG_ACTIVE)))
// File type constants (DDASTestDefinition.h)
#define TESTDEFEXT ".tdf"
#define DDASTYPENAME "DDAS V5"
#define DDASFILEVERS "Ver 500"
// Data file constants (DataFloat.h)
#define FLOATDATANAME "DDAS FlPt"
#define FLOATDATARAW "DDAS fpRAW"
#define FLOATDATAVER "Ver 500"
#define RawExt ".raw"
#define FlPtExt ".fpd"
// Trigger constants (DDASTestDefinition.h)
#define MAXTRIGCHANS 4
#define TRIGCHANDSBL 0x80
```
### Enumerations
```c
// ChannelDefinition.h
enum ChannelFlags { CHANFLAG_ACTIVE };
// DDASTestDefinition.h
enum FileTypeFlags { FILETYPE_IMPORTED4X };
enum HardwareType { HWTYPE_UNKNOWN, HWTYPE_DDAS3, HWTYPE_KAYSERTHREDE, HWTYPE_COUNT };
enum AnalogOptionFlags { ANAOPT_CHANTRIGGERS };
enum MemoryOptionFlags { MEMOPT_TAPEMODE, MEMOPT_PREEVENT, MEMOPT_PREEVENTXXX };
enum RecordModes { RECORDMODE_EVENT, RECORDMODE_TAPE };
// DataFloat.h
enum FileTypes { UNKNOWN, FLOATPOINT, PROCESSED };
enum PeakTypes { PEAKS_MINMAX, PEAKS_3MSCONTIN, PEAKS_3MSCUMUL };
enum FPDVerbosity { FPD_SILENT, FPD_ERRORS, FPD_STATUS, FPD_RESULTS, FPD_VERBOSE };
```
---
## 3. Invariants
1. **Channel numbering**: Channels are 1-indexed in DDAS format. `ChannelNumber` returns `1 + _channelIndex`.
2. **Block size fields**: All binary structures include a `Size` field as the first member that must equal the total byte size of the structure (including the size field itself).
3. **Fixed-size string fields**: All character arrays in structures are fixed-width and must be null-padded to their full length when written (e.g., `FileTypeName[12]`, `Name[64]`).
4. **File type/version strings**: DDAS files use `"DDAS FlPt"` as the file type name and `"Ver 500"` as the version string.
5. **Trigger enable condition**: To enable a trigger, `ChanNo` and `LevelPct` must be nonzero, and `TRIGCHANDSBL` (0x80) must not be set in `LevelPct`.
6. **Hardware type encoding**: `FileTypeFlags` stores Hardware Type in upper 16 bits and File Type in lower 16 bits.
7. **Calibration date epoch**: Transducer calibration dates are stored as seconds since January 1, 1971 (not the Unix epoch of 1970).
8. **Data samples per tick**: Progress reporting uses 1000 samples per tick for granularity.
9. **Maximum trigger channels**: The system supports a maximum of 4 analog trigger channels (`MAXTRIGCHANS`).
---
## 4. Dependencies
### This module depends on:
- `TransducerDefinition.h` (C++ header for `TRANSDUCER` structure - referenced but not provided)
- `FilePath.h` (C++ header for `CFilePath` class - referenced but not provided)
- `<Afxtempl.h>` (MFC template collections for `CArray`, `CList`)
- `System.Windows.Forms` (for `TSVSettingsWindow`)
- `C1.Win.C1FlexGrid` (third-party grid control)
- `DTS.Serialization` namespace (base `Serialization.File`, `Test`, `FilteredData`, `IWriter<T>` types - not provided)
### What depends on this module:
- Unclear from source alone; the module appears to be a serialization plugin that would be loaded by a parent serialization framework.
---
## 5. Gotchas
1. **NotImplementedException in Write overload**: The `Write(string pathname, string id, Test test, bool bFiltering, bool includeGroupNameInISOExport, double minStartTime, int dataCollectionLength)` method throws `NotImplementedException`. Callers must use the full overload with all parameters.
2. **Historical CalDate field removal**: The `CHANNEL` structure's `CalDate` field was removed and replaced with `byteSpares[4]` per revision dated 11/08/04. The calibration date is now stored in the `TRANSDUCER` substructure instead.
3. **Non-standard epoch for calibration dates**: The `DDASChannel.Serialize` method uses `new DateTime(1971, 1, 1, 0, 0, 0)` as the epoch, not the standard Unix epoch (1970). This differs from the C++ header comment which mentions "seconds since 1970."
4. **SLICE-specific channel numbering logic**: In `DDASChannel` constructor, there is a comment indicating SLICE-specific logic for determining `numberOfChannelsPerModule` using the formula `(channel.ParentModule.NumberOfChannels + 2) / 3 * 3`, which assumes 3 channels per bridge module.
5. **Typo in constructor parameter**: `DDASTest` constructor has a parameter named `actualRAngesADC` (typo: "RAnges" instead of "Ranges").
6. **Unused Write method in TSVSettingsWindow**: The `c1GridGlobal_CellChanged` and `gridChannels_CellChanged` methods are empty event handlers.
7. **Hardcoded manufacturer**: In `DDASChannel.Serialize`, the manufacturer is hardcoded as `"CHRYSLER"` and sensor type as `"UNKNOWN"`.
8. **Commented-out code in DDASChannel.Serialize**: There is commented-out code for CFC frequency calculation that was apparently replaced with direct use of `channel.ParentModule.AaFilterRateHz`.
9. **File extension inconsistency**: The `File` class defines `Extension` as `".ddas"`, but `DDASChannel` generates `.fpd` files (floating point data) in its default path construction.