Changelog¶
This changelog is for the main branch. It lists the changes in each release, with the pull request and author of each change. Changes merged since the last release are listed under Current; to add one, see 6. Log your changes in the contributing guide. Older releases are also on GitHub Releases.
Current¶
New Features¶
An interactive beamforming grid viewer in Parameters that shows how the grid parameters relate (#679 by @wesselvannierop)
grid_apex, derived from the probe and transmits, is the point a polar grid fans out from: where steered focused lines meet, a diverging wave’s virtual source, or a curved array’s centre of curvature. It replacesdistance_to_apex(#679 by @wesselvannierop)polar_marginandelevation_marginset a fixed margin around the derivedpolar_limitsandelevation_limits(#679 by @wesselvannierop)
Changed¶
(Breaking) Angle parameters use one set of names from the grid through scan conversion, in 2D and 3D:
rlims,polar_limitsandelevation_limits(see Angle and radius names).rho_range/theta_range/phi_range,azimuth_limits, thefrustum_convert_*functions and thephi_/theta_/rho_arguments ofplot_frustum_verticesare renamed, with deprecated aliases. The polar/cartesian helpers now measure angles toward+x, like the rest of zea (#679 by @wesselvannierop)(Breaking)
zea.ops.ScanConvertoutputs are renamed without aliases:rho_range/theta_range/phi_range/d_rho/d_theta/d_phibecomerlims/polar_limits/elevation_limits/dr/d_polar/d_elevation(#679 by @wesselvannierop)(Breaking) The default pixel grid follows the probe and transmit geometry, so beamformed images change.
polar_limitscover the region the transmits insonify atzlims[1]instead of adding a fixed 15 % margin, andxlims,grid_size_x(λ/4 along the outer arc) andextentfollow the sector or insonified width. Scan conversion fillsextent(#679 by @wesselvannierop)(Breaking) The default
f_numberis derived from the element’s −6 dB directivity, which is 0 (no receive mask) for typical phased arrays (#679 by @wesselvannierop)
Fixed¶
Scanline grids follow the transmit angles from
grid_apex, so steered lines are no longer displayed at the wrong angle (#679 by @wesselvannierop)The default grid for an unsteered plane wave on a curved array spans the array, instead of a zero-width sector (#679 by @wesselvannierop)
Conversion of elevation-steered Verasonics data:
polar_anglesandazimuth_anglesnow hold the spherical transmit angles converted fromTX.Steer, whereazimuth_anglesused to hold the elevation steering angle (#679 by @wesselvannierop)The default
elevation_limits(and soylims) of a 3D grid are the transmits’ elevation angles, where before the range of the sphericalazimuth_anglesφ was used as if it were an elevation angle (#679 by @wesselvannierop)
v0.1.9 (2026-11-10)¶
New Features¶
ADMIRE (Aperture Domain Model Image REconstruction), a model-based beamformer that suppresses off-axis and multipath clutter, as
zea.ops.ADMIREorzea.ops.Beamform(beamformer="admire"). Seezea.beamform.admire(#650 by @tristan-deep)UltraPIPS, a perceptual metric for B-mode ultrasound built on an ultrasound foundation model:
zea.models.ultrapips.UltraPIPS, or theultrapipsmetric inzea.metrics, used likelpips(#649 by @tristan-deep)Transparent GIFs from RGBA frames with
transparent=Trueinzea.io_lib.save_video()andzea.io_lib.save_to_gif()(#663 by @tristan-deep)GIFs that play once, with
loop=Noneinzea.io_lib.save_to_gif()(#680 by @wesselvannierop)zea.func.vmap()accepts nested inputs, dict axes and keyword arguments, likejax.vmap, and can be nested on all backends (#692 by @wesselvannierop)zea appcan serve over HTTPS with--ssl-certfileand--ssl-keyfile(#648 by @Louisvh)Frequency-dependent attenuation in the pressure field, with
attenuation_coefin dB/(cm·MHz) inzea.beamform.pfield.compute_pfield(). It defaults to 0 (lossless) (#682 by @wesselvannierop)zea.ops.BandPassFilterandzea.ops.LowPassFilterIQtake theirbandwidthfrom the newzea.Parameters.bandwidth, derived ascenter_frequency * probe_bandwidth_percent / 100unless set orcenter_frequencyvaries across transmits (#644 by @tristan-deep)
Changed¶
Streaming
hf://datasets no longer runs into the Hugging Face rate limit, so you can train on many batches with many workers without downloading the data. The API is unchanged; two new environment variables,ZEA_MAX_CONCURRENT_REQUESTSandZEA_FIND_H5_SHAPES_WORKERS, tune it (see Environment variables) (#671 by @tristan-deep)Conversion scripts for EchoNet-Dynamic, CAMUS and PICMUS accept the
.zipfile itself. EchoNet-Dynamic reproduces the published split by default, and its polar conversion is about 15 times faster (#676 by @wesselvannierop)(Breaking) In
compute_pfield(),alphaandpercentilealso shape the field whennorm=False, the unusedn_elargument is removed, and probes other than linear and phased arrays raiseNotImplementedError(#657 by @wesselvannierop)(Breaking)
zea.func.vmap()validates axes likejax.vmap, so a list no longer matches a tuple.out_axes=Noneonly works on the nativejax.vmap, and the_use_torch_vmapargument is removed (#692 by @wesselvannierop)Parameters.copy()andset_transmitsare much faster (#656 by @wesselvannierop)(Breaking) The check on cartesian beamforming grids uses per-axis limits from the image’s k-space support instead of λ/2, see How fine should the beamforming grid be?. Auto-sized grids get one more pixel per axis (#673 by @wesselvannierop)
The default
probe_bandwidth_percentis 100 instead of 200, which also narrows the band used bycompute_pfield()(#644 by @tristan-deep)
Fixed¶
A streamed
hf://read that still fails after its retries, such as a dropped connection, no longer ends the epoch: theDataloaderreopens the file and reads the sample again (#690 by @tristan-deep)zea.func.vmap()passes arguments at the right positions with multipleNonearguments. It also keeps all outputs, supports nested andNoneoutputs, supports negative axes when batching, and raises an error for arguments of different lengths (#691 by @wesselvannierop)The pressure field uses the one-way transmit spectrum, averages over frequencies instead of summing, and takes the element positions from
probe_geometry(#657 by @wesselvannierop)t_peakestimated fromwaveforms_two_wayuses the envelope peak; values change where the carrier peak differs from it (#656 by @wesselvannierop)Conversion of Verasonics
BS100BWandBS50BWdata samples I and Q at the same time instants. Data converted with earlier versions, such as some Open-H-RF data, may be affected (#672 by @vincentvdschaft)zea.ops.Normalizeclips its output instead of its input, so results stay withinoutput_range(#681 by @wesselvannierop)waveforms_one_wayandwaveforms_two_wayfollowselected_transmits, like the other per-transmit parameters (#683 by @wesselvannierop)Operations and pipelines can be deep-copied and pickled, also when not registered with Keras, and copies keep their JIT settings (#698 by @tristan-deep)
The shared GIF palette keeps exact colors, so pure black stays
(0, 0, 0)(#680 by @wesselvannierop)Deriving
xlimson a GPU with the torch backend (#661 by @tristan-deep)Jitted ops on the torch backend in the Docker images, which lacked a C++ compiler (#658 by @wesselvannierop)
zea appandload_model_from_hfdownload to the zea cache instead of the Hugging Face cache (#689 by @Louisvh)@cache_outputfunctions that call a recursive function can now be cached. Additionally, the cache key now also includes other@cache_outputfunctions it calls, so editing those invalidates its cache (#703 by @wesselvannierop)
v0.1.8 (2026-10-01)¶
New Features¶
Pipeline configs can declare the modules that define their custom operations, under
pipeline: imports:or withzea process --import(#633 by @tristan-deep)
Changed¶
zea appis more robust and easier to use, with a reworked UI. Mistyped paths are normalized, configs are auto-detected and file metadata loads with a progress bar (#642 by @tristan-deep)
Fixed¶
Slow compilation of the beamforming pipeline on GPU in some settings, by disabling XLA’s fusion autotuner only for
zea.ops.TOFCorrection(#638 by @tristan-deep)zea.ops.TOFCorrection, and thereforezea.ops.Beamform, applies lens correction (apply_lens_correction=True) correctly for curved probes (#634 by @Louisvh)zea.Dataloader(sort_files=True)no longer sorts on the wrong number in filenames likeprefix_X_Y.hdf5(#637 by @tristan-deep)
v0.1.7 (2026-09-21)¶
New Features¶
Conversion script for us4us (ARRUS + gui4us) data. Try it with
zea convert us4us --help(#611 by @tristan-deep)zea processsupports--save-as png(#626 by @tristan-deep)zea.Fileaccepts receive sub-apertures (fewer receive channels than probe elements), defined inscan.rx_aperture_indices, with the matchingparameters.rx_aperture_indicesandparameters.n_rx(#615 by @tristan-deep)
Changed¶
zea datafile operations stream large files in batches instead of loading the whole file into memory (#620 by @tristan-deep)
Fixed¶
Demodulation pads the signal, so the analytic-signal transform no longer wraps echoes around to the first depth samples (#629 by @Felixduelmer)
Streaming
hf://files no longer requires Hugging Face authentication, and uses your token when you are logged in (#625 by @Felixduelmer)
v0.1.6 (2026-09-11)¶
New Features¶
zea.Dataloadercan return metadata alongside the data: scan and probe parameters, annotations and more (#578 by @wesselvannierop)InversionNet speed-of-sound reconstruction model,
zea.models.inversionnet.InversionNet(#607 by @tristan-deep)ABLE (Adaptive Beamforming by Deep Learning) model,
zea.models.able.ABLE(#357 by @benluijten)zea.ops.Refocussupports IQ data (#570 by @RobinVV)Histogram matching with
zea.display.histogram_match()(#532 by @wesselvannierop)zea.simulatorhas an elevation lens option (#566 by @Louisvh), noise and TGC options (#573 by @Louisvh) and a configurable scattering exponent (#587 by @Louisvh)zea toolsCLI, which for now holds a selection tool for manual ROI annotation. Try it withzea tools --help(#579 by @tristan-deep)zea processsupports--track(#592 by @OisinNolan)
Changed¶
(Breaking) Some
zea.Dataloaderarguments were renamed, deprecated or got new defaults; see #578 for the full list (#578 by @wesselvannierop)zea.simulatoris 30 to 600 times faster, by factoring out terms shared by the transmit and receive paths (#550 by @Louisvh)zeaautomatically uses any installed backend when none is set (#585 by @wesselvannierop)zea.logno longer writes a log file (#602 by @wesselvannierop)
Fixed¶
Slow JIT compilation of
zea.Pipelinefor large grids, with the newpatch_sizeargument, now preferred overnum_patches(#596 by @wesselvannierop)Automatic
xlimsfor plane and diverging waves (#495 by @tristan-deep)Verasonics conversion with a single image buffer (#598 by @OisinNolan), or without
ImgDataPin the workspace (#563 by @vincentvdschaft)Off-by-one error in
prepare_scheduleof the diffusion models (#601 by @wesselvannierop)Pipeline warnings no longer flag valid parameters (#603 by @tristan-deep)
v0.1.5 (2026-08-16)¶
New Features¶
zea.Pipelinecan run in mixed precision, which speeds up a DAS B-mode pipeline another 1.5 times (#518 by @wesselvannierop)zea.Pipelinesupports JIT compilation on the PyTorch backend, throughtorch.compile()(#556 by @swpenninga)Synthetic aperture functions
zea.func.decode_hadamard()andzea.func.construct_acquisition_from_synthetic_aperture()(#500 by @vincentvdschaft)t_peakinzea.simulator(#544 by @vincentvdschaft)
Changed¶
(Breaking) Python 3.10 is no longer supported;
zearequires Python 3.11 or newer. Users on Python 3.10 should stay onzea<=0.1.4(#534 by @tristan-deep)(Breaking)
sample()andposterior_sample()of thezea.models.generativemodels both work on(n_samples, *input_shape).posterior_sample()used to work on(batch_size, n_samples, *input_shape); usezea.func.vmap()for batches (#555 by @wesselvannierop)The DAS beamformer is up to 2 times faster and DMAS up to 10 times (#489 by @Louisvh)
Efficient chunking, introduced for
raw_datain v0.1.3, also applies to images, maps and small metadata arrays (#535 by @wesselvannierop)The Docker images are fully installed with uv (#546 by @wesselvannierop)
Fixed¶
Definitions of
zlimsanddistance_to_apex(#542 by @tristan-deep)Stochastic sampling in
zea.models.flow_matching.FlowMatchingModelpreserves the ODE marginals (#551 by @wesselvannierop)flat_aligned_apodizationcan be set explicitly (#552 by @wesselvannierop)init_deviceno longer writes the visible GPU ids toCUDA_VISIBLE_DEVICES(#554 by @wesselvannierop)Non-unit gain in the upmix/downmix roundtrip (#565 by @Louisvh)
v0.1.4 (2026-07-23)¶
New Features¶
Minimum variance beamformer,
zea.ops.MinimumVarianceorzea.ops.Beamform(beamformer="minimum_variance")(#490 by @tristan-deep)New probes
zea.probes.Verasonics_c5_2vandzea.probes.Verasonics_p4_2v, andf_numbersupports curved probes, computed with respect to the element normals (#516 by @tristan-deep)
Changed¶
The CLI parses its arguments with tyro (#521 by @tristan-deep)
Fixed¶
With
h5py>=3.16installed, v0.1.3 wrote.hdf5files in the HDF5 2.0 format, which older h5py/HDF5 installs cannot open. The write format is now capped, so files open with old and new installs alike. Fix files saved with v0.1.3 withzea data resave old_file.hdf5 new_file.hdf5, or read them withh5py>=3.16(#520 by @tristan-deep)
v0.1.3 (2026-07-17)¶
New Features¶
Stream zea files from Hugging Face with
zea.File("hf://...", stream=True): indexing or slicing a dataset downloads only that part. Resave datasets withzea data resavefor the best performance (#504 by @wesselvannierop)Ultrasound computed tomography with
zea.ops.USCTReflectivityDASandzea.func.usct_reflectivity_das()(#506 by @tristan-deep)New file fields
metadata.subject.weightandmetadata.subject.genetic_strain(#513 by @OisinNolan)Custom fields of a
zea.Filecan be indexed by name and with dots, like standard fields (#507 by @tristan-deep)Parameters.t_peakis derived fromwaveforms_two_waywhen available (#501 by @tristan-deep)zea datafile operations accepthf://paths (#502 by @tristan-deep)
Changed¶
HDF5 reads are up to 10 times faster and storage is about 2 times smaller, through new chunking and compression choices (#504 by @wesselvannierop)
Field names in a zea file must be snake_case (#507 by @tristan-deep)
zea data summaryandFile.summary()show the actual values, not just the field descriptions (#503 by @tristan-deep)zea.Pipelinegives clearer warnings and errors (#494 by @tristan-deep), as does reading HDF5 files (#512 by @tristan-deep)Log files are stored in a fixed location, and logging no longer interferes with progress bars (#488 by @wesselvannierop)
Fixed¶
Division by zero at
z=0in the lens-corrected delay computation (#497 by @tristan-deep)zea.ops.TissueSuppressionuses the complex-valued transpose (#514 by @OisinNolan)
v0.1.2 (2026-07-09)¶
New Features¶
Scanline beamforming, with the new
zea.ops.AlignedApodizationandzea.ops.ReceiveApodizationops and theenable_scanline,flat_receive_apodizationandflat_aligned_apodizationparameters (#482 by @tristan-deep)New file fields
metadata.subject.bmi(#469 by @tristan-deep) anddata.attenuation_map(#472 by @tristan-deep)Transmit-only tracks with
TrackSpec(transmit_only=True), which hold onlyscanparameters and nodata, e.g. for shear-wave push pulses or therapeutic exposures (#475 by @OisinNolan)zea.Datasetandzea.Dataloadertake afile_filterargument to keep only files whose content matches a predicate (#470 by @tristan-deep)
Changed¶
The
zeaCLI is split intozea data,zea processandzea app. Try it withzea --help(#477 by @wesselvannierop)
Fixed¶
Discontinuity of the transmit delays at the focus, with the new
focal_region_lengthparameter that smooths the transition (#481 by @tristan-deep)JIT compilation of nested pipelines (#465 by @wesselvannierop)
Shape consistency across data types and tracks (#483 by @wesselvannierop)
Nonevalues in the spec and parameters are no longer cast (#484 by @wesselvannierop)No warning about missing
azimuth_anglesfor 2D grids (#476 by @tristan-deep)
v0.1.1 (2026-06-25)¶
Changed¶
The Docker images ship with up-to-date machine learning libraries (#458 by @wesselvannierop)
set_transmitsis replaced byfind_transmits(#459 by @wesselvannierop)Masks accept arbitrary leading dimensions (#460 by @wesselvannierop)
Improvements to saving Verasonics data (#457 by @tristan-deep)
v0.1.0 (2026-06-22)¶
The first release with the new zea file format, designed for the OpenH-RF initiative. This section condenses the pre-releases v0.1.0a0 to v0.1.0a5; their release notes have the details.
New Features¶
New zea file format, with many more standardized (meta)data fields. Files saved with older versions are still read (#307 by @tristan-deep, #368 by @swpenninga)
A file stores a
probegroup (zea.data.spec.ProbeSpec) next to thescangroup (#379 by @tristan-deep)Multiple acquisition tracks in one file, e.g. B-mode and Doppler transmits that share the probe (#359 by @OisinNolan)
data/aligned_data,data/beamformed_data,data/envelope_dataanddata/imagestorevaluesandcoordinates, so their extent is known (#362 and #380 by @OisinNolan, #383 by @swpenninga)Custom elements in zea files with
zea.data.file.CustomElement(#450 by @wesselvannierop)Optional
acquisition_timefile attribute (#431 by @tristan-deep) andzea.File.timestampsfor the global timestamps of all transmit events (#437 by @OisinNolan)1D signals such as
metadata.ecgcan be stored with irregulartimestamps(#427 by @Felixduelmer), andscan.time_to_next_transmitcan omit its last value (#426 by @Felixduelmer)New
zeaCLI, withzea app(a Gradio app) andzea process(#416 by @tristan-deep)Custom operations in pipelines (#415 by @tristan-deep)
Load large datasets lazily with
zea.Dataset(..., lazy=True)(#419 by @tristan-deep)New ops
zea.ops.Refocus(#336 by @swpenninga) andzea.ops.TissueSuppression(#417 by @vincentvdschaft)New models
zea.models.speckle2self.Speckle2Self(#377 by @tristan-deep),zea.models.flow_matching.FlowMatchingModel(#378 by @swpenninga) and the Diffusion Transformer backbonezea.models.dit.DiTTimeConditional(#413 by @swpenninga)Percentile-based normalization in
zea.ops.Normalize(#353 by @wesselvannierop)passbandargument forzea.ops.BandPassFilter(#356 by @benluijten)zea.Dataloaderhas ashapeattribute and seeds its pipeline (#339 by @wesselvannierop), can disable re-shuffling (#352 by @wesselvannierop) and can zero-pad short videos instead of skipping them (#447 by @Louisvh)zea datafile operations work on folders (#354 by @wesselvannierop)Conversion scripts for PICMUS, CAMUS and CETUS store all metadata (#385 by @tristan-deep), a new EchoXFlow conversion script (#424 by @swpenninga), an improved EchoNet-LVH script (#435 by @wesselvannierop) and
--uploadto Hugging Face for the Verasonics conversion (#404 by @OisinNolan)
Changed¶
(Breaking)
zea.Scanis renamed tozea.Parameters. Load all parameters withzea.File.load_parameters()and pass them to a pipeline withpipeline.prepare_parameters(parameters).probe.center_frequencyis renamed toprobe.probe_center_frequency, and names inscanandprobemust not overlap (#392 by @wesselvannierop)(Breaking)
zea.Interfaceis removed in favor of thezea processCLI (#416 by @tristan-deep)(Breaking)
zea.File.createno longer returns an open file, andprobe.probe_geometryis required to savedata/raw_data(#411 by @wesselvannierop)(Breaking)
data/image_scis no longer a standard field, as images carry their coordinates (#439 by @swpenninga)(Breaking)
generate_zea_datasetis removed (#443 by @swpenninga)data/raw_datacan be stored asint16; addzea.ops.Cast(dtype="float32")at the start of a pipeline to avoid dtype errors (#307 by @tristan-deep)The default compression is
lzfinstead ofgzip(#399 by @tristan-deep)Deprecate
probe_namein favor of theprobegroup (#379 by @tristan-deep)Fewer and more relevant warnings when saving and loading files (#395 and #444 by @tristan-deep, #443 by @swpenninga)
Config validation is redesigned (#412 by @swpenninga)
Faster pressure field computation (#267 by @wesselvannierop)
zeais installed and developed with uv instead of Poetry (#425 by @tristan-deep)
Fixed¶
Near-field artifact in the pressure field (#267 by @wesselvannierop)
Importing
zeawithout tkinter installed (#432 by @OisinNolan)