zea.data.convert.us4us¶

Convert us4us (ARRUS + gui4us) recordings to the zea format.

us4us systems (us4R, us4R-lite) are programmed with the ARRUS Python API, usually through gui4us. A captured acquisition is stored as a Python pickle holding the raw pipeline outputs plus the ARRUS metadata that describes the probe, the TX/RX sequence and the medium:

recording.pkl
├── "data":     list of N frames, each a tuple of M numpy arrays
│               (one array per pipeline output, e.g. image, beamformed IQ,
│               raw channel data)
└── "metadata": sequence of M ``arrus.metadata.ConstMetadata`` objects,
                one per pipeline output

This module maps those outputs onto zea data types and writes a single zea HDF5 file per recording. arrus does not need to be installed: every arrus class in the pickle is replaced by a lightweight stub that keeps the original attribute values (see load_us4us_pickle()).

Usage¶

# Single file, default mapping (pipeline output 0 is a B-mode image)
zea convert us4us recording.pkl recording.hdf5

# Map several pipeline outputs at once
zea convert us4us recording.pkl recording.hdf5 \
    --mapping 0:image 1:beamformed_data 2:raw_data

# Whole directory: every <name>.pkl becomes <dst>/<name>.hdf5
zea convert us4us ./recordings ./converted --mapping 0:image

# Straight from the Hub: an hf:// file or folder is downloaded first
zea convert us4us hf://zeahub/pytest/us4us/recording.pkl recording.hdf5

# Frames and ARRUS metadata pickled separately
zea convert us4us recording.pkl recording.hdf5 --metadata recording_metadata.pkl

<src> and <dst> are either single files (.pkl and .hdf5) or directories, in which case every recording in <src> is converted. Both a file and a directory may be given as an hf:// path, which is downloaded first.

--mapping entries are <pipeline output index>:<zea data type> pairs; a JSON object (--mapping '{"0": "image", "1": "raw_data"}') is accepted as well. Supported zea data types are listed in SUPPORTED_DATA_TYPES.

Some us4us setups pickle the frames and the ARRUS metadata separately. Pass the metadata with --metadata <file.pkl>; a sibling <name>_metadata.pkl (in the same directory, or in the same Hugging Face repo for an hf:// recording) is picked up automatically.

ARRUS metadata used¶

The ARRUS acquisition context is mapped onto the zea scan and probe groups as follows, with ops short for context.raw_sequence.ops (one entry per transmit) and model for context.device.probe[0].model:

  • model.element_pos_x / element_pos_y / element_pos_z -> probe.probe_geometry

  • model.pitch -> probe.element_width (ARRUS does not report the element width; the pitch approximates it, ignoring the kerf)

  • model.curvature_radius -> probe.type, model.model_id -> probe.name, model.lens -> probe.lens_thickness / probe.lens_sound_speed

  • ops[i].tx.excitation.center_frequency -> scan.center_frequency (and scan.demodulation_frequency, probe.probe_center_frequency)

  • ops[i].tx.delays + ops[i].tx.aperture -> scan.t0_delays, shifted so the first active element of each transmit fires at t = 0

  • ops[i].tx.aperture -> scan.tx_apodizations and, through the element positions, scan.transmit_origins (the centre of the active aperture)

  • ops[i].rx.sample_range (or rx.time_range) -> scan.initial_times, shifted onto the same t = 0 as t0_delays

  • ops[i].pri -> scan.time_to_next_transmit

  • context.sequence.tx_focus, or ops[i].tx.focus for a bare TxRxSequence -> scan.focus_distances

  • context.sequence.angles, or ops[i].tx.angle for a bare TxRxSequence -> scan.polar_angles

  • metadata.data_description.sampling_frequency -> scan.sampling_frequency

  • metadata.data_description.spacing.coordinates -> per-pixel coordinates

  • context.medium.speed_of_sound -> scan.sound_speed

Note

Tested against the ARRUS releases listed in TESTED_ARRUS_VERSIONS (gui4us 0.3.x). Files written by other versions are converted on a best-effort basis. A diverged ARRUS release is the usual reason a genuine recording fails to convert, so the converter is built to say so rather than to guess: it validates the structures it needs and names the one that is missing together with the ARRUS version the recording reports, and it warns when any of the optional metadata in _OPTIONAL_ARRUS_FIELDS is absent, since those fall back to a default instead of failing. When a new ARRUS release lands, converting a recording made with it and reading those warnings is the intended way to find out what moved.

Warning

Limitations. This converter targets basic, standard us4us acquisitions with a single, single-axis array probe (linear, convex, phased or ring). Not supported:

  • RCA / multi-probe / matrix acquisitions. Recordings whose context holds more than one probe are rejected with an explicit error, because zea’s probe_geometry and t0_delays assume a single element grid.

  • Recordings without embedded metadata. Some setups save the frame data and the ARRUS metadata as two separate pickles. Point --metadata at the metadata pickle in that case (a sibling *_metadata.pkl next to the data file is picked up automatically).

  • Per-frame changing sequences. The TX/RX sequence of the first metadata entry is assumed to hold for every frame.

  • Custom pipeline outputs. Only the data types in SUPPORTED_DATA_TYPES are understood; anything else (Doppler, segmentation, elastography, …) has no us4us layout convention and must be converted with a bespoke script using zea.File.create().

  • Per-transmit (LRI) map outputs. A gui4us pipeline that saves ReconstructLri before the Mean step emits one image per transmit, which zea’s map data types cannot hold: they have no transmit axis. Such an output is rejected rather than reshaped into something unreadable.

  • Image dynamic range. ARRUS B-mode images are log-compressed but not normalized, while zea expects float images in dB with a maximum of 0, so float images are shifted by their global maximum (uint8 images are stored unchanged).

  • Coordinates. Per-pixel coordinates are stored when ARRUS reports a grid (data_description.spacing). An output without a grid whose first axis has one entry per transmit is taken to be organized per scan line: it is transposed to (z, x) = (depth, transmit) and its coordinates are derived from the transmit origins and the depth axis, assuming a constant speed of sound.

Module Attributes

SUPPORTED_DATA_TYPES

zea data types this converter knows how to build from a us4us pipeline output.

DEFAULT_MAPPING

pipeline output 0 is a B-mode image.

TESTED_ARRUS_VERSIONS

ARRUS releases this converter was developed and tested against, as major.minor prefixes.

Functions

convert_us4us(args)

Convert one or more us4us (ARRUS + gui4us) pickle recordings to the zea format.

convert_us4us_file(src, dst[, mapping, ...])

Convert a single us4us .pkl recording to a zea HDF5 file.

load_us4us_pickle(path)

Load a us4us pickle with an allowlisted unpickler.

parse_mapping(mapping)

Normalize a --mapping value into {output_index: zea_data_type}.

Exceptions

Us4usConversionError

Raised when a pickle cannot be interpreted as a us4us recording.

zea.data.convert.us4us.DEFAULT_MAPPING = {0: 'image'}¶

pipeline output 0 is a B-mode image.

Type:

Mapping used when --mapping is not given

zea.data.convert.us4us.SUPPORTED_DATA_TYPES = ('raw_data', 'beamformed_data', 'envelope_data', 'image')¶

zea data types this converter knows how to build from a us4us pipeline output. Deliberately narrower than zea.data.spec.DataSpec: a data type is only listed here once _prepare_output() has an explicit branch for its us4us layout, so that unsupported types fail loudly instead of silently writing arrays that downstream readers cannot interpret.

zea.data.convert.us4us.TESTED_ARRUS_VERSIONS = ('0.12', '0.13', '0.14')¶

ARRUS releases this converter was developed and tested against, as major.minor prefixes. A recording from another release is still converted, but every error and warning says which version it reports and which ones are supported: an ARRUS release that moves or renames metadata is by far the most likely reason for a conversion of a genuine us4us recording to fail or to come out lossy.

exception zea.data.convert.us4us.Us4usConversionError[source]¶

Bases: ValueError

Raised when a pickle cannot be interpreted as a us4us recording.

Subclasses ValueError so callers can keep catching that.

zea.data.convert.us4us.convert_us4us(args)[source]¶

Convert one or more us4us (ARRUS + gui4us) pickle recordings to the zea format.

Parameters:

args –

Object with the attributes:

  • src: Source .pkl file, or a directory holding *.pkl files. Either may also be an hf:// path.

  • dst: Destination .hdf5 file when src is a file, or the destination directory when src is a directory (each <name>.pkl becomes <dst>/<name>.hdf5).

  • mapping (optional): Pipeline output index to zea data type, in any form accepted by parse_mapping().

  • metadata (optional): Pickle holding the ARRUS metadata for recordings that store data and metadata separately (local or hf://).

  • overwrite (optional): Replace existing destination files.

  • separate_tracks (optional): Write each mapped output to its own zea track.

Raises:
  • FileNotFoundError – If src does not exist, or is a directory without any .pkl files.

  • Us4usConversionError – If a recording cannot be interpreted.

Return type:

None

zea.data.convert.us4us.convert_us4us_file(src, dst, mapping=None, *, metadata_path=None, overwrite=False, separate_tracks=False)[source]¶

Convert a single us4us .pkl recording to a zea HDF5 file.

Parameters:
  • src – Source .pkl file, local or an hf:// path.

  • dst – Destination .hdf5 file.

  • mapping – Pipeline output index to zea data type, in any form accepted by parse_mapping(). Defaults to DEFAULT_MAPPING.

  • metadata_path – Optional pickle holding the ARRUS metadata, for recordings that store data and metadata separately (local or hf://). When omitted, a sibling <name>_metadata.pkl is used if present, in the same repo for an hf:// recording.

  • overwrite (bool) – Replace dst if it already exists.

  • separate_tracks (bool) – Write every mapped output to its own zea track instead of storing them side by side in a single track.

Returns:

The written HDF5 file.

Return type:

Path

Raises:

Us4usConversionError – If the pickle is not a us4us recording, or uses a layout this converter does not support.

zea.data.convert.us4us.load_us4us_pickle(path)[source]¶

Load a us4us pickle with an allowlisted unpickler.

Parameters:

path – Path to the .pkl file.

Returns:

The unpickled object, with every arrus instance replaced by an attribute-preserving stub.

Warning

Pickle is not a safe format for arbitrary input. Even with the allowlist enforced by the loader, only run this on .pkl files produced by us4us / ARRUS acquisition setups you control – never on files received from untrusted third parties.

zea.data.convert.us4us.parse_mapping(mapping)[source]¶

Normalize a --mapping value into {output_index: zea_data_type}.

Accepts the CLI form (a list of "<index>:<data_type>" strings), a JSON object string ('{"0": "image"}'), or an already-parsed dict.

Parameters:

mapping – Mapping specification, or None for DEFAULT_MAPPING.

Returns:

Pipeline output index (int) to zea data type (str).

Return type:

dict

Raises:

Us4usConversionError – If the specification is malformed, has duplicate indices, or names a data type outside SUPPORTED_DATA_TYPES.