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,110 @@
---
source_files:
- Common/DTS.Common.SerializationPlus/Control/ReviewableAttribute.cs
- Common/DTS.Common.SerializationPlus/Control/IntervalSec.cs
generated_at: "2026-04-16T03:30:45.406675+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "1a23a7f0b15c8ac6"
---
# Documentation: `DTS.Slice.Control` Namespace `ReviewableAttribute` and `IntervalSec`
---
## 1. Purpose
This module provides foundational types for representing *reviewable* attributes and time intervals within the DTS Slice Control subsystem. `ReviewableAttribute` is an abstract base class for attributes whose values are dynamically computed (e.g., for display in a UI review tab), while `IntervalSec` models a time interval with `Begin` and `End` times in seconds and supports conversion to/from a corresponding serialization type. Together, they support structured, dynamic data representation and time-based filtering or annotation in control/analysis workflows.
---
## 2. Public Interface
### `ReviewableAttribute` (abstract class)
- **`ReviewableAttribute(string name, DetermineValueString calculateValue)`**
Constructor. Initializes the attribute with a display `name` and a delegate `calculateValue` used to compute the `Value` on demand. Throws `ReviewableAttribute.Exception` on failure.
- **`public string Name { get; }`**
Read-only property returning the attributes display name (e.g., `"Temperature"`).
- **`public string Value { get; }`**
Read-only property that invokes the `CalculateValue` delegate to compute the current value. On delegate invocation failure, logs the exception and returns `"N/A"` (does *not* throw).
- **`public delegate string DetermineValueString();`**
Delegate type used for the `CalculateValue` property—represents a parameterless method returning a `string`.
- **`private DetermineValueString CalculateValue { get; set; }`**
Private property storing the delegate used to compute `Value`. Throws `ApplicationException` if accessed before initialization.
> **Note**: `ReviewableAttribute` inherits from `Exceptional` (from `DTS.Utilities`), implying exception-handling infrastructure is integrated (e.g., custom exception types like `ReviewableAttribute.Exception`).
---
### `IntervalSec` (concrete class)
- **`IntervalSec()`**
Parameterless constructor. Leaves `Begin` and `End` uninitialized (default to `0` due to `Property<double>` initialization).
- **`IntervalSec(double begin, double end)`**
Constructor initializing `Begin` and `End` to specified values. Throws generic `Exception` on failure.
- **`public double Begin { get; set; }`**
Read/write property for the intervals start time in seconds.
- **`public double End { get; set; }`**
Read/write property for the intervals end time in seconds.
- **`public static implicit operator Serialization.Test.IntervalSec(IntervalSec thisInterval)`**
Implicit conversion to `DTS.Serialization.Test.IntervalSec`, using `Begin` and `End`.
- **`public static implicit operator IntervalSec(Serialization.Test.IntervalSec thatInterval)`**
Implicit conversion from `DTS.Serialization.Test.IntervalSec`, constructing a new instance.
- **`public override bool Equals(object obj)`**
Memberwise equality test against another `IntervalSec`. Returns `false` if `obj` is `null` or not an `IntervalSec`.
- **`public override int GetHashCode()`**
Returns base hash code (no custom hashing logic—relies on `Exceptional` base behavior).
> **Note**: `IntervalSec` inherits from `Exceptional` and uses `Property<double>` (from `DTS.Utilities.DotNetProgrammingConstructs`) for its fields.
---
## 3. Invariants
- **`ReviewableAttribute`**
- `Name` is immutable after construction (only set in constructor).
- `CalculateValue` *must* be set during construction; accessing it before initialization throws `ApplicationException`.
- `Value` may return `"N/A"` on delegate failure but never throws (exceptions are logged and suppressed).
- `Name` and `CalculateValue` are required for valid initialization; partial initialization is disallowed.
- **`IntervalSec`**
- `Begin` and `End` default to `0` if not explicitly set (via `Property<double>` default value).
- No invariant enforces `Begin ≤ End`; callers must ensure logical consistency.
- Equality and hash code rely solely on `Begin` and `End` values.
---
## 4. Dependencies
### Dependencies *of* this module:
- `DTS.Utilities` (provides `Exceptional` base class and logging via `APILogger`)
- `DTS.Utilities.DotNetProgrammingConstructs` (provides `Property<T>` for property wrappers)
- `DTS.Serialization.Test.IntervalSec` (for implicit conversions in `IntervalSec`)
### Dependencies *on* this module:
- **`ReviewableAttribute`** is likely extended by concrete subclasses (not shown) to implement domain-specific attributes (e.g., for test result review).
- **`IntervalSec`** is used to model time ranges, likely in filtering or data selection logic (e.g., for time-windowed analysis). Its conversions suggest tight coupling with serialization layers.
---
## 5. Gotchas
- **`ReviewableAttribute.Value` suppresses exceptions silently**: If `CalculateValue` throws, the error is logged via `APILogger` but `Value` returns `"N/A"`. This may mask failures if callers do not check logs.
- **`CalculateValue` is not thread-safe**: No synchronization is evident; concurrent access to `Value` may yield inconsistent results if the delegate is stateful.
- **`IntervalSec` uses `double` for time**: Potential for floating-point precision issues (e.g., comparison errors); no tolerance-based equality is provided.
- **`Equals` does not handle `null` gracefully in the `that` cast**: While `obj` is checked for `null`, `that` is assigned via `as`, so `that` will be `null` if `obj` is not `IntervalSec`. The code then calls `that.Begin`, which will throw `NullReferenceException`.
- **Fix needed**: Add `&& that != null` before accessing `that.Begin`.
- **`GetHashCode()` is not overridden meaningfully**: Returns `base.GetHashCode()`, which may not align with `Equals` semantics (violating .NET best practices for value types).
- **`IntervalSec` parameterless constructor leaves properties uninitialized in a logical sense** (though technically initialized to `0`), which may cause unexpected behavior if used without explicit assignment.

View File

