.. _config: Parameters ========== .. note:: For the HDF5 data format and file I/O see :doc:`data-acquisition`. For pipeline operations see :doc:`pipeline`. ---------------------------- Parameters in the file ---------------------------- Every ``zea`` HDF5 file stores all parameters needed to process the acquisition alongside the raw data. They are split into two groups: **Probe** (``probe/``) Fixed for the whole acquisition — element geometry, center frequency, bandwidth, lens properties. Shared across all tracks. Defined by :class:`~zea.data.spec.ProbeSpec`. **Scan** (``scan/``) Per-track transmit sequence — delays, apodizations, angles, waveforms, sound speed. Each track has its own :class:`~zea.data.spec.ScanSpec`. See the :ref:`group-reference` table for the complete field listing. ---------------------------- zea.Parameters ---------------------------- :meth:`~zea.File.load_parameters` merges the probe and scan groups into a single :class:`~zea.Parameters` object and adds derived quantities (``wavelength``, ``n_tx``, ``grid``, ``xlims``/``zlims``, ``selected_transmits``): .. code-block:: python with zea.File("data.hdf5") as f: parameters = f.load_parameters() # single-track parameters = f.tracks[0].load_parameters() # multi-track ---------------------------- Config ---------------------------- A config is a YAML file (loaded as :class:`~zea.Config`) that specifies where the data lives, the pipeline to run, the device to use, and any parameter overrides. .. doctest:: >>> from zea import Config >>> from zea.config import check_config >>> config = Config.from_path("../configs/config_picmus_rf.yaml") >>> config = check_config(config) # fills defaults, validates >>> config.pipeline.operations # doctest: +NORMALIZE_WHITESPACE ['demodulate', {'name': 'downsample', 'params': {'factor': 4}}, {'name': 'beamform', 'params': {'beamformer': 'delay_and_sum', 'enable_pfield': False}}, 'envelope_detect', 'normalize', 'log_compress'] >>> config.to_yaml("my_config.yaml") .. testcleanup:: import os os.remove("my_config.yaml") Supported keys ~~~~~~~~~~~~~~ **data** — where to find the file .. list-table:: :header-rows: 1 :widths: 20 15 65 * - Key - Default - Description * - ``path`` - ``null`` - Full path to the HDF5 file. Supports local absolute paths, paths relative to the user data root (set in ``users.yaml``), and Hugging Face Hub paths (``hf://org/repo/path/to/file.hdf5``). * - ``local`` - ``true`` - Whether to use local data (``true``) or data at a remote location (``false``). Use ``null`` when the ``users.yaml`` paths are single paths, shared by both. * - ``indices`` - ``null`` - Which frames to load: ``null`` (default), ``'all'``, a single ``int``, or a list of positive ints. **parameters** — override any field from the :ref:`group-reference` or pass custom keys straight through to the pipeline: .. code-block:: yaml parameters: center_frequency: 5.0e6 xlims: [-0.02, 0.02] grid_size_x: 512 **pipeline** — list of operations (see :doc:`pipeline`): .. list-table:: :header-rows: 1 :widths: 20 15 65 * - Key - Default - Description * - ``operations`` - ``[identity]`` - Ordered list of operations. Each entry is either an operation name (string) or a mapping with ``name`` and optional ``params``. * - ``jit_options`` - ``'ops'`` - JIT scope: ``'ops'`` (compile each op), ``'pipeline'`` (compile the whole pipeline), or ``null`` (disable JIT). * - ``with_batch_dim`` - ``true`` - Whether operations expect a leading batch dimension. **Top-level keys** .. list-table:: :header-rows: 1 :widths: 20 15 65 * - Key - Default - Description * - ``device`` - ``'auto:1'`` - Target hardware: ``cpu``, ``gpu``, ``cuda``, ``gpu:0``, ``auto:1`` (auto-select; ``-1`` for last device). * - ``hide_devices`` - ``null`` - Device indices to exclude from auto-selection (int or list of ints). * - ``git`` - ``null`` - Git commit or branch recorded for reproducibility. The top-level config is **open**: arbitrary extra sections (``model:``, etc.) are accepted and passed through unchanged. ---------------------------- Defining a beamforming grid ---------------------------- A :class:`zea.Parameters` object builds a default beamforming grid from what a file records: the probe geometry, the transmits (``polar_angles``, ``transmit_origins`` and ``focus_distances``) and the record length. You choose the grid type with ``grid_type`` and ``enable_scanline``, and can tune the result with a few overrides. Positions are in the transducer frame: ``z = 0`` at the middle of the array, ``+z`` into the medium, and angles measured from ``+z``, positive toward ``+x`` (see :ref:`angle-conventions`). :attr:`~zea.Parameters.zlims` Depths below the transducer. Defaults to the end of the record, ``sound_speed * n_ax / sampling_frequency / 2``. :attr:`~zea.Parameters.xlims` The lateral extent of the grid. For a cartesian grid it covers what the transmits insonify down to ``zlims[1]``, and at least the probe width. For a polar grid it is the width of the sector; an explicit value sets the width of the scan-converted image instead (crop or pad). :attr:`~zea.Parameters.grid_apex` The point a polar grid fans out from, ``(0, 0, -d)`` on the central axis at or behind the array. It is derived from where the transmits fan out from: the point where steered transmit axes meet (the middle of the array, a virtual apex behind a flat array whose transmits are spread over it, or a curved array's centre of curvature), the virtual source of unsteered diverging waves, or else a curved array's centre of curvature. :attr:`~zea.Parameters.polar_limits` The angles of the first and last column of a polar grid: the range of the transmit angles, widened to cover what the transmits insonify at ``zlims[1]``. A focused transmit adds no margin; plane and diverging waves widen it. Set :attr:`~zea.Parameters.polar_margin` to widen by a fixed angle instead. :attr:`~zea.Parameters.rlims` The radii of the first and last row of a polar grid, measured from the apex: ``zlims - grid_apex[2]``. Scan conversion reads the polar image through ``rlims`` and ``polar_limits``. :attr:`~zea.Parameters.extent` For a polar grid, the window the scan-converted image fills: ``xlims`` wide, and on a flat array starting at ``zlims[0]``, which crops what a virtual apex places behind the array. :attr:`~zea.Parameters.enable_scanline` One column per focused transmit: a polar grid at the transmit angles when their axes meet in one point, or a vertical column under each transmit when they are parallel. :attr:`~zea.Parameters.f_number` The receive cone of each element. Defaults to the element's -6 dB acceptance angle, so 0 (no cone) for most phased arrays. It masks pixels but does not change the grid. Both figures below are drawn by the pixel grid explorer, a JavaScript port of the code checked against reference values computed by zea (``docs/explorer``). **Open the explorer** on either one to change the probe, transmits and overrides; the address then holds every setting, so you can share a link to the exact grid. .. raw:: html

