class.group_data - moduleus/urx GitHub Wiki

Group_data

URX class that contains the recording of a group execution.

Parameters

UAC URX Parameter Datatype Description
event_timestamps Array of array of double Timestamp, in [s], of each event recorded in the group. The first dimension represents the sequence-index, the second dimension represents the event-index.
Stored as a vector of vector of double.
group Reference to group Reference to the group in the acquisition.
Stored as a weak pointer from field groups of acquisition.
group_timestamp double Timestamp of this group_data, in [s]. Default NaN.
raw_data Array of int16 or int32 or float or double, real or complex Raw RF data. The array is one-dimensional. See notes.
Stored as a shared pointer.
sequence_timestamps Array of double Timestamps of sequences, in [s].

Notes

The object group_data stores the raw data and timestamp information associated with one execution of a group. An acquisition may have executed $n$ times the same group, therefor $n$ instances of group_data reference the same instance of group.

Timestamps

Timestamps are a mecanism to record the real-world instant at which data is aquired. Timestamp information should be created by the hardware of the ultrasound acquisition system to ensure that any round-off error or nondeterministic behavior is recorded. Duration between groups, sequences and events should be deduced by substrating their respective timestamps.

The group_timestamp field indicates the execution time of a group, which is useful for replaying parts of the acquisition with accurate timing and for verifying time intervals between specific groups, such as between a push and the following ultrafast in elastography.

The following diagram shows an example of a group executing its sequence four times:

With the example above the content of group_data is:

group_data : {
    group_timestamp : 100,
    sequence_timestamp : [105, 115, 130, 145]
}

The same sequence (i.e. list of events) is executed four times. A sequence always execute the same events in the same order, albeit with different delays between events. The following diagrams show the detail of the 4 repetitions of the sequence, every time events number 1, 2 or 3 are executed:

With the example above the group_data is:

group_data : {
    group_timestamp : 100,
    sequence_timestamp : [105, 115, 130, 145],
    event_timestamps : [
        [105, 106, 111], 
        [115, 118, 121], 
        [130, 133, 135], 
        [146, 150, 147]
    ]
} 

Note the order or the events is the timing diagram for the fourth repetition of the sequence and the associated event_timestamps.

Raw Data

The raw_data field contains the raw ultrasound data, sometimes called RF data.

  • An ultrasound group is the repetition of a sequence (See group.sequence).
  • A sequence is a list of events.
  • An event contains the RF-lines of all the active probe elements.
  • An RF-line contains the sampled values of a signal.

Using the following conventions:

  • the i-th sample of a RF-line is $S_i$
  • the j-th RF-line of an event is $RF_j$
  • the k-th event of a sequence is $Event_k$
  • the n-th sequence of a group is $Seq_n$

The following diagram represents the memory layout of the raw_data:

rawdata_memory_map.drawio.svg{width="60%"}

At the highest level (leftmost column), the group contains the sequences $F_n$. All the sequences of a group have the same size. Zooming in on the sequence $F_n$ (second column) shows the events $E_k$. Events within a sequence can have different sizes, but a given event $E_k$ has always the same size across all repetitions of the sequence. Zooming in on the event $E_k$ (third column) shows the RF-lines $C_j$, all RF-lines of an event have the same size. At the lowest level (rightmost column), the RF-line contains the sampled data $S_i$.

There are no gaps or padding in the raw_data memory layout.

When $S_i = A_i + j \cdot B_i$ are complex values (i.e. not real), the real part is stored first, then the imaginary part: $[..., A_i, B_i, A_{i+1}, B_{i+1}, A_{i+2}, B_{i+2}, ...]$

The following conditions must be enforced:

  • Within an event all RF-lines contain the same number of samples, defined in event[i].receive_setup.number_samples. Beware that the number of samples can be different between events of the same sequence.
  • Within a sequence, the number of signals can vary, depending on the length of event[i].receive_setup.probe_elements.
  • A group repeats the same sequence over and over, the number and order of the events cannot change.

The number of samples in event $k$ is given by: $Ns('event', k) = event(k).receive\_setup.probe\_elements.size() * event(k).receive\_setup.number\_samples$

The number of RF-samples in a sequence is given by (all sequences have the same number of stored samples):

$Ns('seq') = \sum_{k=1}^{N_{ev}}{Ns(event, k)}$

By convension, the raw values in the field raw_data are:

  • Positives when the pressure on the transducer is high.
  • Negatives when the pressure on the transducer is low.

The acquisition system should make sure to correct the sign of the data in cases where the transducer polarization had inverted the excitation.

Storage in URX

raw_data is represented by a two dimensional array. Each line represent one value.

If you have only one column, value are in real only format (datatype is RF).

If you have two columns, value are in complex format (datatype is IQ). The first column is real part and the second column is imaginary part.

Storage in memory

Data are stored in non-typed field.

To know the type of data, you need to read data_type and sampling_type from group field. If format is complex, you can use std::complex<Type>.

See Also

acquisition | data_type | group

⚠️ **GitHub.com Fallback** ⚠️