Files
DP44/enriched-qwen3-coder-next/Common/DTS.Common.Serialization/Control/Event.md
2026-04-17 14:55:32 -04:00

230 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
source_files:
- Common/DTS.Common.Serialization/Control/Event/DasModuleAccessor.cs
- Common/DTS.Common.Serialization/Control/Event/DasChannelAccessor.cs
- Common/DTS.Common.Serialization/Control/Event/ChannelAccessor.cs
- Common/DTS.Common.Serialization/Control/Event/ModuleChannelAccessor.cs
- Common/DTS.Common.Serialization/Control/Event/DasModuleChannelAccessor.cs
- Common/DTS.Common.Serialization/Control/Event/TestInformation.cs
- Common/DTS.Common.Serialization/Control/Event/Event.cs
generated_at: "2026-04-16T03:41:53.208866+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "e1ba9340d986b9b2"
---
# Documentation: `DTS.Slice.Control.Event` Accessor Classes and Related Types
## 1. Purpose
This module provides accessor objects and supporting infrastructure for navigating and manipulating event data within the DTS Slice Control system. Specifically, it defines hierarchical dictionary-based accessors (`DasModuleAccessor`, `DasChannelAccessor`, `DasModuleChannelAccessor`, `ChannelAccessor`, `ModuleChannelAccessor`) that enable lookup of modules and channels by DAS ID, module number, and channel number combinations. It also includes the core `Event` class (a partial class with multiple files), which serves as the in-memory representation of a DAS event—encapsulating test metadata, modules, channels, and derived properties such as validation flags and serialization support. The module bridges low-level DAS serialization data (e.g., `DTS.Serialization.Test`) and higher-level control logic by offering structured, type-safe access to event components.
## 2. Public Interface
All accessor classes and the `Event` class reside in the `DTS.Slice.Control` namespace and are declared as `public partial class Event`.
### `Event` Class
- **`Event()`**
Default constructor. Initializes all properties to their default values.
- **`Event(string id, string description)`**
Initializes an `Event` with the given `id` and `description`. Throws a wrapped exception on failure.
- **`Event(Test test, Test.ReportErrors reportErrors)`**
Initializes an `Event` by converting from a `DTS.Serialization.Test` object via `FromDtsSerializationTest`. Rethrows exceptions directly.
- **`Event(string id, string description, List<Module> modules)`**
Initializes an `Event` with `id`, `description`, and a list of `Module`s.
- **`Event(List<IDASCommunication> dases, EventInfoAggregate info)`**
Initializes an `Event` by aggregating configuration and channel data from a list of DAS devices (`IDASCommunication`) and `EventInfoAggregate`. Populates `Modules`, `DasModules`, `DasChannels`, and `DasModuleChannels`. Throws `UserException` for missing DAS info or configuration. Validates test ID consistency across DAS units.
- **`string Id { get; set; }`**
Gets/sets the events test ID.
- **`string Description { get; set; }`**
Gets/sets the events description.
- **`Guid Guid { get; set; }`**
Gets/sets the globally unique identifier for the event. Default is `Guid.Empty`.
- **`UInt16 FaultFlags { get; set; }`**
Gets/sets the global fault flags for the event.
- **`DateTime InceptionDate { get; private set; }`**
Gets the creation date of the event (set during construction). Defaults to `DateTime.Now`.
- **`List<Module> Modules { get; set; }`**
Gets/sets the list of `Module` objects associated with this event.
- **`List<Module.Channel> CalculatedChannels { get; set; }`**
Gets/sets the list of calculated channels.
- **`DasModuleAccessor DasModules { get; private set; }`**
Returns a `DasModuleAccessor` keyed by DAS ID (`Common.DAS.Concepts.DAS.Id`), mapping to a `List<Module>`.
- **`DasChannelAccessor DasChannels { get; private set; }`**
Returns a `DasChannelAccessor` keyed by DAS ID, mapping to a `List<Module.Channel>`.
- **`DasModuleChannelAccessor DasModuleChannels { get; private set; }`**
Returns a `DasModuleChannelAccessor` keyed by DAS ID, mapping to a `ModuleChannelAccessor`.
- **`int LastAbsoluteChannelNumberInEvent { get; }`**
Returns the highest absolute channel number across all modules and channels.
- **`bool IsTooLargeFor32BitVisualization { get; }`**
Returns `true` if the total data volume (based on `TooLargeFor32BitVisualizationBytesPerSampleThreshold`) exceeds 2GB (0x7FFFFFFF bytes).
- **`double TooLargeFor32BitVisualizationBytesPerSampleThreshold { get; private set; }`**
Threshold in bytes per sample used for 32-bit visualization size checks. Default: `2.0`.
- **`bool ContainsChannelsActiveInvalidZeroingWindows { get; }`**
Returns `true` if any channel has `ZeroMethod == AverageOverTime` and an invalid averaging window.
- **`List<Module.Channel> ChannelsWithActiveInvalidZeroingWindows { get; }`**
Returns the list of channels with active but invalid zeroing windows (e.g., window outside data range or negative indices).
- **`static string BaseSerializationDirectory { get; set; }`**
Gets/sets the base directory path for event serialization.
- **`static string GetEventSerializationDirectory(string eventId)`**
Returns the full path for the serialization directory of the given `eventId`.
- **`bool Equals(object obj)`**
Overrides `Equals` to compare `Id`, `Description`, `Guid`, `Modules`, and `FaultFlags`.
- **`int GetHashCode()`**
Overrides `GetHashCode`.
- **`Test ToDtsSerializationTest()`**
Converts this `Event` to a `DTS.Serialization.Test`. Removes unconfigured/dummy channels before serialization.
- **`void FromDtsSerializationTest(Test that, Test.ReportErrors reportErrors)`**
Populates this `Event` from a `DTS.Serialization.Test`. Re-throws `InvalidDataException` directly; wraps others.
- **`static implicit operator Test(Event sliceControlEvent)`**
Implicit conversion operator to `DTS.Serialization.Test`.
- **`static bool IsG5(IDASCommunication idas)`**
Returns `true` if the DAS serial number starts with `"5M"`.
- **`static bool IsSlice6DBModule(Module module)`**
Returns `true` if `module.Description.ToLower() == "slice6db module"`.
### Accessor Classes
- **`DasModuleAccessor : ExceptionalDictionary<Common.DAS.Concepts.DAS.Id, List<Module>>`**
Keyed by DAS ID, maps to list of `Module`s. Used to retrieve modules by DAS.
- **`DasChannelAccessor : ExceptionalDictionary<Common.DAS.Concepts.DAS.Id, List<Module.Channel>>`**
Keyed by DAS ID, maps to list of `Module.Channel`s. Used to retrieve channels by DAS.
- **`DasModuleChannelAccessor : ExceptionalDictionary<Common.DAS.Concepts.DAS.Id, ModuleChannelAccessor>`**
Keyed by DAS ID, maps to a `ModuleChannelAccessor`. Enables 3-level lookup: DAS ID → module index → channel index.
- **`ChannelAccessor : ExceptionalDictionary<int, Module.Channel>`**
Keyed by `int` (module channel number), maps to a `Module.Channel`. Used as the innermost accessor.
- **`ModuleChannelAccessor : ExceptionalDictionary<int, ChannelAccessor>`**
Keyed by `int` (module array index), maps to a `ChannelAccessor`. Enables lookup of channels by module number.
- **`TestInformation : Exceptional`** *(private)*
Holds test metadata (`Id`, `Description`) per DAS. Used internally during event construction.
### Helper Methods (in `Event`)
- **`bool IsDummyChannel(Module.Channel channel)`**
Returns `true` if `channel.ChannelDescriptionString.ToLower() == "dummy arm channel"`.
- **`bool IsTom(DASModule module)`**
Returns `true` if module is a TOM (based on serial number or channel type).
- **`void PurgeUnconfiguredChannels()`**
Removes unconfigured or dummy channels from all modules.
- **`bool IsEmptyModule(Module module)`**
Returns `true` if module has no configured/non-dummy channels.
## 3. Invariants
- **`DasModules`, `DasChannels`, `DasModuleChannels` are always initialized**
These properties are initialized in the `Property<T>` declaration with new accessor instances and are marked `readonly`/`true` (immutable reference after construction).
- **Module array indices must match list positions**
The constructor for `Event(List<IDASCommunication>, EventInfoAggregate)` asserts:
`Debug.Assert(DasModules[das.SerialNumber].Count - 1 == dasModule.ModuleArrayIndex);`
This implies modules are inserted in order, and empty slots are filled with placeholder `Module` instances.
- **Test ID must be consistent across all DAS units**
During construction, if any DAS reports a different `TestID`, an exception is thrown.
- **Channel absolute numbers are assigned sequentially**
`absoluteChannelNumber` is incremented per channel added, and `Module.Channel.AbsoluteNumber` is set during `Channel.CreateChannel`.
- **`InceptionDate` is set once at construction**
The setter is `private`, and the property is initialized with `DateTime.Now` or the serialization date.
- **`TooLargeFor32BitVisualizationBytesPerSampleThreshold` is immutable after construction**
Marked `readonly` and `true` in `Property<T>`.
- **`IsSlice6DBModule` check is case-insensitive**
Compares `module.Description.ToLower()` to `"slice6db module"`.
- **`InvalidWindowAverage` is `short.MinValue`**
Used to detect uninitialized or invalid window averages in zeroing logic.
## 4. Dependencies
### Internal Dependencies (within this module)
- `DTS.Slice.Control.Event.Module` and nested types (`Module.Channel`, `Module.AnalogInputChannel`, etc.)
- `DTS.Common.Utilities.ExceptionalDictionary<TKey, TValue>`
- `DTS.Common.Utilities.DotNetProgrammingConstructs.Property<T>`
- `DTS.Slice.Control.Event.TestInformation` (private helper)
### External Dependencies
- `DTS.Serialization.Test` (from `DTS.Serialization` namespace)
- `DTS.DASLib.Service.IDASCommunication`, `DASModule`, `DASChannel`, `EthernetTDAS`
- `DTS.Common.Utilities.Logging.APILogger`
- `System.Collections.Generic.List<T>`, `System.Guid`, `System.DateTime`, `System.Diagnostics.Debug`
- `DTS.Serialization.StringResources.Strings` (for error messages)
### Inferred Usage
- `EventInfoAggregate` is required for `Event(List<IDASCommunication>, EventInfoAggregate)` constructor.
- `Test.ReportErrors` delegate is used in `FromDtsSerializationTest`.
- Serialization infrastructure (`DTS.Serialization`) is used for round-trip conversion (`ToDtsSerializationTest`, `FromDtsSerializationTest`).
## 5. Gotchas
- **`DasModuleChannels` property key is `"DTS.Slice.Control.Event.DasModules"` (typo)**
In the `Event` constructor, the `Property<DasModuleChannelAccessor>` for `DasModuleChannels` is initialized with the key `"DTS.Slice.Control.Event.DasModules"` instead of `"DTS.Slice.Control.Event.DasModuleChannels"`. This is likely a copy-paste bug.
- **`DasModuleChannelAccessor` uses `int` keys for module/channel indices, not typed IDs**
Both `ModuleChannelAccessor` and `ChannelAccessor` use `int` keys (for module number and channel number, respectively), not strongly-typed IDs (see `xxx` comments in source). This risks confusion or errors if indices are misaligned.
- **`InceptionDate` defaults to `DateTime.Now`**
If constructed via the default constructor, `InceptionDate` reflects the current time—not the serialization time. Only the `Event(Test, ...)` constructor sets it from the `Test.InceptionDate`.
- **`IsSlice6DBModule` is case-sensitive on `"slice6db module"`**
Uses `ToLower()` for comparison, but the literal string is lowercase. If the source description varies in casing (e.g., `"Slice6DB Module"`), it may not match.
- **Zeroing window validation is complex and fragile**
`ChannelsWithActiveInvalidZeroingWindows` performs multiple checks (negative indices, window outside data range). Edge cases (e.g., empty `TriggerSampleNumbers`, zero sample rate) are not explicitly handled beyond defaulting to `0`.
- **`PurgeUnconfiguredChannels` modifies `Modules` in-place**
Called during `ToDtsSerializationTest`, this permanently removes channels. If the `Event` object is reused, data may be lost.
- **`IsDummyChannel` and `IsSlice6DBModule` use string comparisons**
Relies on literal string matching (`"dummy arm channel"`, `"slice6db module"`). No constants or enums are defined for these.
- **`IsG5` checks only serial number prefix**
Assumes `"5M"` prefix is sufficient to identify G5 devices. May be brittle if serial number formats change.
- **No thread safety**
Comments in `Event.cs` explicitly note: *"Also need to add thread protection."* and *"Can we set locks in the property accessors..."* — no synchronization is present.
- **`TestInformation` is private and not exposed**
While used internally, it is not part of the public API. Its properties (`Id`, `Description`) are not validated beyond assignment.
- **`TooLargeFor32BitVisualizationBytesPerSampleThreshold` is hardcoded to `2.0`**
The justification in comments is detailed, but the value is not configurable at runtime (only via reflection or subclassing).