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,47 @@
---
source_files:
- DataPRO/Modules/RegionOfInterest/RegionOfInterestChannels/Properties/AssemblyInfo.cs
generated_at: "2026-04-17T16:29:51.547543+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "32704f1fe9f321d7"
---
# Properties
### Purpose
This module contains the assembly metadata configuration for the `RegionOfInterestChannels` assembly. It is a standard .NET Properties folder that defines assembly identity, versioning information, and COM visibility settings through assembly-level attributes. This module exists to provide build-time configuration and does not contain executable logic.
### Public Interface
No public types or functions are exposed. This module consists entirely of assembly-level attributes:
- `AssemblyTitle` - Set to "RegionOfInterestChannels"
- `AssemblyDescription` - Empty
- `AssemblyConfiguration` - Empty
- `AssemblyCompany` - Empty
- `AssemblyProduct` - Set to "RegionOfInterestChannels"
- `AssemblyCopyright` - Set to "Copyright © 2018"
- `AssemblyTrademark` - Empty
- `AssemblyCulture` - Empty
- `ComVisible` - Set to `false`
- `Guid` - "bdb25406-3e28-4e62-ae2a-622120f933da"
- `AssemblyVersion` - "1.0.0.0"
- `AssemblyFileVersion` - "1.0.0.0"
### Invariants
- The assembly version and file version are synchronized at "1.0.0.0".
- COM visibility is disabled for all types in this assembly by default.
- The GUID "bdb25406-3e28-4e62-ae2a-622120f933da" uniquely identifies this assembly's type library.
### Dependencies
**Imports:**
- `System.Reflection`
- `System.Runtime.CompilerServices`
- `System.Runtime.InteropServices`
**Dependents:** Unclear from source alone - this is a properties module that would be referenced by any project consuming the RegionOfInterestChannels assembly.
### Gotchas
None identified from source alone. This is standard boilerplate assembly metadata.
---

View File

@@ -0,0 +1,24 @@
---
source_files:
- DataPRO/Modules/RegionOfInterest/RegionOfInterestChannels/Resources/TranslateExtension.cs
- DataPRO/Modules/RegionOfInterest/RegionOfInterestChannels/Resources/StringResources.Designer.cs
generated_at: "2026-04-17T16:28:42.807502+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "d7f01f47dc29f209"
---
# Resources
### Purpose
This module provides localization infrastructure for the RegionOfInterestChannels subsystem. It includes a WPF markup extension for XAML-based string localization and a strongly-typed resource class containing user-facing messages related to channel-to-ROI (Region of Interest) assignments and validation warnings.
### Public Interface
**`TranslateExtension` (class, inherits `MarkupExtension`)**
- `public TranslateExtension(string key)` — Constructor accepting a resource key.
- `public override object ProvideValue(IServiceProvider serviceProvider)` — Returns localized string for the key, or `"#stringnotfound# <key>"` if not found. Returns `"#stringnotfound#"` if key is null or empty.
- Decorated with `[MarkupExtensionReturnType(typeof(string))]` for XAML type safety.
**`StringResources` (internal sealed class)**
- `internal static global::System.Resources.Resource

View File

@@ -0,0 +1,97 @@
---
source_files:
- DataPRO/Modules/RegionOfInterest/RegionOfInterestChannels/View/StateListIndexConverter.cs
- DataPRO/Modules/RegionOfInterest/RegionOfInterestChannels/View/RegionOfInterestChannelsView.xaml.cs
- DataPRO/Modules/RegionOfInterest/RegionOfInterestChannels/View/RegionOfInterestChannelsDataTemplateSelector.cs
- DataPRO/Modules/RegionOfInterest/RegionOfInterestChannels/View/GridViewColumns.cs
generated_at: "2026-04-17T15:54:07.829323+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "3a91a38b574329b5"
---
# RegionOfInterestChannels View Module Documentation
## 1. Purpose
This module provides the WPF view layer for the Region of Interest Channels feature. It implements a dynamic, data-driven `GridView` system where columns are generated at runtime based on a source collection, with specialized column headers for searching (string columns) and select-all functionality (boolean columns). The module includes a `DataTemplateSelector` for rendering different cell types (text vs. checkbox), a multi-value converter for state lookup by index, and attached properties that enable declarative column configuration in XAML.
---
## 2. Public Interface
### StateListIndexConverter
**Implements:** `IMultiValueConverter`
| Method | Signature | Behavior |
|--------|-----------|----------|
| `Convert` | `object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)` | Expects exactly 2 values: `values[0]` as `IEnumerable<State>` and `values[1]` as `int` index. Returns the `State` element at that index, or `null` if validation fails. |
| `ConvertBack` | `object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)` | Throws `NotImplementedException`. |
---
### RegionOfInterestChannelsView
**Implements:** `IRegionOfInterestChannelsView`
| Method | Signature | Behavior |
|--------|-----------|----------|
| Constructor | `RegionOfInterestChannelsView()` | Calls `InitializeComponent()`. |
| `GridViewColumnHeader_OnClick` | `void GridViewColumnHeader_OnClick(object sender, RoutedEventArgs e)` | Extracts column tag from `GridViewColumnHeaderSearchable` or `GridViewColumnHeaderSelectable` (via sender or visual tree traversal), casts `DataContext` to `IRegionOfInterestChannelsViewModel`, and calls `vm.Sort(columnTag, true)`. |
| `TextBlock_Loaded` | `void TextBlock_Loaded(object sender, RoutedEventArgs e)` | Auto-expands column width if the loaded `TextBlock` is wider than the current column width. Forces re-measure by setting `Width` to `ActualWidth` then back to `double.NaN`. |
---
### RegionOfInterestChannelsDataTemplateSelector
**Inherits:** `DataTemplateSelector`
| Property | Type | Description |
|----------|------|-------------|
| `TextBlockDataTemplate` | `DataTemplate` | Template for string-type cells. |
| `CheckBoxDataTemplate` | `DataTemplate` | Template for boolean-type cells. |
| Method | Signature | Behavior |
|--------|-----------|----------|
| `SelectTemplate` | `DataTemplate SelectTemplate(object item, DependencyObject container)` | For `ChannelEnabler` items: traverses the visual tree to find the column index, uses reflection to get the property type from the column header, and returns the appropriate template. Sets `container.Tag` to either the property value (for strings) or the column offset index (for booleans). Returns `TextBlockDataTemplate` for non-`ChannelEnabler` items. |
---
### GridViewColumns (Static Class)
Provides attached properties for dynamic `GridView` column generation.
| Attached Property | Type | Target | Description |
|-------------------|------|--------|-------------|
| `ColumnsSource` | `object` | `GridView` | Source collection for dynamic column generation. Changes trigger column creation/removal. |
| `CellDataTemplateSelector` | `DataTemplateSelector` | `GridView` | Selector used to choose cell templates. Takes precedence over `CellDataTemplate`. |
| `CellDataTemplate` | `DataTemplate` | `GridView` | Default cell template. |
| `HeaderTextMember` | `string` | `GridView` | Property name on column source items to use for header text. |
| `DisplayMember` | `string` | `GridView` | Property name for display binding (currently commented out in implementation). |
| Private Method | Behavior |
|----------------|----------|
| `ColumnsSourceChanged` | Clears existing columns, removes old handlers, adds new handlers, and creates columns from the new source. |
| `CreateColumn` | Creates a `GridViewColumn` with header type determined by `MemberType`: `bool``GridViewColumnHeaderSelectable`, `string``GridViewColumnHeaderSearchable`, default → plain string. Wires up `SelectAll`, `Search`, and `ClickHandler` events. |
| `ColumnsSource_CollectionChanged` | Handles `Add`, `Move`, `Remove`, `Replace`, `Reset` actions to synchronize `GridView.Columns` with the source collection. |
| `GetArrayIndex` | Parses an array index from a string in format `...[n]...`. Returns `-1` on parse failure. |
---
## 3. Invariants
1. **StateListIndexConverter input contract:** `values` must be non-null, have length exactly 2, `values[0]` must be `IEnumerable<State>`, `values[1]` must be `int`, and the index must be within bounds of the collection. Violation returns `null`.
2. **GridViewColumns registration:** The static dictionary `_gridViewsByColumnsSource` maintains a mapping from `ICollectionView` to `List<GridView>`. All `GridView`s sharing the same `ColumnsSource` will be synchronized on collection changes.
3. **Column header type mapping:** Column headers are created based on `MemberType` property of the column source:
- `typeof(bool)``GridViewColumnHeaderSelectable`
- `typeof(string)``GridViewColumnHeaderSearchable`
- Other → plain `string` header
4. **Template precedence:** In `CreateColumn`, the comment explicitly states: `selector < template < displaymember` (selector takes highest precedence).
5. **DataTemplateSelector column detection:** `RegionOfInterestChannelsDataTemplateSelector.SelectTemplate` assumes the column header's `ToString()` (with spaces removed) matches a property name on `ChannelEnabler`.
---
## 4. Dependencies
### This

View File

@@ -0,0 +1,222 @@
---
source_files:
- DataPRO/Modules/RegionOfInterest/RegionOfInterestChannels/ViewModel/RegionOfInterestChannelsViewModel.cs
generated_at: "2026-04-17T16:01:10.834469+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "d3277795540da0ac"
---
# RegionOfInterestChannelsViewModel Documentation
## 1. Purpose
This module provides a ViewModel for managing Region of Interest (ROI) channel selections within a data acquisition/testing system. It handles the display, filtering, sorting, and selection of channels that can be associated with multiple regions of interest. The ViewModel supports two distinct data sources: live test setups (via `SetGroups`) and recorded test data (via `SetTest`), presenting channels in a configurable grid with ROI-specific checkbox columns for channel inclusion.
## 2. Public Interface
### RegionOfInterestChannelsViewModel (implements IRegionOfInterestChannelsViewModel)
**Constructor:**
```csharp
public RegionOfInterestChannelsViewModel(
IRegionOfInterestChannelsView view,
Prism.Regions.IRegionManager regionManager,
Prism.Events.IEventAggregator eventAggregator,
Unity.IUnityContainer unityContainer)
```
Initializes the ViewModel, wires up view DataContext, creates interaction requests, subscribes to `RaiseNotification` and `BusyIndicatorChangeNotification` events, and initializes `RegionsOfInterest` as an empty `BindingList<IRegionOfInterest>`.
**Properties:**
| Property | Type | Description |
|----------|------|-------------|
| `IsDirty` | `bool` | Indicates unsaved changes (private setter). |
| `IsBusy` | `bool` | Controls busy indicator state. |
| `IsMenuIncluded` | `bool` | Menu inclusion flag. |
| `IsNavigationIncluded` | `bool` | Navigation inclusion flag. |
| `View` | `IRegionOfInterestChannelsView` | Associated view instance. |
| `RegionsOfInterest` | `BindingList<IRegionOfInterest>` | Collection of ROIs; setter scrubs invalid channel references. |
| `AllChannelsUnfiltered` | `List<GroupChannel>` | All channels before filtering. |
| `AllChannels` | `ObservableCollection<GroupChannel>` | Channels displayed in UI (filtered). |
| `AllChannelSSNs` | `string[]` | Array of hardware\serialNumber strings for all channels. |
| `ChannelList` | `BindingList<ChannelEnabler>` | Grid data source with ROI checkbox states. |
| `Columns` | `ObservableCollection<ColumnDescriptor>` | Dynamic column definitions for grid. |
| `NotificationRequest` | `InteractionRequest<Notification>` | Prism interaction request for notifications. |
| `ConfirmationRequest` | `InteractionRequest<Confirmation>` | Prism interaction request for confirmations. |
| `ISOViewMode` | `IsoViewMode` | Controls which channel naming convention to display. |
**Methods:**
```csharp
public void SetParent(object o)
```
Stores a parent object reference for event publishing context.
```csharp
public void SetTest(string path, IsoViewMode viewMode)
```
Loads test data from file path for export/viewing scenarios. Populates `_testSummary` and builds channel list from `ITestChannel` objects.
```csharp
public void SetGroups(ITestSetup testSetup, Dictionary<string, IDASHardware> serialNumberToHardware, IsoViewMode viewMode)
```
Primary initialization for test setup scenarios. Processes groups, channels, and hardware assignments. Detects and reports phantom DAS channel assignments.
```csharp
public void Filter(string term)
```
Sets search term and applies filtering.
```csharp
public void SetFilter(PossibleFilters bridgeFilter)
```
Sets bridge filter type and applies filtering.
```csharp
public void Filter(object tag, string term)
```
Sets field-specific filter (tag parsed as `Fields` enum) and applies filtering.
```csharp
public void ClearAllFilters()
```
Clears all field-based filters.
```csharp
public void Sort(object o, bool bColumnClick)
```
Sorts `ChannelList` by specified field. Toggles ascending/descending on repeated column clicks.
```csharp
public void SelectAll(int roiIndex, bool selection)
```
Sets all channel checkboxes for a specific ROI index to the given selection state.
```csharp
public bool Validate(ref List<string> errors)
```
Returns `true` (no validation implemented).
**Events:**
- `PropertyChanged` - Standard `INotifyPropertyChanged` implementation.
---
### ChannelEnabler (public sealed, implements INotifyPropertyChanged)
Represents a single row in the channel grid with ROI inclusion states.
**Properties:**
| Property | Type | Description |
|----------|------|-------------|
| `LastIndexChanged` | `int` | Index of last changed ROI checkbox. |
| `ROIIncludes` | `BindingList<State>` | Checkbox states per ROI. |
| `UserCode`, `UserChannelName`, `ChannelName` | `string` | User-defined channel identifiers. |
| `GuidString` | `string` | Unique identifier for this row. |
| `ChannelId` | `long` | Numeric channel ID. |
| `ISOCode`, `ISOChannelName` | `string` | ISO standard identifiers. |
| `Hardware`, `SerialNumber`, `SensorName` | `string` | Hardware/sensor info. |
| `DASSerialNumber`, `SampleRate`, `DisplayUnits` | `string` | DAS and measurement info. |
| `Code`, `GroupName` | `string` | Additional identifiers. |
**Methods:**
```csharp
public string GetChannelName(IsoViewMode isoViewMode)
```
Returns appropriate channel name based on `IsoViewMode`.
---
### State (public sealed, implements INotifyPropertyChanged)
Boolean checkbox state wrapper.
**Constructor:** `public State(bool c)`
**Properties:**
- `Checked` (bool) - Checkbox state.
**Methods:**
- `public void Toggle()` - Inverts `Checked`.
---
### ROIChannelEnabler (public sealed, implements INotifyPropertyChanged)
**Constructor:** `public ROIChannelEnabler(string suffix, string channel, bool enabled)`
**Properties:** `ROISuffix`, `ChannelName`, `IsEnabled` (all string/bool with change notification).
---
### ColumnDescriptor (public sealed)
**Properties:** `HeaderText` (string), `DisplayMember` (string), `MemberType` (Type).
---
### Fields (public enum)
Values: `ChannelName`, `DisplayName`, `SerialNumber`, `SensorName`, `DASSerialNumber`, `SampleRate`, `ISOCode`, `DisplayUnits`, `GroupName`, `ROIIncludes`.
---
### ChannelEnablerComparer (sealed, IComparer<ChannelEnabler>)
Internal comparer for sorting `ChannelEnabler` instances by any `Fields` value via reflection.
## 3. Invariants
1. **Channel ID Format Compatibility:** `ParseChannelId` must handle both legacy format (`<name>_<index>_<uniqueId>` or GUID-based) and current format (numeric only). Returns `-1` on parse failure.
2. **Channel Exclusion Rules:** Channels with `IsDisabled == true` or `SensorId < 0` are always excluded from processing and display.
3. **Digital Output Exclusion:** Channels with `IsDigitalOutput()` or `IsTestSpecificDigitalOutput` are scrubbed from ROI lists (FB14896).
4. **ROI-Channel Synchronization:** `ChannelEnabler.ROIIncludes` count must equal `_regionsOfInterest.Count`. Each index corresponds to the ROI at that index.
5. **Event Handler Lifecycle:** `ChannelList` setter detaches previous list's `ListChanged` handler before attaching to new list.
6. **Column Generation Order:** Columns are generated in fixed order: Group Name → User/ISO codes (based on `ISOViewMode`) → Hardware → Serial Number → Sensor Name → DAS Serial Number → Sample Rate → Display Units → ROI columns (dynamic).
## 4. Dependencies
**External Dependencies (from imports and usage):**
- `Prism.Regions.IRegionManager` - Region management for view composition
- `Prism.Events.IEventAggregator` - Event pub/sub for decoupled communication
- `Unity.IUnityContainer` - Dependency injection container
- `DTS.Common.Classes.Groups.GroupChannel` - Channel data model
- `DTS.Common.Enums.IsoViewMode` - Channel naming mode enum
- `DTS.Common.Enums.Sensors` / `DTS.Common.Enums.Hardware` - Enumeration types
- `DTS.Common.Events.RaiseNotification`, `BusyIndicatorChangeNotification`, `RegionOfInterestChannelsSelectedEvent`, `PageErrorEvent` - Event types
- `DTS.Common.Interface.*` - Various interfaces (channels, groups, ROI, test definition)
- `DTS.Common.Interactivity` - `InteractionRequest<T>`, `Notification`, `Confirmation`
- `DTS.SensorDB.SensorsCollection`, `DTS.SensorDB.SensorCalibrationList` - Sensor database access
- `DTS.Common.Classes.Viewer.TestMetadata.TestMetadataList` - Test metadata loading
- `DTS.Serialization.SliceRaw.File.PersistentChannel` - Channel persistence
**Dependents (inferred):**
- `IRegionOfInterestChannelsView` - The associated view
- Components publishing `RaiseNotification` and `BusyIndicatorChangeNotification` events
- Components subscribing to `RegionOfInterestChannelsSelectedEvent`
## 5. Gotchas
1. **Null `AllChannels` from Export Tile (13477):** When accessed from the export tile, `AllChannels` can be null. The `AllChannelSSNs` getter checks for this and falls back to `AllTestChannels`.
2. **Null `SensorData` in Download Route (18349):** In the download data route, `SensorData` can be null. Accessing it throws an exception. Code checks `if (null != ach.SensorData)` before access.
3. **Legacy ChannelId Parsing (44068):** Older `.dts` files have ChannelId formats like `"H3-3ch_0_2"` or `"f9f0bfe8-afc4-4730-8045-8f1e45340573_0_8533"`. Current format is just the unique number. `ParseChannelId` handles both.
4. **Channel Name Scrubbing (FB16120):** The `RegionsOfInterest` setter scrubs channel names not found in `AllChannelsUnfiltered` to handle bad/corrupt data.
5. **Embedded Channel Hardware Resolution:** Channels with `IsTestSpecificEmbedded` require special hardware resolution via `TestTemplateBase.GetEmbeddedChannelHardware()` rather than using `ch.Hardware` directly.
6. **"Assigned by ID" Prefix Stripping:** Hardware strings may have a leading "Assigned by ID" prefix that must be stripped via `RegionOfInterest.RemoveAssignedByIDFromHardwareString()`.
7. **Phantom DAS Assignment Detection:** `SetGroups` detects channels with `DASId > 0` but `DASChannelIndex < 0` and publishes a `PageErrorEvent` with `StringResources.PhantomDASChannelAssignment`.
8. **Sort Toggle Behavior:** When sorting, if the list is already in the target order (detected via `SequenceEqual`), the sort direction is automatically flipped for the user.
9. **Calibration Caching (FB18875):** Sensor calibrations are cached via `GetLatestCalibrations()` for performance, but are noted as not needed for ROI view.
10. **CURRENT_SUFFIX Handling:** `ParseChannelId` strips `DTS.Common.Constants.CURRENT_SUFFIX` from channel IDs before parsing.