Files

163 lines
11 KiB
Markdown
Raw Permalink Normal View History

2026-04-17 14:55:32 -04:00
---
source_files:
- DataPRO/EquipmentExchange/CrashDesignerTestSetup.cs
generated_at: "2026-04-16T03:44:55.174600+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "75b4cd844b9f7d36"
---
# EquipmentExchange
## Documentation: `CrashDesignerTestSetup` Module
---
### 1. Purpose
This module defines the data model and XML deserialization logic for importing test setup configurations generated by *CrashDesigner* (a proprietary crash testing application). Its primary role is to parse an XML file conforming to a specific schema (with root `<TestSetupDefinition>`) into a strongly-typed object graph (`CrashDesignerTestSetup`), enabling downstream components to access test metadata, channel groupings, and data acquisition (DAQ) hardware configuration in a structured manner. It also provides a utility method (`GetEqxElectricalMethod`) to map equipment bridge types to internal sensor configuration flags used elsewhere in the system.
---
### 2. Public Interface
#### `CrashDesignerTestSetup` Class
- **`string Name { get; set; }`**
The name of the test setup, extracted from the `Name` attribute of the `<TestSetupDefinition>` XML element.
- **`static void GetEqxElectricalMethod(string eqxBridge, out bool isProportional, out DTS.Common.Enums.Sensors.SensorConstants.BridgeType bridgeType)`**
Maps a string-based equipment bridge identifier (`eqxBridge`) to internal sensor configuration flags.
- `isProportional`: `true` for passive bridges (e.g., `FullBridge`, `HalfBridge`, `QuarterBridge`), `false` for active sensors (e.g., `Active`, `ActiveSensor`, `HalfBridgeActive`, `QuarterBridgeActive`).
- `bridgeType`: One of `DTS.Common.Enums.Sensors.SensorConstants.BridgeType` (`FullBridge`, `HalfBridge`, `QuarterBridge`, `IEPE`).
- Special case: `"PiezoInput"``IEPE`, `isProportional = true`.
- **`static CrashDesignerTestSetup ReadXML(string importFile)`**
Loads and deserializes an XML file (`importFile`) into a `CrashDesignerTestSetup` instance.
- Requires root element `<TestSetupDefinition>` with `Name` attribute.
- Delegates parsing of `<General>`, `<ChannelGroups>`, and `<DataAcquisitionUnit>` sub-elements to respective `ReadXml` methods.
- Logs unknown XML elements via `Trace.WriteLine`.
#### Nested Classes & Methods
- **`GeneralSection`**
- **Properties**: `DateGenerated`, `GeneratorName`, `Description`, `TestType`, `PreTriggerTime`, `PostTriggerTime`, `OutputDataDirectory`, `TestSetupGroup` (string array).
- **`void ReadXml(XmlElement root)`**: Parses child elements corresponding to `GeneralSection.Fields` enum values.
- `PreTriggerTimeReadout``PreTriggerTime`
- `PostTriggerTimeReadout``PostTriggerTime`
- `TestSetupGroup` → appends to internal list (multiple allowed).
- Uses invariant culture for numeric/date parsing; logs failures.
- **`ChannelGroupsSection`**
- **`Group[] Groups { get; }`**: Array of `Group` objects.
- **`void ReadXml(XmlElement root)`**: Parses `<Group>` child elements.
- **`Group`**
- **Properties**: `Name`, `Id`, `Parent`, `Description`.
- **`bool HasProperty(string key)` / `string GetProperty(string key)` / `void SetProperty(string key, string value)`**: Key-value store for arbitrary properties.
- **`KnownFormats` enum**: Lists 30+ standardized property keys (e.g., `ISOTitle`, `TestDate`, `CustomerName`, `Velocity`, `Mass`, `ImpactSide`) with `[Description]` attributes matching their XML element names.
- **`static Group ReadXml(XmlElement root)`**: Parses `Id`, `Parent` attributes, `<Name>`, `<Description>`, and `<Property Name="..." Value="...">` elements.
- **`DataAcquisitionSection`**
- **`DataAcquisitionUnit[] DataAcquisitionUnits { get; }`**: Array of DAQ units.
- **`void ReadXml(XmlElement element)`**: Parses a *single* `<DataAcquisitionUnit>` element (note: despite the name, only one unit is supported per XML file per current implementation).
- **`DataAcquisitionUnit`**
- **Properties**: Extensive hardware metadata (e.g., `Name`, `Type`, `SerialNr`, `Manufacturer`, `SampleFrequencyHz`, `AnalogInputChannelCount`, `Trigger`, `Enabled`, `DataBaseUID`, etc.).
- **`TriggerSection Trigger { get; }`**: Nested class with `TriggerMode`, `RecBus`, `T0Bus`, `Filter`.
- **`AnalogInChannelSection AnalogChannels { get; }`**: Contains parsed analog input channels.
- **`static DataAcquisitionUnit ReadXml(XmlElement root)`**: Parses all DAQ-specific XML elements.
- Uses `GetDouble` helper (returns `NaN` on parse failure).
- Handles nested `<Trigger>` and `<AnalogInChannel>` elements.
- **`TriggerSection`**
- **`void ReadXml(XmlElement root)`**: Parses `<TriggerMode>`, `<RecBus>`, `<T0Bus>`, `<Filter>` elements.
- **`AnalogInChannelSection`**
- **`AnalogInChannel[] Channels { get; }`**: Array of analog channels.
- **`void ReadXml(XmlElement element)`**: Parses a *single* `<AnalogInChannel>` element.
- **`AnalogInChannel`**
- **Properties**: 50+ fields covering channel configuration, sensor details, calibration, and signal conditioning (e.g., `Enabled`, `Id`, `GroupId`, `ChannelName`, `BridgeType`, `Sensitivity`, `ExcitationVoltage`, `OffsetFlag`, `ShuntPosFlag`, `NextCalibrationDate`, `PhysicalUnit`, `Direction`, `InvertFlag`, `CalculatedGain`, `SensorStatusUsable`, `VoltageEngineeringUnit`).
- **`static AnalogInChannel ReadXml(XmlElement root)`**: Parses all channel XML elements.
- Uses `GetDate` helper (returns `DateTime.MinValue` on parse failure).
- **Bug/Quirk**: In `ShuntPosMaxToleranceV` parsing, incorrectly assigns to `ShuntGainPos` instead of `ShuntPosMaxToleranceV` (see *Gotchas*).
- **`static DateTime GetDate(string text)`**
Helper for parsing `DateTime` from XML text (invariant culture, `DateTimeStyles.None`). Returns `DateTime.MinValue` on failure.
- **`static double GetDouble(string text)`**
Helper for parsing `double` from XML text (invariant culture, `NumberStyles.Any`). Returns `double.NaN` on failure.
---
### 3. Invariants
- **XML Structure**:
- Root element must be `<TestSetupDefinition>` with a `Name` attribute.
- Valid child elements under `<TestSetupDefinition>` are strictly: `<General>`, `<ChannelGroups>`, `<DataAcquisitionUnit>`. Unknown elements are logged but ignored.
- `<General>` supports only elements defined in `GeneralSection.Fields` enum.
- `<ChannelGroups>` must contain one or more `<Group>` elements.
- `<DataAcquisitionUnit>` must contain exactly one `<DataAcquisitionUnit>` element (per current `ReadXml` implementation).
- `<AnalogInChannel>` elements are parsed individually and appended to the channel list.
- **Data Parsing**:
- Numeric/date fields use `CultureInfo.InvariantCulture` for parsing.
- Failure to parse numeric/date fields results in default values (`0`, `DateTime.MinValue`, `double.NaN`) and a `Trace.WriteLine` warning.
- `Group` properties are stored in a dictionary; unknown keys are preserved.
- `AnalogInChannel.Enabled`, `DataConversionEnabled`, etc., default to `false` if attribute/element missing.
- **Object State**:
- `General`, `ChannGroups`, `DataAcquisition` are initialized to non-null instances (via property initializers).
- `Group.Groups`, `DataAcquisitionUnits`, `AnalogChannels.Channels` arrays are lazily populated via `ReadXml`.
---
### 4. Dependencies
- **External Types**:
- `System.Xml.XmlDocument`, `System.Xml.XmlElement`, `System.Xml.XmlNode`
- `System.ComponentModel.DescriptionAttribute` (used in `Group.KnownFormats`)
- `DTS.Common.Enums.Sensors.SensorConstants.BridgeType` (referenced in `GetEqxElectricalMethod`)
- **Module Dependencies**:
- This module *depends on* the `DTS.Common` assembly (for `BridgeType` enum).
- *Used by*: Downstream components consuming `CrashDesignerTestSetup` objects (e.g., test execution, DAQ configuration, reporting).
- **Notable**: The `DataAcquisitionSection` class has a commented-out property `public DataAcquisitionSection DataAcquisitionUnit { get; set; }`, suggesting a design change or legacy artifact.
---
### 5. Gotchas
- **Shunt Parsing Bug**:
In `AnalogInChannel.ReadXml`, the `ShuntPosMaxToleranceV` case incorrectly assigns to `ShuntGainPos` instead of `ShuntPosMaxToleranceV`:
```csharp
case "ShuntPosMaxToleranceV": analog.ShuntGainPos = GetDouble(element.InnerText); break; // WRONG!
```
This will overwrite `ShuntGainPos` and leave `ShuntPosMaxToleranceV` at its default (`0`).
**Impact**: Shunt calibration tolerance data may be corrupted.
- **Single DAQ Unit Assumption**:
`DataAcquisitionSection.ReadXml` only processes *one* `<DataAcquisitionUnit>` element (appends to `_units` list once), despite the XML schema potentially supporting multiple. This may cause data loss if the input file contains multiple `<DataAcquisitionUnit>` elements.
- **Ambiguous `PreTriggerTimeReadout`/`PostTriggerTimeReadout`**:
The XML element names (`PreTriggerTimeReadout`, `PostTriggerTimeReadout`) do not match the property names (`PreTriggerTime`, `PostTriggerTime`). This could confuse developers unfamiliar with the enum mapping.
- **`KnownFormats` Enum Mismatch**:
The `KnownFormats` enum uses `[Description]` attributes (e.g., `[Description("ISO Title")]`), but XML parsing for `Group` properties relies on `element.LocalName` matching the enum *name* (e.g., `ISOTitle`), not the description. This is correct per current code but may be error-prone.
- **`GetEqxElectricalMethod` Behavior**:
- `"Active"` and `"ActiveSensor"` both set `isProportional = false`, but the distinction is not documented.
- `"PiezoInput"` is the *only* case that sets `bridgeType = IEPE`; other active bridges use `FullBridge`/`HalfBridge`/`QuarterBridge` with `isProportional = false`.
- **No Validation**:
The class performs no semantic validation (e.g., checking `SampleFrequencyHz` is within `MinSampleFrequencyHz`/`MaxSampleFrequencyHz`, or `GroupId` references exist). Invalid data may propagate silently.
- **Missing `DataAcquisitionUnit` Property**:
The commented-out property `public DataAcquisitionSection DataAcquisitionUnit { get; set; }` suggests confusion between `DataAcquisitionSection` (container) and `DataAcquisitionUnit` (item). The current design uses `DataAcquisition.DataAcquisitionUnits` (array), which is correct, but the commented line may indicate historical instability.
- **No Error Handling for XML Load**:
`ReadXML` calls `doc.Load(importFile)` without try/catch. File I/O errors (e.g., missing file, malformed XML) will throw unhandled exceptions.
- **Culture Sensitivity**:
While numeric/date parsing uses invariant culture, string comparisons (e.g., `element.LocalName == "General"`) are case-sensitive and culture-sensitive. XML element names must match *exactly* (e.g., `"General"`, not `"general"`).