Files
DP44/enriched-qwen3-coder-next/DataPRO/DataPRO/Controls/Downloads.md
2026-04-17 14:55:32 -04:00

8.7 KiB
Raw Blame History

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
DataPRO/DataPRO/Controls/Downloads/SimpleDownloadOptions.xaml.cs
2026-04-16T04:16:58.151139+00:00 Qwen/Qwen3-Coder-Next-FP8 1 3bde5e65d5656708

Downloads

Purpose

The SimpleDownloadOptions user control provides the UI and logic for configuring region-of-interest (ROI) and event-based download parameters in the DataPRO application. It enables users to define, validate, and manage one or more ROIs (each with start/end time, channel selection, and suffix), display associated event metadata, and enforce constraints based on the current recording mode, data boundaries, and test setup configuration. It serves as a dedicated page in a multi-step download workflow, integrating with Prism/Unity DI for view model resolution and leveraging shared interfaces (IRegionOfInterestChannelsViewModel, IRegionOfInterest, IDownloadEvent) to decouple UI from domain logic.


Public Interface

Constructor

  • SimpleDownloadOptions()
    Initializes the control, registers AddROICommand and RemoveROICommand as routed commands bound to AddROI and RemoveROI handlers, and calls InitializeComponent().

Properties

  • Visibility RoiVisibility { get; set; }
    Controls visibility of the ROI selection UI (bound via INotifyPropertyChanged).
  • Visibility EventDetailsVisibility { get; set; }
    Controls visibility of event details UI.
  • Visibility DataDetailsVisibility { get; private set; }
    Controls visibility of data summary (start/end, sample rate, etc.); set to Visible after Initialize.
  • Visibility ChannelDetailsVisibility { get; private set; }
    Controls visibility of channel-specific ROI details; set to Visible only when RegionsOfInterest.Count > 1.
  • string DownloadPath { get; private set; }
    Full path to the default download folder (set in Initialize).
  • double DataStart { get; private set; }
    Start time (in seconds) of the available data window.
  • double DataEnd { get; private set; }
    End time (in seconds) of the available data window.
  • double PreTriggerSeconds { get; private set; }
    Pre-trigger buffer duration (negative start offset for circular/active modes).
  • double PostTriggerSeconds { get; private set; }
    Post-trigger buffer duration (positive end offset for recorder/active modes).
  • double SampleRateAggregate { get; private set; }
    Aggregate sample rate across DAS units; NaN if inconsistent.
  • string SPSText { get; }
    Human-readable sample rate string (e.g., "1,000" or "Multiple sample rates" if NaN).
  • RecordingModes RecordingMode { get; private set; }
    Current recording mode (e.g., CircularBuffer, Recorder).
  • BindingList<IRegionOfInterest> RegionsOfInterest { get; private set; }
    List of ROI definitions (populated in Initialize).
  • BindingList<IDownloadEvent> EventsToDownload { get; private set; }
    List of events to download (populated in Initialize).

Methods

  • void SetEnabled(bool bEnable)
    Enables/disables the control on the UI thread; skips if CurrentUser is null. Uses Dispatcher for cross-thread safety.
  • void SetParent(object o)
    Delegates to _roiChannelsVm.SetParent(o) (if _roiChannelsVm is initialized).
  • void StartSearch(string term)
    Delegates to _roiChannelsVm.Filter(term) (if _roiChannelsVm is initialized).
  • bool ValidatePage(double PreTriggerSeconds, double PostTriggerSeconds, RecordingModes recordingMode, ref List<string> errors)
    Validates ROI and channel configurations. Calls ValidateROIControl and _roiChannelsVm.Validate(ref errors). Returns false if any validation error is added to errors.
  • void ClearView()
    Resets all UI state: clears RegionsOfInterest/EventsToDownload, sets DataStart/DataEnd/PreTriggerSeconds/PostTriggerSeconds to 0, resets RecordingMode to CircularBuffer, and collapses DataDetailsVisibility, ChannelDetailsVisibility, and RoiVisibility.
  • void Initialize(double dataStart, double dataEnd, double preTrigger, double postTrigger, RecordingModes recordingMode, BindingList<IRegionOfInterest> regionsOfInterest, BindingList<IDownloadEvent> eventsToDownload, Dictionary<string, IDASHardware> hardwareLookup, TestTemplate testTemplate, IReadOnlyDictionary<int, double> eventLengthByIndex)
    Populates control state: sets data boundaries, sample rate, recording mode, and ROI/event lists; resolves and initializes _roiChannelsVm; computes SampleRateAggregate; sets DownloadPath; configures event lengths; and triggers property change notifications.

Commands

  • RoutedCommand AddROICommand { get; }
    Command bound to AddROI handler; adds a new ROI with default suffix, start/end offsets, and all channels.
  • RoutedCommand RemoveROICommand { get; }
    Command bound to RemoveROI handler; removes the ROI from RegionsOfInterest (extracted from e.OriginalSource), resets suffix if only one ROI remains.

Invariants

  • RegionsOfInterest must contain at least one enabled ROI (validated in ValidateROIControl).
  • ROI suffixes must be unique (validated by checking GroupBy(roi => roi.Suffix).Count() == RegionsOfInterest.Count).
  • For enabled ROIs: Start < End (errors added if Start == End or Start > End).
  • For enabled ROIs in non-hybrid modes:
    • Circular buffer modes: ROI duration (|End - Start|) ≤ PreTriggerSeconds + PostTriggerSeconds.
    • Circular buffer/Active modes: roi.Start ≥ -PreTriggerSeconds (start time not before data window).
    • Recorder modes: roi.Start ≤ PostTriggerSeconds (start time within data window).
    • Active modes: roi.Start ≥ DataStart (start time not before available data).
  • For multiple ROIs: Each enabled ROI must include at least one channel (roi.ChannelIds.Any() or roi.ChannelNames.Contains(chanName)).
  • All non-blank, non-digital-out channels in _currentTestSetup must be included in at least one enabled ROI (validated via channel lookup against ROI channel IDs/names).
  • DataDetailsVisibility is Visible only after Initialize completes.
  • ChannelDetailsVisibility is Visible only when RegionsOfInterest.Count > 1.

Dependencies

  • External Libraries/Namespaces:
    • System, System.Windows, System.ComponentModel, Prism.Ioc, Unity (for DI via ContainerLocator.Container).
    • DTS.Common.* (enums: RecordingModes, DASFactory, Sensors; interfaces: IRegionOfInterestChannelsViewModel, IRegionOfInterest, IDownloadEvent; classes: TestTemplate, SensorConstants, StringResources).
  • Internal Dependencies:
    • SimpleDownloadOptions.xaml (XAML file defining UI layout).
    • IRegionOfInterestChannelsView/IRegionOfInterestChannelsViewModel (resolved via Unity; manages channel selection UI).
    • TestTemplate (used for channel/ROI validation and hardware lookup).
    • IDASHardware (used to compute sample rate and filter DAS units).
  • Consumers:
    • Likely consumed by a parent wizard/page (via SetParent(object o) and StartSearch(string term)).
    • ValidatePage is called by a higher-level validator (e.g., download wizard step).

Gotchas

  • Channel ID vs. Channel Name Fallback: For multiple ROIs, validation checks ChannelIds first; if null/empty, falls back to ChannelNames (legacy DB compatibility). This is explicitly commented (see code comments referencing issues #13914, #14060, #30129).
  • Sample Rate Aggregation: SampleRateAggregate is set to NaN if any DAS unit has a different sample rate (not just "care about sample rate" units). The loop skips units where !d.CareAboutSampleRate, but if all units are skipped, SampleRateAggregate remains the first DASs rate (potentially misleading).
  • ROI Channel Validation Logic:
    • For multiple ROIs, channel validation assumes all channels must be covered across ROIs (not per-ROI).
    • Special handling for TSR AIR and voltage insertion channels (e.g., stripping Assigned by ID prefix, parent DAS name).
  • Event Length Population: eventLengthByIndex uses 0-based indexing (downloadEvent.EventNumber - 1), but event numbers are typically 1-based.
  • Thread Safety: SetEnabled uses Dispatcher for thread safety, but other properties (e.g., RegionsOfInterest) are modified directly without thread checks.
  • Hardcoded Default: RecordingMode resets to CircularBuffer in ClearView() (not configurable).
  • Expander Height Management: GridLengthConverter is used to set row heights for ROI/event expanders (hardcoded "4*"/"Auto"), which may conflict with layout changes in XAML.
  • No-Op in SetEnabled: If CurrentUser is null, SetEnabled silently returns without setting IsEnabled.