Files

144 lines
9.0 KiB
Markdown
Raw Permalink Normal View History

2026-04-17 14:55:32 -04:00
---
source_files:
- DataPRO/IService/StateMachine/StatusAndParameters/Realtime/RealtimeParameters.cs
- DataPRO/IService/StateMachine/StatusAndParameters/Realtime/RealtimeStatusInformation.cs
generated_at: "2026-04-16T04:01:39.522280+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "13ae579216023a96"
---
# Realtime
## Documentation: Realtime Parameters and Status Module
---
### 1. **Purpose**
This module encapsulates the configuration (`RealtimeParameters`) and runtime state management (`RealtimeStatusInformation`) for initiating and controlling *realtime data acquisition* in the DAS (Distributed Acoustic Sensing) system. It serves as the interface between the state machine and the underlying `RealtimeService`, handling parameter propagation, sample rate/AAF (Anti-Alias Filter) configuration, and synchronization primitives for starting/stopping realtime acquisition across multiple DAS units. It enables both single-sample and multi-sample polling modes, with configurable delays, channel selection, and hardware-specific AAF computation.
---
### 2. **Public Interface**
#### `RealtimeParameters` (class)
- **`List<IDASCommunication> UnitsToStartRealtime { get; set; }`**
List of DAS units to be started in realtime mode.
- **`int RealtimeDelayBetweenPollsInMilliSecond { get; set; }`**
Delay (in ms) between successive polling attempts during realtime acquisition.
- **`bool AllowMultipleSampleRealtime { get; set; }`**
Flag indicating whether multiple samples per poll are allowed.
- **`bool UseSingleSampleMode { get; set; }`**
Flag to enable single-sample mode (overrides multi-sample behavior).
- **`List<int> ModuleIndices { get; set; }`**
List of module indices to be used in realtime acquisition.
- **`Dictionary<IDASCommunication, byte[]> IdasToActiveChannels { get; set; }`**
Mapping from DAS unit to its active channel bitmask (each byte represents 8 channels).
- **`double RealtimeSampleRate { get; set; }`**
Target sample rate (Hz) for realtime acquisition.
- **`byte RealtimeSampleRateAAFilterRatio { get; set; }`**
Ratio used to compute AAF cutoff: `AAF = sampleRate / RealtimeSampleRateAAFilterRatio`.
- **`bool SliceTurnOffAAFRealtime { get; set; }`**
Flag to override AAF and disable it for hardware that supports it (see `DFConstantsAndEnums.SupportsTurnOffAAFRealtime`).
- **`void Reset()`**
Initializes all properties to default values (empty collections, zero numerics, `false` booleans).
#### `RealtimeStatusInformation` (class)
- **`bool IsInRealtime { get; }`**
Returns `true` if realtime acquisition is currently active (based on `stopRealtimeEvent` state). Uses a 2ms timeout for non-blocking check.
- **`void StopRealtime()`**
Signals termination of realtime acquisition by setting `stopRealtimeEvent`.
- **`void StartRealtime()`**
Overload that reads parameters from `States.Instance.Realtime.Status.RealtimeParams` and invokes the full `StartRealtime(...)` overload on a background `Task`.
- **`void StartRealtime(List<IDASCommunication> ldas, List<int> moduleArrayIndicies, bool useSingleSampleMode, double realtimeSampleRate, int realtimeDelayBetweenPolls, bool allowMultipleSampleRealtime, Action<double, double> SetRealtimeSampleRateAAF, Action CompleteAction, Dictionary<IDASCommunication, byte[]> idasToActiveChannels, Callback StartRealtimeCallback)`**
Core method that:
- Wraps `StartRealtimeCallback` in a `Callback` delegate and appends status completion/failure handlers.
- Resets `stopRealtimeEvent` and instantiates `RealtimeService`.
- If `useSingleSampleMode` is `true`: calls `RealtimeService.StartActivePolling(...)`.
- Else: calls `RealtimeService.Start(...)` with computed AAF via `GetRealtimeAAFForHardware`.
- Invokes `SetRealtimeSampleRateAAF` with `(sampleRate, AAF)` for the first DAS (or `NaN, NaN` if no DAS).
- Waits for either `stopRealtimeEvent` (external stop) or `mr` (service availability), then waits for `realtimeDoneFromService` (service completion).
- Logs exceptions, sets `CouldNotStartRealtime = true`, and always invokes `CompleteAction` in `finally`.
- **`Action<double, double> SetRealtimeSampleRateAAF { get; set; }`**
Callback to notify caller of current sample rate and computed AAF (used for UI updates or validation).
- **`Action CompleteAction { get; set; }`**
Action invoked upon completion (success or failure) of `StartRealtime(...)`.
- **`bool CouldNotStartRealtime { get; set; }`**
Set to `true` if an exception occurs during `StartRealtime(...)`.
- **`Callback StartRealtimeCallback { get; set; }`**
User-provided callback invoked by `RealtimeService` during acquisition.
- **`private float GetRealtimeAAFForHardware(IDASCommunication idas, double samplerate)`**
Computes AAF cutoff based on:
- If `SliceTurnOffAAFRealtime` is `true` *and* hardware supports it → returns `Common.Constants.SLICE2_NO_AAF_REALTIME_RATE`.
- Else if `RealtimeSampleRateAAFilterRatio == 0` → returns `samplerate`.
- Else → returns `samplerate / RealtimeSampleRateAAFilterRatio`.
- **`void Reset()`**
Clears `CompleteAction`, resets `realtimeDoneFromService`, sets `stopRealtimeEvent`, and clears `CouldNotStartRealtime`.
---
### 3. **Invariants**
- `RealtimeDelayBetweenPollsInMilliSecond` must be ≥ 0 (no validation enforced in code; assumed caller responsibility).
- `RealtimeSampleRateAAFilterRatio` must be ≥ 0 (zero implies AAF = sample rate).
- `RealtimeSampleRate` must be > 0 when `UseSingleSampleMode == false`, otherwise behavior is undefined (no explicit check).
- `UnitsToStartRealtime` and `IdasToActiveChannels` must be consistent: every `IDASCommunication` in `UnitsToStartRealtime` must have an entry in `IdasToActiveChannels` (no enforcement; caller responsibility).
- `ModuleIndices` is only used when `UseSingleSampleMode == false`.
- `IsInRealtime` is `true` iff `stopRealtimeEvent` is *not* signaled (i.e., `WaitOne(2, false)` returns `false`).
- `CompleteAction` is **always** invoked in `StartRealtime(...)`s `finally` block, regardless of success/failure.
- `realtimeDoneFromService.WaitOne()` is called *after* `stopRealtimeEvent.Set()` in `StartRealtime(...)`, ensuring the service has fully stopped before proceeding.
---
### 4. **Dependencies**
#### Dependencies *of this module*:
- **`DTS.Common.Interface.DASFactory.IDASCommunication`**: Interface for DAS units.
- **`DTS.Common.Enums.DASFactory.DFConstantsAndEnums`**: Used for `SupportsTurnOffAAFRealtime`.
- **`DTS.Common.Constants.SLICE2_NO_AAF_REALTIME_RATE`**: Hardcoded AAF value when AAF is disabled.
- **`DTS.DASLib.Service.StateMachine.States`**: Access to global state (`States.Instance.Realtime.Status.RealtimeParams`).
- **`DTS.DASLib.Service.RealtimeService`**: Core service for starting/stopping acquisition.
- **`DTS.Common.Interface.StatusAndProgressBar.Callback` & `CallbackData`**: For async completion callbacks.
- **`DTS.Common.Utilities.Logging.APILogger`**: For exception logging.
- **`System.Threading`**: `ManualResetEvent`, `Task`, `Thread`.
#### Dependencies *on this module*:
- **`RealtimeStatusInformation.StartRealtime()`** is invoked by the state machine (likely via `States.Instance.Realtime.Status.RealtimeStatus.StartRealtime()`).
- **`RealtimeParameters`** is used as `RealtimeStatus.RealtimeParams` (inferred from usage in `RealtimeStatusInformation`).
- **`SetRealtimeSampleRateAAF`** callback is likely implemented by UI or monitoring components to update sample rate/AAF displays.
---
### 5. **Gotchas**
- **`RealtimeDelayBetweenPollsInMilliSecond` is passed as `int` but may be interpreted as `ms` by `RealtimeService`** — ensure caller uses integer milliseconds (no fractional values).
- **`GetRealtimeAAFForHardware` uses only the *first DAS* (`ldas[0]`) to compute AAF** when setting `SetRealtimeSampleRateAAF`, even if multiple DAS units are present. This assumes identical AAF behavior across units (not validated).
- **`UseSingleSampleMode` bypasses AAF computation and calls `StartActivePolling`**, which may have different behavior than `Start` (e.g., no AAF, no module indices).
- **`RealtimeService.ServiceAvailable` event is subscribed inside `StartRealtime(...)`, but the wait loop (`mr.WaitOne`) may exit prematurely if `mr` is set before `stopRealtimeEvent` is signaled**, potentially leading to race conditions if `RealtimeService` becomes available slowly.
- **`stopRealtimeEvent` is set twice** — once in `StopRealtime()` and again in `StartRealtime(...)`s `finally` block. While idempotent for `ManualResetEvent`, this could confuse debugging.
- **No validation of `IdasToActiveChannels` entries** — e.g., mismatched channel counts or invalid bitmasks are not caught.
- **`CouldNotStartRealtime` is set on *any* exception**, but the `catch` block does *not* rethrow or provide structured error info — callers must inspect this flag after `StartRealtime`.
- **`Reset()` does *not* clear `SetRealtimeSampleRateAAF`, `CompleteAction`, or `StartRealtimeCallback`** — only `CompleteAction` is cleared in `Reset()`. Other properties retain their values unless explicitly overwritten.
None identified beyond these.