DataΒΆ
This page covers the zea data format, how files are structured, how to create and
read files, and where to get existing datasets. More detail data handling classes can
be found in zea.data module documentation.
Note
For the configuration system (model, pipeline, and scan parameters in YAML), see Config. Example notebooks on data handling live in Examples.
The philosophy behind the zea data format is to store data alongside all necessary parameters to
process it (e.g. Scan parameters), and additional metadata (e.g. acquisition conditions, patient info, etc.)
in a single file. This makes it easy to manage and share data, and ensures that all necessary information
is always available when loading a file.
Additionally, to support the cognitive ultrasound framework, the zea data format is designed to allow for flexible and efficient access to a part of the data (e.g. a single frame or transmit) without the need to load the entire file into memory.
Working with zea data filesΒΆ
zea stores each acquisition as a single HDF5 file following the schema. The primary API is zea.File. It operates similarly to h5py.File, but with an additional interface of parsing parameters into Scan and Probe objects, and validating the file against the zea data spec.
Open and read an existing file
from zea import File
with File("my_acquisition.hdf5") as f:
raw = f.data.raw_data[:] # all frames
raw0 = f.data.raw_data[0] # first frame only
scan = f.scan() # returns zea.Scan
probe = f.probe() # returns zea.Probe
# For remote files (Hugging Face Hub):
with File("hf://zeahub/picmus/.../contrast_speckle.hdf5") as f:
raw0 = f.data.raw_data[0] # first frame
See zea.File for the full API reference.
Create a new file
Use zea.File.create() to build a validated file from NumPy arrays.
All inputs are checked against the full schema before anything is written to
disk:
import numpy as np
from zea import File
n_frames, n_tx, n_el, n_ax = 2, 32, 128, 512
raw = np.zeros((n_frames, n_tx, n_ax, n_el, 1), dtype=np.float32)
geom = np.zeros((n_el, 3), dtype=np.float32)
scan = {
"probe_geometry": geom,
"sampling_frequency": np.float32(40e6),
"center_frequency": np.float32(7e6),
"demodulation_frequency": np.float32(7e6),
"initial_times": np.zeros(n_tx, dtype=np.float32),
"t0_delays": np.zeros((n_tx, n_el), dtype=np.float32),
"tx_apodizations": np.ones((n_tx, n_el), dtype=np.float32),
"focus_distances": np.full(n_tx, np.inf, dtype=np.float32),
"transmit_origins": np.zeros((n_tx, 3), dtype=np.float32),
"polar_angles": np.zeros(n_tx, dtype=np.float32),
"time_to_next_transmit": np.ones((n_frames, n_tx), dtype=np.float32) * 1e-4,
}
f = File.create(
"my_acquisition.hdf5",
data={"raw_data": raw},
scan=scan,
probe_name="L11-4v",
)
f.close()
zea data format referenceΒΆ
Files created with zea 0.0.12 and later are fully described by the
FileSpec class.
Note
The spec is the single source of truth. The documentation below is
automatically generated from zea.data.spec.
Run python docs/source/spec_doc.py to refresh it after spec changes.
File hierarchyΒΆ
Every zea HDF5 file follows the layout shown below.
data_file.hdf5 (attrs: probe_name, us_machine, description, zea_version)
βββ data/
β βββ raw_data float32 | int16 (n_frames, n_tx, n_ax, n_el, n_ch)
β βββ aligned_data float32 | int16 (n_frames, n_tx, n_ax, n_el, n_ch)
β βββ beamformed_data float32 (n_frames, grid_z, grid_x, n_ch)
β βββ envelope_data float32 (n_frames, grid_z, grid_x)
β βββ image_sc float32 (n_frames, grid_z_sc, grid_x_sc)
β βββ image/ group (Image)
β βββ segmentation/ group (Segmentation)
β βββ sos_map/ group (SosMap)
β βββ strain_percentage_map/ group (StrainPercentageMap)
β βββ tissue_doppler/ group (TissueDopplerMap)
β βββ color_doppler/ group (ColorDopplerMap)
β βββ <custom>/ group (any spatial map)
βββ scan/
β βββ probe_geometry float32 (n_el, 3)
β βββ sampling_frequency float32 scalar
β βββ center_frequency float32 scalar | (n_tx,)
β βββ t0_delays float32 (n_tx, n_el)
β βββ β¦
βββ metadata/
β βββ subject/ group (Subject)
β βββ annotations/ group (Annotations)
β βββ ecg/ group (Signal1D)
β βββ β¦
βββ metrics/
βββ β¦
Root attributesΒΆ
Stored as HDF5 root-level attributes (not groups).
Attribute |
Type |
Description |
Values |
|
|---|---|---|---|---|
|
|
Name of the ultrasound probe. |
e.g. |
optional |
|
|
Name of the ultrasound system. |
e.g. |
optional |
|
|
Free-text description of the acquisition. |
optional |
|
|
|
Version of zea that wrote this file (set automatically). |
optional |
Group referenceΒΆ
Click a group tab to explore its fields. Fields marked optional may be absent; all others are required.
Data group containing raw channel data, derived pipeline products, and optional spatial map groups.
Pipeline arrays
Field |
Type |
Shape |
Unit |
Description |
|
|---|---|---|---|---|---|
|
|
(n_frames, n_tx, n_ax, n_el, n_ch) |
Raw channel data. |
optional |
|
|
|
(n_frames, n_tx, n_ax, n_el, n_ch) |
Time-of-flight corrected data. |
optional |
|
|
group |
β |
optional |
||
|
group |
β |
optional |
||
|
group |
β |
optional |
||
|
group |
β |
optional |
||
|
group |
β |
optional |
||
|
group |
β |
optional |
||
|
group |
β |
optional |
||
|
group |
β |
optional |
||
|
group |
β |
optional |
||
|
group |
β |
optional |
Spatial map groups
Each spatial map is an HDF5 sub-group with the same three fields:
values (the data array), extent (spatial bounds in metres, shape
(6,) ordered as (xmin, xmax, ymin, ymax, zmax, zmin)), and
optionally labels (channel names when values has an n_ch
dimension).
Custom spatial maps are also accepted β any extra key passed to
DataSpec is validated as a generic
Map sub-group.
beamformed_data
Beamformed (beamsummed) data. Values are float32 in (n_frames, z, x, n_ch) or (n_frames, z, x, y, n_ch); labels names each channel (RF or I/Q).
Field |
Type |
Shape |
Unit |
|
|---|---|---|---|---|
|
|
(n_frames, z, x, y, n_ch) or (n_frames, z, x, n_ch) |
β |
required |
|
|
(n_frames, 6) or (6) |
β |
optional |
|
|
(n_ch) |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
envelope_data
Envelope-detected data. Values are float32 in (n_frames, z, x) or (n_frames, z, x, y).
Field |
Type |
Shape |
Unit |
|
|---|---|---|---|---|
|
|
(n_frames, z, x, y) or (n_frames, z, x) |
β |
required |
|
|
(n_frames, 6) or (6) |
β |
optional |
|
|
(n_spatial_ch) |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
image_sc
Scan-converted image. Values are float32 in (n_frames, z, x) or (n_frames, z, x, y).
Field |
Type |
Shape |
Unit |
|
|---|---|---|---|---|
|
|
(n_frames, x, z, y) or (n_frames, x, z) |
β |
required |
|
|
(n_frames, 6) or (6) |
β |
optional |
|
|
(n_spatial_ch) |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
image
Reconstructed (log-compressed) image. Values are uint8 in (n_frames, z, x) or (n_frames, z, x, y).
Field |
Type |
Shape |
Unit |
|
|---|---|---|---|---|
|
|
(n_frames, x, z, y) or (n_frames, x, z) |
β |
required |
|
|
(n_frames, 6) or (6) |
β |
optional |
|
|
(n_spatial_ch) |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
segmentation
Semantic segmentation mask. Values are bool in (n_frames, z, x, y, n_labels); labels names each channel.
Field |
Type |
Shape |
Unit |
|
|---|---|---|---|---|
|
|
(n_frames, z, x, y, n_spatial_ch) or (n_frames, z, x, y) or (n_frames, z, x) |
β |
required |
|
|
(n_frames, 6) or (6) |
β |
optional |
|
|
(n_spatial_ch) |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
sos_map
Speed-of-sound map in m/s. Values are float32.
Field |
Type |
Shape |
Unit |
|
|---|---|---|---|---|
|
|
(n_frames, z, x, y, n_spatial_ch) or (n_frames, z, x, y) or (n_frames, z, x) |
β |
required |
|
|
(n_frames, 6) or (6) |
β |
optional |
|
|
(n_spatial_ch) |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
strain_percentage_map
Strain map in %. Values are float32.
Field |
Type |
Shape |
Unit |
|
|---|---|---|---|---|
|
|
(n_frames, z, x, y, n_spatial_ch) or (n_frames, z, x, y) or (n_frames, z, x) |
β |
required |
|
|
(n_frames, 6) or (6) |
β |
optional |
|
|
(n_spatial_ch) |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
shear_wave_elastography_map
Shear-wave elastography map in m/s. Values are float32.
Field |
Type |
Shape |
Unit |
|
|---|---|---|---|---|
|
|
(n_frames, z, x, y, n_spatial_ch) or (n_frames, z, x, y) or (n_frames, z, x) |
β |
required |
|
|
(n_frames, 6) or (6) |
β |
optional |
|
|
(n_spatial_ch) |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
tissue_doppler
Tissue Doppler velocity map in m/s. Values are float32.
Field |
Type |
Shape |
Unit |
|
|---|---|---|---|---|
|
|
(n_frames, z, x, y, n_spatial_ch) or (n_frames, z, x, y) or (n_frames, z, x) |
β |
required |
|
|
(n_frames, 6) or (6) |
β |
optional |
|
|
(n_spatial_ch) |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
color_doppler
Color Doppler velocity map in m/s. Positive = towards probe. Values are float32.
Field |
Type |
Shape |
Unit |
|
|---|---|---|---|---|
|
|
(n_frames, z, x, y, n_spatial_ch) or (n_frames, z, x, y) or (n_frames, z, x) |
β |
required |
|
|
(n_frames, 6) or (6) |
β |
optional |
|
|
(n_spatial_ch) |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
Scan group with acquisition and transmit sequence parameters.
Field |
Type |
Shape |
Unit |
Description |
|
|---|---|---|---|---|---|
|
|
(n_el, 3) |
m |
Probe geometry (x, y, z) per element. |
required |
|
|
scalar |
Hz |
Sampling frequency. |
required |
|
|
scalar or (n_tx) |
Hz |
Center frequency of the transmit pulse. |
required |
|
|
scalar or (n_tx) |
Hz |
Demodulation frequency. |
required |
|
|
(n_tx) |
s |
A/D converter start times per transmit. |
required |
|
|
(n_tx, n_el) |
s |
Transmit delays per element. |
required |
|
|
(n_tx, n_el) |
Transmit apodization per element. |
required |
|
|
|
(n_tx) |
m |
Transmit focus distances. |
required |
|
|
(n_tx, 3) |
m |
Transmit beam origins (x, y, z). |
required |
|
|
(n_tx) |
rad |
Polar angles of transmit beams. |
required |
|
|
(n_frames, n_tx) |
s |
Time between transmit events. |
optional |
|
|
(n_tx) |
rad |
Azimuthal angles of transmit beams. |
optional |
|
|
scalar |
m/s |
Speed of sound. |
optional |
|
|
(n_ax) |
Time-gain-compensation curve. |
optional |
|
|
|
scalar |
m |
Element width of the probe. |
optional |
|
|
(n_tx, n_samples_one_way) |
V |
One-way transmit waveforms. |
optional |
|
|
(n_tx, n_samples_two_way) |
V |
Two-way transmit waveforms. |
optional |
Optional metadata group for subject, acquisition context, annotations,
and extra time-series signals (ECG, voice narration, probe orientation).
Extra signal keys are accepted and validated as
SignalND sub-groups.
Field |
Type |
Shape |
Unit |
Description |
|
|---|---|---|---|---|---|
|
group |
β |
optional |
||
|
|
scalar |
Credit or attribution for the dataset. |
optional |
|
|
group |
Sampled probe pose at the transducer tip. |
optional |
||
|
group |
Voice narration signal. |
optional |
||
|
group |
Electrocardiogram signal. |
optional |
||
|
|
scalar |
Free-text report associated with the study. |
optional |
|
|
group |
Frame-level annotations. |
optional |
Sub-groups
subject β Subject
Subject metadata associated with the study.
Field |
Type |
Shape |
Unit |
|
|---|---|---|---|---|
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
|
|
scalar |
β |
optional |
annotations β Annotations
Frame-level annotations, either per frame or broadcast labels.
Field |
Type |
Shape |
Unit |
|
|---|---|---|---|---|
|
|
(n_frames) or scalar |
β |
optional |
|
|
(n_frames) |
β |
optional |
|
|
(n_frames) |
β |
optional |
|
|
(n_frames) or scalar |
β |
optional |
probe_pose β ProbePose
Sampled probe pose metadata at the tip of the transducer.
Field |
Type |
Shape |
Unit |
Description |
|
|---|---|---|---|---|---|
|
|
(T, 3) |
m |
Position of the transducer tip, ordered as (x, y, z), where x is lateral along the transducer, y is elevation (out of plane), and z is axial (depth). |
required |
|
|
(T, 3) or (T, 4) |
Orientation associated with the transducer-tip pose in the x-lateral, y-elevation, z-axial coordinate convention, interpreted according to rotation_representation. |
required |
|
|
|
scalar |
Rotation parameterization: one of euler_xyz, quaternion_wxyz, or quaternion_xyzw. |
required |
|
|
|
scalar |
s |
Time offset between the first transmit event of the ultrasound acquisition and sample 0 of this data. Negative means this data starts before the first transmit event; positive means it starts after. |
required |
|
|
scalar |
Hz |
Sampling frequency. |
required |
ecg / voice_narration β Signal1D
One-dimensional sampled signal with timing metadata.
Field |
Type |
Shape |
Unit |
Description |
|
|---|---|---|---|---|---|
|
|
Signal samples. |
required |
||
|
|
scalar |
s |
Time offset between the first transmit event of the ultrasound acquisition and sample 0 of this data. Negative means this data starts before the first transmit event; positive means it starts after. |
required |
|
|
scalar |
Hz |
Sampling frequency. |
required |
Optional metrics group for acquisition-level quality and performance metrics.
Field |
Type |
Shape |
Unit |
Description |
|
|---|---|---|---|---|---|
|
|
(n_frames) |
β |
optional |
|
|
|
(n_frames) |
β |
optional |
Custom fieldsΒΆ
Beyond the standard data types (raw_data, beamformed_data, β¦), you can attach arbitrary
custom spatial maps and custom metadata to any zea file.
Custom spatial maps (data group)
A custom map is a named entry in the data group that associates a pixel array with a physical
extent. Pass it as a sub-dict under the key you want:
import numpy as np
from zea import File
n_frames = 2
values = np.zeros((n_frames, 64, 64, 1), dtype=np.uint8) # (frames, z, x[, channels])
extent = np.array([x_min, x_max, y_min, y_max, z_min, z_max], dtype=np.float32) # metres
f = File.create(
"my_acquisition.hdf5",
data={
"raw_data": raw,
"my_overlay": { # <-- Example of a custom field not in the zea spec
"values": values,
"extent": extent,
# optional: "labels", "description", "unit"
},
},
scan=scan,
)
f.close()
# Reading back
with File("my_acquisition.hdf5") as f:
overlay_values = f.data.my_overlay.values[:]
overlay_extent = f.data.my_overlay.extent[:]
Custom metadata (metadata group)
Standard metadata fields (credit, annotations, text_report, subject, ecg, β¦)
are validated by MetadataSpec. Pass a plain dict to File.create
metadata argument.
f = File.create(
"my_acquisition.hdf5",
data={"raw_data": raw},
scan=scan,
metadata={
"credit": "My Lab, 2024",
"text_report": "Normal acquisition, no pathology.",
"annotations": {
"label": np.array(["healthy", "healthy"]),
},
},
)
Custom signal keys (anything beyond the standard names) are accepted and stored as
SignalND entries: a dict with samples, start_time_offset, and
sampling_frequency:
import numpy as np
from zea import File
n_samples = 500
respiratory_signal = {
"samples": np.sin(np.linspace(0, 2 * np.pi, n_samples)).astype(np.float32),
"start_time_offset": np.float32(-0.5), # seconds before first transmit
"sampling_frequency": np.float32(10.0), # Hz
}
f = File.create(
"my_acquisition.hdf5",
data={"raw_data": raw},
scan=scan,
metadata={
"credit": "My Lab, 2024",
"respiratory_signal": respiratory_signal, # <-- custom SignalND field
},
)
f.close()
# Reading back
with File("my_acquisition.hdf5") as f:
meta = f.metadata()
samples = meta.respiratory_signal.samples # numpy array
fs = meta.respiratory_signal.sampling_frequency
See MetadataSpec for the full list of supported standard fields.
Supported datasets & conversionΒΆ
The zea toolbox supports several public and research ultrasound datasets.
Conversion scripts live in
zea/data/convert/
and can be invoked as:
python -m zea.data.convert --dataset "echonet" --src <src> --dst <dst>
python -m zea.data.convert --dataset "camus" --src <src> --dst <dst>
python -m zea.data.convert --dataset "picmus" --src <src> --dst <dst>
Supported datasets:
EchoNet-Dynamic β large-scale cardiac ultrasound.
EchoNet-LVH β cardiac dataset for left ventricular hypertrophy.
CAMUS β Cardiac Acquisitions for Multi-structure Ultrasound Segmentation.
PICMUS β Plane-wave Imaging Challenge in Medical Ultrasound.
Custom β any dataset can be converted by following the layout described above.
Data acquisition platformsΒΆ
Verasonics
Record data with your Verasonics script, save the workspace to .mat, then convert:
python -m zea.data.convert --dataset "verasonics" --src <src> --dst <dst>
See zea.data.convert.verasonics for details.
us4us β to be added in a future release.