tutorials.9 - moduleus/urx GitHub Wiki

Python

import numpy as np
import ultrasound_acquisition_configuration as uac
import ultrasound_rawdata_exchange as urx


def compare_complex_arrays(arr1, arr2, rtol=1e-05, atol=1e-08):
    def is_real_array(arr):
        return arr.dtype != complex and not (arr.ndim == 2 and arr.shape[1] == 2)

    if is_real_array(arr1) and is_real_array(arr2):
        return np.allclose(arr1, arr2, rtol=rtol, atol=atol)

    def to_complex(arr):
        if arr.dtype == complex:
            return arr
        elif arr.ndim == 2 and arr.shape[1] == 2:
            return arr[:, 0] + 1j * arr[:, 1]
        else:
            return arr.astype(complex)

    complex1 = to_complex(arr1)
    complex2 = to_complex(arr2)

    return np.allclose(complex1, complex2, rtol=rtol, atol=atol)


uac_filename = "./t8-python.uac"
urx_filename = "./t9-python.urx"

# Generate urx without group_data
uac_dataset = uac.loadFromFile(uac_filename)
urx_dataset = uac.toUrx(uac_dataset)

# The urx file must exist and be saved before using stream.
urx.saveToFile(urx_filename, urx_dataset, urx.WriterOptions(False, False, False))

group_idx = 0

sequence_size = sum(
    len(event.receive_setup.active_elements) * event.receive_setup.number_samples
    for event in urx_dataset.acquisition.groups[group_idx].sequence
)

raw_data_vector_short = np.arange(sequence_size, dtype=np.int16)

stream = urx.Stream(urx_filename, urx_dataset)
stream.writerOptions().clean_unusable_data = True
group_data = stream.createGroupData(urx_dataset.acquisition.groups[group_idx], 2.0)

# It's not mandatory to write the full sequence at once.
group_data.append(raw_data_vector_short, 9.0, [8.0])

# Stream and GroupDataStream keep an HDF5 object. So destroy it to release lock on file.
del group_data
del stream

dataset_loaded = urx.Dataset()
stream = urx.Stream(urx_filename, dataset_loaded)
stream.readerOptions().raw_data_load_policy = urx.RawDataLoadPolicy.STREAM
stream.loadFromFile()

group_data_idx = 0

# Buffer must reserve memory.
buffer = np.ndarray((sequence_size), dtype=np.int16)

# It's not mandatory to write the full sequence at once.
stream.readRawData(
    group_data_idx,
    buffer,
    0,  # Index of the sequence in the buffer.
    0,  # Index of the sequence in the urx file.
    1,  # Count of sequence to read.
)

if not compare_complex_arrays(raw_data_vector_short, buffer):
    raise Exception("Something went wrong")

MATLAB

UacFilename = "./t8-matlab.uac";
UrxFilename = "./t9-matlab.urx";

% Generate urx without GroupData
UacDataset = uac.loadFromFile(UacFilename);
UrxDataset = uac.toUrx(UacDataset);

% The urx file must exist and be saved before using stream.
urx.saveToFile(UrxFilename, UrxDataset, false, false, false);

GroupIdx = 1;

SequenceSize = sum(arrayfun(@(event) length(event.receiveSetup.activeElements) * event.receiveSetup.numberSamples, UrxDataset.acquisition.groups(GroupIdx).sequence));

RawDataVectorShort = urx.RawData_int16_t_real(SequenceSize);
%for n = 1:SequenceSize
%    RawDataVectorShort.data(1, n) = n;
%end

Stream = urx.Stream(UrxFilename, UrxDataset);
GroupData = Stream.createGroupData(UrxDataset.acquisition.groups(GroupIdx), 2.0);

% It's not mandatory to write the full sequence at once.
GroupData.append(RawDataVectorShort, 9.0, [8.0]);

% Stream and GroupDataStream keep an HDF5 object. So destroy it to release lock on file.
clear GroupData
clear Stream

DatasetLoaded = urx.Dataset();
Stream = urx.Stream(UrxFilename, DatasetLoaded);
Stream.setReaderOptions(urx.RawDataLoadPolicy.STREAM);
Stream.loadFromFile();

GroupDataIdx = 1;

% Buffer must reserve memory.
Buffer = urx.RawData_int16_t_real(SequenceSize);

% It's not mandatory to write the full sequence at once.
Stream.readRawData(...
    GroupDataIdx,...
    Buffer,...
    1,...  % Index of the sequence in the buffer.
    1,...  % Index of the sequence in the urx file.
    1);  % Count of sequence to read.

assert(isequal(RawDataVectorShort, Buffer));

C++

#include <cstddef>
#include <ios>
#include <iostream>
#include <memory>
#include <numeric>
#include <ostream>
#include <string>
#include <utility>
#include <vector>

#include <urx/acquisition.h>
#include <urx/dataset.h>
#include <urx/detail/double_nan.h>
#include <urx/detail/raw_data.h>
#include <urx/event.h>
#include <urx/group.h>
#include <urx/receive_setup.h>
#include <urx/utils/io/reader_options.h>
#include <urx/utils/io/stream.h>
#include <urx/utils/io/writer.h>
#include <urx/utils/io/writer_options.h>

#include <uac/dataset.h>
#include <uac/utils/io/reader.h>
#include <uac/utils/to_urx.h>

int main() {
  const std::string uac_filename = "./t8-cpp.uac";
  const std::string urx_filename = "./t9-cpp.urx";

  // Generate urx without group_data
  const std::shared_ptr<uac::Dataset> uac_dataset =
      uac::utils::io::reader::loadFromFile(uac_filename);
  const std::shared_ptr<urx::Dataset> urx_dataset = uac::utils::toUrx(*uac_dataset);

  // The urx file must exist and be saved before using stream.
  urx::utils::io::writer::saveToFile(urx_filename, *urx_dataset, {false, false, false});

  const size_t group_idx = 0;

  const size_t sequence_size =
      std::accumulate(urx_dataset->acquisition.groups[group_idx]->sequence.begin(),
                      urx_dataset->acquisition.groups[group_idx]->sequence.end(), 0LL,
                      [](size_t start, const urx::Event& event) {
                        return start + event.receive_setup.active_elements.size() *
                                           event.receive_setup.number_samples;
                      });
  const std::shared_ptr<urx::RawData> raw_data_vector_short =
      std::make_shared<urx::RawDataVector<short>>(sequence_size);
  short* buf = static_cast<short*>(raw_data_vector_short->getBuffer());
  for (size_t i = 0; i < sequence_size; i++) {
    buf[i] = static_cast<short>(i);
  }

  {
    // Stream and GroupDataStream keep an HDF5 object. So destroy it to release lock on file.
    urx::utils::io::Stream stream(urx_filename, urx_dataset);

    stream.writerOptions().setChunkGroupData(true);
    urx::utils::io::GroupDataStream group_data =
        stream.createGroupData(urx_dataset->acquisition.groups[group_idx], urx::DoubleNan(2.));

    // It's not mandatory to write the full sequence at once.
    group_data.append(raw_data_vector_short, 9., {8.});
  }

  {
    const std::shared_ptr<urx::Dataset> dataset_loaded = std::make_shared<urx::Dataset>();
    urx::utils::io::Stream stream(urx_filename, dataset_loaded);
    stream.readerOptions().setRawDataLoadPolicy(urx::utils::io::RawDataLoadPolicy::STREAM);
    stream.loadFromFile();

    const size_t group_data_idx = 0;

    // Buffer must reserve memory.
    const std::shared_ptr<urx::RawData> buffer =
        std::make_shared<urx::RawDataVector<short>>(sequence_size);

    // It's not mandatory to write the full sequence at once.
    stream.readRawData(group_data_idx, buffer,
                       0,   // Index of the sequence in the buffer.
                       0,   // Index of the sequence in the urx file.
                       1);  // Count of sequence to read.

    if (*buffer != *raw_data_vector_short) {
      std::cout << "Something went wrong.\n";
    }
  }

  return 0;
}
⚠️ **GitHub.com Fallback** ⚠️