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_geometrymodel.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_speedops[i].tx.excitation.center_frequency->scan.center_frequency(andscan.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 att = 0ops[i].tx.aperture->scan.tx_apodizationsand, through the element positions,scan.transmit_origins(the centre of the active aperture)ops[i].rx.sample_range(orrx.time_range) ->scan.initial_times, shifted onto the samet = 0ast0_delaysops[i].pri->scan.time_to_next_transmitcontext.sequence.tx_focus, orops[i].tx.focusfor a bareTxRxSequence->scan.focus_distancescontext.sequence.angles, orops[i].tx.anglefor a bareTxRxSequence->scan.polar_anglesmetadata.data_description.sampling_frequency->scan.sampling_frequencymetadata.data_description.spacing.coordinates-> per-pixelcoordinatescontext.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_geometryandt0_delaysassume a single element grid.Recordings without embedded metadata. Some setups save the frame data and the ARRUS metadata as two separate pickles. Point
--metadataat the metadata pickle in that case (a sibling*_metadata.pklnext 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_TYPESare understood; anything else (Doppler, segmentation, elastography, …) has no us4us layout convention and must be converted with a bespoke script usingzea.File.create().Per-transmit (LRI) map outputs. A gui4us pipeline that saves
ReconstructLribefore theMeanstep 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 (
uint8images 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
zea data types this converter knows how to build from a us4us pipeline output. |
|
pipeline output 0 is a B-mode image. |
|
ARRUS releases this converter was developed and tested against, as |
Functions
|
Convert one or more us4us (ARRUS + gui4us) pickle recordings to the zea format. |
|
Convert a single us4us |
|
Load a us4us pickle with an allowlisted unpickler. |
|
Normalize a |
Exceptions
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
--mappingis 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.minorprefixes. 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:
ValueErrorRaised when a pickle cannot be interpreted as a us4us recording.
Subclasses
ValueErrorso 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.pklfile, or a directory holding*.pklfiles. Either may also be anhf://path.dst: Destination.hdf5file whensrcis a file, or the destination directory whensrcis a directory (each<name>.pklbecomes<dst>/<name>.hdf5).mapping(optional): Pipeline output index to zea data type, in any form accepted byparse_mapping().metadata(optional): Pickle holding the ARRUS metadata for recordings that store data and metadata separately (local orhf://).overwrite(optional): Replace existing destination files.separate_tracks(optional): Write each mapped output to its own zea track.
- Raises:
FileNotFoundError – If
srcdoes not exist, or is a directory without any.pklfiles.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
.pklrecording to a zea HDF5 file.- Parameters:
src – Source
.pklfile, local or anhf://path.dst – Destination
.hdf5file.mapping – Pipeline output index to zea data type, in any form accepted by
parse_mapping(). Defaults toDEFAULT_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.pklis used if present, in the same repo for anhf://recording.overwrite (
bool) – Replacedstif 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
.pklfile.- Returns:
The unpickled object, with every
arrusinstance 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
.pklfiles 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
--mappingvalue 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
NoneforDEFAULT_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.