Skip to content

fix/improve the matching between emitted timing event Tags and corresponding detected sampled HW trigger edges in the picoscope block #168

Open
@wirew0rm

Description

@wirew0rm

goal: implement a robust, (stand-alone) unit-testable synchronisation flow so that each timing block emitted (UTC-based) event is aligned with sample-based edges (if hw_trigger == true) or mapped to equivalent sample indices (otherwise, i.e. if hw_trigger == false). Ensure that expired or impossible-to-match events are gracefully expired, and store clock-offset metadata when a valid match is found.
General sliding window time-synchronisation strategy:

  1. Extend Timing Event Structure
    * add local_time (uint64_t, nanoseconds since epoch, new default Tag definition) to each timing event Tag map referencing the earliest local clock when the event as been received from the timing receiver.
    * introduce trigger_meta_information::hw_trigger(bool) indicating whether the event is associated with a digital IO hardware trigger or not.
    * introduce trigger_meta_information::local_timing_clock_drift (uint64_t) storing the clock offset (in ns) between the tag source and local data stream.
  2. Time-to-Sample Mapping
    * for each data chunk (arriving at known intervals), compute the chunk’s local time range from the sampling rate and local host clock.
    * match events (hw_trigger == true) to hardware edges by aligning their “Timing Tag Timestamp” with edges in the chunk.
    * for events with no hardware trigger, map the event/tag to the corresponding sample index by comparing the time-stamps and counting samples to the nearest known matched HW trigger or absolute time reference.
  3. Edge Boundaries & Overlaps
    * overlapping triggers in the same sample range must be attached in sorted order (according to UTC/TAI receiver time) to that sample.
    * N.B. consider an overlap region or slightly enlarged chunk boundary so partial triggers are not lost.
  4. Data Loss / Stale Events
    * mark subsequent data as resync needed if chunks are missing to prevent incorrect matching.
    * discard or expire old events when their local_time timestamp falls too far behind the current chunk’s local time (configurable limit based on polling/chunk size).
  5. Clock Drift / Offset
    * track and periodically update local_timing_clock_drift to adjust for differences between the local clock and the timing tag source (i.e. poor-man's-clock-PLL).
    * events may be dropped or flagged for manual resynchronisation if mismatch is too large
  6. Multiple Overlapping Triggers
    * allow multiple TimingEvents to match a single hardware edge if their UTC time-stamps lie within the same sample.
  7. Testability and Composability
    * matcher logic must be standalone that accepts synthetic input events and sample data.
    * no direct hardware or chunk fetch calls inside the logic
  8. Performance Constraints
    * typical event rates of up to ~1 kHz are exepced. Should be manageable w.r.t. using queue-based or list-based matching but should nevertheless be optimised. goal: 1kHz trigger rate, ~250 MS/s sample rates, worst-case latency << 100 ms (for the digitizer block should probably < 10 ms to account for other delays/uncertainties in the chain).
  9. Additional Corner Cases to be considered:
    * multiple tags per single edge (overlapping triggers).
    * fewer or more edges than tags.
    * tags arriving too late (chunk already processed).
    * large drift and time-offsets between tag timestamps and local clock.
    * missing chunks causing partial or mismatched data.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Status

Finished Implementation (2)

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions