This commit is contained in:
2026-04-17 14:55:32 -04:00
commit bc3ac1d4c9
18017 changed files with 4371742 additions and 0 deletions

View File

@@ -0,0 +1,235 @@
---
source_files:
- Common/DTS.Common.DAS.Concepts/Test/Module/RecordingMode.cs
- Common/DTS.Common.DAS.Concepts/Test/Module/TiltAxes.cs
generated_at: "2026-04-16T02:05:00.800450+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "d40daed59089dfb4"
---
# Module
## Documentation: `DTS.Common.DAS.Concepts.Test.Module`
---
### 1. Purpose
This module provides utility types and methods for handling tilt sensor configuration and computation within the DTS DAS (Data Acquisition System) framework. It encapsulates domain-specific concepts such as axis labeling, polarity inversion, mounting offsets, and calibration-aware conversion of raw ADC values to tilt angles in degrees. The module supports dynamic axis ordering (e.g., `IXYIZ`, `ZYX`) and ignored axes, enabling flexible tilt sensor mounting configurations. It also includes string ↔ enumeration conversion helpers and core tilt calculation logic used in calibration and real-time data processing.
---
### 2. Public Interface
All public members reside within the nested `Test.Module` class.
#### **`GetRecordingModeFromString(string recordingMode)`**
```csharp
public static DFConstantsAndEnums.RecordingMode GetRecordingModeFromString(string recordingMode)
```
- **Behavior**: Parses the input string into a `DFConstantsAndEnums.RecordingMode` enum value using `Enum.Parse`. Throws an `Exception` (wrapping the original) if parsing fails or input is `null`.
#### **`TiltAxis` class**
```csharp
public class TiltAxis
{
public int AxisNumber { get; set; }
public double CurrentTilt { get; set; }
public string Label { get; set; }
public int Inversion { get; set; } = 1;
public bool IsIgnored { get; set; } = false;
public double MountedOffset { get; set; } = 0.0;
public double TargetOffset { get; set; } = 0.0;
}
```
- **Purpose**: Represents a single tilt sensor axis configuration. Properties define axis identity, current measurement, label (`X`, `Y`, `Z`), inversion factor (`+1` or `-1`), ignore flag, and offset values (in degrees).
#### **`TiltAxesHelper` class**
```csharp
public class TiltAxesHelper
{
public Dictionary<int, TiltAxis> AxisConfigurations { get; set; }
public TiltAxis AxisOne { get; set; }
public TiltAxis AxisTwo { get; set; }
public double LevelTolerance { get; set; } = 0.5;
public TiltAxesHelper();
public TiltAxesHelper(string TiltAxes, double MountOffsetAxisOne, double MountOffsetAxisTwo,
double TargetAxisOne, double TargetAxisTwo, double LevelTolerance,
int AxisIgnored, bool UseForTiltCalculation);
public string AxesToString();
}
```
- **Behavior**:
- Default constructor initializes `AxisConfigurations` with keys `1`, `2`, `3`, each containing a new `TiltAxis`.
- Parameterized constructor parses a `TiltAxes` string (e.g., `"IXIYIZ"`) to populate `AxisConfigurations[i].Label` and `Inversion`, sets `IsIgnored` for the specified axis, and assigns `AxisOne`/`AxisTwo` references to the *non-ignored* axes.
- **Bug Note**: In the constructor, `AxisOne = AxisConfigurations[2];` is assigned twice when `AxisIgnored == 2` (should likely be `AxisTwo = AxisConfigurations[3];`).
- `AxesToString()`: Reconstructs the orientation string from `AxisConfigurations` (e.g., `"IXIYIZ"``"IXIYIZ"`).
#### **`TiltAxesSimple` enum**
```csharp
public enum TiltAxesSimple
{
XYZ = 0, XZY = 1, YXZ = 2, YZX = 3, ZXY = 4, ZYX = 5
}
```
- Represents the simplified axis ordering (ignoring inversion markers `I`).
#### **`SimplifyTiltAxes(TiltAxes axes)`**
```csharp
public static TiltAxesSimple SimplifyTiltAxes(TiltAxes axes)
```
- **Behavior**: Strips `I` characters from `axes.ToString()` and parses the result into `TiltAxesSimple`.
#### **`GetTiltAxesFromString(string tiltAxes)`**
```csharp
public static TiltAxes GetTiltAxesFromString(string tiltAxes)
```
- **Behavior**: Parses the input string into a `TiltAxes` enum value using `Enum.Parse`. Throws an `Exception` (wrapping the original) on failure.
#### **`GetPolaritiesFromTiltAxes(TiltAxes ta)`**
```csharp
public static int[] GetPolaritiesFromTiltAxes(TiltAxes ta)
```
- **Behavior**: Returns an array of `+1` or `-1` for each axis, where `-1` corresponds to an `I` (inverted) axis in the `TiltAxes` string.
#### **`GetBoolPolaritiesFromTiltAxes(TiltAxes tiltAxes)`**
```csharp
public static bool[] GetBoolPolaritiesFromTiltAxes(TiltAxes tiltAxes)
```
- **Behavior**: Returns a `bool[3]` where `true` indicates an inverted axis (`I`), `false` indicates non-inverted (`P`). Iterates over the string representation, setting `rv[ax] = true` when encountering `'I'`, and increments `ax` only on non-`I` characters.
#### **`TiltSensorCalAttributes` enum**
```csharp
public enum TiltSensorCalAttributes
{
TILTSENSOR_CAL_1_GainAxis1 = 0,
TILTSENSOR_CAL_2_ZeroAxis1 = 1,
TILTSENSOR_CAL_3_ZeroDomAxis2PosAxis1 = 2,
TILTSENSOR_CAL_4_ZeroDomAxis2NegAxis1 = 3,
TILTSENSOR_CAL_5_ZeroDomAxis3PosAxis1 = 4,
TILTSENSOR_CAL_6_ZeroDomAxis3NegAxis1 = 5,
TILTSENSOR_CAL_7_GainAxis2 = 6,
TILTSENSOR_CAL_8_ZeroAxis2 = 7,
TILTSENSOR_CAL_9_ZeroDomAxis1PosAxis2 = 8,
TILTSENSOR_CAL_10_ZeroDomAxis1NegAxis2 = 9,
TILTSENSOR_CAL_11_ZeroDomAxis3PosAxis2 = 10,
TILTSENSOR_CAL_12_ZeroDomAxis3NegAxis2 = 11,
TILTSENSOR_CAL_13_GainAxis3 = 12,
TILTSENSOR_CAL_14_ZeroAxis3 = 13,
TILTSENSOR_CAL_15_ZeroDomAxis1PosAxis3 = 14,
TILTSENSOR_CAL_16_ZeroDomAxis1NegAxis3 = 15,
TILTSENSOR_CAL_17_ZeroDomAxis2PosAxis3 = 16,
TILTSENSOR_CAL_18_ZeroDomAxis3NegAxis3 = 17,
}
```
- Defines indices into the `tiltSensorCals` array for calibration parameters.
#### **`GetTiltDegreesEU(...)` overloads**
```csharp
public static double[] GetTiltDegreesEU(short[] tiltSensorADC, double[] tiltSensorCals);
public static double[] GetTiltDegreesEU(short[] tiltSensorADC, double[] tiltSensorCals,
TiltAxes axes, int ignoredAxis, float[] mountOffsetAxis);
```
- **Behavior**: Converts raw ADC values (`tiltSensorADC`, length ≥ 3) to tilt angles (degrees) using calibration data (`tiltSensorCals`, length ≥ 18). Returns a `double[3]` where the ignored axis is `double.NaN`, and the other two axes are computed and rounded to 3 decimal places (via `SIGNIFICANT_DIGITS = 1000`).
- Uses `GetDominantTiltAxis`, `GetTiltGains`, `GetTiltZeroData`, and axis-specific scaling factors (`xFactor`, `yFactor`, `zFactor`) derived from `axes`.
- Applies mounting offsets from `mountOffsetAxis[0]` and `mountOffsetAxis[1]` to the non-ignored axes.
#### **`GetTiltZeroData(...)`**
```csharp
public static double[] GetTiltZeroData(short[] tiltSensorADC, double[] tiltSensorCals, int dominantAxis)
```
- **Behavior**: Returns a `double[3]` of zero-point offsets. Uses base zero values (`TILTSENSOR_CAL_2/8/14`) and conditionally overrides them with dominant-axis-specific values (`TILTSENSOR_CAL_3/4`, `9/10`, `15/16`, etc.) based on the sign of `tiltSensorADC[dominantAxis]`.
#### **`GetDominantTiltAxis(...)`**
```csharp
public static int GetDominantTiltAxis(short[] tiltSensorADC)
```
- **Behavior**: Returns the index (`0`, `1`, or `2`) of the axis with the largest absolute ADC value.
#### **`GetTiltGains(...)`**
```csharp
public static double[] GetTiltGains(double[] tiltSensorCals)
```
- **Behavior**: Returns a `double[3]` of gain values (`TILTSENSOR_CAL_1/7/13`). Uses `1.0` if a gain is `0.0`.
#### **`AxisLabel` enum**
```csharp
public enum AxisLabel { X = 0, Y = 1, Z = 2 }
```
#### **`GetAxisLabelFromTiltAxes(...)` overloads**
```csharp
public static AxisLabel[] GetAxisLabelFromTiltAxes(TiltAxes tiltAxes);
public static AxisLabel[] GetAxisLabelFromTiltAxes(string tiltAxes);
```
- **Behavior**: Returns an `AxisLabel[3]` array corresponding to the non-`I` characters in the `TiltAxes` string (e.g., `"IXYIZ"``[Y, Z, X]`).
#### **`ConvertBoolToInvertString(bool isInverted)`**
```csharp
public static string ConvertBoolToInvertString(bool isInverted)
```
- **Behavior**: Returns `"I"` if `isInverted` is `true`, else `""`.
#### **`GetOrientationLabelFromAxisInfo(...)`**
```csharp
public static string GetOrientationLabelFromAxisInfo(string[] axisLabels, bool[] invertAxis)
```
- **Behavior**: Concatenates `invertAxis[i] ? "I" : ""` + `axisLabels[i]` for each axis (e.g., `["X","Y","Z"]`, `[true,false,false]``"IXYZ"`).
#### **`GetTiltAxesFromAxisInfo(...)`**
```csharp
public static TiltAxes GetTiltAxesFromAxisInfo(string[] axisLabels, bool[] invertAxis)
```
- **Behavior**: Calls `GetOrientationLabelFromAxisInfo`, then `GetTiltAxesFromString`.
#### **`GetMountOffsetsOrTargetsFromAxisInfo(...)`**
```csharp
public static float[] GetMountOffsetsOrTargetsFromAxisInfo(float[] perAxisValue, int axisToIgnore)
```
- **Behavior**: Returns a `float[2]` containing the values for the two *non-ignored* axes. `axisToIgnore` is `1`, `2`, or `3` (1-indexed).
- Example: `axisToIgnore=1``[perAxisValue[1], perAxisValue[2]]`.
---
### 3. Invariants
- **`TiltAxes` string format**: Must be 6 characters long, alternating axis label (`X`, `Y`, `Z`) and polarity (`P` or `N`). Inversion is represented by `I` (e.g., `IX`), but `I` is *not* a label—it is a polarity marker.
- Valid examples: `"IXIYIZ"`, `"IXYZ"`, `"ZYX"`, `"IXZIY"`.
- Invalid: `"IXIY"` (length ≠ 6), `"IXIXIX"` (repeated labels), `"IXIYIP"` (invalid polarity).
- **`TiltAxesSimple` values**: Derived by removing all `I` characters from `TiltAxes.ToString()`. Must be a permutation of `"XYZ"`.
- **`GetTiltDegreesEU` output**: The ignored axis is always `double.NaN`; the other two axes are rounded to 3 decimal places.
- **Calibration array indexing**: `tiltSensorCals` must have ≥ 18 elements; indices correspond strictly to `TiltSensorCalAttributes`.
- **`GetDominantTiltAxis`**: Uses the axis with the largest absolute value (handles negative ADCs correctly).
---
### 4. Dependencies
- **Imports/Usings**:
- `DTS.Common.Enums.DASFactory.DFConstantsAndEnums` (for `RecordingMode`, `TiltAxes`)
- `DTS.Common.Utilities` (likely contains `DegreesFromADC`)
- `System`, `System.Collections.Generic`, `System.Linq`, `System.Text`, `System.ComponentModel`
- **External Types Used**:
- `DFConstantsAndEnums.RecordingMode` (enum)
- `DTS.Common.Enums.DASFactory.DFConstantsAndEnums.TiltAxes` (enum, defined elsewhere)
- `DTS.Common.Utilities.DegreesFromADC.GetDegrees(...)` (used in `GetTiltDegreesEU`)
- **Depended Upon By**:
- Likely used by tilt sensor drivers, calibration tools, and data processing pipelines (e.g., `DataPRO`—per comment in `SIGNIFICANT_DIGITS`).
---
### 5. Gotchas
- **Constructor Bug in `TiltAxesHelper`**: When `AxisIgnored == 2`, `AxisOne` is assigned twice (`AxisConfigurations[1]`), and `AxisTwo` is never set. Likely should be:
```csharp
AxisOne = AxisConfigurations[1];
AxisTwo = AxisConfigurations[3]; // but note: AxisConfigurations is 1-indexed!
```
However, `AxisConfigurations` uses keys `1`, `2`, `3`, but `TiltAxis.AxisNumber` is not initialized in the constructor—this may cause off-by-one errors if `AxisNumber` is expected to match the dictionary key.
- **`TiltAxes` Enum Values**: The source file does *not* define the `TiltAxes` enum itself (only uses it). Its members (e.g., `IXYIZ`, `ZYX`) are assumed to exist in `DFConstantsAndEnums`. The code assumes all permutations with optional `I` are valid enum values.
- **`GetTiltZeroData` Logic**: Uses `dominantAxis` to select *dominant-axis-specific* zero points. This is non-trivial: zero points differ based on which axis is dominant (e.g., `ZeroDomAxis1PosAxis2` vs `ZeroDomAxis1NegAxis2`).
- **`SIGNIFICANT_DIGITS = 1000`**: Hardcoded to enforce 3 decimal places (0.001 precision). This is a legacy design choice (see internal case 34373).
- **`GetTiltDegreesEU` ADC Indexing**: Assumes `tiltSensorADC[0]`, `[1]`, `[2]` correspond to the physical axes *in the order they appear in the calibration array*, not the `TiltAxes` label order. The `axes` parameter only affects sign and axis assignment in the output array.
- **`GetBoolPolaritiesFromTiltAxes`**: The loop increments `ax` only on non-`I` characters, so the resulting `bool[]` is *not* aligned with the original axis order if `I` is present. For `"IXYIZ"`, `rv[0]` corresponds to `Y`, `rv[1]` to `Z`, `rv[2]` to `X`—this may be counterintuitive.
- **`GetPolaritiesFromTiltAxes`**: Returns `+1` for `P`, `-1` for `I`, but the mapping is based on the same non-`I`-indexed logic as `GetBoolPolaritiesFromTiltAxes`.

View File

@@ -0,0 +1,108 @@
---
source_files:
- Common/DTS.Common.DAS.Concepts/Test/Module/Channel/Sensor/SensorUnits.cs
- Common/DTS.Common.DAS.Concepts/Test/Module/Channel/Sensor/ExcitationVoltage.cs
generated_at: "2026-04-16T02:04:34.963354+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "00bbefe8072cdb62"
---
# Sensor
## Documentation Page: Sensor Unit and Excitation Voltage Handling in `DTS.Common.DAS.Concepts.Test.Module.Channel.Sensor`
---
### 1. **Purpose**
This module provides supporting infrastructure for sensor channel configuration within the DTS DAS (Data Acquisition System) concepts framework—specifically, it defines the enumeration of sensitivity unit types (`SensUnits`) used to interpret sensor calibration data, and provides utility methods for converting between excitation voltage options and their numeric magnitudes (e.g., 2.0 V, 5.0 V). It exists to standardize how sensor sensitivity and excitation conditions are represented and transformed across the system, enabling consistent scaling and unit conversion for physical measurements.
---
### 2. **Public Interface**
All public members reside within the nested type hierarchy `Test.Module.Channel.Sensor`.
#### **`SensUnits` Enum**
- **Namespace**: `DTS.Common.DAS.Concepts.Test.Module.Channel.Sensor`
- **Definition**:
```csharp
public enum SensUnits
{
NONE = 0,
mV = 1,
mVperV = 2,
mVperVperEU = 3,
mVperEU = 4
}
```
- **Behavior**:
- Represents the unit types for sensor sensitivity.
- Each value has a `[Description]` attribute indicating its human-readable form (e.g., `"mV/V/EU"` for `mVperVperEU`).
- `NONE` indicates a polynomial sensor (no sensitivity unit).
- Values are mutually exclusive and exhaustive for sensitivity unit specification.
#### **`GetExcitationVoltageMagnitudeFromEnum(ExcitationVoltageOptions.ExcitationVoltageOption target)`**
- **Namespace**: `DTS.Common.DAS.Concepts.Test.Module.Channel.Sensor`
- **Signature**:
```csharp
public static double GetExcitationVoltageMagnitudeFromEnum(ExcitationVoltageOptions.ExcitationVoltageOption target)
```
- **Behavior**:
- Converts a given `ExcitationVoltageOptions.ExcitationVoltageOption` enum value to its associated voltage magnitude (in volts).
- Uses an internal `VoltageMagnitudeAttributeCoder` (not visible in source but referenced) to decode the magnitude.
- Throws `ArgumentException` on failure (e.g., invalid enum or missing attribute).
#### **`GetExcitationVoltageEnumFromMagnitude(double magnitude)`**
- **Namespace**: `DTS.Common.DAS.Concepts.Test.Module.Channel.Sensor`
- **Signature**:
```csharp
public static ExcitationVoltageOptions.ExcitationVoltageOption GetExcitationVoltageEnumFromMagnitude(double magnitude)
```
- **Behavior**:
- Converts a numeric voltage magnitude (e.g., `5.0`) to the corresponding `ExcitationVoltageOptions.ExcitationVoltageOption` enum value.
- Uses `VoltageMagnitudeAttributeCoder.EncodeAttributeValue()` internally.
- On failure (e.g., magnitude not supported), logs via `APILogger` and returns `ExcitationVoltageOptions.ExcitationVoltageOption.Undefined`.
> **Note**: The `ExcitationVoltageOptions` type and its `VoltageMagnitudeAttribute`/`VoltageMagnitudeAttributeCoder` classes are *referenced* but *not defined* in the provided source files. Their full definitions must be found elsewhere (e.g., in `DTS.Common.Enums` or related files).
---
### 3. **Invariants**
- **`SensUnits` enum values are exhaustive and mutually exclusive** for sensitivity unit specification; no other unit types are defined in this module.
- **`GetExcitationVoltageMagnitudeFromEnum`** requires a valid `ExcitationVoltageOptions.ExcitationVoltageOption` field with a `VoltageMagnitudeAttribute`; otherwise, it throws.
- **`GetExcitationVoltageEnumFromMagnitude`** is *permissive*: it returns `Undefined` on failure instead of throwing, and always logs the failure.
- Voltage magnitudes are assumed to be in **volts (V)**.
- The mapping between enum values and magnitudes is **fixed and pre-defined** (e.g., `Volt5` → `5.0`), and enforced by `VoltageMagnitudeAttribute`.
---
### 4. **Dependencies**
#### **Internal Dependencies (within this module)**:
- `DTS.Common.DAS.Concepts.Test.Module.Channel.Sensor` (nested class hierarchy).
- `System.ComponentModel` (for `[Description]` attributes).
- `DTS.Common.Enums` (contains `ExcitationVoltageOptions` type).
- `DTS.Common.Utilities.Logging` (for `APILogger`).
#### **External Dependencies**:
- `DTS.Common.Enums.ExcitationVoltageOptions` — defines the `ExcitationVoltageOption` enum and `VoltageMagnitudeAttribute` (not included here).
- `DTS.Common.Utilities.AttributeCoder<TEnum, TAttr, TVal>` — base class used by `VoltageMagnitudeAttributeCoder` (not included here).
#### **Dependents**:
- Any code that configures or interprets sensor sensitivity (e.g., calibration, scaling, or unit conversion logic in DAS modules).
- Hardware abstraction layers that set or read excitation voltage settings.
---
### 5. **Gotchas**
- **Incomplete Source**: The `ExcitationVoltageOptions` type and its `VoltageMagnitudeAttribute`/`VoltageMagnitudeAttributeCoder` are *not defined* in the provided files. Their behavior and supported enum values are inferred from usage and comments, but cannot be verified from this source alone.
- **Commented-Out Code**: The `ExcitationVoltageOption` enum and related classes (`VoltageMagnitudeAttribute`, `VoltageMagnitudeAttributeCoder`) are commented out in `ExcitationVoltage.cs`. This suggests possible deprecation or refactoring—**do not assume active use** unless confirmed by other files.
- **Error Handling Asymmetry**: `GetExcitationVoltageMagnitudeFromEnum` throws on error, while `GetExcitationVoltageEnumFromMagnitude` silently returns `Undefined`. This inconsistency may lead to unhandled exceptions if callers assume symmetric behavior.
- **No Validation on Magnitude Input**: `GetExcitationVoltageEnumFromMagnitude` does not validate input range (e.g., negative voltages), potentially returning `Undefined` for invalid values without clear indication of *why*.
- **Hardcoded Enum Values**: The `SensUnits` enum uses explicit integer values (`0`, `1`, `2`, …). Changing or inserting values may break serialization or persistence if values are stored externally (e.g., in config files or databases).
> **None identified from source alone** for `SensUnits` behavior, but the excitation voltage handling is partially obscured by commented-out code and missing definitions.