Files
2026-04-17 14:55:32 -04:00

124 lines
10 KiB
Markdown
Raw Permalink 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/Classes/TMAT/TmtSingleFile.cs
- Common/DTS.Common/Classes/TMAT/TmtSplitFiles.cs
- Common/DTS.Common/Classes/TMAT/TMTBase.cs
generated_at: "2026-04-16T03:16:31.984201+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "39a472cd530a38e8"
---
# Documentation: TMATS Template Handling Module
## 1. Purpose
This module provides functionality for reading, updating, and serializing TMATS (Test Measurement and Test Specification) template files used in DAS (Data Acquisition System) configuration workflows. It supports two template formats—single-file (`TmtSingleFile`) and split-file (`TmtSplitFile`)—and abstracts the underlying file structure through a common interface (`ITMTTemplate`) and base class (`TmtBase`). The module enables dynamic substitution of predefined placeholder patterns (e.g., `{TEST ID}`, `{{CHANNEL {0} NAME}}`) with runtime values, ensuring generated test configurations conform to TMATS specifications.
## 2. Public Interface
### Enums (used in interface methods)
- **`TMTGlobalKeys`**
Enum of global (non-channel-specific) placeholder keys. Each field is annotated with a `[TMTKey(...)]` attribute specifying the literal pattern to search for in template files (e.g., `{TEST ID}`, `{DAS SERIAL NUMBER}`). Used in `UpdateValue(TMTGlobalKeys, string)`.
- **`TMTChannelKeys`**
Enum of channel-specific placeholder keys for *single-file* templates. Each field uses a format string with `{0}` for channel number (e.g., `{{CHANNEL {0} NAME}}`). Used in `UpdateValue(TMTChannelKeys, string, int)`.
- **`TMTChannelKeysEx`**
Enum of channel-specific placeholder keys for *split-file* templates. Keys use simpler, non-formatted patterns (e.g., `{CHANNEL NAME}`, `{CHANNEL NUMBER}`). Used in `UpdateValue(TMTChannelKeysEx, string, int)`.
### Classes
#### `TMTKey` (Helper class)
- **`public static string GetKey(TMTGlobalKeys key)`**
Returns the literal pattern string associated with the given `TMTGlobalKeys` enum value (e.g., `"TEST ID}"``"{TEST ID}"`).
- **`public static string GetKey(TMTChannelKeysEx key)`**
Returns the literal pattern string for `TMTChannelKeysEx` keys.
- **`public static string GetKey(TMTChannelKeys key, int channelNumber)`**
Returns the formatted pattern string for `TMTChannelKeys` keys, substituting `{0}` with `channelNumber` (e.g., `"{CHANNEL {0} NAME}"``"{CHANNEL 1 NAME}"` for `channelNumber=1`).
#### `TmtBase` (Abstract base class)
- **`public static string TMT_LimitString(string s)`**
Truncates input string `s` to a maximum of 200 characters (per `TMT_MAX_CHANNEL_LENGTH`). Used to enforce TMATS file length constraints.
- **`public static void UpdateChannelField(...)`**
High-level helper to update a single channel field in a template. Handles type-specific formatting (e.g., scaling, signedness, masking via `RunTestVariables.MaskEUMetaData`). Calls `template.UpdateValue(...)` internally.
- **`public static void UpdateGlobalField(...)`**
High-level helper to update a single global field in a template. Populates fields like serial number, sample rate, channel IDs, timestamps, etc., using data from `IDASCommunication`, `IConfigurationData`, and parameters. Calls `template.UpdateValue(...)` internally.
- **`public static int GetNumberOfStreamedChannels(IDASCommunication das)`**
Returns the number of streamed channels based on hardware type and module configuration. Special handling for `SLICE6_AIR_TC` (hardcoded 24) and reconfigurable devices (e.g., TSR AIR).
- **Abstract methods (must be implemented by derived classes):**
- `public abstract void UpdateValue(TMTChannelKeysEx key, string value, int channelNumber);`
- `public abstract void UpdateValue(TMTGlobalKeys key, string value);`
- `public abstract void UpdateValue(TMTChannelKeys key, string value, int channelNumber);`
- `public abstract string[] GetAllLines();`
#### `TmtSingleFile` (Concrete implementation)
- **`public TmtSingleFile(string templateLocation)`**
Constructor. Reads all lines from `templateLocation` into an internal `_allLines` list. Does *not* throw if file is missing; `_allLines` remains empty.
- **`public override void UpdateValue(TMTChannelKeysEx key, string value, int channelNumber)`**
Replaces *all* occurrences of `pattern = TMTKey.GetKey(key)` in `_allLines` with `value`. Does *not* consider channel context—applies to *all* matching lines.
- **`public override void UpdateValue(TMTGlobalKeys key, string value)`**
Replaces *all* occurrences of `pattern = TMTKey.GetKey(key)` in `_allLines` with `value`.
- **`public override void UpdateValue(TMTChannelKeys key, string value, int channelNumber)`**
Replaces *all* occurrences of `pattern = TMTKey.GetKey(key, channelNumber)` in `_allLines` with `value`.
- **`public override string[] GetAllLines()`**
Returns a copy of `_allLines` as an array.
#### `TmtSplitFile` (Concrete implementation)
- **`public TmtSplitFile(string dasTemplate, string channelTemplate)`**
Constructor. Reads global lines from `dasTemplate` into `_lines`, and channel template lines from `channelTemplate` into `_channelTemplate`. Does *not* throw if files are missing; corresponding lists remain empty.
- **`public override string[] GetAllLines()`**
Returns concatenation of `_lines` (global section) followed by channel sections for all channel numbers present in `_allChannels`. Channel sections are inserted in ascending numeric order (from `min` to `max` key). If no channels exist, returns only `_lines`.
- **`public override void UpdateValue(TMTChannelKeysEx key, string value, int channelNumber)`**
Ensures a channel entry exists for `channelNumber` in `_allChannels` (via `AddChannelIfNeeded`), then replaces *all* occurrences of `pattern = TMTKey.GetKey(key)` in that channels line list with `value`.
- **`public override void UpdateValue(TMTGlobalKeys key, string value)`**
Replaces *all* occurrences of `pattern = TMTKey.GetKey(key)` in `_lines` with `value`.
- **`public override void UpdateValue(TMTChannelKeys key, string value, int channelNumber)`**
Replaces *all* occurrences of `pattern = TMTKey.GetKey(key, channelNumber)` in `_lines` (global section) with `value`.
⚠️ **Note**: This method does *not* operate on per-channel data in `_allChannels`—it updates the global template file.
## 3. Invariants
- **Template file existence is not enforced**: Constructors for both `TmtSingleFile` and `TmtSplitFile` silently proceed if the specified file(s) do not exist, resulting in empty `_allLines`/`_lines`/`_channelTemplate` lists.
- **Pattern matching is substring-based**: `Contains(pattern)` is used to locate lines for replacement. This may cause unintended matches if patterns are substrings of unrelated text (e.g., `{NAME}` would match `{NAME OF PROGRAM}`).
- **All replacements are global per line list**: Each `UpdateValue` call replaces *every* occurrence of the pattern in the relevant line collection (e.g., all lines in `_allLines` for `TmtSingleFile`). There is no support for updating only the *first* occurrence or a specific line index.
- **Channel keys for split files are stored separately**: In `TmtSplitFile`, `TMTChannelKeysEx` updates affect per-channel data in `_allChannels`, while `TMTChannelKeys` updates affect only the global `_lines`.
- **Channel numbering is 1-based**: `UpdateChannelField` uses `1 + channelIndex` for `TMTChannelKeysEx.ChannelNumber`.
- **String length is capped at 200 characters**: `TMT_LimitString` enforces this limit for channel names and other string fields.
## 4. Dependencies
- **Enums**: `DTS.Common.Enums.DASFactory.TMTGlobalKeys`, `DTS.Common.Enums.DASFactory.TMTChannelKeys`, `DTS.Common.Enums.DASFactory.TMTChannelKeysEx` (defined in same file).
- **Interfaces**: `DTS.Common.Interface.DASFactory.IDASCommunication`, `DTS.Common.Interface.DASFactory.Config.IConfigurationData`.
- **Constants/Types**: `DTS.Common.Enums.DASFactory.DFConstantsAndEnums.ModuleType`, `DTS.Common.Enums.Hardware.HardwareTypes`, `DTS.Common.Constants.Constants.UDP_STREAM_CH10_TF2`, `RunTestVariables` (static class with `MaskEUMetaData` field).
- **System**: `System.IO.File`, `System.Collections.Generic`, `System.Linq`, `System.Reflection`, `System.DateTime`.
- **Consumers**: This module is used by higher-level code that generates TMATS files (e.g., test execution or configuration tools), likely via `TmtBase.UpdateChannelField` and `TmtBase.UpdateGlobalField`.
## 5. Gotchas
- **`TMTChannelKeys` in `TmtSplitFile` updates global lines, not per-channel lines**: Calling `UpdateValue(TMTChannelKeys, ...)` on a `TmtSplitFile` instance updates the global template file (`_lines`), *not* the per-channel template (`_channelTemplate` or `_allChannels`). This is likely unintentional and may cause incorrect behavior if channel-specific global keys (e.g., `{{CHANNEL {0} NAME}}`) are expected to be updated per channel.
- **No validation of pattern existence**: `TMTKey.GetKey(...)` returns `string.Empty` if the enum value lacks a `[TMTKey]` attribute or reflection fails. This results in replacing empty strings (i.e., no-op or unintended global replacement).
- **Substring matching may cause false positives**: Using `Contains(pattern)` can match patterns embedded in other text (e.g., `{CHANNEL 1 NAME}` would match lines containing `{{CHANNEL 10 NAME}}`).
- **Channel numbering assumptions**: `GetNumberOfStreamedChannels` assumes specific hardware types and module counts. The logic for reconfigurable devices (e.g., TSR AIR) is hardcoded and may not cover all future configurations.
- **No error handling for file I/O**: `File.ReadAllLines` may throw `IOException` or `UnauthorizedAccessException`, but these are not caught or handled.
- **`_allChannels` dictionary may have gaps**: `GetAllLines` iterates from `min` to `max` key, inserting only existing channels. If channels 1, 2, and 5 exist, channels 3 and 4 are skipped—this may be intentional or a bug depending on TMATS spec requirements.
- **`TMT_MAX_CHANNEL_LENGTH` is hardcoded**: While documented as 200 (increased from 50), this is not configurable and may need adjustment for future TMATS versions.