@@ -0,0 +1,110 @@
---
source_files:
- Common/DTS.Common.SerializationPlus/Control/Event/DasModuleAccessor.cs
- Common/DTS.Common.SerializationPlus/Control/Event/DasChannelAccessor.cs
- Common/DTS.Common.SerializationPlus/Control/Event/ChannelAccessor.cs
- Common/DTS.Common.SerializationPlus/Control/Event/ModuleChannelAccessor.cs
- Common/DTS.Common.SerializationPlus/Control/Event/DasModuleChannelAccessor.cs
- Common/DTS.Common.SerializationPlus/Control/Event/TestInformation.cs
generated_at: "2026-04-16T03:30:58.722127+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "cdfba6906b172be2"
---
# Event
## Documentation: DTS.Slice.Control.Event Accessor Types
---
### 1. **Purpose**
This module defines a set of specialized accessor types used to navigate hierarchical channel and module data associated with a DAS (Data Acquisition System) event. These types (`DasModuleAccessor`, `DasChannelAccessor`, `DasModuleChannelAccessor`, `ModuleChannelAccessor`, `ChannelAccessor`) are nested within the `Event` class and provide structured, type-safe access to event data indexed by DAS identifiers (e.g., DAS ID, module number, channel number). They are intended to be instantiated and populated during `Event` construction, enabling consumers to retrieve module and channel information using multi-level keys. The module also includes `TestInformation`, an internal helper class to encapsulate test metadata (ID and description) associated with the event.
---
### 2. **Public Interface**
All classes are nested within `DTS.Slice.Control.Event` and are declared `public`.
| Type | Inheritance | Constructor(s) | Key Type | Value Type | Description |
|------|-------------|----------------|----------|------------|-------------|
| `DasModuleAccessor` | `ExceptionalDictionary<Common.DAS.Concepts.DAS.Id, List<Module>>` | `DasModuleAccessor()` | `Common.DAS.Concepts.DAS.Id` | `List<Module>` | Maps a DAS ID to a list of modules associated with that DAS in the event. |
| `DasChannelAccessor` | `ExceptionalDictionary<Common.DAS.Concepts.DAS.Id, List<Module.Channel>>` | `DasChannelAccessor()` | `Common.DAS.Concepts.DAS.Id` | `List<Module.Channel>` | Maps a DAS ID to a list of channels (across all modules) associated with that DAS in the event. |
| `ChannelAccessor` | `ExceptionalDictionary<int, Module.Channel>` | `ChannelAccessor()` | `int` | `Module.Channel` | Maps a *module-local* channel number (as `int`) to a `Module.Channel` instance. Used internally by `ModuleChannelAccessor`. |
| `ModuleChannelAccessor` | `ExceptionalDictionary<int, ChannelAccessor>` | `ModuleChannelAccessor()` | `int` | `ChannelAccessor` | Maps a *module ID* (as `int`) to a `ChannelAccessor`, which in turn maps channel numbers to channels. Used internally by `DasModuleChannelAccessor`. |
| `DasModuleChannelAccessor` | `ExceptionalDictionary<Common.DAS.Concepts.DAS.Id, ModuleChannelAccessor>` | `DasModuleChannelAccessor()` | `Common.DAS.Concepts.DAS.Id` | `ModuleChannelAccessor` | Maps a DAS ID to a `ModuleChannelAccessor`, enabling lookup of channels by DAS ID → module ID → channel number. |
| `TestInformation` | `Exceptional` | `TestInformation()`<br>`TestInformation(string id, string description)` | — | — | Internal class holding test ID and description. Not intended for direct external use. |
> **Note**: All accessor types inherit from `ExceptionalDictionary<TKey, TValue>` (from `DTS.Common.Utilities`), implying they support exception-based error handling for missing keys (e.g., `KeyNotFoundException` or custom behavior defined in `ExceptionalDictionary`).
---
### 3. **Invariants**
- **Hierarchical Key Structure**:
- `DasModuleChannelAccessor``ModuleChannelAccessor``ChannelAccessor``Module.Channel`
provides a 3-level lookup: `DAS.Id``int (module ID)``int (channel number)``Module.Channel`.
- `DasModuleAccessor` and `DasChannelAccessor` provide 2-level lookup: `DAS.Id``List<Module>` or `List<Module.Channel>`.
- **Null Handling**:
- All `Property<T>` fields in `TestInformation` are initialized with `null` as the default value and `false` for `allowNull` (per constructor args), but the `Property<T>` wrapper likely enforces nullability semantics (exact behavior depends on `Property<T>` implementation, not visible here).
- **No Validation Logic Visible**:
- No validation rules (e.g., range checks on channel/module IDs) are present in the source. Assumption: validation (if any) is handled upstream or by `ExceptionalDictionary`.
- **Partial Class**:
- All types are declared `partial class Event`, meaning these accessors are part of a larger `Event` class defined elsewhere (likely in `DTS.Slice.Control.Event.cs`, referenced in comments).
---
### 4. **Dependencies**
#### Internal Dependencies (from source):
- `DTS.Common.Utilities.ExceptionalDictionary<TKey, TValue>`
Base class for all accessor types.
- `DTS.Common.Utilities.Property<T>`
Used in `TestInformation` for property encapsulation.
- `DTS.Common.DASResource`
Namespace imported by `TestInformation` (likely contains DAS resource types).
- `DTS.Common.Utilities.DotNetProgrammingConstructs`
Namespace imported by `TestInformation` (likely contains `Property<T>` or similar constructs).
- `DTS.Slice.Control.Event`
All types are nested inside `Event` (partial class).
- `Common.DAS.Concepts.DAS.Id`
Key type for DAS-level accessors (`DasModuleAccessor`, `DasChannelAccessor`, `DasModuleChannelAccessor`).
#### External Dependencies (inferred):
- `DTS.Slice.Control.Module` and `Module.Channel`
Referenced as value types in `DasModuleAccessor` and `DasChannelAccessor`. Must be defined elsewhere in the `DTS.Slice.Control` namespace.
- `DTS.Common.Utilities`
Core utilities library (contains `ExceptionalDictionary`, `Property<T>`, `Strings`).
#### What Depends on This Module?
- Any code that consumes `Event` objects and needs to access channel/module data by DAS identifiers (e.g., event processing, analysis, or reporting modules).
- Likely used in serialization/deserialization logic for `Event` (given `SerializationPlus` in namespace path).
---
### 5. **Gotchas**
- **Ambiguous Integer Keys**:
- `ChannelAccessor` uses `int` as key for channel number, and `ModuleChannelAccessor` uses `int` as key for module ID. These are *not* strongly typed (e.g., no `DAS.Module.Id` or `DAS.Module.Channel.Id`), despite comments (`xxx change this int to ...`) suggesting future refactoring. This risks confusion or misuse if module/channel IDs overlap or are misinterpreted.
- **No Public Setters or Initialization Logic Visible**:
- All accessor types have only parameterless constructors. It is unclear how they are populated (likely via internal logic in the parent `Event` class). Consumers must assume they are constructed and filled by the `Event` constructor.
- **`TestInformation` is `private sealed class`**:
- Not exposed outside `Event`, so external code cannot instantiate or inspect it directly. Only accessible via `Event`s public surface (not shown here).
- **Missing Context on `ExceptionalDictionary` Behavior**:
- Since all types inherit from `ExceptionalDictionary`, behavior for missing keys (e.g., exceptions, defaults) depends on that base class. Without its source, exact runtime behavior is unknown.
- **No Documentation for `Module` or `Module.Channel` Types**:
- The types `Module` and `Module.Channel` are used as value types but not defined here. Their structure and relationship to DAS IDs is critical for correct usage but not documented in this module.
- **Historical Quirk in Comments**:
- All files include `// *** see DTS.Slice.Control.Event.cs ***`, indicating these are fragments of a larger file split for maintainability. This may complicate navigation for new developers.
None identified beyond the above.

View File

@@ -0,0 +1,140 @@
---
source_files:
- Common/DTS.Common.SerializationPlus/Control/Event/Module/ReviewableDasSerialNumberAttribute.cs
- Common/DTS.Common.SerializationPlus/Control/Event/Module/ReviewableAttribute.cs
- Common/DTS.Common.SerializationPlus/Control/Event/Module/ReviewableSampleRateAttribute.cs
generated_at: "2026-04-16T03:31:05.140610+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "b7f5fb3360deccec"
---
# Module
## Documentation: `ReviewableDasSerialNumberAttribute` and Related Classes
---
### 1. **Purpose**
This module provides concrete implementations of `ReviewableAttribute` for capturing and exposing read-only metadata about a `DTS.Slice.Control.Event.Module` instance—specifically, attributes that are relevant during event review or audit workflows. These attributes (e.g., DAS serial number, sample rate, hardware anti-aliasing filter rate, test description) are lazily evaluated via delegates and formatted for display in UI or reporting contexts. The classes exist to support structured, consistent, and type-safe access to module-level configuration and identity data during review processes.
---
### 2. **Public Interface**
All classes are `public` nested within `DTS.Slice.Control.Event.Module`.
#### `ReviewableDasSerialNumberAttribute`
- **Signature**:
```csharp
public class ReviewableDasSerialNumberAttribute : ReviewableAttribute
```
- **Constructor**:
```csharp
public ReviewableDasSerialNumberAttribute(Event.Module module)
```
- **Behavior**:
Initializes a reviewable attribute named `"DAS Serial Number"` whose value is lazily retrieved from `module.DasSerialNumber`. Uses the base classs `DetermineValueString` delegate mechanism.
#### `ReviewableSampleRateAttribute`
- **Signature**:
```csharp
public class ReviewableSampleRateAttribute : ReviewableAttribute
```
- **Constructor**:
```csharp
public ReviewableSampleRateAttribute(Event.Module module)
```
- **Behavior**:
Initializes a reviewable attribute named `"Sample Rate"`. Value is `module.SampleRateHz.ToString("N")` (numeric formatting with thousand separators, no decimal places implied by `"N"` default).
#### `ReviewableTestDescriptionAttribute`
- **Signature**:
```csharp
public class ReviewableTestDescriptionAttribute : ReviewableAttribute
```
- **Constructor**:
```csharp
public ReviewableTestDescriptionAttribute(Event.Module module)
```
- **Behavior**:
Initializes a reviewable attribute named `"Test Description"`. Value is `module.ParentEvent.Description`. *Note: This accesses the parent `Event`, not the `Module` directly.*
#### `ReviewableHardwareFrequencyAttribute`
- **Signature**:
```csharp
public class ReviewableHardwareFrequencyAttribute : ReviewableAttribute
```
- **Constructor**:
```csharp
public ReviewableHardwareFilterAttribute(Event.Module module)
```
- **Behavior**:
Initializes a reviewable attribute named `"HW AAF"` (Hardware Anti-Alias Filter). Value is `module.AaFilterRateHz.ToString("N2")` (2 decimal places).
---
### 3. **Invariants**
- **All attributes are immutable after construction**: The `name` and `DetermineValueString` delegate are set in the base constructor and never modified.
- **Value evaluation is deferred**: The delegate passed to `base(...)` is invoked only when the attributes value is requested (e.g., for display), not at construction time.
- **`ReviewableAttribute` base constructor enforces non-null `name` and `calculateValue`**: The protected constructor expects both parameters; the public constructor in subclasses always supplies them.
- **`ReviewableDasSerialNumberAttribute` and other subclasses must be instantiated with a non-null `Event.Module`**: Otherwise, accessing `module.DasSerialNumber`, `module.SampleRateHz`, etc., will throw a `NullReferenceException`.
- **`ReviewableAttribute` has two constructors, but only one is usable**:
- The single-parameter constructor (`ReviewableAttribute(Event.Module)`) is *intentionally non-functional* and throws `NotImplementedException` via a wrapper `Exception`.
- Only the two-parameter protected constructor (`ReviewableAttribute(string, DetermineValueString)`) is used in practice.
---
### 4. **Dependencies**
#### Dependencies *of* this module:
- `DTS.Slice.Control.Event.Module` — Required for `module.DasSerialNumber`, `module.SampleRateHz`, `module.AaFilterRateHz`, and `module.ParentEvent`.
- `DTS.Slice.Control.ReviewableAttribute` — Base class for `ReviewableAttribute`. (Implied by inheritance; source not provided, but referenced in `ReviewableAttribute.cs`.)
- `DTS.Utilities` — Used for formatting (e.g., `.ToString("N")`), though standard .NET formatting would suffice.
#### Dependencies *on* this module:
- Any code that needs to expose module metadata for review (e.g., UI forms, audit logging, export tools) will instantiate these classes and pass them to a review framework built around `ReviewableAttribute`.
#### Inferred relationships:
- `Event.Module` must define the following properties (not visible in source, but required):
- `string DasSerialNumber`
- `double SampleRateHz`
- `double AaFilterRateHz`
- `Event ParentEvent` (with `string Description`)
- `ReviewableAttribute` inherits from `Slice.Control.ReviewableAttribute`, which must define:
- Constructor: `ReviewableAttribute(string name, DetermineValueString calculateValue)`
- Property/method to retrieve the formatted value string (via `DetermineValueString` delegate).
---
### 5. **Gotchas**
- **Misleading XML comment for `ReviewableSampleRateAttribute` and `ReviewableHardwareFrequencyAttribute`**:
Both are documented as “A reviewable filter frequency attribute attached to a specific channel.” — but they are attached to a `Module`, not a `Channel`. (The `ReviewableDasSerialNumberAttribute` comment is similarly inaccurate.)
- **`ReviewableTestDescriptionAttribute` accesses `module.ParentEvent.Description`**:
This implies a parent-child relationship (`Module` → `Event`). If `module.ParentEvent` is `null`, this will throw `NullReferenceException`.
- **`ReviewableAttribute` constructor design is fragile**:
The single-parameter constructor exists solely to fail at runtime. This is a code smell—ideally, it would be `private` or removed entirely.
- **String formatting is hardcoded**:
`"N"` and `"N2"` are used directly in delegates. Changing formatting (e.g., locale, precision) requires source modification.
- **No null-safety in value delegates**:
None of the delegates check for null (e.g., `module.DasSerialNumber` could be `null`, but `ToString()` is called unconditionally). This may yield `"False"` or `""` depending on type, or throw if `DasSerialNumber` is a non-nullable value type.
- **Typo in `ReviewableHardwareFrequencyAttribute` constructor name in source**:
The XML comment says `channel`, but the parameter is named `module`. This is minor but inconsistent.
- **No documentation for `DetermineValueString` delegate type**:
Its signature and contract are unknown from source alone. Assumed to be `Func<string>` or similar.
- **No tests or usage examples provided**:
Behavior is inferred solely from constructor and inheritance. Actual runtime behavior (e.g., how values are consumed) is not verifiable from source.
---
*Note: All inferences assume standard .NET conventions and the structural clues in the provided source. Behavior of `DetermineValueString` and the parent `ReviewableAttribute` class cannot be fully confirmed without their source.*

View File

@@ -0,0 +1,88 @@
---
source_files:
- Common/DTS.Common.SerializationPlus/Control/Event/Module/AnalogInputChannel/ReviewableShuntDeflectionAttribute.cs
- Common/DTS.Common.SerializationPlus/Control/Event/Module/AnalogInputChannel/ReviewableFilterFrequencyAttribute.cs
- Common/DTS.Common.SerializationPlus/Control/Event/Module/AnalogInputChannel/ReviewableIsoCodeAttribute.cs
- Common/DTS.Common.SerializationPlus/Control/Event/Module/AnalogInputChannel/ReviewableDescriptionAttribute.cs
- Common/DTS.Common.SerializationPlus/Control/Event/Module/AnalogInputChannel/ReviewableSerialNumberAttribute.cs
- Common/DTS.Common.SerializationPlus/Control/Event/Module/AnalogInputChannel/ReviewableUnitsAttribute.cs
- Common/DTS.Common.SerializationPlus/Control/Event/Module/AnalogInputChannel/ReviewableMinMaxEuAttribute.cs
- Common/DTS.Common.SerializationPlus/Control/Event/Module/AnalogInputChannel/ReviewableCfcAttribute.cs
- Common/DTS.Common.SerializationPlus/Control/Event/Module/AnalogInputChannel/ReviewableTargetShuntDeflectionAttribute.cs
- Common/DTS.Common.SerializationPlus/Control/Event/Module/AnalogInputChannel/ReviewableMeasuredShuntDeflectionAttribute.cs
- Common/DTS.Common.SerializationPlus/Control/Event/Module/AnalogInputChannel/ReviewableShuntDeflectionPercentageAttribute.cs
generated_at: "2026-04-16T03:31:33.249057+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "248b93b117b62a27"
---
# `DTS.Slice.Control.Event.Module.AnalogInputChannel.ReviewableAttribute` Derivatives
## 1. Purpose
This module defines a set of concrete `ReviewableAttribute` subclasses used to expose specific channel metadata and calibration-related values for review in the DTS Slice control event system. Each attribute encapsulates a human-readable label and a delegate that dynamically computes a formatted string representation of a channel property at runtime—primarily for inclusion in audit trails, calibration reports, or diagnostic UIs. These attributes are attached to `AnalogInputChannel` instances and provide a standardized way to surface configuration, calibration, and measurement data without hardcoding display logic elsewhere in the system.
## 2. Public Interface
All classes are nested within `DTS.Slice.Control.Event.Module.AnalogInputChannel` and inherit from `Slice.Control.Event.Module.Channel.ReviewableAttribute`. Each constructor takes a single parameter of type `Event.Module.Channel` and passes a label string and a `Func<string>` (via `delegate { ... }`) to the base constructor.
| Class | Constructor Signature | Label | Behavior |
|-------|------------------------|-------|----------|
| `ReviewableShuntDeflectionAttribute` | `ReviewableShuntDeflectionAttribute(Event.Module.Channel channel)` | `"Shunt Deflection (mV)"` | Returns `MeasuredShuntDeflectionMv.ToString("F1")`, where `MeasuredShuntDeflectionMv` is accessed via `(channel as IShuntAware).MeasuredShuntDeflectionMv`. |
| `ReviewableFilterFrequencyAttribute` | `ReviewableFilterFrequencyAttribute(Event.Module.Channel channel)` | `"Filter Frequency"` | Returns `(int)(channel.CurrentFilter as SaeJ211Filter).CutoffFrequencyHz` formatted with `ToString("N")`. |
| `ReviewableIsoCodeAttribute` | `ReviewableIsoCodeAttribute(Event.Module.Channel channel)` | `"ISO Code"` | Returns `(channel as AnalogInputChannel).IsoCode.ToString()`. |
| `ReviewableDescriptionAttribute` | `ReviewableDescriptionAttribute(Event.Module.Channel channel)` | `"Description"` | Returns `channel.ChannelDescriptionString`. |
| `ReviewableSerialNumberAttribute` | `ReviewableSerialNumberAttribute(Event.Module.Channel channel)` | `"Serial Number"` | Returns `(channel as AnalogInputChannel).SerialNumber.ToString()`. |
| `ReviewableUnitsAttribute` | `ReviewableUnitsAttribute(Event.Module.Channel channel)` | `"Units"` | Returns `(channel as IEngineeringUnitAware).EngineeringUnits.ToString()`. |
| `ReviewableMinMaxEuAttribute` | `ReviewableMinMaxEuAttribute(Event.Module.Channel channel)` | `"Max/Min (EU)"` | Returns `"${DataMaxFilteredEu:F1}/${DataMinFilteredEu:F1}"`. |
| `ReviewableCfcAttribute` | `ReviewableCfcAttribute(Event.Module.Channel channel)` | `"CFC"` | Returns `"N/A"` if `channel.CurrentFilter.Type == ChannelFilter.AdHoc`; otherwise returns `new CfcValueAttributeCoder().DecodeAttributeValue((channel.CurrentFilter as SaeJ211Filter).Type).ToString()`. |
| `ReviewableTargetShuntDeflectionAttribute` | `ReviewableTargetShuntDeflectionAttribute(Event.Module.Channel channel)` | `"Target Shunt Deflection (mV)"` | Returns `TargetShuntDeflectionMv.ToString("F1")`, via `(channel as IShuntAware).TargetShuntDeflectionMv`. |
| `ReviewableTargetCalSignalAttribute` | `ReviewableTargetCalSignalAttribute(Event.Module.Channel channel)` | `"Target Calibration Signal (mV)"` | Returns `TargetCalSignalMv.ToString("F1")`, via `(channel as ICalSignalAware).TargetCalSignalMv`. |
| `ReviewableMeasuredShuntDeflectionAttribute` | `ReviewableMeasuredShuntDeflectionAttribute(Event.Module.Channel channel)` | `"Measured Shunt Deflection (mV)"` | Same as `ReviewableShuntDeflectionAttribute`. |
| `ReviewableMeasuredCalSignalAttribute` | `ReviewableMeasuredCalSignalAttribute(Event.Module.Channel channel)` | `"Measured Calibration Signal (mV)"` | Same as `ReviewableTargetCalSignalAttribute` but for measured values: `(channel as ICalSignalAware).MeasuredCalSignalMv.ToString("F1")`. |
| `ReviewableShuntDeflectionPercentageAttribute` | `ReviewableShuntDeflectionPercentageAttribute(Event.Module.Channel channel)` | `"Shunt Error (%)"` | Computes `(100.0 * (MeasuredShuntDeflectionMv - TargetShuntDeflectionMv) / TargetShuntDeflectionMv).ToString("F1")`. |
| `ReviewableCalSignalPercentageAttribute` | `ReviewableCalSignalPercentageAttribute(Event.Module.Channel channel)` | `"Calibration Signal Error (%)"` | Computes `(100.0 * (MeasuredCalSignalMv - TargetCalSignalMv) / TargetCalSignalMv).ToString("F1")`. |
> **Note**: `IShuntAware`, `ICalSignalAware`, and `IEngineeringUnitAware` are interfaces defined in `DTS.DAS.Concepts.DAS.Channel`. `SaeJ211Filter`, `CfcValueAttributeCoder`, and `ChannelFilter` are defined in `DTS.Utilities`.
## 3. Invariants
- **All attributes require the `channel` parameter to be non-null**, and to support the specific interface(s) accessed in their delegate (e.g., `IShuntAware` for shunt-related attributes). Failure to meet this requirement will cause a runtime `InvalidCastException` or `NullReferenceException`.
- **Format consistency**: All numeric outputs use `"F1"` (1 decimal place) or `"N"` (thousands separator, no decimals) formatting as shown. No validation or range checking is performed on the underlying values.
- **No side effects**: The delegates are pure functions; they do not mutate state.
- **No ordering guarantees**: The module does not define or enforce any ordering among these attributes when used collectively (e.g., in a list or collection).
- **Type assumptions**: The code assumes `channel.CurrentFilter` is always a `SaeJ211Filter` when accessing `.Type` or `.CutoffFrequencyHz`. If `CurrentFilter` is not a `SaeJ211Filter`, this will throw at runtime.
## 4. Dependencies
### Internal Dependencies (from source):
- `DTS.Slice.Control.Event.Module.Channel.ReviewableAttribute` — base class (not shown, but referenced).
- `DTS.DAS.Concepts.DAS.Channel.IShuntAware` — for `MeasuredShuntDeflectionMv`, `TargetShuntDeflectionMv`.
- `DTS.DAS.Concepts.DAS.Channel.ICalSignalAware` — for `MeasuredCalSignalMv`, `TargetCalSignalMv`.
- `DTS.DAS.Concepts.DAS.Channel.IEngineeringUnitAware` — for `EngineeringUnits`.
- `DTS.Utilities.SaeJ211Filter` — used in `ReviewableFilterFrequencyAttribute` and `ReviewableCfcAttribute`.
- `DTS.Utilities.CfcValueAttributeCoder` — used in `ReviewableCfcAttribute`.
- `DTS.Utilities.ChannelFilter` — used in `ReviewableCfcAttribute` (specifically `ChannelFilter.AdHoc` constant).
- `DTS.Slice.Control.Event.Module.AnalogInputChannel` — for `IsoCode`, `SerialNumber`, and `ChannelDescriptionString` properties.
### External Dependencies:
- `System` (core namespaces: `System`, `System.Linq`, `System.Text`, `System.Collections.Generic`).
- `DTS.Utilities` — assembly reference required.
### Inferred Consumers:
- Likely consumed by UI or reporting layers that enumerate `ReviewableAttribute` instances on channels (e.g., for serialization, audit logging, or calibration review forms).
- May be used in conjunction with `DTS.Slice.Control.Event` infrastructure (e.g., event logging, data export).
## 5. Gotchas
- **Redundant classes**: `ReviewableShuntDeflectionAttribute` and `ReviewableMeasuredShuntDeflectionAttribute` have identical implementation and labels. Same for `ReviewableTargetCalSignalAttribute` and `ReviewableMeasuredCalSignalAttribute`. This duplication may cause confusion or inconsistency if one is updated but not the other.
- **Unsafe casts**: Multiple attributes use `as` casts without null checks (e.g., `(channel as IShuntAware)`). If the channel does not implement the interface, the cast yields `null`, leading to `NullReferenceException` when accessing `.MeasuredShuntDeflectionMv`.
- **Assumed filter type**: `ReviewableFilterFrequencyAttribute` and `ReviewableCfcAttribute` assume `channel.CurrentFilter` is always a `SaeJ211Filter`. If `CurrentFilter` is another type (e.g., `AdHoc`), a runtime `InvalidCastException` occurs.
- **Division by zero risk**: `ReviewableShuntDeflectionPercentageAttribute` and `ReviewableCalSignalPercentageAttribute` divide by `TargetShuntDeflectionMv` or `TargetCalSignalMv` without checking for zero. If the target is `0.0`, this throws `DivideByZeroException`.
- **Missing null guard in `ReviewableCfcAttribute`**: The commented-out line suggests prior use of `CfcValueAttributeCoder`, but the current logic only handles `AdHoc` explicitly. If `CurrentFilter.Type` is neither `AdHoc` nor a valid `SaeJ211Filter.Type`, `CfcValueAttributeCoder.DecodeAttributeValue(...)` may throw or return unexpected results.
- **Inconsistent casing**: `ReviewableDescriptionAttribute.cs` file header incorrectly labels it as `"ReviewableCfcAttribute.cs"` — likely a copy-paste artifact.
- **No documentation of `IsoCode`, `SerialNumber`, `ChannelDescriptionString`**: These properties are used but not defined in the provided source; their existence and type must be inferred from usage.
- **No documentation of `CfcValueAttributeCoder` behavior**: The behavior of `DecodeAttributeValue(...)` (e.g., what it returns for invalid inputs) is unknown from this source.
> **Recommendation**: Add runtime null checks and guard against zero denominators in percentage attributes. Consider consolidating duplicate classes or clarifying their intended distinction.

View File

@@ -0,0 +1,130 @@
---
source_files:
- Common/DTS.Common.SerializationPlus/Control/Event/Module/Channel/ReviewableAttribute.NotApplicableException.cs
- Common/DTS.Common.SerializationPlus/Control/Event/Module/Channel/DataValues.cs
- Common/DTS.Common.SerializationPlus/Control/Event/Module/Channel/CalculatedChannel.cs
generated_at: "2026-04-16T03:31:25.911180+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "680d00c25a548384"
---
# Channel
## Documentation: `DTS.Slice.Control` Channel Subsystem — Calculated Channels and Related Types
---
### 1. Purpose
This module provides core infrastructure for modeling *calculated* channels within the DTS control/event data model. It defines abstract and concrete channel types that represent derived time-series data (e.g., integrals, derivatives, FFTs, scaled/offset signals), along with supporting infrastructure such as `DataValues` (for internal data storage, optionally using memory-mapped files) and `NotApplicableException` (for enforcing attribute-applicability constraints). The calculated channel hierarchy supports engineering unit (EU) reporting, configurable X-axis units, and integration with review workflows via extensible `ReviewableAttribute` mechanisms—though the latter is partially commented out in the current source.
---
### 2. Public Interface
#### `Event.Module.Channel.DataValues`
- **`DataValues()`**
Initializes an instance using in-memory storage (i.e., `UseMemoryMappedFile = false`).
- **`DataValues(bool useMemoryMappedFile)`**
Initializes an instance, optionally enabling memory-mapped file storage for large datasets.
- **`UseMemoryMappedFile` (property, `bool`)**
Gets/sets whether the instance uses memory-mapped files instead of in-memory lists. Defaults to `false`.
#### `Event.Module.Channel.CalculatedChannel` *(abstract)*
- **`Operation` enum**
Defines supported calculation types: `Integral`, `Derivative`, `HeadInjuryCriteria`, `FFT`, `ImportedCSV`, `Resultant`, `TSR`, `Scale`, `Offset`, `Sine`, `Cosine`.
- **`CalculationType` (property, `Operation`)**
Immutable operation performed by this channel.
- **`X`, `Y` (properties, `double[]`)**
Read-only arrays of X and Y data points.
- **`XAxis` (property, `XUnits`)**
X-axis unit type (`Hz`, `msec`, `sec`, `samples`).
- **`XUnitsString` (property, `string`)**
Human-readable unit string for the X-axis (e.g., `"Hz"`, `"ms"`).
- **`EngineeringUnits` (property, `string`)**
Gets/sets the Y-axis engineering unit label.
- **`SupportsADC`, `SupportsEU`, `SupportsmV` (override properties, `bool`)**
Indicate that this channel *does not* support raw ADC/mV values (`false`), but *does* support engineering units (`true`).
- **`ActualMaxRangeEu`, `ActualMinRangeEu`, `DataHalfRangeValueEu`, `DataMaxEu`, `DataMinEu`, `DataRangeEu` (override properties, `double`)**
Derived from the `Y` data array (e.g., min/max, range, half-range).
- **`IsConfigured` (override property, `bool`)**
Always returns `true`; setting throws `NotSupportedException`.
- **`GetUnfilteredDataEu()` (override method, `List<double>`)**
Returns a copy of the internal `_y` list (unfiltered EU data).
- **`ToString()` (override method, `string`)**
Returns `ChannelDescriptionString` if non-null/empty; otherwise `"N/A"`.
- **Constructors**
`CalculatedChannel(string name, XUnits xAxis, string yAxis, double[] xValues, double[] yValues, Operation calcType, int number, Module parentModule)`
Initializes the channel with data, units, and metadata.
#### `Event.Module.Channel.FFTCalculatedChannel`
- **`PeakFrequency` (property, `double`)**
Peak frequency value (computed during FFT processing).
- **Constructor**
`FFTCalculatedChannel(..., double peakFrequency)`
Extends `CalculatedChannel` with peak frequency.
#### `Event.Module.Channel.IntegralCalculatedChannel`, `DerivativeCalculatedChannel`, `ScaleCalculatedChannel`, `OffsetCalculatedChannel`, `ResultantCalculatedChannel`, `AdditiveVectorCalculatedChannel`, `SineCalculatedChannel`, `CosineCalculatedChannel`
- **Constructors**
All follow the same signature as `CalculatedChannel`, passing `calcType` to the base class.
#### `Event.Module.Channel.ReviewableAttribute.NotApplicableException`
- **`NotApplicableException()`**
Default constructor.
- **`NotApplicableException(string msg)`**
Constructor with message.
- **`NotApplicableException(string msg, Exception innerEx)`**
Constructor with message and inner exception.
> **Note**: Several methods in `CalculatedChannel` (e.g., `ToDtsSerializationTestModuleChannel`, `FromDtsSerializationTestModuleChannel`, `SetPropertyValuesFrom(DASChannel)`, `SetPropertyValuesFrom(IDiagnosticResult)`) throw `NotSupportedException` or `NotImplementedException`. Similarly, `ActualMaxRangeMv`, `ActualMinRangeMv`, `DataZeroLevelAdc`, `SensorCapacityEU`, `DesiredRangeEU`, and `GetUnfilteredDataMV()` are unimplemented.
---
### 3. Invariants
- **`IsConfigured` is immutable**: Setting `IsConfigured` to any value throws `NotSupportedException`.
- **`EngineeringUnits` is mutable but not validated**: No constraints on the `EngineeringUnits` string value.
- **`X`/`Y` arrays are immutable after construction**: The underlying `_x`/`_y` lists are copied into the constructor; `X`/`Y` properties return arrays (not lists), preventing external mutation.
- **`SupportsADC`/`SupportsmV` are fixed to `false`**: Calculated channels do not represent raw sensor data.
- **`ActualMinRangeEu`/`ActualMaxRangeEu` assume non-empty `Y`**: If `Y` is empty, `.Min()`/`.Max()` will throw `InvalidOperationException` (not handled in source).
- **`DataValues.UseMemoryMappedFile` is immutable after construction**: Though the property setter exists, the backing `Property<bool>` is initialized with `false` for `isReadOnly`, but the constructor does not enforce immutability post-initialization.
---
### 4. Dependencies
- **Imports/Usings**:
- `DTS.Common.Utilities` and `DTS.Common.Utilities.DotNetProgrammingConstructs` (`DataValues` uses `Property<T>`).
- `DTS.Common.Interface.DASFactory.Diagnostics` (`CalculatedChannel` references `IDiagnosticResult`).
- `DTS.Common.SerializationPlus` (`CalculatedChannel` references serialization types like `Serialization.Test.Module.Channel`).
- `DTS.Slice.Control` (self-referential partial classes).
- **External Types Referenced** (but not defined here):
- `DASLib.Service.DASChannel`
- `IDiagnosticResult`
- `Common.DAS.Concepts.DAS.Channel.IEngineeringUnitAware` (implemented interface)
- `Serialization.Test.Module.Channel`
- `ChannelFilter`, `DefaultSaeJ211Filter` (used in constructor)
- `Module`, `Event`, `ReviewableAttribute` (via partial class nesting)
- **Depended upon by**:
The `CalculatedChannel` hierarchy is part of the `Event.Module.Channel` namespace and likely consumed by higher-level event processing, serialization, or UI review components (e.g., `ReviewableAttribute` subclasses, though commented out).
---
### 5. Gotchas
- **`DataValues` constructor silently swallows exceptions**: Any exception during construction (e.g., memory-mapped file initialization) is rethrown as a generic `Exception` with a fixed message, losing original exception details beyond the inner exception.
- **`DataValues` does not expose data accessors**: The class inherits from `Exceptional` (not shown), but no public methods/properties to read/write data are visible here—suggesting data access is handled elsewhere (e.g., via `Channel` base class).
- **`CalculatedChannel` methods throw `NotImplementedException`/`NotSupportedException`**: Many methods (e.g., `ToDtsSerializationTestModuleChannel`, `SetPropertyValuesFrom`, `GetUnfilteredDataMV`) are unimplemented. Calling them will cause runtime failures.
- **`DataHalfRangeValueEu` uses arithmetic mean, not half-range**: Despite the name, it computes `0.5 * (min + max)` (i.e., midpoint), not half the range (`0.5 * (max - min)`).
- **`XUnitsString` returns `"N/A"` for unknown `XUnits`**: This may cause UI/display issues if `"N/A"` is not handled gracefully.
- **`DataValues` constructor parameter `useMemoryMappedFile` is unused in the body**: The `if (UseMemoryMappedFile)` block is empty—no actual initialization logic is present.
- **`CalculatedChannel` constructors copy arrays**: `new List<double>(xValues)` and `new List<double>(yValues)` are used, but `X`/`Y` return arrays—ensuring immutability but potentially causing confusion if callers expect reference equality.
- **`OffsetCalculatedChannel` has typo in constructor parameter**: `yVAlues` (capital `A`) instead of `yValues`.
- **`HICCalculatedChannel` is commented out**: Though referenced in the source, the full implementation is commented out, making `HeadInjuryCriteria` support incomplete.
- **`ReviewableAttribute` subclasses are commented out**: The `InitializeReviewableAttributes` override and associated attribute classes (e.g., `ReviewablePeakFrequencyAttribute`, `ReviewableHICAttribute`) are commented out—review functionality is not active in this build.
---
*Documentation generated from source files dated 2009. No runtime behavior beyond what is statically visible in the provided code is assumed.*

View File

@@ -0,0 +1,183 @@
---
source_files:
- Common/DTS.Common.SerializationPlus/Filter/IFilterable.cs
- Common/DTS.Common.SerializationPlus/Filter/IFilter.cs
- Common/DTS.Common.SerializationPlus/Filter/Filter.cs
- Common/DTS.Common.SerializationPlus/Filter/ChannelDefaultSaeJ211Filter.cs
- Common/DTS.Common.SerializationPlus/Filter/SaeJ211Filter.cs
generated_at: "2026-04-16T03:30:37.411361+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "b7c704a804b34580"
---
# Documentation: DTS.Common.SerializationPlus.Filter Module
## 1. Purpose
This module provides a filter abstraction and implementation framework for processing event module channel data in the DTS.Slice.Control system. It enables application of standardized SAE J211-compliant filters (e.g., CFC-defined filters like 6G, 12G, etc.) or ad hoc cutoff frequencies to raw channel data, supporting both channel-based and raw array-based filtering. The module is designed for serialization/deserialization scenarios (e.g., saving/loading filter configurations), and integrates with legacy TDC software behavior via a toggle for sample shifting. It serves as a foundational component for data post-processing in crash event analysis workflows.
## 2. Public Interface
### Interfaces
#### `IFilterable`
Represents an object (e.g., a channel or module) that can have filters applied and managed.
- **`bool UseFilterCaching { get; set; }`**
Controls whether filtered results are cached for reuse.
- **`List<IFilter> AvailableFilters { get; }`**
Returns a list of filters that can be applied to this object.
- **`IFilter CurrentFilter { get; set; }`**
Gets or sets the currently active filter.
- **`double[] GetDataFilteredBy(IFilter filter, Event.Module.Channel.DataDisplayUnits displayUnits)`**
Applies the specified `filter` to the objects data and returns filtered data in the requested `displayUnits` (e.g., ADC, EU, mV).
#### `IFilter`
Defines the contract for a filter implementation.
- **`string Name { get; }`**
Human-readable name of the filter (e.g., `"6G"`, `"12.5Hz"`).
- **`bool IsCfc { get; }`**
Returns `true` if the filter corresponds to a defined CFC ( Crash Filter Characteristic ) value (i.e., not `Unfiltered`, `UnfilteredZero`, or `AdHoc`).
- **`ChannelFilter Type { get; }`**
Returns the best-matching `ChannelFilter` enum value for the filter (e.g., `ChannelFilter.SixG`, `ChannelFilter.AdHoc`).
- **`double CutoffFrequencyHz { get; }`**
Returns the cutoff frequency in Hz.
- **`char IsoDescription { get; }`**
Returns the ISO description character (e.g., `'A'`, `'B'`) for the filter type, decoded via `IsoDescriptionAttributeCoder`.
- **`double[] Apply(Event.Module.Channel input, Event.Module.Channel.DataDisplayUnits displayUnits, bool bUseLegacyTDCSofwareFilterAdjustment)`**
Applies the filter to data from the specified `input` channel, returning filtered data in the requested `displayUnits`. Uses `bUseLegacyTDCSofwareFilterAdjustment` to optionally shift output by one sample to match legacy TDC behavior.
- **`double[] Apply(double[] data, double sampleRate, bool bUseLegacyTDCSoftwareFilterAdjustment)`**
Applies the filter to a raw `data` array using the provided `sampleRate`. Same legacy adjustment behavior.
- **`string ToBaseString()`**
Returns the base name of the filter (e.g., `"6G"`), *without* the `"Default (...)"` prefix used by `DefaultSaeJ211Filter`.
### Classes
#### `Filter` (abstract)
Base class implementing `IFilter`. All concrete filters derive from this.
- Declares abstract implementations of all `IFilter` members (e.g., `Name`, `IsCfc`, `Type`, `CutoffFrequencyHz`, `Apply(...)`, `ToBaseString()`).
#### `SaeJ211Filter` (abstract)
Base class for SAE J211-compliant filters. Supports initialization via CFC type or ad hoc frequency.
- **`SaeJ211Filter(ChannelFilter originalType)`**
Constructor for CFC-based filters. Throws if `originalType == ChannelFilter.AdHoc`.
- **`SaeJ211Filter(double cutoffFrequencyHz)`**
Constructor for ad hoc filters. Sets `OriginalType = ChannelFilter.AdHoc`.
- **`SaeJ211Filter(SaeJ211Filter originalFilter)`**
Copy constructor.
- **`ChannelFilter OriginalType { get; }`**
Stores the original filter type passed at construction (e.g., `AdHoc` or a CFC enum).
- **`override string Name { get; }`**
Returns `"6G"` for CFC types, or `"12.5Hz"` for ad hoc (via `CutoffFrequencyHz.ToString()` + `"Hz"`).
- **`override string ToBaseString()`**
Returns the same as `Name` (note: differs from `DefaultSaeJ211Filter.ToBaseString()`).
- **`override string ToString()`**
Returns `Name`.
- **`override bool Equals(object obj)`**
Case-insensitive comparison of `Name`.
- **`override int GetHashCode()`**
Hash based on lowercase `Name`.
- **`static Filter Parse(string serialization)`**
Parses a string like `"6G"` or `"12.5Hz"` into a `Filter` instance. Falls back to `Unfiltered` on failure.
#### `DefaultSaeJ211Filter`
Concrete subclass of `SaeJ211Filter` that decorates filter names with `"Default (...)"`.
- **Constructors**
- `DefaultSaeJ211Filter(SaeJ211Filter filter)`
- `DefaultSaeJ211Filter(ChannelFilter filterType)`
- `DefaultSaeJ211Filter(double adHocFrequency)`
- **`override string Name { get; }`**
Returns `"Default (6G)"` (or similar), wrapping the base `Name`.
- **`override string ToBaseString()`**
Returns the *undecorated* base name (e.g., `"6G"`), not `"Default (6G)"`.
## 3. Invariants
- **Filter Type Consistency**:
`IsCfc == true` if and only if `Type != ChannelFilter.Unfiltered && Type != ChannelFilter.UnfilteredZero && Type != ChannelFilter.AdHoc`.
- **Cutoff Frequency Source**:
For CFC-based filters (`OriginalType != AdHoc`), `CutoffFrequencyHz` is derived from the `ChannelFilter` enum value (e.g., `ChannelFilter.SixG == 6.0`). For ad hoc filters, `CutoffFrequencyHz` is set explicitly.
- **`OriginalType` vs `Type`**:
`OriginalType` preserves the *input* filter type (e.g., `AdHoc`), while `Type` is the *resolved* type (e.g., `SixG` if `CutoffFrequencyHz == 6.0`).
- **`Apply(...)` Data Handling**:
Filtering always uses `FilterUtility.ApplyFilter(...)` internally. The `bUseLegacyTDCSoftwareFilterAdjustment` parameter controls whether output is shifted by one sample (to preserve legacy TDC behavior).
- **`Parse(...)` Fallback Behavior**:
`Parse(null)` or `Parse("")` returns `new SaeJ211Filter(ChannelFilter.Unfiltered)`. Invalid strings also fall back to `Unfiltered`.
## 4. Dependencies
### Internal Dependencies (from source)
- `DTS.Slice.Control` namespace:
- `Event.Module.Channel` (data source), `Event.Module.Channel.DataDisplayUnits`, `ChannelFilter` enum.
- `DTS.Common.DAS.Concepts.DAS.Channel`:
- Used in `SaeJ211Filter` for `IsoDescriptionAttributeCoder`.
- `DTS.Common.Utilities`:
- `Property<T>`, `Exceptional`, `APILogger`, `DescriptionAttributeCoder<T>`, `IsoDescriptionAttributeCoder`.
- `DTS.Common.SerializationPlus.Serialization.*`:
- `SliceRaw.File.PersistentChannel`, `TDAS.File.PersistentChannel`, `ILargeDataAware`, `DataTooBigForArrayException`.
### External Dependencies
- `System` (e.g., `Exception`, `StringComparison`, `CultureInfo`, `Enum`).
- Likely `FilterUtility` (from `DTS.Common.DAS.Concepts.DAS.Channel`) is defined elsewhere (referenced but not included in source).
### Inferred Usage
- `IFilterable` is likely implemented by channel or module classes in `DTS.Slice.Control`.
- `Filter.Parse(...)` suggests serialization/deserialization of filter configurations (e.g., in XML or JSON).
## 5. Gotchas
- **`bUseLegacyTDCSofwareFilterAdjustment` Typo**:
In `IFilter.Apply(...)`, the parameter is misspelled (`Sofware` instead of `Software`). This typo is preserved in `Filter.Apply(...)` and `SaeJ211Filter.Apply(...)`.
- **`ToBaseString()` Behavior Differs by Subclass**:
`SaeJ211Filter.ToBaseString()` returns `Name` (e.g., `"6G"`), but `DefaultSaeJ211Filter.ToBaseString()` returns the *undecorated* name (e.g., `"6G"`), while `DefaultSaeJ211Filter.Name` returns `"Default (6G)"`. Ensure callers use `ToBaseString()` when the base name is required.
- **`SaeJ211Filter.Parse(...)` Behavior**:
- Adds `"Hz"` to numeric-only strings (e.g., `"12.5"``"12.5Hz"`).
- Uses `CultureInfo("")` (invariant-like) for parsing, but may fail on non-English decimal separators if `serialization` includes `"Hz"` and culture-sensitive formatting.
- **`OriginalType` vs `Type` Confusion**:
`OriginalType` may be `AdHoc` while `Type` resolves to a CFC value (e.g., if `CutoffFrequencyHz == 6.0`). Do not assume `OriginalType == Type`.
- **`IsCfc` Excludes `UnfilteredZero`**:
`UnfilteredZero` is treated as non-CFC, even though it is a defined `ChannelFilter` enum value.
- **`Apply(...)` Data Source Handling**:
- For `DataDisplayUnits.Adc`, data is pulled from `channel.UnfilteredData`, with special handling for `PersistentChannel` types (including `ILargeDataAware` checks).
- Throws `DataTooBigForArrayException` if data is too large for array loading (TDAS only).
- **No Caching Logic in Interface**:
`UseFilterCaching` is defined in `IFilterable`, but no caching implementation is provided in the source files. Its behavior is unknown.
- **Equality Case-Insensitivity**:
`Equals(...)` and `GetHashCode(...)` use case-insensitive comparison and lowercase hashing. This may cause collisions if filter names differ only in case (though unlikely for `ChannelFilter` enum values).

View File

@@ -0,0 +1,49 @@
---
source_files:
- Common/DTS.Common.SerializationPlus/Properties/AssemblyInfo.cs
generated_at: "2026-04-16T03:30:06.540513+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "acefa3e3d50bcee6"
---
# Properties
### **1. Purpose**
This module is the `DTS.Common.SerializationPlus` assembly, a .NET class library intended to provide enhanced or extended serialization functionality—likely building upon or supplementing standard .NET serialization mechanisms (e.g., `System.Runtime.Serialization`, `System.Text.Json`, or `Newtonsoft.Json`). Based solely on the provided `AssemblyInfo.cs`, the assembly serves as a foundational component in the DTS (presumably *Data Transfer System* or a domain-specific acronym) codebase, encapsulating reusable serialization utilities. However, the actual implementation details (e.g., types, logic, and behavior) are not present in this file, so its specific serialization features remain unknown without examining other source files in the project.
---
### **2. Public Interface**
**No public types, methods, or classes are defined or exposed in this file.**
The `AssemblyInfo.cs` file contains only assembly-level metadata attributes (e.g., title, version, COM visibility). It does not declare any public classes, interfaces, structs, methods, or properties. Therefore, there is **no public interface documented here**.
---
### **3. Invariants**
The only invariant enforced by this file is **metadata consistency** for the assembly:
- The assembly identity is fixed via `AssemblyVersion("1.0.0.0")` and `AssemblyFileVersion("1.0.0.0")`.
- `ComVisible(false)` ensures types in this assembly are not exposed to COM by default.
- The `Guid("b9d1ac5b-7a6f-4b14-9ff8-3a1fc03519e2")` uniquely identifies the typelib *if* the assembly is later made COM-visible (e.g., via `ComVisible(true)` on a type or assembly).
No behavioral invariants (e.g., serialization guarantees, thread-safety, or contract constraints) can be inferred from this file alone.
---
### **4. Dependencies**
**Dependencies of this module (inferred from imports):**
- `System.Reflection`
- `System.Runtime.CompilerServices`
- `System.Runtime.InteropServices`
These are standard .NET runtime namespaces required for assembly metadata and COM interop. No external third-party or project-specific dependencies are declared in this file.
**Dependents (inferred from usage):**
Unknown. This file does not reference any external types or modules, so no direct dependents can be identified from this source alone. However, other modules in the `DTS.Common.*` namespace (e.g., `DTS.Common.SerializationPlus.*`) likely consume types defined elsewhere in this assembly.
---
### **5. Gotchas**
- **No functional logic present**: This file is purely metadata and does not contain any serialization logic. Developers should not expect to find serialization behavior or APIs here.
- **Versioning is static**: Both `AssemblyVersion` and `AssemblyFileVersion` are hardcoded to `"1.0.0.0"`. This may indicate incomplete versioning hygiene (e.g., missing CI/CD integration for automatic versioning), potentially complicating deployment or dependency resolution if multiple builds are used.
- **COM interop is disabled by default**: With `ComVisible(false)` at the assembly level, any COM exposure must be explicitly opted-in at the type level—failure to do so may cause unexpected behavior in legacy COM consumers.
- **Missing documentation**: The `AssemblyDescription` and `AssemblyCompany` attributes are empty strings, suggesting incomplete assembly metadata (though not functionally impactful).
- **None identified from source alone** for serialization-specific quirks, as no serialization-related code is included in this file.

View File

@@ -0,0 +1,178 @@
---
source_files:
- Common/DTS.Common.SerializationPlus/XLSX/Excel.File.cs
- Common/DTS.Common.SerializationPlus/XLSX/Excel.File.Writer.cs
generated_at: "2026-04-16T03:30:27.540490+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "6f0085250a497f9b"
---
# XLSX Export Module Documentation
## 1. Purpose
This module implements XLSX (Excel) file export functionality for test data within the DTS.Serialization framework. It extends `Serialization.File` and implements `IWritable<Test>` to provide structured export of `Test` objects to Excel spreadsheets. The module supports exporting engineering units (EU), millivolt (mV), and analog-to-digital converter (ADC) values based on configurable flags, and includes support for filtered/unfiltered data, time-based slicing (`Start`/`Stop`), and user-selected export headers. It uses the `DocumentFormat.OpenXml` library to generate compliant XLSX files, leveraging a template file (`XLSXExportTemplate.xlsx`) and performing two-pass writing: first for metadata/headers, then for numeric data using SAX-style streaming for performance.
## 2. Public Interface
### `DTS.Serialization.XLSX.File`
- **`public File()`**
Constructor that initializes the XLSX file handler with type name `"XLSX"`.
- **`public IWriter<Test> Exporter { get; }`**
Returns the `IWriter<Test>` instance used to write test data. Lazily instantiates a `Writer` on first access using `DefaultEncoding`. Throws a wrapped exception if instantiation fails.
- **`public bool ExportADC { set; }`**
Sets the `ExportADC` property on the underlying `Writer` instance. Controls whether raw ADC values are exported.
- **`public bool ExportEU { set; }`**
Sets the `ExportEU` property on the underlying `Writer` instance. Controls whether engineering units (EU) values are exported. Default is `true`.
- **`public bool ExportMV { set; }`**
Sets the `ExportMv` property on the underlying `Writer` instance. Controls whether millivolt (mV) values are exported.
### `DTS.Serialization.XLSX.File.Writer`
- **`internal File WriterParent { get; }`**
Reference to the owning `File` instance.
- **`public bool ExportADC { get; set; }`**
Gets or sets whether to export raw ADC values.
- **`public bool ExportEU { get; set; }`**
Gets or sets whether to export engineering units (EU) values. Default is `true`.
- **`public bool ExportMv { get; set; }`**
Gets or sets whether to export millivolt (mV) values.
- **`public double Start { get; set; }`**
Start time (in seconds) for data slicing.
- **`public double Stop { get; set; }`**
Stop time (in seconds) for data slicing.
- **`public bool Filtered { get; set; }`**
Indicates whether filtered data should be exported.
- **`public List<IExportHeader> ExportHeaders { get; set; }`**
List of user-selected headers to include in the export (FB 6410). Only headers with `IsSelected == true` are written.
- **`public void Write(string pathname, string id, Test test, bool bFiltering, bool includeGroupNameInISOExport, double minStartTime, int dataCollectionLength)`**
*Note: This method is declared but has no body in the provided source.* Likely a legacy or stub signature.
- **`public void Write(string pathname, string id, string dataFolder, Test test, bool bFiltering, bool includeGroupNameInISOExport, FilteredData fd, Test.Module.Channel tmChannel, int channelNumber, BeginEventHandler beginEventHandler, CancelEventHandler cancelEventHandler, EndEventHandler endEventHandler, TickEventHandler tickEventHandler, ErrorEventHandler errorEventHandler, CancelRequested cancelRequested, double minStartTime, int dataCollectionLength)`**
Main export method. Writes a `Test` object to an XLSX file at `pathname`. Performs:
- Template file copy and OpenXML document opening.
- Header row indexing via `_headerRowLineIndex` (FB 6410).
- Metadata writing (test date/time, ID, description, channel info, scaling, filter settings).
- Data scaling via `GetDataScaler` and precomputation of scalers in `_aicToScaler`.
- Optional filtering of EU data using `SaeJ211Filter`.
- Two-pass writing: first pass writes headers/metadata; second pass streams data using SAX-style `OpenXmlReader`/`OpenXmlWriter`.
- Interpolation for resampling channels with different sample rates.
- Progress updates every 1000 samples (`UPDATE_INTERVAL`).
- Cleanup: unsets channel data, logs errors, invokes event handlers.
- **`public static Common.DAS.Concepts.DataScaler GetDataScaler(Test.Module.AnalogInputChannel currentAnalogChannel)`**
Constructs and configures a `DataScaler` instance from an `AnalogInputChannel`, including linearization, scaling factors, zero methods, digital channel settings (FB 14469), and excitation voltage properties.
- **`protected Cell GetCell(Worksheet worksheet, string xColumn, uint rowIndex, bool bLookForCell = true)`**
Retrieves or inserts a cell at the specified location. Uses `_rowIndexToRow` cache for performance.
- **`private static Cell InsertCellInWorksheet(string columnName, uint rowIndex, WorksheetPart worksheetPart, string cellReference, bool bLookForCell)`**
Inserts a cell into the worksheet, maintaining OpenXML cell ordering by `CellReference`.
- **`private void WriteTime(WorksheetPart ws, string column, uint row, DateTime time, SharedStringTablePart sharedString)`**
Writes a time value as a shared string with number format ID 14 (time format).
- **`private void WriteTime(WorksheetPart ws, string column, string headerName, DateTime time, SharedStringTablePart sharedString)`**
Overload that writes to the row index associated with `headerName` (FB 6410).
- **`private void WriteDate(WorksheetPart ws, string column, uint row, DateTime date)`**
Writes a date as an OLE Automation date (OADate) with number format.
- **`private void WriteDate(WorksheetPart ws, string column, string headerName, DateTime date)`**
Overload that writes to the row index associated with `headerName` (FB 6410).
- **`private void WriteDouble(WorksheetPart ws, string column, uint row, double value)`**
Writes a numeric value directly to a cell.
- **`private void WriteDouble(WorksheetPart ws, string column, string headerName, double value)`**
Overload that writes to the row index associated with `headerName` (FB 6410).
- **`private void WriteString(WorksheetPart ws, string column, uint row, SharedStringTablePart sharedStringTablePart, string value)`**
Writes a string as a shared string.
- **`private void WriteString(WorksheetPart ws, string column, string headerName, SharedStringTablePart sharedStringTablePart, string value)`**
Overload that writes to the row index associated with `headerName` (FB 6410). Skips duplicate entries via `_alreadyEnteredHeader`.
- **`private int InsertSharedStringItem(string text, SharedStringTablePart shareStringPart)`**
Adds or retrieves a shared string index. Uses `_stringLookup` dictionary for O(1) lookup.
- **`private static string GetColumn(int index)`**
Converts a zero-based column index to Excel column letters (e.g., `0 → "B"`). Starts at column B (index 0 → "B").
- **`private void AddStyleSheet(SpreadsheetDocument sp)`**
Adds a date/time number format (ID 14) to the stylesheet and caches its index in `_dateFormatIndex`.
- **`private void InsertRow(WorksheetPart worksheetPart)`**
Inserts an empty row after the last row in the worksheet.
- **`private void UpdateProgress(double dValue, TickEventHandler tickEventHandler)`**
Invokes the progress event handler if non-null.
- **`internal Writer(File fileType, int encoding)`**
Constructor initializing `Writer` base class, setting default export flags (`ExportEU = true`, others `false`), and storing `WriterParent`.
- **`public void Initialize(...)`**
*Note: This method is declared but has no body in the provided source.* Likely a stub or unused legacy method.
## 3. Invariants
- **Export flags are mutually exclusive in practice**: While `ExportADC`, `ExportEU`, and `ExportMV` are independently settable, the current implementation writes only EU data by default and does not appear to conditionally include ADC/mV in the final data rows (only scaling factors are written regardless of flags). The flags control writer behavior but may not yet fully gate data output.
- **Header row indexing is precomputed**: `_headerRowLineIndex` is built before writing data and must remain consistent during the export. Headers not in this dictionary are skipped.
- **Channel ordering is deterministic**: Channels are sorted by `AbsoluteDisplayOrder`, then by `Number` to ensure reproducible column order.
- **Data slicing respects `Start`/`Stop`**: Pre- and post-trigger sample counts are clamped to `Start * SampleRateHz` and `Stop * SampleRateHz`, respectively.
- **Sample rate resampling uses ceiling**: Channels with lower sample rates are resampled using `rate = ceil(maxSampleRate / channelSampleRate)`.
- **Interpolation is linear**: When `step > 0`, values are interpolated using a linear increment based on neighboring samples.
- **Shared string table is cached**: `_stringLookup` is initialized once per export and reused for performance.
- **Row caching is per-export**: `_rowIndexToRow` is cleared at the start of `Write` and reused within a single export.
## 4. Dependencies
### External Dependencies
- **`DocumentFormat.OpenXml`**: Core library for XLSX manipulation.
- **`DTS.Common.Enums` / `DTS.Common.Enums.Sensors`**: For `SensorConstants`, `IsoViewMode`, and digital channel enums.
- **`DTS.Common.Interface.ExportData`**: For `IExportHeader` and `FilteredData`.
- **`DTS.Common.SerializationPlus`**: Base classes `Serialization.File`, `Writer<File>`, `IWriter<Test>`, `BeginEventHandler`, etc.
- **`DTS.Common.Utilities.Logging`**: For `APILogger`.
- **`DTS.Slice.Control`**: For `SaeJ211Filter` and `UseLegacyTDCSoftwareFiltering`.
### Internal Dependencies
- **`DTS.Common.Concepts.DataScaler`**: Used for channel scaling and linearization.
- **`DTS.Common.DAS.Concepts.DataScaler`**: Full namespace path used in `GetDataScaler`.
- **`DTS.Test`**: `Test`, `Test.Module.Channel`, `Test.Module.AnalogInputChannel`, `Test.Module.ChannelInfo`, `Test.Module.Module`.
- **`DTS.Common.Enums.IsoViewMode`**: Controls ISO/User code display in header.
- **`XLSXExportHeaderLine`**: Enum-like class (likely static class with `GetDescription()` methods) defining header names.
### Inferred Dependencies
- **`XLSXExportTemplate.xlsx`**: Must exist at runtime relative to `AppDomain.CurrentDomain.BaseDirectory\ReportTemplates\`.
- **`UseLegacyTDCSoftwareFiltering`**: Global/static flag used in filtering logic (not defined in source).
## 5. Gotchas
- **`ExportADC`, `ExportEU`, `ExportMV` flags may not fully gate data output**: While setters exist and are passed to the `Writer`, the `Write` method only writes EU data to the data rows. ADC/mV export may be incomplete or unimplemented.
- **`Write(string pathname, string id, Test test, ...)` overload has no body**: Likely a stub or legacy method; only the 14-parameter overload is implemented.
- **`Initialize(...)` method has no body**: May be unused or intended for future implementation.
- **`_rowIndexToRow` is a static field**: Shared across all `Writer` instances in the AppDomain. This could cause race conditions in multi-threaded export scenarios (though current code clears it per export).
- **`_stringLookup` is not thread-safe**: Used without locking; safe only because `Write` is single-threaded per instance.
- **`GetColumn` starts at index 0 → "B"**: Column A is skipped; likely intentional for header/data layout.
- **`Filtered` flag affects both data filtering and filter name display**: When `Filtered == false`, the software filter name is written as `"NONE"` and cutoff frequency is omitted or set to `0`.
- **FB 18024 and FB 6410 references**: Bug fixes embedded in comments (e.g., "FB 6410") indicate historical quirks around header row handling and filter display.
- **FB 14469 fix for digital channels**: Digital channel properties (`Digital`, `DigitalMode`, `DigitalMultiplier`) must be explicitly set on the scaler; otherwise EU values may be incorrect.
- **FB 14513 rounding error mitigation**: Uses `Decimal` for time offset calculations to avoid double-precision rounding issues.
- **FB 14659 channel ordering fix**: Uses `AbsoluteDisplayOrder` (not display order) to ensure correct channel indexing.
- **Performance optimizations removed**: GC calls were commented out due to performance impact (likely legacy 32-bit concern).
- **Two-pass writing complexity**: First pass writes headers/metadata; second pass streams data. This is necessary for SAX-style writing but increases code complexity and potential for bugs.
- **`minStartTime` vs. `dStartTime` alignment**: Time alignment logic (`channelOffsetStart`) is critical for correct sample indexing across channels with different start times.