A polar grid on a curved array fans out from its centre of curvature.

Focused lines that leave from across a phased array: their axes meet behind it in a virtual apex, and the grid fans out from there.

.. _angle-conventions: Angle and radius names ~~~~~~~~~~~~~~~~~~~~~~ zea uses two kinds of angles, in radians, both in the transducer frame (``x`` along the array, ``y`` across it, ``+z`` into the medium): - **Transmit directions** are `spherical coordinates `_, as stored in the file format. - **Grid and scan-conversion angles** are projections onto the x-z and y-z planes, so a 3D volume is a frustum that extends the 2D sector in elevation. .. list-table:: :header-rows: 1 :widths: 14 30 56 * - Symbol - Name - Meaning * - :math:`\theta` - ``polar_angles`` - Spherical polar angle of each transmit: the angle between its direction and ``+z``, signed, positive toward ``+x``. * - :math:`\phi` - ``azimuth_angles`` - Spherical azimuth angle of each transmit: the rotation of its direction around ``z``, from ``+x``. Zero for 2D imaging. * - :math:`r`, :math:`\rho` - ``rlims`` - Radius from :attr:`~zea.Parameters.grid_apex`, of the first and last row [m]. Not the depth: :attr:`~zea.Parameters.zlims` is measured from the array, so ``rlims = zlims - grid_apex[2]``. * - :math:`\operatorname{atan}(x/z)` - ``polar_limits`` - Polar angle of the first and last column of a polar grid, signed, positive toward ``+x``. In 3D, the angle of the projection onto the x-z plane. * - :math:`\operatorname{atan}(y/z)` - ``elevation_limits`` - Elevation angle of the first and last sample of a 3D frustum, signed, positive toward ``+y``. Only in 3D. Defaults to the transmits' elevation angles, widened by 15 % of their range, or by :attr:`~zea.Parameters.elevation_margin`. To find where a transmit falls on the grid, convert its spherical angles: .. math:: \text{polar} = \operatorname{atan}(\tan\theta\cos\phi), \qquad \text{elevation} = \operatorname{atan}(\tan\theta\sin\phi) A transmit steered only along the array has a grid polar angle equal to :math:`\theta`. Once it is also steered in elevation, the two differ. **Signed** :math:`\theta`\ **.** :math:`\theta` is stored with a sign, positive toward ``+x``. 2D data stores :math:`\phi = 0`. 3D data keeps :math:`\phi` in :math:`(-\pi/2, \pi/2]`, so the sign of :math:`\theta` still gives the side in ``x``. .. note:: **Physics vs. mathematics convention.** zea uses the physics convention (ISO 80000-2): :math:`\theta` is the polar angle from ``+z`` and :math:`\phi` the azimuth around ``z``. .. note:: **Ultrasound jargon.** In ultrasound, "azimuth" usually names the *lateral* direction, along the array (``x``). We instead follow the `spherical coordinate system `_ where azimuth :math:`\phi` is the rotation around the ``z`` axis. ---------------------------- API reference ---------------------------- .. autosummary:: zea.Config .. autofunction:: zea.config.check_config :no-index: