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,196 @@
---
source_files:
- Common/DTS.Common.DAS.Concepts/DAS/DAS.Channel.cs
- Common/DTS.Common.DAS.Concepts/DAS/DAS.Channel.IIsoCodeAware.cs
- Common/DTS.Common.DAS.Concepts/DAS/DAS.Channel.ISerialNumberAware.cs
- Common/DTS.Common.DAS.Concepts/DAS/DAS.Channel.IEngineeringUnitAware.cs
- Common/DTS.Common.DAS.Concepts/DAS/DecimationMethod.cs
- Common/DTS.Common.DAS.Concepts/DAS/DAS.Channel.IInversionAware.cs
- Common/DTS.Common.DAS.Concepts/DAS/DTS.DAS.Concepts.IVoltageInsertAware.cs
- Common/DTS.Common.DAS.Concepts/DAS/DAS.Channel.ILevelTriggerable.cs
- Common/DTS.Common.DAS.Concepts/DAS/DAS.Channel.Data.cs
- Common/DTS.Common.DAS.Concepts/DAS/DAS.DAS.Concepts.IShuntAware.cs
- Common/DTS.Common.DAS.Concepts/DAS/DAS.Channel.IDecimatable.cs
- Common/DTS.Common.DAS.Concepts/DAS/DAS.Id.cs
generated_at: "2026-04-16T13:24:05.408874+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "f40aa120b967ad3e"
---
# Documentation: DTS.DAS.Concepts.DAS Module
## 1. Purpose
This module provides the core domain abstractions for a Data Acquisition System (DAS). It defines the foundational types for modeling DAS channels, their identifiers, data containers, and optional capabilities (such as decimation, level triggering, calibration awareness, and metadata properties). The module uses interfaces and abstract generic classes to establish a flexible, composable type system that can be extended by concrete implementations.
---
## 2. Public Interface
### Classes
#### `Channel<DataType>`
- **Namespace:** `DTS.DAS.Concepts.DAS`
- **Signature:** `public abstract class Channel<DataType> : Exceptional`
- **Description:** Abstract base class representing a DAS channel. Generic over `DataType`, which defines the type of data contained by channels of this DAS. Inherits from `Exceptional` (from `DTS.Utilities`).
#### `Data<DatumType>`
- **Namespace:** `DTS.DAS.Concepts.DAS.Channel`
- **Signature:** `public abstract class Data<DatumType> : ExceptionalList<DatumType>`
- **Description:** Abstract base class representing a list of channel data. Inherits from `ExceptionalList<DatumType>`. Provides three protected constructors:
- `protected Data()` — Default constructor.
- `protected Data(int capacity)` — Initializes with specified capacity.
- `protected Data(IEnumerable<DatumType> collection)` — Initializes from an existing collection.
#### `Id`
- **Namespace:** `DTS.Common.DAS.Concepts.DAS`
- **Signature:** `public sealed class Id : Exceptional, IComparable<Id>, IEquatable<Id>`
- **Description:** Represents a DAS identifier, encapsulating a string value. Supports implicit bidirectional conversion to/from `string`. Comparison and equality operations are case-insensitive (`StringComparison.OrdinalIgnoreCase`).
- **Key Members:**
- `public Id(string value)` — Constructor.
- `public static implicit operator string(Id id)` — Converts `Id` to `string`.
- `public static implicit operator Id(string id)` — Converts `string` to `Id`.
- `public bool Equals(Id that)` — Case-insensitive equality check.
- `public int CompareTo(Id that)` — Case-insensitive comparison.
- `public override string ToString()` — Returns the underlying string value.
- `public override int GetHashCode()` — Returns hash of the underlying string (or 0 if null).
- Static comparison operators: `==`, `!=`, `<`, `>`, `<=`, `>=`.
---
### Interfaces
#### `IIsoCodeAware`
- **Namespace:** `DTS.DAS.Concepts.DAS.Channel`
- **Members:** `string IsoCode { get; set; }`
- **Description:** Defines ISO code awareness for an object.
#### `ISerialNumberAware`
- **Namespace:** `DTS.DAS.Concepts.DAS.Channel`
- **Members:** `string SerialNumber { get; set; }`
- **Description:** Defines serial number awareness for an object.
#### `IEngineeringUnitAware`
- **Namespace:** `DTS.DAS.Concepts.DAS.Channel`
- **Members:** `string EngineeringUnits { get; set; }`
- **Description:** Defines engineering unit description awareness for an object.
#### `IInversionAware`
- **Namespace:** `DTS.DAS.Concepts.DAS.Channel`
- **Members:** `bool IsInverted { get; set; }`
- **Description:** Defines inversion state awareness for an object.
#### `ILinearized`
- **Namespace:** `DTS.DAS.Concepts.DAS.Channel`
- **Members:** `LinearizationFormula LinearizationFormula { get; set; }`
- **Description:** Defines linearization formula awareness. (Note: `LinearizationFormula` type is referenced but not defined in the provided sources.)
#### `IVoltageInsertionAware`
- **Namespace:** `DTS.DAS.Concepts.DAS.Channel`
- **Members:**
- `double ExpectedGain { get; set; }` — Measured shunt deflection value.
- `double MeasuredGain { get; set; }` — Target shunt deflection value.
- **Description:** Defines voltage insertion (shunt-check) awareness.
#### `ILevelTriggerable`
- **Namespace:** `DTS.DAS.Concepts.DAS.Channel`
- **Members:**
- `double? TriggerBelowThresholdEu { get; set; }` — "Trigger below" threshold; set to `null` to deactivate.
- `double? TriggerAboveThresholdEu { get; set; }` — "Trigger above" threshold; set to `null` to deactivate.
- `LevelTriggerTypes LevelTriggerType { get; set; }` — The level trigger type.
- **Description:** Defines level triggerability for a channel.
#### `IShuntAware`
- **Namespace:** `DTS.DAS.Concepts.DAS.Channel`
- **Members:**
- `double MeasuredShuntDeflectionMv { get; set; }` — Measured shunt deflection in millivolts.
- `double TargetShuntDeflectionMv { get; set; }` — Target shunt deflection in millivolts.
- **Description:** Defines shunt-check awareness.
#### `ICalSignalAware`
- **Namespace:** `DTS.DAS.Concepts.DAS.Channel`
- **Members:**
- `double MeasuredCalSignalMv { get; set; }` — Measured calibration signal in millivolts.
- `double TargetCalSignalMv { get; set; }` — Target calibration signal in millivolts.
- **Description:** Defines calibration signal awareness.
#### `IDecimatable<out T>`
- **Namespace:** `DTS.DAS.Concepts.DAS.Channel`
- **Members:**
- `uint PointsPerPoint { get; set; }` — Number of points to squeeze into a single index point.
- `DecimationMethod DecimationType { get; set; }` — Decimation method to apply.
- `T[] ToDecimatedArray()` — Generates a decimated array using the current `DecimationMethod`.
- `T this[long i] { get; }` — Indexer returning values from the decimated set.
- **Description:** Defines decimation capability for a DAS channel. Covariant in `T` (`out T`).
---
### Enums
#### `DecimationMethod`
- **Namespace:** `DTS.Common.DAS.Concepts.DAS` (also defined in `DTS.DAS.Concepts.DAS.Channel`)
- **Values:**
- `Point` — Use the value of the `PointsPerPoint`-th point as the representative value.
- `Average` — Use the average of the `PointsPerPoint` values.
- `PeakMagnitude` — Use the peak magnitude value of the `PointsPerPoint` values.
- **Description:** Specifies how to determine the representative value for decimated data sets.
#### `LevelTriggerTypes`
- **Namespace:** `DTS.DAS.Concepts.DAS.Channel`
- **Signature:** `[Flags] public enum LevelTriggerTypes`
- **Values:**
- `NONE = 0x00`
- `OutsideWindow = 0x01`
- `InsideWindow = 0x02`
- `LessThan = 0x04`
- `GreaterThan = 0x08`
- **Description:** Bitwise flags for specifying level trigger behavior.
---
## 3. Invariants
- `Channel<DataType>` is abstract and cannot be instantiated directly; it must be subclassed.
- `Data<DatumType>` is abstract and cannot be instantiated directly; it must be subclassed.
- `Id` is sealed and cannot be inherited.
- `Id.value` is `readonly` — once constructed, the underlying string cannot be changed.
- `Id` equality and comparison operations are always case-insensitive (`StringComparison.OrdinalIgnoreCase`).
- `IDecimatable<out T>` is covariant in `T`, allowing assignment compatibility for derived types.
- `LevelTriggerTypes` is a flags enum; values can be combined with bitwise operations.
- Nullable thresholds (`TriggerBelowThresholdEu`, `TriggerAboveThresholdEu`) use `null` to indicate deactivation.
---
## 4. Dependencies
### This module depends on:
- `DTS.Utilities` — Provides `Exceptional` (base class for `Channel<DataType>`) and `ExceptionalList<DatumType>` (base class for `Data<DatumType>`).
- `DTS.Common.Utilities` — Provides `Exceptional` (base class for `Id`).
- `System` — For `IComparable<T>`, `IEquatable<T>`, `FlagsAttribute`, `StringComparison`.
- `System.Collections.Generic` — For `IEnumerable<T>`.
### What depends on this module:
- Not determinable from the provided sources alone. Consumers would typically be concrete DAS channel implementations, data processing pipelines, or configuration systems that implement these interfaces and extend these base classes.
---
## 5. Gotchas
1. **Duplicate `DecimationMethod` enum definition:** This enum is defined in two different namespaces:
- `DTS.Common.DAS.Concepts.DAS` (in `DecimationMethod.cs`)
- `DTS.DAS.Concepts.DAS.Channel` (in `DAS.Channel.IDecimatable.cs`)
This could cause ambiguity or require explicit namespace qualification when both namespaces are imported.
2. **Developer uncertainty about `Id` class:** The source contains a comment questioning the class's existence: `"DTM - why does this class exist? it's only encapsulating a string"` and `"why does this class even exist?"` in the XML documentation. This suggests possible tech debt or historical artifact.
3. **Misleading XML summary in `IVoltageInsertionAware`:** The file header comment references "shunt-check awareness," but the interface is named `IVoltageInsertionAware` and deals with gain values, not shunt deflection directly.
4. **Undocumented `LinearizationFormula` type:** The `ILinearized` interface references a `LinearizationFormula` type that is not defined in any of the provided source files. Its structure and behavior are unknown from the source alone.
5. **Namespace inconsistency:** Files use different namespace roots:
- `DTS.DAS.Concepts.DAS` (most files)
- `DTS.Common.DAS.Concepts.DAS` (`DecimationMethod.cs`, `DAS.Id.cs`)
This may cause confusion or require multiple `using` directives.

View File

@@ -0,0 +1,115 @@
---
source_files:
- Common/DTS.Common.DAS.Concepts/DAS/Channel/LevelTriggerTypes.cs
- Common/DTS.Common.DAS.Concepts/DAS/Channel/Channel.cs
- Common/DTS.Common.DAS.Concepts/DAS/Channel/TimestampPartTypes.cs
- Common/DTS.Common.DAS.Concepts/DAS/Channel/Data.cs
generated_at: "2026-04-16T02:05:03.519331+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "0f3b00d01b342d9f"
---
# Channel
## Documentation: DAS Channel Concepts Module
---
### 1. Purpose
This module defines core conceptual types used to represent data acquisition system (DAS) channel behavior and data structures within the DTS Common library. It provides foundational enums (`LevelTriggerTypes`, `TimestampPartTypes`) for configuring trigger conditions and interpreting timestamp components, and abstract base classes (`Channel<TDataType>`, `Data<TDatumType>`) that serve as the basis for concrete channel and data implementations in the DAS subsystem. The module exists to standardize how channel-level logic (e.g., threshold triggers) and data containers are modeled internally, decoupling high-level application logic (e.g., slice control app) from hardware-specific implementations.
---
### 2. Public Interface
#### Enums
- **`LevelTriggerTypes`** (`[Flags]` enum)
Represents configurable trigger conditions for a channel. Values are bit flags:
- `NONE = 0x00`: No trigger condition.
- `OutsideWindow = 0x01`: Trigger when value is outside a specified window.
- `InsideWindow = 0x02`: Trigger when value is inside a specified window.
- `LessThan = 0x04`: Trigger when value is less than a threshold.
- `GreaterThan = 0x08`: Trigger when value is greater than a threshold.
*Note:* Combinations (e.g., `LessThan | GreaterThan`) are valid per `[Flags]` semantics, though semantic validity (e.g., `OutsideWindow` + `InsideWindow`) is not enforced here.
- **`TimestampPartTypes`** (`[Flags]` enum with `[Description]` attributes)
Represents components of a timestamp, typically used for parsing or reconstructing high-precision timestamps. Values are bit flags:
- `Marker = 1 << 0` (value `1`): A marker bit (description: `"Marker"`).
- `Seconds_High = 1 << 1` (value `2`): High-order bits of seconds (description: `"Seconds"`).
- `Seconds_Low = 1 << 2` (value `4`): Low-order bits of seconds (description: `"Seconds"`).
- `Nanoseconds_High = 1 << 3` (value `8`): High-order bits of nanoseconds (description: `"Nanoseconds"`).
- `Nanoseconds_Low = 1 << 4` (value `16`): Low-order bits of nanoseconds (description: `"Nanoseconds"`).
- `Reserved = 1 << 5` (value `32`): Reserved bit (description: `"Reserved"`).
*Note:* `Seconds_High` and `Seconds_Low` share the same description `"Seconds"`; similarly for nanosecond components.
#### Abstract Classes
- **`Channel<TDataType>`**
Abstract base class representing a DAS channel in the slice control app. Inherits from `Exceptional` (from `DTS.Common.Utilities`).
- *Generic parameter:* `TDataType` specifies the type of data the channel carries (e.g., `double`, `int`, custom struct).
- *Behavior:* No public methods or properties defined in this source; intended as a base for concrete channel implementations (e.g., `AnalogChannel`, `DigitalChannel`).
- **`Data<TDatumType>`**
Abstract base class representing a list of channel data samples. Inherits from `ExceptionalList<TDatumType>` (from `DTS.Common.Utilities`).
- *Generic parameter:* `TDatumType` specifies the type of individual data samples (e.g., `double`, `SampleRecord`).
- *Constructors:*
- `protected Data()`: Default constructor.
- `protected Data(int capacity)`: Constructor with initial list capacity.
- `protected Data(IEnumerable<TDatumType> collection)`: Constructor that copies elements from a collection.
- *Behavior:* Provides no additional functionality beyond its base list class; intended as a base for concrete data container implementations (e.g., `SampleData`, `EventList`).
---
### 3. Invariants
- **`LevelTriggerTypes`**:
- Values are strictly bit flags (`0x00`, `0x01`, `0x02`, `0x04`, `0x08`).
- Valid combinations must be powers-of-two or bitwise ORs thereof.
- No validation is performed on combinations (e.g., `OutsideWindow | InsideWindow` is syntactically valid but semantically ambiguous).
- **`TimestampPartTypes`**:
- Values are strictly bit flags with explicit bit positions (bits 05).
- `Seconds_High` and `Seconds_Low` are distinct flags despite sharing a description; similarly for `Nanoseconds_High`/`Low`.
- The `Reserved` flag is defined but its usage is unspecified.
- **`Channel<TDataType>` and `Data<TDatumType>`**:
- Both are abstract; direct instantiation is impossible.
- No invariants are enforced in the provided source (e.g., no validation of `TDatumType` constraints).
---
### 4. Dependencies
#### This module depends on:
- `DTS.Common.Utilities`:
- Provides `Exceptional` (base class for `Channel<TDataType>`).
- Provides `ExceptionalList<T>` (base class for `Data<TDatumType>`).
- `System`:
- Core types (`System.FlagsAttribute`, `System.ComponentModel.DescriptionAttribute`, `System.ComponentModel.TypeConverterAttribute`).
- `DTS.Common.Converters`:
- Provides `EnumDescriptionTypeConverter` for `TimestampPartTypes`.
#### This module is depended on by:
- **Inferred consumers**:
- Any code referencing `DTS.Common.DAS.Concepts.DAS.Channel` namespace (e.g., concrete channel implementations, trigger logic, timestamp parsers).
- The `slice control app` (explicitly mentioned in `Channel<TDataType>` summary) is a direct consumer.
- Serialization/deserialization logic likely uses `TimestampPartTypes` (given `TypeConverter` attribute).
---
### 5. Gotchas
- **`LevelTriggerTypes` combinations**:
- `OutsideWindow` and `InsideWindow` are mutually exclusive in practice but not enforced. Combining them (`OutsideWindow | InsideWindow = 0x03`) may lead to undefined behavior in downstream logic.
- `LessThan` and `GreaterThan` can be combined (e.g., for hysteresis), but this is not documented.
- **`TimestampPartTypes` descriptions**:
- `Seconds_High` and `Seconds_Low` share the same `[Description("Seconds")]`; UI/tooling relying solely on `DescriptionAttribute` may not distinguish them.
- `Reserved` flag is defined but its purpose is unspecified—avoid using it unless documented elsewhere.
- **Abstract base classes**:
- `Channel<TDataType>` and `Data<TDatumType>` provide no implementation details beyond inheritance. Behavior (e.g., thread safety, sample ordering) must be inferred from concrete subclasses.
- `Data<TDatumType>` inherits from `ExceptionalList<T>`, but no information about `ExceptionalList<T>`s behavior (e.g., exception handling semantics) is provided here.
- **No versioning or deprecation markers**:
- No attributes (e.g., `[Obsolete]`) or version comments indicate deprecated/legacy usage patterns.
*None identified from source alone.*

View File

@@ -0,0 +1,238 @@
---
source_files:
- Common/DTS.Common.DAS.Concepts/Interfaces/ITriggerable.cs
- Common/DTS.Common.DAS.Concepts/Interfaces/IDataCollectionEnabled.cs
- Common/DTS.Common.DAS.Concepts/Interfaces/ICalibratable.cs
- Common/DTS.Common.DAS.Concepts/Interfaces/ILargeDataAware.cs
- Common/DTS.Common.DAS.Concepts/Interfaces/IRealtimeable.cs
- Common/DTS.Common.DAS.Concepts/Interfaces/IGpioEnabled.cs
- Common/DTS.Common.DAS.Concepts/Interfaces/IDownloadEnabled.cs
- Common/DTS.Common.DAS.Concepts/Interfaces/IArmable.cs
generated_at: "2026-04-16T13:24:49.910550+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "097989360eebf93b"
---
# Documentation: DTS.Common.DAS.Concepts Interfaces
## 1. Purpose
This module defines a set of core interfaces that describe the capabilities of Data Acquisition System (DAS) hardware devices. These interfaces model behaviors such as arming, triggering, calibration, real-time data capture, data download, and GPIO manipulation. The design enables polymorphic treatment of different hardware models (TSR, HEADS, NASCAR variants) through capability-based composition rather than inheritance from a monolithic base class.
---
## 2. Public Interface
### `ITriggerable`
**Namespace:** `DTS.Common.DAS.Concepts`
```csharp
public interface ITriggerable
{
void Trigger();
}
```
A minimal interface representing an object that can be triggered. The `Trigger()` method initiates the trigger action on the implementing object.
---
### `IArmable`
**Namespace:** `DTS.Common.DAS.Concepts`
```csharp
public interface IArmable
{
void Arm();
void Disarm();
ArmStatus ArmStatus { get; }
AvailableArmModes ArmMode { get; }
}
```
Defines the ability to be armed and disarmed. Implementers must provide:
- `Arm()` — transitions the device to an armed state
- `Disarm()` — transitions the device to a disarmed state
- `ArmStatus` (read-only) — current arm status of type `ArmStatus`
- `ArmMode` (read-only) — available arm modes of type `AvailableArmModes`
**Note:** Types `ArmStatus` and `AvailableArmModes` are referenced but not defined in the provided source files.
---
### `IDownloadEnabled`
**Namespace:** `DTS.Common.DAS.Concepts`
```csharp
public interface IDownloadEnabled
{
TsrEvent[] EventList { get; }
double[][] GetEventData(TsrEvent Event, ulong FirstSample, ulong LastSample);
bool DataHasBeenDownloaded { get; }
}
```
Represents an object from which data can be downloaded:
- `EventList` (read-only) — array of `TsrEvent` objects available for download
- `GetEventData(TsrEvent Event, ulong FirstSample, ulong LastSample)` — retrieves event data for the specified sample range; returns a jagged array of `double[]` where each inner array corresponds to a channel
- `DataHasBeenDownloaded` (read-only) — indicates whether data has been downloaded
**Note:** Type `TsrEvent` is referenced but not defined in the provided source files.
---
### `IDataCollectionEnabled`
**Namespace:** `DTS.Common.DAS.Concepts`
```csharp
public interface IDataCollectionEnabled : IArmable, ITriggerable, IDownloadEnabled
{
double[] AvailableSampleRates { get; }
double SampleRate { get; set; }
}
```
Combines arming, triggering, and download capabilities with data collection-specific properties:
- `AvailableSampleRates` (read-only) — array of sample rates supported by the device
- `SampleRate` (read/write) — the currently configured sample rate
---
### `ICalibratable`
**Namespace:** `DTS.Common.DAS.Concepts`
```csharp
public interface ICalibratable
{
string SerialNumber { get; set; }
double Sensitivity { get; set; }
double BatteryVolts { get; set; }
double VddVolts { get; set; }
double SignalConditioningVolts { get; set; }
}
```
Defines properties required for rudimentary calibration. All properties are read/write.
---
### `IRealtimeable`
**Namespace:** `DTS.Common.DAS.Concepts`
```csharp
public class RealtimeSample
{
public double[] DataEU; // Indexes by channel
public ulong SampleNumber;
}
public interface IRealtimeable
{
void StartRealtime(double sampleRate);
void StopRealtime();
RealtimeSample[] GetRealtimeSamples();
}
```
Represents the ability to perform real-time data capture:
- `StartRealtime(double sampleRate)` — begins real-time capture at the specified rate
- `StopRealtime()` — stops real-time capture
- `GetRealtimeSamples()` — retrieves an array of `RealtimeSample` objects captured since the last call
`RealtimeSample` is a companion class containing:
- `DataEU` — array of engineering unit values indexed by channel
- `SampleNumber` — the sample sequence number (`ulong`)
---
### `ILargeDataAware`
**Namespace:** `DTS.Common.DAS.Concepts.DAS.Channel`
```csharp
public interface ILargeDataAware
{
bool IsDataArraySized { get; }
}
```
Defines whether a DAS channel's data set is small enough to safely fit into an array within a "slice" application context (e.g., for filtering or viewer display).
---
### `IGpioEnabled`
**Namespace:** `DTS.Common.DAS.Concepts`
```csharp
public enum Directions
{
Output = 0x00,
Peripheral = 0x01,
Input = 0x02,
InputPulledUp = 0x03,
InputPulledDown = 0x04
}
public interface IGpioEnabled
{
void SetGpio(uint Port, uint Pin, Directions Direction, bool State);
bool GetGpio(uint Port, uint Pin);
}
```
Represents GPIO functionality:
- `SetGpio(uint Port, uint Pin, Directions Direction, bool State)` — configures a GPIO pin with the specified direction and state
- `GetGpio(uint Port, uint Pin)` — retrieves the state of the specified GPIO pin
The `Directions` enum is defined in `DTS.Common.Common.DAS.Concepts.GPIOPin` namespace.
---
## 3. Invariants
1. **Interface Composition:** `IDataCollectionEnabled` requires implementation of `IArmable`, `ITriggerable`, and `IDownloadEnabled`. Any class implementing `IDataCollectionEnabled` must provide all members from these three parent interfaces.
2. **Sample Rate Validity:** `SampleRate` on `IDataCollectionEnabled` should presumably be one of the values in `AvailableSampleRates`, though this constraint is not explicitly enforced in the interface.
3. **Sample Range Ordering:** `GetEventData(TsrEvent Event, ulong FirstSample, ulong LastSample)` implies `FirstSample <= LastSample`, but this is not documented.
4. **Realtime State Machine:** `IRealtimeable` implementations should require `StartRealtime()` to be called before `GetRealtimeSamples()` returns valid data, and `StopRealtime()` to halt sample accumulation.
5. **GPIO Pin Identification:** GPIO pins are identified by `(Port, Pin)` tuple; valid ranges for these parameters are not specified in the interface.
---
## 4. Dependencies
### External Types Referenced (Not Defined in Source)
| Type | Used In | Notes |
|------|---------|-------|
| `ArmStatus` | `IArmable` | Enum or class representing arm state |
| `AvailableArmModes` | `IArmable` | Enum or class representing arm mode options |
| `TsrEvent` | `IDownloadEnabled` | Class representing a downloadable event |
### Namespace Dependencies
- `DTS.Common.Common.DAS.Concepts.GPIOPin` — provides `Directions` enum used by `IGpioEnabled`
- `System` — referenced in `IRealtimeable` and `IDownloadEnabled`
### Interface Inheritance Hierarchy
```
ITriggerable
IArmable
IDownloadEnabled
└── IDataCollectionEnabled : IArmable, ITriggerable, IDownloadEnabled
```
---
## 5. Gotchas
1. **Undefined Types:** The types `ArmStatus`, `AvailableArmModes`, and `TsrEvent` are referenced in interfaces but not defined in the provided source files. Their definitions must exist elsewhere in the codebase.
2. **Namespace Inconsistency:** The `Directions` enum is defined in `DTS.Common.Common.DAS.Concepts.GPIOPin` (note the double "Common"), while the interface using it is in `DTS.Common.DAS.Concepts`. This appears to be a naming quirk.
3. **TODO Comments in `IGpioEnabled`:** The source contains a TODO comment: *"Well have to bring these in as soon as we figure out where to get that enum from."* suggesting the GPIO interface may have been incomplete at the time of writing.
4. **Commented-Out Members in `IDownloadEnabled`:** Several properties are commented out with a TODO questioning their universal applicability:
- `MaximumStoredEventSizeSeconds`
- `DownloadIncrementSamples`
- `ChannelDescription`
- `TimeOffsetMilliseconds`
5. **Historical Context in `IArmable.cs`:** The file contains extensive email discussion comments regarding TSR model variants (NASCAR, TSRPRO, BlastTestTSR, TSRBasic, HEADSII, NGI) and their channel configurations. This suggests the interfaces were designed to accommodate multiple hardware variants with differing capabilities (e.g., mixed sample rates, varying channel counts and bit depths).
6. **RealtimeSample Fields Are Public:** The `RealtimeSample` class exposes `DataEU` and `SampleNumber` as public fields rather than properties, which is inconsistent with typical C# property conventions used elsewhere in these interfaces.
7. **Multi-Rate Data Handling:** Historical comments indicate that some systems (e.g., BlastTestTSR) have channels at different sample rates (40 ksps vs 1 ksps). The current interfaces do not explicitly address how multi-rate scenarios are handled; comments suggest interpolation may occur at a lower level.

View File

@@ -0,0 +1,78 @@
---
source_files:
- Common/DTS.Common.DAS.Concepts/Interfaces/DAS/Channel/ITimestampAware.cs
- Common/DTS.Common.DAS.Concepts/Interfaces/DAS/Channel/ILinearized.cs
- Common/DTS.Common.DAS.Concepts/Interfaces/DAS/Channel/IIsoCodeAware.cs
- Common/DTS.Common.DAS.Concepts/Interfaces/DAS/Channel/ISerialNumberAware.cs
- Common/DTS.Common.DAS.Concepts/Interfaces/DAS/Channel/IInversionAware.cs
- Common/DTS.Common.DAS.Concepts/Interfaces/DAS/Channel/IEngineeringUnitAware.cs
- Common/DTS.Common.DAS.Concepts/Interfaces/DAS/Channel/ICalSignalAware.cs
- Common/DTS.Common.DAS.Concepts/Interfaces/DAS/Channel/IVoltageInsertAware.cs
- Common/DTS.Common.DAS.Concepts/Interfaces/DAS/Channel/IShuntAware.cs
- Common/DTS.Common.DAS.Concepts/Interfaces/DAS/Channel/ILevelTriggerable.cs
- Common/DTS.Common.DAS.Concepts/Interfaces/DAS/Channel/IDecimatable.cs
generated_at: "2026-04-16T02:05:30.336536+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "b4d2ceb184c9ded4"
---
# Documentation: DAS Channel Concept Interfaces
## 1. Purpose
This module defines a set of lightweight, composable interfaces that express *concepts*—behavioral or metadata capabilities—applicable to Data Acquisition System (DAS) channels. Each interface encapsulates a single concern (e.g., timestamping, linearization, shunt calibration awareness) to enable flexible, duck-typed composition of channel implementations without requiring deep inheritance hierarchies. These interfaces are used throughout the DAS framework to conditionally apply logic (e.g., calibration validation, decimation, inversion) based on what capabilities an object advertises at runtime.
## 2. Public Interface
All interfaces are *read-write* property containers; none define methods beyond indexers where noted.
| Interface | Property / Indexer | Type | Description |
|-----------|---------------------|------|-------------|
| `ITimestampAware` | `TimestampPartType` | `TimestampPartTypes` | Indicates which part(s) of a timestamp (e.g., sample time, acquisition time) are relevant for this channel. |
| `ILinearized` | `LinearizationFormula` | `DTS.Common.Classes.Sensors.LinearizationFormula` | Specifies the formula (e.g., polynomial, table-based) used to convert raw ADC values to engineering units. |
| `IIsoCodeAware` | `IsoCode` | `string` | Stores the ISO standard code (e.g., "ISO 6876") associated with the channel or sensor. |
| `ISerialNumberAware` | `SerialNumber` | `string` | Stores the hardware serial number of the sensor or channel. |
| `IInversionAware` | `IsInverted` | `bool` | Indicates whether the channels output should be inverted (e.g., for negative-slope sensors). |
| `IEngineeringUnitAware` | `EngineeringUnits` | `string` | Human-readable description of the engineering unit (e.g., "psi", "°C"). |
| `ICalSignalAware` | `MeasuredCalSignalMv` | `double` | Measured shunt-deflection voltage (in mV) during calibration verification. |
| | `TargetCalSignalMv` | `double` | Expected (target) shunt-deflection voltage (in mV) for calibration verification. |
| `IVoltageInsertionAware` | `ExpectedGain` | `double` | Expected gain (ratio of output change to input change) during voltage insertion/shunt check. |
| | `MeasuredGain` | `double` | Measured gain (ratio of output change to input change) during voltage insertion/shunt check. |
| `IShuntAware` | `MeasuredShuntDeflectionMv` | `double` | Measured shunt-deflection voltage (in mV) during shunt calibration. |
| | `TargetShuntDeflectionMv` | `double` | Target (nominal) shunt-deflection voltage (in mV) for shunt calibration. |
| `ILevelTriggerable` | `SampleAverageADC` | `double?` | Cached ADC sample average used for level-triggering; `null` if not cached. |
| | `TriggerBelowThresholdEu` | `double?` | Lower bound threshold (in engineering units); `null` disables below-threshold triggering. |
| | `TriggerAboveThresholdEu` | `double?` | Upper bound threshold (in engineering units); `null` disables above-threshold triggering. |
| | `LevelTriggerType` | `LevelTriggerTypes` | Specifies the trigger mode (e.g., rising, falling, window). |
| `IDecimatable<T>` | `PointsPerPoint` | `uint` | Number of raw data points compressed into one decimated point. |
| | `DecimationType` | `DecimationMethod` | Algorithm used for decimation (e.g., mean, min/max, median). |
| | `ToDecimatedArray()` | `T[]` | Returns a new array of decimated data using current settings. |
| | `this[long i]` | `T` | Indexer returning the *i*-th decimated value (post-decimation indexing). |
> **Note**: `IDecimatable<T>` is generic. The type parameter `T` represents the data type handled by the channel (e.g., `double`, `float`, or custom sample structs).
## 3. Invariants
- **Property semantics**: All properties are *read-write* (get/set) unless explicitly marked nullable (`?`)—in which case `null` is a valid state indicating absence or deactivation (e.g., `TriggerBelowThresholdEu = null` disables that trigger).
- **Threshold semantics**: For `ILevelTriggerable`, thresholds in engineering units (`TriggerBelowThresholdEu`, `TriggerAboveThresholdEu`) must be `null` to disable their respective triggers; non-null values are assumed valid and active.
- **Decimation indexing**: Implementations of `IDecimatable<T>` must ensure that `this[i]` returns the *i*-th element of the *decimated* sequence, not the raw data. The indexer is read-only and must reflect the current `PointsPerPoint` and `DecimationType`.
- **No implicit defaults**: Interfaces do not define default values; consumers must handle `null`, `0`, or `false` explicitly where appropriate.
## 4. Dependencies
- **Internal dependencies**:
- `DTS.Common.DAS.Concepts` namespace (inferred from `using` and namespace).
- `System` (only `ILevelTriggerable` imports `System`).
- Types `TimestampPartTypes`, `LevelTriggerTypes`, `DecimationMethod`, and `LinearizationFormula` are referenced but not defined here—likely defined in `DTS.Common.Classes.Sensors` or adjacent namespaces.
- **Consumers**: These interfaces are intended to be *implemented* by channel types (e.g., `Channel`, `SensorChannel`) elsewhere in the DAS framework. They are used for runtime type checking (e.g., `if (channel is IShuntAware) { ... }`) and dependency injection or visitor-style logic.
## 5. Gotchas
- **Naming inconsistency**: `IVoltageInsertAware` (file name) vs. `IVoltageInsertionAware` (interface name in source)—likely a typo in the file name (`IVoltageInsertionAware.cs` is correct per interface declaration).
- **Ambiguous `ILevelTriggerable` comment**: The comment about "14042 Flash Clear turns of excitation for s6" is highly specific and may be legacy documentation; its relevance to current implementations is unclear without context.
- **Missing `using` directives**: None of the interfaces import external namespaces beyond `System` in `ILevelTriggerable`, so all referenced types (`TimestampPartTypes`, `DecimationMethod`, etc.) must be in the same namespace or globally accessible—no explicit `using` is declared.
- **No validation semantics**: Interfaces impose no validation (e.g., `MeasuredShuntDeflectionMv` could be negative or NaN). Consumers must enforce domain constraints.
- **`IDecimatable<T>` indexing**: The indexer `this[long i]` is read-only and *must* return decimated values. Implementers must not conflate raw vs. decimated indexing—this is a common source of off-by-one or scale errors.
None identified beyond those noted above.

View File

@@ -0,0 +1,42 @@
---
source_files:
- Common/DTS.Common.DAS.Concepts/Properties/AssemblyInfo.cs
generated_at: "2026-04-16T13:24:25.527422+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "b609c89cbf8012d6"
---
# Documentation: AssemblyInfo.cs (DTS.DAS.Concepts)
## 1. Purpose
This file provides assembly-level metadata and configuration for the `DTS.DAS.Concepts` library. It defines the assembly's identity, version information, copyright details, and COM visibility settings. It acts as the manifest header for the compiled component, ensuring the library is correctly identified by the .NET runtime and host applications.
## 2. Public Interface
This file does not contain public classes, methods, or functions. It applies assembly-level attributes that affect the compiled DLL.
**Attributes Defined:**
* **`AssemblyTitle`**: Set to `"DTS.DAS.Concepts"`. Provides a friendly name for the assembly.
* **`AssemblyDescription`**: Set to an empty string.
* **`AssemblyCompany`**: Set to `"DTS"`.
* **`AssemblyProduct`**: Set to `"DTS.DAS.Concepts"`.
* **`AssemblyCopyright`**: Set to `"Copyright © DTS 2008"`.
* **`AssemblyVersion`**: Set to `"1.06.0081"`. Defines the version used by the common language runtime.
* **`AssemblyFileVersion`**: Set to `"1.06.0081"`. Defines the version displayed in the file properties.
* **`ComVisible`**: Set to `false`. Makes types in this assembly invisible to COM components.
* **`Guid`**: Set to `"9b6f7402-27d3-4cc9-9ff3-3cfe16e0b429"`. Unique identifier for the assembly if exposed to COM.
## 3. Invariants
* **COM Visibility:** All types within this assembly are not visible to COM components by default (`ComVisible(false)`). This must be explicitly overridden on specific types if COM interop is required.
* **Version Synchronization:** The `AssemblyVersion` and `AssemblyFileVersion` are maintained as identical strings (`"1.06.0081"`).
## 4. Dependencies
* **Internal Dependencies:**
* `System.Reflection`: Required for the assembly metadata attributes.
* `System.Runtime.InteropServices`: Required for the `ComVisible` and `Guid` attributes.
* **External Dependencies:** None identified from this file alone. The assembly described (`DTS.DAS.Concepts`) is likely a domain-level library, but its specific code dependencies are not visible here.
## 5. Gotchas
* **Naming Discrepancy:** The source file path includes `DTS.Common.DAS.Concepts`, but the `AssemblyTitle` and `AssemblyProduct` attributes define the name as `"DTS.DAS.Concepts"` (omitting "Common"). This may cause confusion when referencing the DLL versus the project folder.
* **Legacy Structure:** The use of an explicit `AssemblyInfo.cs` for versioning suggests an older .NET Framework project structure (pre-SDK style). Modern projects often auto-generate this information, so manual updates here might be ignored if the project SDK is configured to override them, or conversely, this file might be the source of truth requiring manual updates during releases.
* **Hardcoded Version:** The version `1.06.0081` is hardcoded. Developers must remember to update this string manually for new releases; it does not appear to use automatic versioning (e.g., wildcard `1.0.*`).

View File

@@ -0,0 +1,177 @@
---
source_files:
- Common/DTS.Common.DAS.Concepts/Test/Test.Module.cs
- Common/DTS.Common.DAS.Concepts/Test/Test.Module.Channel.cs
- Common/DTS.Common.DAS.Concepts/Test/Test.Module.Channel.Sensor.cs
- Common/DTS.Common.DAS.Concepts/Test/Test.Module.Channel.Sensor.Bridge.cs
- Common/DTS.Common.DAS.Concepts/Test/Test.Module.Channel.Sensor.SensorUnits.cs
- Common/DTS.Common.DAS.Concepts/Test/Test.Module.Channel.Sensor.ZeroMethod.cs
- Common/DTS.Common.DAS.Concepts/Test/Test.Module.RecordingMode.cs
- Common/DTS.Common.DAS.Concepts/Test/Test.Module.Channel.Sensor.ExcitationVoltage.cs
generated_at: "2026-04-16T13:23:48.867702+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "f6582d95b5debe26"
---
# Documentation: DTS.DAS.Concepts.Test Module
## 1. Purpose
This module provides a hierarchical container structure for Data Acquisition System (DAS) concepts related to test configuration. It defines enumerations and utility classes for sensor configuration (bridge types, coupling modes, excitation voltages, sensitivity units, zero methods) and module recording modes. The structure follows a containment hierarchy of `Test``Module``Channel``Sensor`, where each level serves as a static container for related concepts rather than an instantiable object.
---
## 2. Public Interface
### Container Classes (Non-instantiable)
| Class | Location | Description |
|-------|----------|-------------|
| `Test` | namespace root | Partial class; outer container. See `Test.cs` (not provided). |
| `Test.Module` | nested in `Test` | Sealed partial class; container for module concepts. Private constructor. |
| `Test.Module.Channel` | nested in `Module` | Sealed partial class; container for channel concepts. Private constructor. |
| `Test.Module.Channel.Sensor` | nested in `Channel` | Sealed partial class; container for sensor concepts. Private constructor. |
### Enumerations
#### `Test.Module.Channel.Sensor.CouplingModes`
IEPE coupling modes.
- `AC` — Description: "AC"
- `DC` — Description: "AC/DC"
#### `Test.Module.Channel.Sensor.BridgeType`
Bridge/sensor types using bit-flag values.
- `IEPE` = `1 << 0` — Description: "IEPE"
- `QuarterBridge` = `1 << 1` — Description: "Quarter"
- `HalfBridge` = `1 << 2` — Description: "Bridge-Half"
- `FullBridge` = `1 << 3` — Description: "Bridge-Full"
- `DigitalInput` = `1 << 4` — Description: "DigitalInput"
- `SQUIB` = `1 << 5` — Description: "SQUIB"
- `TOMDigital` = `1 << 6` — Description: "TOMDigital"
#### `Test.Module.Channel.Sensor.SensUnits`
Sensitivity unit types.
- `NONE` = 0 — Description: "NONE" (Polynomial Sensor)
- `mV` = 1 — Description: "mV"
- `mVperV` = 2 — Description: "mV/V"
- `mVperVperEU` = 3 — Description: "mV/V/EU"
- `mVperEU` = 4 — Description: "mV/EU"
#### `Test.Module.Channel.Sensor.ZeroMethodType`
Zero calculation methods (explicit values for legacy compatibility).
- `AverageOverTime` = 0 — Description: "Average Over Time"
- `UsePreEventDiagnosticsZero` = 1 — Description: "Use Diagnostics Zero"
- `None` = 2 — Description: "Absolute Zero"
#### `Test.Module.Channel.Sensor.OriginalZeroMethodType`
Original version of zero method types (implicit values).
- `AverageOverTime` — Description: "Average Over Time"
- `UsePreCalZero` — Description: "Use Diagnostics Zero"
- `None` — Description: "Absolute Zero"
#### `Test.Module.RecordingMode`
Recording mode options.
- `InvalidArmMode` = 0 — Description: "Invalid arm mode"
- `CircularBuffer` = 1 — Description: "Circular buffer"
- `RecorderMode` = 2 — Description: "Recorder mode"
- `AutoCircularBufferMode` = 4 — Description: "Circular buffer Multiple-Events"
- `AutoRecorderMode` = 5 — Description: "Recorder mode Multiple-Events"
- `ImmediateMode` = 0x06 — Description: "Immediate mode"
- `HighPowerRecorderMode` = 0x07 — Description: "High Power mode"
- `LowPowerRecorderMode` = 0x08 — Description: "Low Power mode"
- `ContinuousRecorderMode` = 0x09 — Description: "Continuous mode"
- `HybridRecorderMode` = 0x0A — Description: "Hybrid mode"
- `MultiHybridRecorderMode` = 0x0B — Description: "Hybrid mode Multiple-Events"
#### `Test.Module.Channel.Sensor.ExcitationVoltageOption`
Excitation voltage options with associated magnitude attributes.
- `Undefined` = 1 — `[VoltageMagnitude(0.0)]` — Description: "Undefined"
- `Volt2` = 2 — `[VoltageMagnitude(2.0)]` — Description: "2.0"
- `Volt2_5` = 4 — `[VoltageMagnitude(2.5)]` — Description: "2.5"
- `Volt3` = 8 — `[VoltageMagnitude(3.0)]` — Description: "3.0"
- `Volt5` = 16 — `[VoltageMagnitude(5.0)]` — Description: "5.0"
- `Volt10` = 32 — `[VoltageMagnitude(10.0)]` — Description: "10.0"
- `Volt1` = 64 — `[VoltageMagnitude(1.0)]` — Description: "1.0"
### Public Methods
#### `Test.Module.GetRecordingModeFromString`
```csharp
public static RecordingMode GetRecordingModeFromString(string recordingMode)
```
Converts a string representation of a recording mode enumeration into its corresponding `RecordingMode` value. Throws `Exception` if parsing fails or input is invalid.
#### `Test.Module.Channel.Sensor.GetExcitationVoltageMagnitudeFromEnum`
```csharp
public static double GetExcitationVoltageMagnitudeFromEnum(ExcitationVoltageOption target)
```
Extracts the numeric voltage magnitude from an `ExcitationVoltageOption` using the `VoltageMagnitudeAttribute`. Throws `Exception` on failure.
#### `Test.Module.Channel.Sensor.GetExcitationVoltageEnumFromMagnitude`
```csharp
public static ExcitationVoltageOption GetExcitationVoltageEnumFromMagnitude(double magnitude)
```
Converts a voltage magnitude to the corresponding `ExcitationVoltageOption`. Throws `NotSupportedException` if no matching enum exists.
### Nested Classes
#### `Test.Module.Channel.Sensor.VoltageMagnitudeAttribute`
```csharp
[AttributeUsage(AttributeTargets.Field)]
public class VoltageMagnitudeAttribute : System.Attribute
```
Custom attribute for attaching a `double` magnitude value to enum fields.
- Constructor: `VoltageMagnitudeAttribute(double value)`
- Property: `Value` (readonly `double`)
#### `Test.Module.Channel.Sensor.VoltageMagnitudeAttributeCoder`
```csharp
public class VoltageMagnitudeAttributeCoder : AttributeCoder<ExcitationVoltageOption, VoltageMagnitudeAttribute, double>
```
Utility class for encoding/decoding voltage magnitude values to/from `ExcitationVoltageOption` enum values. Inherits from `AttributeCoder<TEnum, TAttribute, TValue>` (defined in `DTS.Utilities`).
---
## 3. Invariants
- **Non-instantiation**: `Module`, `Channel`, and `Sensor` classes have private constructors and are not intended for instantiation. They serve as static containers only.
- **Enum value stability**: `ZeroMethodType` enum values are explicitly defined (0, 1, 2) to maintain legacy compatibility with GM ISF imports. The order/values must not be changed.
- **Bit-flag pattern**: `BridgeType` enum uses bit-shifted values (`1 << n`), suggesting these may be used as flags for bitwise operations.
- **Non-contiguous enum values**: `ExcitationVoltageOption` uses non-contiguous values (1, 2, 4, 8, 16, 32, 64) that do not follow a simple bit-flag pattern.
- `RecordingMode` uses a mix of decimal and hexadecimal explicit values.
---
## 4. Dependencies
### Imports Used by This Module
- `System` — Core .NET types, `Exception`, `NotSupportedException`, `AttributeUsage`
- `System.ComponentModel``DescriptionAttribute` for enum display names
- `DTS.Utilities``AttributeCoder<TEnum, TAttribute, TValue>` base class
### External References
- `Test.cs` — Referenced in comments but not provided; likely contains the root `Test` partial class definition.
### Dependents
- Cannot be determined from source alone. Other modules likely consume these enums and utility methods for test configuration and sensor setup.
---
## 5. Gotchas
1. **Legacy enum compatibility**: The comment in `ZeroMethodType` explicitly warns that "Lots of legacy compatibility (e.g. importing GM ISF) depends on the order/value of this enum." Modifying these values will break backward compatibility.
2. **Duplicate zero method enums**: Two enums exist for zero methods (`ZeroMethodType` and `OriginalZeroMethodType`) with slightly different member names (`UsePreEventDiagnosticsZero` vs `UsePreCalZero`). The relationship between them and which should be used for new code is unclear from source alone.
3. **Incomplete documentation**: Several `RecordingMode` enum members have "???" in their XML documentation comments, indicating incomplete or missing descriptions:
- `ImmediateMode`
- `HighPowerRecorderMode`
- `LowPowerRecorderMode`
- `ContinuousRecorderMode`
- `HybridRecorderMode`
- `MultiHybridRecorderMode`
4. **Non-standard enum values**: `ExcitationVoltageOption` enum values (1, 2, 4, 8, 16, 32, 64) are powers of 2 but `Undefined` starts at 1 rather than 0, and the values don't align with typical bit-flag usage patterns.
5. **File name mismatch**: The file `Test.Module.Channel.Sensor.SensorUnits.cs` has a header comment referencing "Test.Module.Channel.Sensor.ExcitationVoltage.cs" — appears to be a copy-paste error.

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.