124 lines
10 KiB
Markdown
124 lines
10 KiB
Markdown
|
|
---
|
|||
|
|
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 channel’s 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.
|