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

15 KiB

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
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
2026-04-17T15:32:53.691261+00:00 zai-org/GLM-5-FP8 1 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>.

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.

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.

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.

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.

public TSVSettingsWindow(TSVTest test)   // Constructor, populates grids from test data

C++ Structures

CHANNEL (ChannelDefinition.h)

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)

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)

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)

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)

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)

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

// 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

// 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.