Skip to content

Transducers

All transducers share the TransducerBase interface: patch geometry, per-element compute_delays / compute_apodization, rigid transform, and 3-D show. Units are mm at the API surface. See the Transducers user guide.

Shared interface — TransducerBase

TransducerBase

TransducerBase()

Bases: ABC

Abstract base class for all transducer types.

Subclasses must implement: - _compute_element_centers() -> element positions in 3-D space - _build_subdivisions() -> rectangular patch geometry

Everything else (delay law, apodization setter/getter, mesh generation, visualization, state dict) is provided here and shared by all types.

Attributes:

Name Type Description
type str

Short type identifier (e.g. 'linear', 'matrix', 'circular').

name str

Human-readable class name.

n_elements int

Number of independently controlled elements (1 for mono-element types).

elem_width float

Characteristic element width in metres (used for patch-size reporting).

elem_height float

Characteristic element height in metres.

no_sub_x, no_sub_y int

Subdivision count along each axis (controls simulation accuracy).

fc float

Centre frequency in Hz (required by the eSDIva simulator).

speed_of_sound_mps float

Default propagation speed used when no c argument is supplied.

compute_delays

compute_delays(
    focus_mm=None,
    *,
    angle_steering_deg=None,
    c: Optional[float] = None,
    inline: bool = True,
    plot: bool = False,
) -> ndarray

Compute per-element time delays for electronic focusing or plane-wave steering.

Exactly one of focus_mm or angle_steering_deg must be provided.

Parameters:

Name Type Description Default
focus_mm (array - like, shape(2) or (3,))

Focal point in mm. If 2-D [x, z], y=0 is assumed. Mutually exclusive with angle_steering_deg.

None
angle_steering_deg float or (float, float)

Plane-wave steering angle(s) in degrees. A single float steers in the xz-plane only: (θ_x, θ_y=0). A tuple (θ_x, θ_y) steers in both xz and yz planes (matrix or 3-D arrays). Mutually exclusive with focus_mm.

None
c float

Speed of sound in m/s. Defaults to speed_of_sound_mps (1540).

None
inline bool

If True (default) store result in self.delays.

True
plot bool

If True, display a delay plot after computation.

False

Returns:

Type Description
ndarray

Delays in seconds, shape (n_elements,) (minimum delay is always 0).

Raises:

Type Description
ValueError

If both or neither of focus_mm / angle_steering_deg are given, or if the steering angles exceed the physical limit sin²θ_x + sin²θ_y > 1.

compute_apodization

compute_apodization(
    focus_mm=None,
    *,
    FoverD: Optional[float] = None,
    apodization_type: Optional[str] = None,
    plot: bool = False,
    inline: bool = True,
) -> ndarray

Return uniform full-aperture apodization (all ones).

Mono-element transducers use the full aperture by definition. Multi-element subclasses (linear, matrix) override this method with window-based aperture selection.

For mono-element transducers, patch-wise apodization can still be set directly via set_apodization().

Parameters:

Name Type Description Default
focus_mm array - like

Accepted for API consistency with multi-element subclasses.

None
FoverD float

Accepted for API consistency.

None
apodization_type str

Accepted for API consistency.

None
plot bool

Accepted for API consistency.

False
inline bool

If True (default), store result in self.apodization.

True

Returns:

Type Description
ndarray

Uniform apodization weights, shape (n_elements,).

set_apodization

set_apodization(weights: ndarray) -> None

Set per-element apodization weights directly.

Parameters:

Name Type Description Default
weights ndarray

Apodization weights, shape (n_elements,).

required

set_impulse_response

set_impulse_response(ir: Optional[ndarray]) -> None

Set the transducers impulse response.

Parameters:

Name Type Description Default
ir ndarray or None

Impulse response array. Converted to 1-D float32 and ravelled. None = ideal (delta) response.

required

set_excitation

set_excitation(exc: Optional[ndarray]) -> None

Set the transducers excitation pulse.

Parameters:

Name Type Description Default
exc ndarray or None

Excitation array. Converted to 1-D float32 and ravelled. None = impulse (delta) excitation.

required

transform

transform(T_matrix) -> None

Rigidly move the aperture in space (rotation then translation).

Applies the homogeneous transform to the computed geometry — patch vertices, patch frames (centres, normals, tangents) and element centres — so the SIR simulation and the visualisation both see the moved aperture. Patch widths are rotation-invariant and unchanged.

Delays and apodization are firing-time / weight state, not geometry, so they are untouched: a focus computed before the move still aims at the old global-frame target — call compute_delays / compute_apodization again after moving if the beam must follow.

Parameters:

Name Type Description Default
T_matrix (4, 4) array-like

Homogeneous rigid-body transform. The upper-left 3×3 block is the rotation (orthogonal, det +1); the last column is the translation in mm (user-facing unit).

required

Raises:

Type Description
ValueError

If T_matrix is not (4, 4) or its 3×3 block is not a proper rotation — scaling or reflection would corrupt the patch widths and normals the SIR kernel relies on.

Notes

Simulators snapshot the transducer geometry at construction: after transforming, refresh them with sim.set("transducer", tx) (Emission) or sim.set("tx", tx) / sim.set("rx", rx) (Reception). clean() discards cached geometry, so a rebuilt transducer returns to its canonical pose (the transform is not replayed).

clean

clean() -> None

Release cached geometry arrays to free memory.

get_mesh

get_mesh() -> PolyData

Build a PyVista surface mesh of the transducer.

Returns:

Type Description
PolyData

Mesh with 'Apodization' and 'Delays' as cell arrays.

show

show(
    *,
    window_size: Tuple[int, int] = (800, 600),
    scalars: str = "Apodization",
    notebook: bool = False,
    jupyter_backend: Optional[str] = None,
    colorbar_title: Optional[str] = None,
    **kwargs,
) -> None

Interactive 3-D visualisation of the transducer surface.

Parameters:

Name Type Description Default
window_size (int, int)

Pixel dimensions of the render window.

(800, 600)
scalars (Apodization, Delays)

Which cell array to colour by.

'Apodization'
notebook bool

Enable Jupyter notebook rendering.

False
jupyter_backend str

Backend string passed to PyVista ('static', 'trame' …).

None
colorbar_title str

Override the default colour-bar label.

None
**kwargs

Forwarded to plotter.add_mesh().

{}

Array transducers

LinearArrayTransducer

LinearArrayTransducer(
    *,
    n_elements: int,
    element_width_mm: float,
    element_height_mm: float,
    kerf_mm: float,
    no_sub_x: int,
    no_sub_y: int,
    elevation_focus_mm: Optional[float] = None,
    frequency_Hz: Optional[float] = None,
)

Bases: TransducerBase

1-D linear array transducer.

Elements are laid out along x. Electronic beam steering and focusing are controlled via compute_delays / compute_apodization. Elevation focusing (y-direction) is achieved by curving the element surface into a cylindrical arc.

Parameters:

Name Type Description Default
n_elements int

Number of active elements.

required
element_width_mm float

Element dimension along the steering axis (x), in mm.

required
element_height_mm float

Element dimension in the elevation axis (y), in mm.

required
kerf_mm float

Gap between adjacent elements in mm (≥ 0).

required
no_sub_x int

Subdivisions per element in x (lateral, ≥ 1).

required
no_sub_y int

Subdivisions per element in y (elevation, ≥ 1). Must be ≥ 2 when elevation_focus_mm is set.

required
elevation_focus_mm float

Radius of curvature for the cylindrical lens in mm. None (default) means a flat aperture.

None
frequency_Hz float

Centre frequency in Hz. Defaults to 1 MHz with a warning.

None

speed_of_sound_mps instance-attribute

speed_of_sound_mps: float = 1540.0

_apodization instance-attribute

_apodization: Optional[ndarray] = None

_delays instance-attribute

_delays: Optional[ndarray] = None

_elevation_lens_sag instance-attribute

_elevation_lens_sag: Optional[float] = None

apodization_type instance-attribute

apodization_type: Optional[str] = None

FoverD instance-attribute

FoverD: Optional[float] = None

_impulse_response instance-attribute

_impulse_response: Optional[ndarray] = None

_excitation instance-attribute

_excitation: Optional[ndarray] = None

_element_centers instance-attribute

_element_centers: Optional[ndarray] = None

_sub_quad_verts instance-attribute

_sub_quad_verts: Optional[List[ndarray]] = None

_sub_area instance-attribute

_sub_area: Optional[float] = None

_sub_el_idx instance-attribute

_sub_el_idx: Optional[List[int]] = None

_sub_patch_frames instance-attribute

_sub_patch_frames: Optional[Dict] = None

element_centers property

element_centers: ndarray

3-D element centre positions, shape (n_elements, 3) in metres.

Returns:

Type Description
ndarray

Array of shape (n_elements, 3) with element positions in metres.

elevation_lens_sag property writable

elevation_lens_sag: float

Depth (m) a cylindrical elevation lens dishes the surface back at its centre.

Zero for flat/unfocused apertures. For a lens of radius R and element height h the surface centre sits R − √(R² − (h/2)²) behind the rim. The pulse-echo time origin is referenced to the first-arriving edge (the rim), but a focused elevation aperture's echo peaks one lens transit later, so reception adds this sag — as a propagation time, once per aperture — to align the RF origin with a lens-focused reference.

Settable: assign a value in metres to override the geometric default — needed for imported geometries (e.g. a Field II xdc_focused_array probe) whose lens curvature is present in the patches but whose focal parameters are not known to eSDIva. Assign None to restore the default. Subclasses with a native lens supply the default via _default_elevation_lens_sag.

Returns:

Type Description
float

Lens sag in metres (0.0 for flat/unfocused apertures).

sub_quad_verts property

sub_quad_verts: List[ndarray]

List of quad-vertex arrays (4, 3) for every patch, in metres.

Returns:

Type Description
list of ndarray

Each element is a (4, 3) array of corner positions.

sub_area property

sub_area: float

Patch area in m² (same for all patches in a uniform grid).

Returns:

Type Description
float

Area of each sub-patch in square metres.

sub_el_idx property

sub_el_idx: List[int]

Element index for each patch; maps patch to parent element.

Returns:

Type Description
list of int

Index of the parent element for each sub-patch.

n_sub_patches property

n_sub_patches: int

Total number of rectangular sub-patches across all elements.

Returns:

Type Description
int

Number of sub-patches.

sub_patch_frames property

sub_patch_frames: Dict

Per-patch rigid-body frames used by the SIR kernel.

Returns a dict with keys centers, normals, tangents_u, tangents_v, wu, wv — all ndarrays indexed by patch.

For flat transducers the default implementation computes frames from the vertex edge vectors (v[1]-v[0] and v[3]-v[0]), which is exact for any flat, arbitrarily-oriented patch. Curved transducers override _build_patch_frames to return surface-accurate frames derived from the parametric surface equations.

Returns:

Type Description
dict

Patch-frame arrays keyed by centers, normals, etc.

apodization property writable

apodization: ndarray

Per-element apodization weights, shape (n_elements,).

Returns:

Type Description
ndarray

Apodization weights for each element.

delays property writable

delays: ndarray

Per-element delays in seconds, shape (n_elements,).

Returns:

Type Description
ndarray

Delay values for each element in seconds.

tx_N_active property

tx_N_active: int

Number of elements with non-zero apodization.

Returns:

Type Description
int

Count of active elements.

impulse_response property writable

impulse_response: Optional[ndarray]

Electromechanical impulse response of the transducer element.

1-D float32 array sampled at the simulation sampling frequency. Represents the electrical-to-acoustic (TX) or acoustic-to-electrical (RX) transfer function. Applied via convolution in the frequency domain.

None = ideal (delta function) — no filtering.

Returns:

Type Description
ndarray or None

Impulse response array of shape (L_ir,), or None.

excitation property writable

excitation: Optional[ndarray]

Excitation pulse for this transducer.

1-D float32 array sampled at the simulation sampling frequency. None = impulse (delta) excitation.

Returns:

Type Description
ndarray or None

Excitation array of shape (L_exc,), or None.

_build_patch_frames

_build_patch_frames() -> Dict

Default patch-frame builder for flat transducers.

Computes each patch's local frame directly from its corner vertices:

  • tangent_u = normalised v[1] - v[0] (first edge)
  • tangent_v = v[3] - v[0] orthogonalised against tangent_u
  • normal = tangent_u × tangent_v
  • wu = ‖v[1] - v[0]‖
  • wv = ‖v[3] - v[0]‖

This is exact for truly flat patches and gives a good approximation for very gently curved surfaces. Subclasses whose geometry is significantly curved should override this method (or set _sub_patch_frames as a side-effect inside _build_subdivisions).

compute_delays

compute_delays(
    focus_mm=None,
    *,
    angle_steering_deg=None,
    c: Optional[float] = None,
    inline: bool = True,
    plot: bool = False,
) -> ndarray

Compute per-element time delays for electronic focusing or plane-wave steering.

Exactly one of focus_mm or angle_steering_deg must be provided.

Parameters:

Name Type Description Default
focus_mm (array - like, shape(2) or (3,))

Focal point in mm. If 2-D [x, z], y=0 is assumed. Mutually exclusive with angle_steering_deg.

None
angle_steering_deg float or (float, float)

Plane-wave steering angle(s) in degrees. A single float steers in the xz-plane only: (θ_x, θ_y=0). A tuple (θ_x, θ_y) steers in both xz and yz planes (matrix or 3-D arrays). Mutually exclusive with focus_mm.

None
c float

Speed of sound in m/s. Defaults to speed_of_sound_mps (1540).

None
inline bool

If True (default) store result in self.delays.

True
plot bool

If True, display a delay plot after computation.

False

Returns:

Type Description
ndarray

Delays in seconds, shape (n_elements,) (minimum delay is always 0).

Raises:

Type Description
ValueError

If both or neither of focus_mm / angle_steering_deg are given, or if the steering angles exceed the physical limit sin²θ_x + sin²θ_y > 1.

set_apodization

set_apodization(weights: ndarray) -> None

Set per-element apodization weights directly.

Parameters:

Name Type Description Default
weights ndarray

Apodization weights, shape (n_elements,).

required

set_delays

set_delays(delays: ndarray) -> None

Set per-element delays directly (normalised so minimum = 0).

Parameters:

Name Type Description Default
delays ndarray

Delays in seconds, shape (n_elements,).

required

set_impulse_response

set_impulse_response(ir: Optional[ndarray]) -> None

Set the transducers impulse response.

Parameters:

Name Type Description Default
ir ndarray or None

Impulse response array. Converted to 1-D float32 and ravelled. None = ideal (delta) response.

required

set_excitation

set_excitation(exc: Optional[ndarray]) -> None

Set the transducers excitation pulse.

Parameters:

Name Type Description Default
exc ndarray or None

Excitation array. Converted to 1-D float32 and ravelled. None = impulse (delta) excitation.

required

get_mesh

get_mesh() -> PolyData

Build a PyVista surface mesh of the transducer.

Returns:

Type Description
PolyData

Mesh with 'Apodization' and 'Delays' as cell arrays.

show

show(
    *,
    window_size: Tuple[int, int] = (800, 600),
    scalars: str = "Apodization",
    notebook: bool = False,
    jupyter_backend: Optional[str] = None,
    colorbar_title: Optional[str] = None,
    **kwargs,
) -> None

Interactive 3-D visualisation of the transducer surface.

Parameters:

Name Type Description Default
window_size (int, int)

Pixel dimensions of the render window.

(800, 600)
scalars (Apodization, Delays)

Which cell array to colour by.

'Apodization'
notebook bool

Enable Jupyter notebook rendering.

False
jupyter_backend str

Backend string passed to PyVista ('static', 'trame' …).

None
colorbar_title str

Override the default colour-bar label.

None
**kwargs

Forwarded to plotter.add_mesh().

{}

plot_apodization

plot_apodization(
    apodization: Optional[ndarray] = None,
    *,
    figsize: Tuple[int, int] = (6, 5),
    ax=None,
)

Plot apodization weights as a line/stem chart.

For 2-D matrix transducers, override this method to produce an image.

Parameters:

Name Type Description Default
apodization ndarray

Weights to plot. Defaults to self.apodization.

None
figsize tuple of int

Figure size in inches (width, height).

(6, 5)
ax Axes

Axes to draw on. If None, a new figure is created.

None

Returns:

Type Description
Axes or None

The axes object if ax was provided, otherwise None.

plot_delays

plot_delays(
    delays: Optional[ndarray] = None,
    *,
    figsize: Tuple[int, int] = (6, 5),
    ax=None,
)

Plot per-element delays in microseconds.

Parameters:

Name Type Description Default
delays ndarray

Delays to plot. Defaults to self.delays.

None
figsize tuple of int

Figure size in inches (width, height).

(6, 5)
ax Axes

Axes to draw on. If None, a new figure is created.

None

Returns:

Type Description
Axes or None

The axes object if ax was provided, otherwise None.

plot_delays_apodization

plot_delays_apodization(
    figsize: Tuple[int, int] = (10, 4),
) -> None

Side-by-side delay and apodization plot.

Parameters:

Name Type Description Default
figsize tuple of int

Figure size in inches (width, height).

(10, 4)

transform

transform(T_matrix) -> None

Rigidly move the aperture in space (rotation then translation).

Applies the homogeneous transform to the computed geometry — patch vertices, patch frames (centres, normals, tangents) and element centres — so the SIR simulation and the visualisation both see the moved aperture. Patch widths are rotation-invariant and unchanged.

Delays and apodization are firing-time / weight state, not geometry, so they are untouched: a focus computed before the move still aims at the old global-frame target — call compute_delays / compute_apodization again after moving if the beam must follow.

Parameters:

Name Type Description Default
T_matrix (4, 4) array-like

Homogeneous rigid-body transform. The upper-left 3×3 block is the rotation (orthogonal, det +1); the last column is the translation in mm (user-facing unit).

required

Raises:

Type Description
ValueError

If T_matrix is not (4, 4) or its 3×3 block is not a proper rotation — scaling or reflection would corrupt the patch widths and normals the SIR kernel relies on.

Notes

Simulators snapshot the transducer geometry at construction: after transforming, refresh them with sim.set("transducer", tx) (Emission) or sim.set("tx", tx) / sim.set("rx", rx) (Reception). clean() discards cached geometry, so a rebuilt transducer returns to its canonical pose (the transform is not replayed).

clean

clean() -> None

Release cached geometry arrays to free memory.

copy

copy() -> TransducerBase

Return a deep copy of this transducer, including all state and cached geometry.

Returns:

Type Description
TransducerBase

Independent copy: mutating its delays/apodization/geometry leaves the original untouched.

get_state_dict

get_state_dict() -> Dict[str, Any]

Return a snapshot of the current apodization / delay state.

Returns:

Type Description
dict

Keys apodization, delays, apodization_type, FoverD.

set_state_dict

set_state_dict(state: Dict[str, Any]) -> None

Restore apodization / delay state from a dictionary.

Parameters:

Name Type Description Default
state dict

State dictionary as returned by get_state_dict().

required

ConvexArrayTransducer

ConvexArrayTransducer(
    *,
    n_elements: int,
    element_width_mm: float,
    element_height_mm: float,
    kerf_mm: float,
    radius_of_curvature_mm: float,
    no_sub_x: int,
    no_sub_y: int,
    elevation_focus_mm: Optional[float] = None,
    frequency_Hz: Optional[float] = None,
)

Bases: TransducerBase

Convex (curvilinear) linear array transducer.

Elements are arranged on a convex cylindrical arc in the XZ plane — the standard geometry for abdominal, cardiac, and obstetric probes. The centre of curvature sits behind the probe face at z = -R, so outer elements are tilted outward and the field of view widens with depth.

The centre element is positioned at the origin with its normal pointing in +z (depth direction). Electronic beam steering and focusing are controlled by compute_delays / compute_apodization.

Parameters:

Name Type Description Default
n_elements int

Number of active elements.

required
element_width_mm float

Arc-length dimension of each element (azimuth), in mm.

required
element_height_mm float

Element dimension in the elevation axis (y), in mm.

required
kerf_mm float

Arc-length gap between adjacent elements, in mm (≥ 0).

required
radius_of_curvature_mm float

Radius of the convex arc in mm. Larger values give a flatter probe. Typical clinical values: 40 – 80 mm.

required
no_sub_x int

Patch subdivisions per element along the arc (azimuth, ≥ 1).

required
no_sub_y int

Patch subdivisions per element in elevation (y, ≥ 1). Must be ≥ 2 when elevation_focus_mm is set.

required
elevation_focus_mm float

Cylindrical elevation-lens focus depth in mm. When provided, each element surface is curved in the y-direction so that z(y) = R_elev - √(R_elev² - y²), producing a geometric line focus at elevation_focus_mm depth in elevation. Equivalent to the acoustic lens of a focused convex probe (FIELD II xdc_focused_convex). Must be ≥ element_height_mm / 2.

None
frequency_Hz float

Centre frequency in Hz. Defaults to 1 MHz with a warning.

None

speed_of_sound_mps instance-attribute

speed_of_sound_mps: float = 1540.0

_apodization instance-attribute

_apodization: Optional[ndarray] = None

_delays instance-attribute

_delays: Optional[ndarray] = None

_elevation_lens_sag instance-attribute

_elevation_lens_sag: Optional[float] = None

apodization_type instance-attribute

apodization_type: Optional[str] = None

FoverD instance-attribute

FoverD: Optional[float] = None

_impulse_response instance-attribute

_impulse_response: Optional[ndarray] = None

_excitation instance-attribute

_excitation: Optional[ndarray] = None

_element_centers instance-attribute

_element_centers: Optional[ndarray] = None

_sub_quad_verts instance-attribute

_sub_quad_verts: Optional[List[ndarray]] = None

_sub_area instance-attribute

_sub_area: Optional[float] = None

_sub_el_idx instance-attribute

_sub_el_idx: Optional[List[int]] = None

_sub_patch_frames instance-attribute

_sub_patch_frames: Optional[Dict] = None

element_centers property

element_centers: ndarray

3-D element centre positions, shape (n_elements, 3) in metres.

Returns:

Type Description
ndarray

Array of shape (n_elements, 3) with element positions in metres.

elevation_lens_sag property writable

elevation_lens_sag: float

Depth (m) a cylindrical elevation lens dishes the surface back at its centre.

Zero for flat/unfocused apertures. For a lens of radius R and element height h the surface centre sits R − √(R² − (h/2)²) behind the rim. The pulse-echo time origin is referenced to the first-arriving edge (the rim), but a focused elevation aperture's echo peaks one lens transit later, so reception adds this sag — as a propagation time, once per aperture — to align the RF origin with a lens-focused reference.

Settable: assign a value in metres to override the geometric default — needed for imported geometries (e.g. a Field II xdc_focused_array probe) whose lens curvature is present in the patches but whose focal parameters are not known to eSDIva. Assign None to restore the default. Subclasses with a native lens supply the default via _default_elevation_lens_sag.

Returns:

Type Description
float

Lens sag in metres (0.0 for flat/unfocused apertures).

sub_quad_verts property

sub_quad_verts: List[ndarray]

List of quad-vertex arrays (4, 3) for every patch, in metres.

Returns:

Type Description
list of ndarray

Each element is a (4, 3) array of corner positions.

sub_area property

sub_area: float

Patch area in m² (same for all patches in a uniform grid).

Returns:

Type Description
float

Area of each sub-patch in square metres.

sub_el_idx property

sub_el_idx: List[int]

Element index for each patch; maps patch to parent element.

Returns:

Type Description
list of int

Index of the parent element for each sub-patch.

n_sub_patches property

n_sub_patches: int

Total number of rectangular sub-patches across all elements.

Returns:

Type Description
int

Number of sub-patches.

sub_patch_frames property

sub_patch_frames: Dict

Per-patch rigid-body frames used by the SIR kernel.

Returns a dict with keys centers, normals, tangents_u, tangents_v, wu, wv — all ndarrays indexed by patch.

For flat transducers the default implementation computes frames from the vertex edge vectors (v[1]-v[0] and v[3]-v[0]), which is exact for any flat, arbitrarily-oriented patch. Curved transducers override _build_patch_frames to return surface-accurate frames derived from the parametric surface equations.

Returns:

Type Description
dict

Patch-frame arrays keyed by centers, normals, etc.

apodization property writable

apodization: ndarray

Per-element apodization weights, shape (n_elements,).

Returns:

Type Description
ndarray

Apodization weights for each element.

delays property writable

delays: ndarray

Per-element delays in seconds, shape (n_elements,).

Returns:

Type Description
ndarray

Delay values for each element in seconds.

tx_N_active property

tx_N_active: int

Number of elements with non-zero apodization.

Returns:

Type Description
int

Count of active elements.

impulse_response property writable

impulse_response: Optional[ndarray]

Electromechanical impulse response of the transducer element.

1-D float32 array sampled at the simulation sampling frequency. Represents the electrical-to-acoustic (TX) or acoustic-to-electrical (RX) transfer function. Applied via convolution in the frequency domain.

None = ideal (delta function) — no filtering.

Returns:

Type Description
ndarray or None

Impulse response array of shape (L_ir,), or None.

excitation property writable

excitation: Optional[ndarray]

Excitation pulse for this transducer.

1-D float32 array sampled at the simulation sampling frequency. None = impulse (delta) excitation.

Returns:

Type Description
ndarray or None

Excitation array of shape (L_exc,), or None.

_build_patch_frames

_build_patch_frames() -> Dict

Default patch-frame builder for flat transducers.

Computes each patch's local frame directly from its corner vertices:

  • tangent_u = normalised v[1] - v[0] (first edge)
  • tangent_v = v[3] - v[0] orthogonalised against tangent_u
  • normal = tangent_u × tangent_v
  • wu = ‖v[1] - v[0]‖
  • wv = ‖v[3] - v[0]‖

This is exact for truly flat patches and gives a good approximation for very gently curved surfaces. Subclasses whose geometry is significantly curved should override this method (or set _sub_patch_frames as a side-effect inside _build_subdivisions).

compute_delays

compute_delays(
    focus_mm=None,
    *,
    angle_steering_deg=None,
    c: Optional[float] = None,
    inline: bool = True,
    plot: bool = False,
) -> ndarray

Compute per-element time delays for electronic focusing or plane-wave steering.

Exactly one of focus_mm or angle_steering_deg must be provided.

Parameters:

Name Type Description Default
focus_mm (array - like, shape(2) or (3,))

Focal point in mm. If 2-D [x, z], y=0 is assumed. Mutually exclusive with angle_steering_deg.

None
angle_steering_deg float or (float, float)

Plane-wave steering angle(s) in degrees. A single float steers in the xz-plane only: (θ_x, θ_y=0). A tuple (θ_x, θ_y) steers in both xz and yz planes (matrix or 3-D arrays). Mutually exclusive with focus_mm.

None
c float

Speed of sound in m/s. Defaults to speed_of_sound_mps (1540).

None
inline bool

If True (default) store result in self.delays.

True
plot bool

If True, display a delay plot after computation.

False

Returns:

Type Description
ndarray

Delays in seconds, shape (n_elements,) (minimum delay is always 0).

Raises:

Type Description
ValueError

If both or neither of focus_mm / angle_steering_deg are given, or if the steering angles exceed the physical limit sin²θ_x + sin²θ_y > 1.

set_apodization

set_apodization(weights: ndarray) -> None

Set per-element apodization weights directly.

Parameters:

Name Type Description Default
weights ndarray

Apodization weights, shape (n_elements,).

required

set_delays

set_delays(delays: ndarray) -> None

Set per-element delays directly (normalised so minimum = 0).

Parameters:

Name Type Description Default
delays ndarray

Delays in seconds, shape (n_elements,).

required

set_impulse_response

set_impulse_response(ir: Optional[ndarray]) -> None

Set the transducers impulse response.

Parameters:

Name Type Description Default
ir ndarray or None

Impulse response array. Converted to 1-D float32 and ravelled. None = ideal (delta) response.

required

set_excitation

set_excitation(exc: Optional[ndarray]) -> None

Set the transducers excitation pulse.

Parameters:

Name Type Description Default
exc ndarray or None

Excitation array. Converted to 1-D float32 and ravelled. None = impulse (delta) excitation.

required

get_mesh

get_mesh() -> PolyData

Build a PyVista surface mesh of the transducer.

Returns:

Type Description
PolyData

Mesh with 'Apodization' and 'Delays' as cell arrays.

show

show(
    *,
    window_size: Tuple[int, int] = (800, 600),
    scalars: str = "Apodization",
    notebook: bool = False,
    jupyter_backend: Optional[str] = None,
    colorbar_title: Optional[str] = None,
    **kwargs,
) -> None

Interactive 3-D visualisation of the transducer surface.

Parameters:

Name Type Description Default
window_size (int, int)

Pixel dimensions of the render window.

(800, 600)
scalars (Apodization, Delays)

Which cell array to colour by.

'Apodization'
notebook bool

Enable Jupyter notebook rendering.

False
jupyter_backend str

Backend string passed to PyVista ('static', 'trame' …).

None
colorbar_title str

Override the default colour-bar label.

None
**kwargs

Forwarded to plotter.add_mesh().

{}

plot_apodization

plot_apodization(
    apodization: Optional[ndarray] = None,
    *,
    figsize: Tuple[int, int] = (6, 5),
    ax=None,
)

Plot apodization weights as a line/stem chart.

For 2-D matrix transducers, override this method to produce an image.

Parameters:

Name Type Description Default
apodization ndarray

Weights to plot. Defaults to self.apodization.

None
figsize tuple of int

Figure size in inches (width, height).

(6, 5)
ax Axes

Axes to draw on. If None, a new figure is created.

None

Returns:

Type Description
Axes or None

The axes object if ax was provided, otherwise None.

plot_delays

plot_delays(
    delays: Optional[ndarray] = None,
    *,
    figsize: Tuple[int, int] = (6, 5),
    ax=None,
)

Plot per-element delays in microseconds.

Parameters:

Name Type Description Default
delays ndarray

Delays to plot. Defaults to self.delays.

None
figsize tuple of int

Figure size in inches (width, height).

(6, 5)
ax Axes

Axes to draw on. If None, a new figure is created.

None

Returns:

Type Description
Axes or None

The axes object if ax was provided, otherwise None.

plot_delays_apodization

plot_delays_apodization(
    figsize: Tuple[int, int] = (10, 4),
) -> None

Side-by-side delay and apodization plot.

Parameters:

Name Type Description Default
figsize tuple of int

Figure size in inches (width, height).

(10, 4)

transform

transform(T_matrix) -> None

Rigidly move the aperture in space (rotation then translation).

Applies the homogeneous transform to the computed geometry — patch vertices, patch frames (centres, normals, tangents) and element centres — so the SIR simulation and the visualisation both see the moved aperture. Patch widths are rotation-invariant and unchanged.

Delays and apodization are firing-time / weight state, not geometry, so they are untouched: a focus computed before the move still aims at the old global-frame target — call compute_delays / compute_apodization again after moving if the beam must follow.

Parameters:

Name Type Description Default
T_matrix (4, 4) array-like

Homogeneous rigid-body transform. The upper-left 3×3 block is the rotation (orthogonal, det +1); the last column is the translation in mm (user-facing unit).

required

Raises:

Type Description
ValueError

If T_matrix is not (4, 4) or its 3×3 block is not a proper rotation — scaling or reflection would corrupt the patch widths and normals the SIR kernel relies on.

Notes

Simulators snapshot the transducer geometry at construction: after transforming, refresh them with sim.set("transducer", tx) (Emission) or sim.set("tx", tx) / sim.set("rx", rx) (Reception). clean() discards cached geometry, so a rebuilt transducer returns to its canonical pose (the transform is not replayed).

clean

clean() -> None

Release cached geometry arrays to free memory.

copy

copy() -> TransducerBase

Return a deep copy of this transducer, including all state and cached geometry.

Returns:

Type Description
TransducerBase

Independent copy: mutating its delays/apodization/geometry leaves the original untouched.

get_state_dict

get_state_dict() -> Dict[str, Any]

Return a snapshot of the current apodization / delay state.

Returns:

Type Description
dict

Keys apodization, delays, apodization_type, FoverD.

set_state_dict

set_state_dict(state: Dict[str, Any]) -> None

Restore apodization / delay state from a dictionary.

Parameters:

Name Type Description Default
state dict

State dictionary as returned by get_state_dict().

required

MatrixArrayTransducer

MatrixArrayTransducer(
    *,
    n_elements_x: int,
    n_elements_y: int,
    element_width_mm,
    element_height_mm,
    kerf_x_mm: float,
    kerf_y_mm: float,
    no_sub_x: int,
    no_sub_y: int,
    frequency_Hz: Optional[float] = None,
    dir_angle_deg: float = 30.0,
)

Bases: TransducerBase

2-D matrix (multi-row) array transducer.

Parameters:

Name Type Description Default
n_elements_x int

Number of elements in the x-direction (lateral).

required
n_elements_y int

Number of elements in the y-direction (elevation).

required
element_width_mm float or array-like of length n_elements_x

Element width(s) in x, in mm. A scalar applies the same width to every column; an array allows per-column width variation.

required
element_height_mm float or array-like of length n_elements_y

Element height(s) in y, in mm. Scalar or per-row array.

required
kerf_x_mm float

Inter-element gap in x, in mm (≥ 0).

required
kerf_y_mm float

Inter-element gap in y, in mm (≥ 0).

required
no_sub_x int

Subdivisions per element in x (≥ 1).

required
no_sub_y int

Subdivisions per element in y (≥ 1).

required
frequency_Hz float

Centre frequency in Hz.

None
dir_angle_deg float

Half-angle directivity cone used when computing the active aperture for a given F/D. Default is 30°.

30.0

speed_of_sound_mps instance-attribute

speed_of_sound_mps: float = 1540.0

_apodization instance-attribute

_apodization: Optional[ndarray] = None

_delays instance-attribute

_delays: Optional[ndarray] = None

_elevation_lens_sag instance-attribute

_elevation_lens_sag: Optional[float] = None

apodization_type instance-attribute

apodization_type: Optional[str] = None

FoverD instance-attribute

FoverD: Optional[float] = None

_impulse_response instance-attribute

_impulse_response: Optional[ndarray] = None

_excitation instance-attribute

_excitation: Optional[ndarray] = None

_element_centers instance-attribute

_element_centers: Optional[ndarray] = None

_sub_quad_verts instance-attribute

_sub_quad_verts: Optional[List[ndarray]] = None

_sub_area instance-attribute

_sub_area: Optional[float] = None

_sub_el_idx instance-attribute

_sub_el_idx: Optional[List[int]] = None

_sub_patch_frames instance-attribute

_sub_patch_frames: Optional[Dict] = None

element_centers property

element_centers: ndarray

3-D element centre positions, shape (n_elements, 3) in metres.

Returns:

Type Description
ndarray

Array of shape (n_elements, 3) with element positions in metres.

elevation_lens_sag property writable

elevation_lens_sag: float

Depth (m) a cylindrical elevation lens dishes the surface back at its centre.

Zero for flat/unfocused apertures. For a lens of radius R and element height h the surface centre sits R − √(R² − (h/2)²) behind the rim. The pulse-echo time origin is referenced to the first-arriving edge (the rim), but a focused elevation aperture's echo peaks one lens transit later, so reception adds this sag — as a propagation time, once per aperture — to align the RF origin with a lens-focused reference.

Settable: assign a value in metres to override the geometric default — needed for imported geometries (e.g. a Field II xdc_focused_array probe) whose lens curvature is present in the patches but whose focal parameters are not known to eSDIva. Assign None to restore the default. Subclasses with a native lens supply the default via _default_elevation_lens_sag.

Returns:

Type Description
float

Lens sag in metres (0.0 for flat/unfocused apertures).

sub_quad_verts property

sub_quad_verts: List[ndarray]

List of quad-vertex arrays (4, 3) for every patch, in metres.

Returns:

Type Description
list of ndarray

Each element is a (4, 3) array of corner positions.

sub_area property

sub_area: float

Patch area in m² (same for all patches in a uniform grid).

Returns:

Type Description
float

Area of each sub-patch in square metres.

sub_el_idx property

sub_el_idx: List[int]

Element index for each patch; maps patch to parent element.

Returns:

Type Description
list of int

Index of the parent element for each sub-patch.

n_sub_patches property

n_sub_patches: int

Total number of rectangular sub-patches across all elements.

Returns:

Type Description
int

Number of sub-patches.

sub_patch_frames property

sub_patch_frames: Dict

Per-patch rigid-body frames used by the SIR kernel.

Returns a dict with keys centers, normals, tangents_u, tangents_v, wu, wv — all ndarrays indexed by patch.

For flat transducers the default implementation computes frames from the vertex edge vectors (v[1]-v[0] and v[3]-v[0]), which is exact for any flat, arbitrarily-oriented patch. Curved transducers override _build_patch_frames to return surface-accurate frames derived from the parametric surface equations.

Returns:

Type Description
dict

Patch-frame arrays keyed by centers, normals, etc.

apodization property writable

apodization: ndarray

Per-element apodization weights, shape (n_elements,).

Returns:

Type Description
ndarray

Apodization weights for each element.

delays property writable

delays: ndarray

Per-element delays in seconds, shape (n_elements,).

Returns:

Type Description
ndarray

Delay values for each element in seconds.

tx_N_active property

tx_N_active: int

Number of elements with non-zero apodization.

Returns:

Type Description
int

Count of active elements.

impulse_response property writable

impulse_response: Optional[ndarray]

Electromechanical impulse response of the transducer element.

1-D float32 array sampled at the simulation sampling frequency. Represents the electrical-to-acoustic (TX) or acoustic-to-electrical (RX) transfer function. Applied via convolution in the frequency domain.

None = ideal (delta function) — no filtering.

Returns:

Type Description
ndarray or None

Impulse response array of shape (L_ir,), or None.

excitation property writable

excitation: Optional[ndarray]

Excitation pulse for this transducer.

1-D float32 array sampled at the simulation sampling frequency. None = impulse (delta) excitation.

Returns:

Type Description
ndarray or None

Excitation array of shape (L_exc,), or None.

_default_elevation_lens_sag

_default_elevation_lens_sag() -> float

Geometric lens sag (m) of this transducer type; 0 for flat apertures.

_build_patch_frames

_build_patch_frames() -> Dict

Default patch-frame builder for flat transducers.

Computes each patch's local frame directly from its corner vertices:

  • tangent_u = normalised v[1] - v[0] (first edge)
  • tangent_v = v[3] - v[0] orthogonalised against tangent_u
  • normal = tangent_u × tangent_v
  • wu = ‖v[1] - v[0]‖
  • wv = ‖v[3] - v[0]‖

This is exact for truly flat patches and gives a good approximation for very gently curved surfaces. Subclasses whose geometry is significantly curved should override this method (or set _sub_patch_frames as a side-effect inside _build_subdivisions).

compute_delays

compute_delays(
    focus_mm=None,
    *,
    angle_steering_deg=None,
    c: Optional[float] = None,
    inline: bool = True,
    plot: bool = False,
) -> ndarray

Compute per-element time delays for electronic focusing or plane-wave steering.

Exactly one of focus_mm or angle_steering_deg must be provided.

Parameters:

Name Type Description Default
focus_mm (array - like, shape(2) or (3,))

Focal point in mm. If 2-D [x, z], y=0 is assumed. Mutually exclusive with angle_steering_deg.

None
angle_steering_deg float or (float, float)

Plane-wave steering angle(s) in degrees. A single float steers in the xz-plane only: (θ_x, θ_y=0). A tuple (θ_x, θ_y) steers in both xz and yz planes (matrix or 3-D arrays). Mutually exclusive with focus_mm.

None
c float

Speed of sound in m/s. Defaults to speed_of_sound_mps (1540).

None
inline bool

If True (default) store result in self.delays.

True
plot bool

If True, display a delay plot after computation.

False

Returns:

Type Description
ndarray

Delays in seconds, shape (n_elements,) (minimum delay is always 0).

Raises:

Type Description
ValueError

If both or neither of focus_mm / angle_steering_deg are given, or if the steering angles exceed the physical limit sin²θ_x + sin²θ_y > 1.

set_apodization

set_apodization(weights: ndarray) -> None

Set per-element apodization weights directly.

Parameters:

Name Type Description Default
weights ndarray

Apodization weights, shape (n_elements,).

required

set_delays

set_delays(delays: ndarray) -> None

Set per-element delays directly (normalised so minimum = 0).

Parameters:

Name Type Description Default
delays ndarray

Delays in seconds, shape (n_elements,).

required

set_impulse_response

set_impulse_response(ir: Optional[ndarray]) -> None

Set the transducers impulse response.

Parameters:

Name Type Description Default
ir ndarray or None

Impulse response array. Converted to 1-D float32 and ravelled. None = ideal (delta) response.

required

set_excitation

set_excitation(exc: Optional[ndarray]) -> None

Set the transducers excitation pulse.

Parameters:

Name Type Description Default
exc ndarray or None

Excitation array. Converted to 1-D float32 and ravelled. None = impulse (delta) excitation.

required

get_mesh

get_mesh() -> PolyData

Build a PyVista surface mesh of the transducer.

Returns:

Type Description
PolyData

Mesh with 'Apodization' and 'Delays' as cell arrays.

show

show(
    *,
    window_size: Tuple[int, int] = (800, 600),
    scalars: str = "Apodization",
    notebook: bool = False,
    jupyter_backend: Optional[str] = None,
    colorbar_title: Optional[str] = None,
    **kwargs,
) -> None

Interactive 3-D visualisation of the transducer surface.

Parameters:

Name Type Description Default
window_size (int, int)

Pixel dimensions of the render window.

(800, 600)
scalars (Apodization, Delays)

Which cell array to colour by.

'Apodization'
notebook bool

Enable Jupyter notebook rendering.

False
jupyter_backend str

Backend string passed to PyVista ('static', 'trame' …).

None
colorbar_title str

Override the default colour-bar label.

None
**kwargs

Forwarded to plotter.add_mesh().

{}

plot_delays_apodization

plot_delays_apodization(
    figsize: Tuple[int, int] = (10, 4),
) -> None

Side-by-side delay and apodization plot.

Parameters:

Name Type Description Default
figsize tuple of int

Figure size in inches (width, height).

(10, 4)

transform

transform(T_matrix) -> None

Rigidly move the aperture in space (rotation then translation).

Applies the homogeneous transform to the computed geometry — patch vertices, patch frames (centres, normals, tangents) and element centres — so the SIR simulation and the visualisation both see the moved aperture. Patch widths are rotation-invariant and unchanged.

Delays and apodization are firing-time / weight state, not geometry, so they are untouched: a focus computed before the move still aims at the old global-frame target — call compute_delays / compute_apodization again after moving if the beam must follow.

Parameters:

Name Type Description Default
T_matrix (4, 4) array-like

Homogeneous rigid-body transform. The upper-left 3×3 block is the rotation (orthogonal, det +1); the last column is the translation in mm (user-facing unit).

required

Raises:

Type Description
ValueError

If T_matrix is not (4, 4) or its 3×3 block is not a proper rotation — scaling or reflection would corrupt the patch widths and normals the SIR kernel relies on.

Notes

Simulators snapshot the transducer geometry at construction: after transforming, refresh them with sim.set("transducer", tx) (Emission) or sim.set("tx", tx) / sim.set("rx", rx) (Reception). clean() discards cached geometry, so a rebuilt transducer returns to its canonical pose (the transform is not replayed).

clean

clean() -> None

Release cached geometry arrays to free memory.

copy

copy() -> TransducerBase

Return a deep copy of this transducer, including all state and cached geometry.

Returns:

Type Description
TransducerBase

Independent copy: mutating its delays/apodization/geometry leaves the original untouched.

get_state_dict

get_state_dict() -> Dict[str, Any]

Return a snapshot of the current apodization / delay state.

Returns:

Type Description
dict

Keys apodization, delays, apodization_type, FoverD.

set_state_dict

set_state_dict(state: Dict[str, Any]) -> None

Restore apodization / delay state from a dictionary.

Parameters:

Name Type Description Default
state dict

State dictionary as returned by get_state_dict().

required

Mono-element transducers

FlatCircularTransducer

FlatCircularTransducer(
    *,
    diameter_mm: float,
    no_sub_diameter: int = 25,
    ratio_big_patches: float = 0.85,
    refine_factor: int = 3,
    frequency_Hz: Optional[float] = None,
)

Bases: TransducerBase

Flat circular piston transducer (mono-element).

The aperture is approximated by a square grid of rectangular patches; only patches whose centre falls within the circle are included. Increasing no_sub_diameter improves the circular approximation and the spatial accuracy of the SIR simulation.

Parameters:

Name Type Description Default
diameter_mm float

Outer diameter of the active aperture in mm.

required
no_sub_diameter int

Number of coarse patches across the diameter. A value of 20–40 is typically sufficient for far-field calculations.

25
ratio_big_patches float

Fraction of the radius filled with coarse patches (0–1). The outer 1 - ratio_big_patches fraction is refined. Default 0.85.

0.85
refine_factor int

Subdivision factor for boundary patches. Each boundary patch is replaced by refine_factor² smaller patches. Default 3.

3
frequency_Hz float

Centre frequency in Hz. Defaults to 1 MHz.

None
Notes

Because this is a mono-element transducer, compute_delays returns [0.0] and compute_apodization returns [1.0]. All physical focusing is achieved through the excitation pulse shape and SIR convolution, not electronic delays.

speed_of_sound_mps instance-attribute

speed_of_sound_mps: float = 1540.0

_apodization instance-attribute

_apodization: Optional[ndarray] = None

_delays instance-attribute

_delays: Optional[ndarray] = None

_elevation_lens_sag instance-attribute

_elevation_lens_sag: Optional[float] = None

apodization_type instance-attribute

apodization_type: Optional[str] = None

FoverD instance-attribute

FoverD: Optional[float] = None

_impulse_response instance-attribute

_impulse_response: Optional[ndarray] = None

_excitation instance-attribute

_excitation: Optional[ndarray] = None

_element_centers instance-attribute

_element_centers: Optional[ndarray] = None

_sub_quad_verts instance-attribute

_sub_quad_verts: Optional[List[ndarray]] = None

_sub_area instance-attribute

_sub_area: Optional[float] = None

_sub_el_idx instance-attribute

_sub_el_idx: Optional[List[int]] = None

_sub_patch_frames instance-attribute

_sub_patch_frames: Optional[Dict] = None

element_centers property

element_centers: ndarray

3-D element centre positions, shape (n_elements, 3) in metres.

Returns:

Type Description
ndarray

Array of shape (n_elements, 3) with element positions in metres.

elevation_lens_sag property writable

elevation_lens_sag: float

Depth (m) a cylindrical elevation lens dishes the surface back at its centre.

Zero for flat/unfocused apertures. For a lens of radius R and element height h the surface centre sits R − √(R² − (h/2)²) behind the rim. The pulse-echo time origin is referenced to the first-arriving edge (the rim), but a focused elevation aperture's echo peaks one lens transit later, so reception adds this sag — as a propagation time, once per aperture — to align the RF origin with a lens-focused reference.

Settable: assign a value in metres to override the geometric default — needed for imported geometries (e.g. a Field II xdc_focused_array probe) whose lens curvature is present in the patches but whose focal parameters are not known to eSDIva. Assign None to restore the default. Subclasses with a native lens supply the default via _default_elevation_lens_sag.

Returns:

Type Description
float

Lens sag in metres (0.0 for flat/unfocused apertures).

sub_quad_verts property

sub_quad_verts: List[ndarray]

List of quad-vertex arrays (4, 3) for every patch, in metres.

Returns:

Type Description
list of ndarray

Each element is a (4, 3) array of corner positions.

sub_area property

sub_area: float

Patch area in m² (same for all patches in a uniform grid).

Returns:

Type Description
float

Area of each sub-patch in square metres.

sub_el_idx property

sub_el_idx: List[int]

Element index for each patch; maps patch to parent element.

Returns:

Type Description
list of int

Index of the parent element for each sub-patch.

n_sub_patches property

n_sub_patches: int

Total number of rectangular sub-patches across all elements.

Returns:

Type Description
int

Number of sub-patches.

sub_patch_frames property

sub_patch_frames: Dict

Per-patch rigid-body frames used by the SIR kernel.

Returns a dict with keys centers, normals, tangents_u, tangents_v, wu, wv — all ndarrays indexed by patch.

For flat transducers the default implementation computes frames from the vertex edge vectors (v[1]-v[0] and v[3]-v[0]), which is exact for any flat, arbitrarily-oriented patch. Curved transducers override _build_patch_frames to return surface-accurate frames derived from the parametric surface equations.

Returns:

Type Description
dict

Patch-frame arrays keyed by centers, normals, etc.

apodization property writable

apodization: ndarray

Per-element apodization weights, shape (n_elements,).

Returns:

Type Description
ndarray

Apodization weights for each element.

delays property writable

delays: ndarray

Per-element delays in seconds, shape (n_elements,).

Returns:

Type Description
ndarray

Delay values for each element in seconds.

tx_N_active property

tx_N_active: int

Number of elements with non-zero apodization.

Returns:

Type Description
int

Count of active elements.

impulse_response property writable

impulse_response: Optional[ndarray]

Electromechanical impulse response of the transducer element.

1-D float32 array sampled at the simulation sampling frequency. Represents the electrical-to-acoustic (TX) or acoustic-to-electrical (RX) transfer function. Applied via convolution in the frequency domain.

None = ideal (delta function) — no filtering.

Returns:

Type Description
ndarray or None

Impulse response array of shape (L_ir,), or None.

excitation property writable

excitation: Optional[ndarray]

Excitation pulse for this transducer.

1-D float32 array sampled at the simulation sampling frequency. None = impulse (delta) excitation.

Returns:

Type Description
ndarray or None

Excitation array of shape (L_exc,), or None.

_default_elevation_lens_sag

_default_elevation_lens_sag() -> float

Geometric lens sag (m) of this transducer type; 0 for flat apertures.

_build_patch_frames

_build_patch_frames() -> Dict

Default patch-frame builder for flat transducers.

Computes each patch's local frame directly from its corner vertices:

  • tangent_u = normalised v[1] - v[0] (first edge)
  • tangent_v = v[3] - v[0] orthogonalised against tangent_u
  • normal = tangent_u × tangent_v
  • wu = ‖v[1] - v[0]‖
  • wv = ‖v[3] - v[0]‖

This is exact for truly flat patches and gives a good approximation for very gently curved surfaces. Subclasses whose geometry is significantly curved should override this method (or set _sub_patch_frames as a side-effect inside _build_subdivisions).

compute_delays

compute_delays(
    focus_mm=None,
    *,
    angle_steering_deg=None,
    c: Optional[float] = None,
    inline: bool = True,
    plot: bool = False,
) -> ndarray

Compute per-element time delays for electronic focusing or plane-wave steering.

Exactly one of focus_mm or angle_steering_deg must be provided.

Parameters:

Name Type Description Default
focus_mm (array - like, shape(2) or (3,))

Focal point in mm. If 2-D [x, z], y=0 is assumed. Mutually exclusive with angle_steering_deg.

None
angle_steering_deg float or (float, float)

Plane-wave steering angle(s) in degrees. A single float steers in the xz-plane only: (θ_x, θ_y=0). A tuple (θ_x, θ_y) steers in both xz and yz planes (matrix or 3-D arrays). Mutually exclusive with focus_mm.

None
c float

Speed of sound in m/s. Defaults to speed_of_sound_mps (1540).

None
inline bool

If True (default) store result in self.delays.

True
plot bool

If True, display a delay plot after computation.

False

Returns:

Type Description
ndarray

Delays in seconds, shape (n_elements,) (minimum delay is always 0).

Raises:

Type Description
ValueError

If both or neither of focus_mm / angle_steering_deg are given, or if the steering angles exceed the physical limit sin²θ_x + sin²θ_y > 1.

compute_apodization

compute_apodization(
    focus_mm=None,
    *,
    FoverD: Optional[float] = None,
    apodization_type: Optional[str] = None,
    plot: bool = False,
    inline: bool = True,
) -> ndarray

Return uniform full-aperture apodization (all ones).

Mono-element transducers use the full aperture by definition. Multi-element subclasses (linear, matrix) override this method with window-based aperture selection.

For mono-element transducers, patch-wise apodization can still be set directly via set_apodization().

Parameters:

Name Type Description Default
focus_mm array - like

Accepted for API consistency with multi-element subclasses.

None
FoverD float

Accepted for API consistency.

None
apodization_type str

Accepted for API consistency.

None
plot bool

Accepted for API consistency.

False
inline bool

If True (default), store result in self.apodization.

True

Returns:

Type Description
ndarray

Uniform apodization weights, shape (n_elements,).

set_apodization

set_apodization(weights: ndarray) -> None

Set per-element apodization weights directly.

Parameters:

Name Type Description Default
weights ndarray

Apodization weights, shape (n_elements,).

required

set_delays

set_delays(delays: ndarray) -> None

Set per-element delays directly (normalised so minimum = 0).

Parameters:

Name Type Description Default
delays ndarray

Delays in seconds, shape (n_elements,).

required

set_impulse_response

set_impulse_response(ir: Optional[ndarray]) -> None

Set the transducers impulse response.

Parameters:

Name Type Description Default
ir ndarray or None

Impulse response array. Converted to 1-D float32 and ravelled. None = ideal (delta) response.

required

set_excitation

set_excitation(exc: Optional[ndarray]) -> None

Set the transducers excitation pulse.

Parameters:

Name Type Description Default
exc ndarray or None

Excitation array. Converted to 1-D float32 and ravelled. None = impulse (delta) excitation.

required

get_mesh

get_mesh() -> PolyData

Build a PyVista surface mesh of the transducer.

Returns:

Type Description
PolyData

Mesh with 'Apodization' and 'Delays' as cell arrays.

show

show(
    *,
    window_size: Tuple[int, int] = (800, 600),
    scalars: str = "Apodization",
    notebook: bool = False,
    jupyter_backend: Optional[str] = None,
    colorbar_title: Optional[str] = None,
    **kwargs,
) -> None

Interactive 3-D visualisation of the transducer surface.

Parameters:

Name Type Description Default
window_size (int, int)

Pixel dimensions of the render window.

(800, 600)
scalars (Apodization, Delays)

Which cell array to colour by.

'Apodization'
notebook bool

Enable Jupyter notebook rendering.

False
jupyter_backend str

Backend string passed to PyVista ('static', 'trame' …).

None
colorbar_title str

Override the default colour-bar label.

None
**kwargs

Forwarded to plotter.add_mesh().

{}

plot_apodization

plot_apodization(
    apodization: Optional[ndarray] = None,
    *,
    figsize: Tuple[int, int] = (6, 5),
    ax=None,
)

Plot apodization weights as a line/stem chart.

For 2-D matrix transducers, override this method to produce an image.

Parameters:

Name Type Description Default
apodization ndarray

Weights to plot. Defaults to self.apodization.

None
figsize tuple of int

Figure size in inches (width, height).

(6, 5)
ax Axes

Axes to draw on. If None, a new figure is created.

None

Returns:

Type Description
Axes or None

The axes object if ax was provided, otherwise None.

plot_delays

plot_delays(
    delays: Optional[ndarray] = None,
    *,
    figsize: Tuple[int, int] = (6, 5),
    ax=None,
)

Plot per-element delays in microseconds.

Parameters:

Name Type Description Default
delays ndarray

Delays to plot. Defaults to self.delays.

None
figsize tuple of int

Figure size in inches (width, height).

(6, 5)
ax Axes

Axes to draw on. If None, a new figure is created.

None

Returns:

Type Description
Axes or None

The axes object if ax was provided, otherwise None.

plot_delays_apodization

plot_delays_apodization(
    figsize: Tuple[int, int] = (10, 4),
) -> None

Side-by-side delay and apodization plot.

Parameters:

Name Type Description Default
figsize tuple of int

Figure size in inches (width, height).

(10, 4)

transform

transform(T_matrix) -> None

Rigidly move the aperture in space (rotation then translation).

Applies the homogeneous transform to the computed geometry — patch vertices, patch frames (centres, normals, tangents) and element centres — so the SIR simulation and the visualisation both see the moved aperture. Patch widths are rotation-invariant and unchanged.

Delays and apodization are firing-time / weight state, not geometry, so they are untouched: a focus computed before the move still aims at the old global-frame target — call compute_delays / compute_apodization again after moving if the beam must follow.

Parameters:

Name Type Description Default
T_matrix (4, 4) array-like

Homogeneous rigid-body transform. The upper-left 3×3 block is the rotation (orthogonal, det +1); the last column is the translation in mm (user-facing unit).

required

Raises:

Type Description
ValueError

If T_matrix is not (4, 4) or its 3×3 block is not a proper rotation — scaling or reflection would corrupt the patch widths and normals the SIR kernel relies on.

Notes

Simulators snapshot the transducer geometry at construction: after transforming, refresh them with sim.set("transducer", tx) (Emission) or sim.set("tx", tx) / sim.set("rx", rx) (Reception). clean() discards cached geometry, so a rebuilt transducer returns to its canonical pose (the transform is not replayed).

clean

clean() -> None

Release cached geometry arrays to free memory.

copy

copy() -> TransducerBase

Return a deep copy of this transducer, including all state and cached geometry.

Returns:

Type Description
TransducerBase

Independent copy: mutating its delays/apodization/geometry leaves the original untouched.

get_state_dict

get_state_dict() -> Dict[str, Any]

Return a snapshot of the current apodization / delay state.

Returns:

Type Description
dict

Keys apodization, delays, apodization_type, FoverD.

set_state_dict

set_state_dict(state: Dict[str, Any]) -> None

Restore apodization / delay state from a dictionary.

Parameters:

Name Type Description Default
state dict

State dictionary as returned by get_state_dict().

required

ConcaveCircularTransducer

ConcaveCircularTransducer(
    *,
    diameter_mm: float,
    focus_mm: float,
    no_sub_diameter: int = 25,
    method: str = "cartesian",
    ratio_big_patches: float = 0.85,
    refine_factor: int = 3,
    normalize_patch_size: bool = False,
    frequency_Hz: Optional[float] = None,
)

Bases: TransducerBase

Spherically focused single-element transducer (bowl / concave disc).

The transducer surface is a spherical cap. All points on the surface are equidistant from the geometric focus, so the acoustic wave converges at that point without any electronic delays. Common in HIFU therapy and TUS.

focus_mm is the focal length — the radius of curvature of the bowl, i.e. the value printed on a transducer datasheet (Field II xdc_concave Rfocus). The surface apex sits at z = 0, the geometric focus at z = focus_mm in front of the bowl, and the rim is lifted to z = +sag where sag = R - sqrt(R² - (D/2)²). focus_mm = D/2 gives a hemisphere.

Parameters:

Name Type Description Default
diameter_mm float

Outer diameter of the bowl aperture in mm.

required
focus_mm float

Focal length = radius of curvature in mm. Must be >= D/2 (the aperture radius). focus_mm = D/2 = hemisphere.

required
no_sub_diameter int

Target number of patches across the diameter.

25
method (cartesian, spherical)

'cartesian' (default) uses the arc-length reparameterised Cartesian grid via :func:subdivide_parametric_surface — good for shallow bowls. 'spherical' uses ring-based spherical-coordinate tiling via :func:subdivide_spherical_cap — preferred at high curvature or for hemispheres.

'cartesian'
ratio_big_patches float

Fraction of the surface covered by coarse patches (0–1). The remaining region is refined. For spherical method, controls inner ring refinement; for cartesian, controls border refinement. Default 0.85.

0.85
refine_factor int

Subdivision factor in the refined region. Default 3.

3
normalize_patch_size bool

If True, set patch widths to the arc-length step size, ignoring Jacobian stretch. Produces uniform-sized patches. Useful with method='cartesian' at high curvature to avoid rim-patch inflation.

False
frequency_Hz float

Centre frequency in Hz. Defaults to 1 MHz.

None

speed_of_sound_mps instance-attribute

speed_of_sound_mps: float = 1540.0

_apodization instance-attribute

_apodization: Optional[ndarray] = None

_delays instance-attribute

_delays: Optional[ndarray] = None

_elevation_lens_sag instance-attribute

_elevation_lens_sag: Optional[float] = None

apodization_type instance-attribute

apodization_type: Optional[str] = None

FoverD instance-attribute

FoverD: Optional[float] = None

_impulse_response instance-attribute

_impulse_response: Optional[ndarray] = None

_excitation instance-attribute

_excitation: Optional[ndarray] = None

_element_centers instance-attribute

_element_centers: Optional[ndarray] = None

_sub_quad_verts instance-attribute

_sub_quad_verts: Optional[List[ndarray]] = None

_sub_area instance-attribute

_sub_area: Optional[float] = None

_sub_el_idx instance-attribute

_sub_el_idx: Optional[List[int]] = None

_sub_patch_frames instance-attribute

_sub_patch_frames: Optional[Dict] = None

element_centers property

element_centers: ndarray

3-D element centre positions, shape (n_elements, 3) in metres.

Returns:

Type Description
ndarray

Array of shape (n_elements, 3) with element positions in metres.

elevation_lens_sag property writable

elevation_lens_sag: float

Depth (m) a cylindrical elevation lens dishes the surface back at its centre.

Zero for flat/unfocused apertures. For a lens of radius R and element height h the surface centre sits R − √(R² − (h/2)²) behind the rim. The pulse-echo time origin is referenced to the first-arriving edge (the rim), but a focused elevation aperture's echo peaks one lens transit later, so reception adds this sag — as a propagation time, once per aperture — to align the RF origin with a lens-focused reference.

Settable: assign a value in metres to override the geometric default — needed for imported geometries (e.g. a Field II xdc_focused_array probe) whose lens curvature is present in the patches but whose focal parameters are not known to eSDIva. Assign None to restore the default. Subclasses with a native lens supply the default via _default_elevation_lens_sag.

Returns:

Type Description
float

Lens sag in metres (0.0 for flat/unfocused apertures).

sub_quad_verts property

sub_quad_verts: List[ndarray]

List of quad-vertex arrays (4, 3) for every patch, in metres.

Returns:

Type Description
list of ndarray

Each element is a (4, 3) array of corner positions.

sub_area property

sub_area: float

Patch area in m² (same for all patches in a uniform grid).

Returns:

Type Description
float

Area of each sub-patch in square metres.

sub_el_idx property

sub_el_idx: List[int]

Element index for each patch; maps patch to parent element.

Returns:

Type Description
list of int

Index of the parent element for each sub-patch.

n_sub_patches property

n_sub_patches: int

Total number of rectangular sub-patches across all elements.

Returns:

Type Description
int

Number of sub-patches.

sub_patch_frames property

sub_patch_frames: Dict

Per-patch rigid-body frames used by the SIR kernel.

Returns a dict with keys centers, normals, tangents_u, tangents_v, wu, wv — all ndarrays indexed by patch.

For flat transducers the default implementation computes frames from the vertex edge vectors (v[1]-v[0] and v[3]-v[0]), which is exact for any flat, arbitrarily-oriented patch. Curved transducers override _build_patch_frames to return surface-accurate frames derived from the parametric surface equations.

Returns:

Type Description
dict

Patch-frame arrays keyed by centers, normals, etc.

apodization property writable

apodization: ndarray

Per-element apodization weights, shape (n_elements,).

Returns:

Type Description
ndarray

Apodization weights for each element.

delays property writable

delays: ndarray

Per-element delays in seconds, shape (n_elements,).

Returns:

Type Description
ndarray

Delay values for each element in seconds.

tx_N_active property

tx_N_active: int

Number of elements with non-zero apodization.

Returns:

Type Description
int

Count of active elements.

impulse_response property writable

impulse_response: Optional[ndarray]

Electromechanical impulse response of the transducer element.

1-D float32 array sampled at the simulation sampling frequency. Represents the electrical-to-acoustic (TX) or acoustic-to-electrical (RX) transfer function. Applied via convolution in the frequency domain.

None = ideal (delta function) — no filtering.

Returns:

Type Description
ndarray or None

Impulse response array of shape (L_ir,), or None.

excitation property writable

excitation: Optional[ndarray]

Excitation pulse for this transducer.

1-D float32 array sampled at the simulation sampling frequency. None = impulse (delta) excitation.

Returns:

Type Description
ndarray or None

Excitation array of shape (L_exc,), or None.

_default_elevation_lens_sag

_default_elevation_lens_sag() -> float

Geometric lens sag (m) of this transducer type; 0 for flat apertures.

compute_delays

compute_delays(
    focus_mm=None,
    *,
    angle_steering_deg=None,
    c: Optional[float] = None,
    inline: bool = True,
    plot: bool = False,
) -> ndarray

Compute per-element time delays for electronic focusing or plane-wave steering.

Exactly one of focus_mm or angle_steering_deg must be provided.

Parameters:

Name Type Description Default
focus_mm (array - like, shape(2) or (3,))

Focal point in mm. If 2-D [x, z], y=0 is assumed. Mutually exclusive with angle_steering_deg.

None
angle_steering_deg float or (float, float)

Plane-wave steering angle(s) in degrees. A single float steers in the xz-plane only: (θ_x, θ_y=0). A tuple (θ_x, θ_y) steers in both xz and yz planes (matrix or 3-D arrays). Mutually exclusive with focus_mm.

None
c float

Speed of sound in m/s. Defaults to speed_of_sound_mps (1540).

None
inline bool

If True (default) store result in self.delays.

True
plot bool

If True, display a delay plot after computation.

False

Returns:

Type Description
ndarray

Delays in seconds, shape (n_elements,) (minimum delay is always 0).

Raises:

Type Description
ValueError

If both or neither of focus_mm / angle_steering_deg are given, or if the steering angles exceed the physical limit sin²θ_x + sin²θ_y > 1.

compute_apodization

compute_apodization(
    focus_mm=None,
    *,
    FoverD: Optional[float] = None,
    apodization_type: Optional[str] = None,
    plot: bool = False,
    inline: bool = True,
) -> ndarray

Return uniform full-aperture apodization (all ones).

Mono-element transducers use the full aperture by definition. Multi-element subclasses (linear, matrix) override this method with window-based aperture selection.

For mono-element transducers, patch-wise apodization can still be set directly via set_apodization().

Parameters:

Name Type Description Default
focus_mm array - like

Accepted for API consistency with multi-element subclasses.

None
FoverD float

Accepted for API consistency.

None
apodization_type str

Accepted for API consistency.

None
plot bool

Accepted for API consistency.

False
inline bool

If True (default), store result in self.apodization.

True

Returns:

Type Description
ndarray

Uniform apodization weights, shape (n_elements,).

set_apodization

set_apodization(weights: ndarray) -> None

Set per-element apodization weights directly.

Parameters:

Name Type Description Default
weights ndarray

Apodization weights, shape (n_elements,).

required

set_delays

set_delays(delays: ndarray) -> None

Set per-element delays directly (normalised so minimum = 0).

Parameters:

Name Type Description Default
delays ndarray

Delays in seconds, shape (n_elements,).

required

set_impulse_response

set_impulse_response(ir: Optional[ndarray]) -> None

Set the transducers impulse response.

Parameters:

Name Type Description Default
ir ndarray or None

Impulse response array. Converted to 1-D float32 and ravelled. None = ideal (delta) response.

required

set_excitation

set_excitation(exc: Optional[ndarray]) -> None

Set the transducers excitation pulse.

Parameters:

Name Type Description Default
exc ndarray or None

Excitation array. Converted to 1-D float32 and ravelled. None = impulse (delta) excitation.

required

get_mesh

get_mesh() -> PolyData

Build a PyVista surface mesh of the transducer.

Returns:

Type Description
PolyData

Mesh with 'Apodization' and 'Delays' as cell arrays.

show

show(
    *,
    window_size: Tuple[int, int] = (800, 600),
    scalars: str = "Apodization",
    notebook: bool = False,
    jupyter_backend: Optional[str] = None,
    colorbar_title: Optional[str] = None,
    **kwargs,
) -> None

Interactive 3-D visualisation of the transducer surface.

Parameters:

Name Type Description Default
window_size (int, int)

Pixel dimensions of the render window.

(800, 600)
scalars (Apodization, Delays)

Which cell array to colour by.

'Apodization'
notebook bool

Enable Jupyter notebook rendering.

False
jupyter_backend str

Backend string passed to PyVista ('static', 'trame' …).

None
colorbar_title str

Override the default colour-bar label.

None
**kwargs

Forwarded to plotter.add_mesh().

{}

plot_apodization

plot_apodization(
    apodization: Optional[ndarray] = None,
    *,
    figsize: Tuple[int, int] = (6, 5),
    ax=None,
)

Plot apodization weights as a line/stem chart.

For 2-D matrix transducers, override this method to produce an image.

Parameters:

Name Type Description Default
apodization ndarray

Weights to plot. Defaults to self.apodization.

None
figsize tuple of int

Figure size in inches (width, height).

(6, 5)
ax Axes

Axes to draw on. If None, a new figure is created.

None

Returns:

Type Description
Axes or None

The axes object if ax was provided, otherwise None.

plot_delays

plot_delays(
    delays: Optional[ndarray] = None,
    *,
    figsize: Tuple[int, int] = (6, 5),
    ax=None,
)

Plot per-element delays in microseconds.

Parameters:

Name Type Description Default
delays ndarray

Delays to plot. Defaults to self.delays.

None
figsize tuple of int

Figure size in inches (width, height).

(6, 5)
ax Axes

Axes to draw on. If None, a new figure is created.

None

Returns:

Type Description
Axes or None

The axes object if ax was provided, otherwise None.

plot_delays_apodization

plot_delays_apodization(
    figsize: Tuple[int, int] = (10, 4),
) -> None

Side-by-side delay and apodization plot.

Parameters:

Name Type Description Default
figsize tuple of int

Figure size in inches (width, height).

(10, 4)

transform

transform(T_matrix) -> None

Rigidly move the aperture in space (rotation then translation).

Applies the homogeneous transform to the computed geometry — patch vertices, patch frames (centres, normals, tangents) and element centres — so the SIR simulation and the visualisation both see the moved aperture. Patch widths are rotation-invariant and unchanged.

Delays and apodization are firing-time / weight state, not geometry, so they are untouched: a focus computed before the move still aims at the old global-frame target — call compute_delays / compute_apodization again after moving if the beam must follow.

Parameters:

Name Type Description Default
T_matrix (4, 4) array-like

Homogeneous rigid-body transform. The upper-left 3×3 block is the rotation (orthogonal, det +1); the last column is the translation in mm (user-facing unit).

required

Raises:

Type Description
ValueError

If T_matrix is not (4, 4) or its 3×3 block is not a proper rotation — scaling or reflection would corrupt the patch widths and normals the SIR kernel relies on.

Notes

Simulators snapshot the transducer geometry at construction: after transforming, refresh them with sim.set("transducer", tx) (Emission) or sim.set("tx", tx) / sim.set("rx", rx) (Reception). clean() discards cached geometry, so a rebuilt transducer returns to its canonical pose (the transform is not replayed).

clean

clean() -> None

Release cached geometry arrays to free memory.

copy

copy() -> TransducerBase

Return a deep copy of this transducer, including all state and cached geometry.

Returns:

Type Description
TransducerBase

Independent copy: mutating its delays/apodization/geometry leaves the original untouched.

get_state_dict

get_state_dict() -> Dict[str, Any]

Return a snapshot of the current apodization / delay state.

Returns:

Type Description
dict

Keys apodization, delays, apodization_type, FoverD.

set_state_dict

set_state_dict(state: Dict[str, Any]) -> None

Restore apodization / delay state from a dictionary.

Parameters:

Name Type Description Default
state dict

State dictionary as returned by get_state_dict().

required

ConvexCircularTransducer

ConvexCircularTransducer(
    *,
    diameter_mm: float,
    focus_mm: float,
    no_sub_diameter: int = 25,
    method: str = "cartesian",
    ratio_big_patches: float = 0.85,
    refine_factor: int = 3,
    normalize_patch_size: bool = False,
    frequency_Hz: Optional[float] = None,
)

Bases: TransducerBase

Spherically convex single-element transducer (dome / convex disc).

The surface is a spherical dome that bulges toward the propagation medium (positive-z direction). The convex surface diverges — its virtual focus is at z = -R (behind the transducer).

focus_mm is the focal length — the radius of curvature of the dome (the value on a transducer datasheet). The dome apex sits at z = 0, the virtual focus at z = -focus_mm behind the transducer, and the rim recedes to z = -sag. focus_mm = D/2 gives a hemisphere.

Surface z-profile (apex at z = 0, rim at z = -sag):

sag = R - √(R² - (D/2)²)
z(r) = √(R² - r²) - R    r = √(x² + y²) ≤ D/2

Parameters:

Name Type Description Default
diameter_mm float

Outer diameter of the dome aperture in mm.

required
focus_mm float

Focal length = radius of curvature in mm. Must be >= D/2 (the aperture radius). focus_mm = D/2 = hemisphere.

required
no_sub_diameter int

Target number of patches across the diameter.

25
method (cartesian, spherical)

'cartesian' (default) or 'spherical' (preferred at high curvature).

'cartesian'
ratio_big_patches float

Fraction of surface with coarse patches. Default 0.85.

0.85
refine_factor int

Subdivision factor in the refined region. Default 3.

3
normalize_patch_size bool

If True, set patch widths to the arc-length step size, ignoring Jacobian stretch. Produces uniform-sized patches.

False
frequency_Hz float

Centre frequency in Hz. Defaults to 1 MHz.

None

speed_of_sound_mps instance-attribute

speed_of_sound_mps: float = 1540.0

_apodization instance-attribute

_apodization: Optional[ndarray] = None

_delays instance-attribute

_delays: Optional[ndarray] = None

_elevation_lens_sag instance-attribute

_elevation_lens_sag: Optional[float] = None

apodization_type instance-attribute

apodization_type: Optional[str] = None

FoverD instance-attribute

FoverD: Optional[float] = None

_impulse_response instance-attribute

_impulse_response: Optional[ndarray] = None

_excitation instance-attribute

_excitation: Optional[ndarray] = None

_element_centers instance-attribute

_element_centers: Optional[ndarray] = None

_sub_quad_verts instance-attribute

_sub_quad_verts: Optional[List[ndarray]] = None

_sub_area instance-attribute

_sub_area: Optional[float] = None

_sub_el_idx instance-attribute

_sub_el_idx: Optional[List[int]] = None

_sub_patch_frames instance-attribute

_sub_patch_frames: Optional[Dict] = None

element_centers property

element_centers: ndarray

3-D element centre positions, shape (n_elements, 3) in metres.

Returns:

Type Description
ndarray

Array of shape (n_elements, 3) with element positions in metres.

elevation_lens_sag property writable

elevation_lens_sag: float

Depth (m) a cylindrical elevation lens dishes the surface back at its centre.

Zero for flat/unfocused apertures. For a lens of radius R and element height h the surface centre sits R − √(R² − (h/2)²) behind the rim. The pulse-echo time origin is referenced to the first-arriving edge (the rim), but a focused elevation aperture's echo peaks one lens transit later, so reception adds this sag — as a propagation time, once per aperture — to align the RF origin with a lens-focused reference.

Settable: assign a value in metres to override the geometric default — needed for imported geometries (e.g. a Field II xdc_focused_array probe) whose lens curvature is present in the patches but whose focal parameters are not known to eSDIva. Assign None to restore the default. Subclasses with a native lens supply the default via _default_elevation_lens_sag.

Returns:

Type Description
float

Lens sag in metres (0.0 for flat/unfocused apertures).

sub_quad_verts property

sub_quad_verts: List[ndarray]

List of quad-vertex arrays (4, 3) for every patch, in metres.

Returns:

Type Description
list of ndarray

Each element is a (4, 3) array of corner positions.

sub_area property

sub_area: float

Patch area in m² (same for all patches in a uniform grid).

Returns:

Type Description
float

Area of each sub-patch in square metres.

sub_el_idx property

sub_el_idx: List[int]

Element index for each patch; maps patch to parent element.

Returns:

Type Description
list of int

Index of the parent element for each sub-patch.

n_sub_patches property

n_sub_patches: int

Total number of rectangular sub-patches across all elements.

Returns:

Type Description
int

Number of sub-patches.

sub_patch_frames property

sub_patch_frames: Dict

Per-patch rigid-body frames used by the SIR kernel.

Returns a dict with keys centers, normals, tangents_u, tangents_v, wu, wv — all ndarrays indexed by patch.

For flat transducers the default implementation computes frames from the vertex edge vectors (v[1]-v[0] and v[3]-v[0]), which is exact for any flat, arbitrarily-oriented patch. Curved transducers override _build_patch_frames to return surface-accurate frames derived from the parametric surface equations.

Returns:

Type Description
dict

Patch-frame arrays keyed by centers, normals, etc.

apodization property writable

apodization: ndarray

Per-element apodization weights, shape (n_elements,).

Returns:

Type Description
ndarray

Apodization weights for each element.

delays property writable

delays: ndarray

Per-element delays in seconds, shape (n_elements,).

Returns:

Type Description
ndarray

Delay values for each element in seconds.

tx_N_active property

tx_N_active: int

Number of elements with non-zero apodization.

Returns:

Type Description
int

Count of active elements.

impulse_response property writable

impulse_response: Optional[ndarray]

Electromechanical impulse response of the transducer element.

1-D float32 array sampled at the simulation sampling frequency. Represents the electrical-to-acoustic (TX) or acoustic-to-electrical (RX) transfer function. Applied via convolution in the frequency domain.

None = ideal (delta function) — no filtering.

Returns:

Type Description
ndarray or None

Impulse response array of shape (L_ir,), or None.

excitation property writable

excitation: Optional[ndarray]

Excitation pulse for this transducer.

1-D float32 array sampled at the simulation sampling frequency. None = impulse (delta) excitation.

Returns:

Type Description
ndarray or None

Excitation array of shape (L_exc,), or None.

_default_elevation_lens_sag

_default_elevation_lens_sag() -> float

Geometric lens sag (m) of this transducer type; 0 for flat apertures.

compute_delays

compute_delays(
    focus_mm=None,
    *,
    angle_steering_deg=None,
    c: Optional[float] = None,
    inline: bool = True,
    plot: bool = False,
) -> ndarray

Compute per-element time delays for electronic focusing or plane-wave steering.

Exactly one of focus_mm or angle_steering_deg must be provided.

Parameters:

Name Type Description Default
focus_mm (array - like, shape(2) or (3,))

Focal point in mm. If 2-D [x, z], y=0 is assumed. Mutually exclusive with angle_steering_deg.

None
angle_steering_deg float or (float, float)

Plane-wave steering angle(s) in degrees. A single float steers in the xz-plane only: (θ_x, θ_y=0). A tuple (θ_x, θ_y) steers in both xz and yz planes (matrix or 3-D arrays). Mutually exclusive with focus_mm.

None
c float

Speed of sound in m/s. Defaults to speed_of_sound_mps (1540).

None
inline bool

If True (default) store result in self.delays.

True
plot bool

If True, display a delay plot after computation.

False

Returns:

Type Description
ndarray

Delays in seconds, shape (n_elements,) (minimum delay is always 0).

Raises:

Type Description
ValueError

If both or neither of focus_mm / angle_steering_deg are given, or if the steering angles exceed the physical limit sin²θ_x + sin²θ_y > 1.

compute_apodization

compute_apodization(
    focus_mm=None,
    *,
    FoverD: Optional[float] = None,
    apodization_type: Optional[str] = None,
    plot: bool = False,
    inline: bool = True,
) -> ndarray

Return uniform full-aperture apodization (all ones).

Mono-element transducers use the full aperture by definition. Multi-element subclasses (linear, matrix) override this method with window-based aperture selection.

For mono-element transducers, patch-wise apodization can still be set directly via set_apodization().

Parameters:

Name Type Description Default
focus_mm array - like

Accepted for API consistency with multi-element subclasses.

None
FoverD float

Accepted for API consistency.

None
apodization_type str

Accepted for API consistency.

None
plot bool

Accepted for API consistency.

False
inline bool

If True (default), store result in self.apodization.

True

Returns:

Type Description
ndarray

Uniform apodization weights, shape (n_elements,).

set_apodization

set_apodization(weights: ndarray) -> None

Set per-element apodization weights directly.

Parameters:

Name Type Description Default
weights ndarray

Apodization weights, shape (n_elements,).

required

set_delays

set_delays(delays: ndarray) -> None

Set per-element delays directly (normalised so minimum = 0).

Parameters:

Name Type Description Default
delays ndarray

Delays in seconds, shape (n_elements,).

required

set_impulse_response

set_impulse_response(ir: Optional[ndarray]) -> None

Set the transducers impulse response.

Parameters:

Name Type Description Default
ir ndarray or None

Impulse response array. Converted to 1-D float32 and ravelled. None = ideal (delta) response.

required

set_excitation

set_excitation(exc: Optional[ndarray]) -> None

Set the transducers excitation pulse.

Parameters:

Name Type Description Default
exc ndarray or None

Excitation array. Converted to 1-D float32 and ravelled. None = impulse (delta) excitation.

required

get_mesh

get_mesh() -> PolyData

Build a PyVista surface mesh of the transducer.

Returns:

Type Description
PolyData

Mesh with 'Apodization' and 'Delays' as cell arrays.

show

show(
    *,
    window_size: Tuple[int, int] = (800, 600),
    scalars: str = "Apodization",
    notebook: bool = False,
    jupyter_backend: Optional[str] = None,
    colorbar_title: Optional[str] = None,
    **kwargs,
) -> None

Interactive 3-D visualisation of the transducer surface.

Parameters:

Name Type Description Default
window_size (int, int)

Pixel dimensions of the render window.

(800, 600)
scalars (Apodization, Delays)

Which cell array to colour by.

'Apodization'
notebook bool

Enable Jupyter notebook rendering.

False
jupyter_backend str

Backend string passed to PyVista ('static', 'trame' …).

None
colorbar_title str

Override the default colour-bar label.

None
**kwargs

Forwarded to plotter.add_mesh().

{}

plot_apodization

plot_apodization(
    apodization: Optional[ndarray] = None,
    *,
    figsize: Tuple[int, int] = (6, 5),
    ax=None,
)

Plot apodization weights as a line/stem chart.

For 2-D matrix transducers, override this method to produce an image.

Parameters:

Name Type Description Default
apodization ndarray

Weights to plot. Defaults to self.apodization.

None
figsize tuple of int

Figure size in inches (width, height).

(6, 5)
ax Axes

Axes to draw on. If None, a new figure is created.

None

Returns:

Type Description
Axes or None

The axes object if ax was provided, otherwise None.

plot_delays

plot_delays(
    delays: Optional[ndarray] = None,
    *,
    figsize: Tuple[int, int] = (6, 5),
    ax=None,
)

Plot per-element delays in microseconds.

Parameters:

Name Type Description Default
delays ndarray

Delays to plot. Defaults to self.delays.

None
figsize tuple of int

Figure size in inches (width, height).

(6, 5)
ax Axes

Axes to draw on. If None, a new figure is created.

None

Returns:

Type Description
Axes or None

The axes object if ax was provided, otherwise None.

plot_delays_apodization

plot_delays_apodization(
    figsize: Tuple[int, int] = (10, 4),
) -> None

Side-by-side delay and apodization plot.

Parameters:

Name Type Description Default
figsize tuple of int

Figure size in inches (width, height).

(10, 4)

transform

transform(T_matrix) -> None

Rigidly move the aperture in space (rotation then translation).

Applies the homogeneous transform to the computed geometry — patch vertices, patch frames (centres, normals, tangents) and element centres — so the SIR simulation and the visualisation both see the moved aperture. Patch widths are rotation-invariant and unchanged.

Delays and apodization are firing-time / weight state, not geometry, so they are untouched: a focus computed before the move still aims at the old global-frame target — call compute_delays / compute_apodization again after moving if the beam must follow.

Parameters:

Name Type Description Default
T_matrix (4, 4) array-like

Homogeneous rigid-body transform. The upper-left 3×3 block is the rotation (orthogonal, det +1); the last column is the translation in mm (user-facing unit).

required

Raises:

Type Description
ValueError

If T_matrix is not (4, 4) or its 3×3 block is not a proper rotation — scaling or reflection would corrupt the patch widths and normals the SIR kernel relies on.

Notes

Simulators snapshot the transducer geometry at construction: after transforming, refresh them with sim.set("transducer", tx) (Emission) or sim.set("tx", tx) / sim.set("rx", rx) (Reception). clean() discards cached geometry, so a rebuilt transducer returns to its canonical pose (the transform is not replayed).

clean

clean() -> None

Release cached geometry arrays to free memory.

copy

copy() -> TransducerBase

Return a deep copy of this transducer, including all state and cached geometry.

Returns:

Type Description
TransducerBase

Independent copy: mutating its delays/apodization/geometry leaves the original untouched.

get_state_dict

get_state_dict() -> Dict[str, Any]

Return a snapshot of the current apodization / delay state.

Returns:

Type Description
dict

Keys apodization, delays, apodization_type, FoverD.

set_state_dict

set_state_dict(state: Dict[str, Any]) -> None

Restore apodization / delay state from a dictionary.

Parameters:

Name Type Description Default
state dict

State dictionary as returned by get_state_dict().

required

FocusedCircularTransducer

FocusedCircularTransducer(
    *,
    diameter_mm: float,
    focus_mm: float,
    no_sub_diameter: int = 25,
    ratio_big_patches: float = 0.85,
    refine_factor: int = 3,
    focus_axis: str = "y",
    frequency_Hz: Optional[float] = None,
)

Bases: TransducerBase

Cylindrically focused single-element transducer (line focus).

The aperture is a circular disk (not rectangular), curved along one axis only — either y (elevation, default) or x (lateral) — creating a cylindrical surface. The resulting pressure field is focused along a line perpendicular to the curved axis.

focus_mm is the focal length — the radius of curvature of the arc (the value on a transducer datasheet). R = focus_mm; the line focus is at z = focus_mm. Must be >= D/2 (the aperture radius).

Typical use cases:

  • 2-D cross-sectional imaging with a fixed elevation focus.
  • Line-focused therapeutic ultrasound along a tissue region.
  • Single-element stand-in for the elevation lens of a linear array.

The curvature follows Field II's lens convention (xdc_focused_array): the flat aperture face — the curved-axis rim — sits at z = 0 and the surface dishes back toward the backing, so a point at coordinate val along the curved axis lies at

z(val) = [R - √(R² - val²)] - sag ,   sag = R - √(R² - R_ap²)

where val is the x- or y-coordinate of each patch corner (depending on focus_axis) and R_ap the aperture radius. The centre line is the deepest point at z = -sag; elevation_lens_sag exposes the sag so reception can add the lens transit to the RF time origin.

Parameters:

Name Type Description Default
diameter_mm float

Outer diameter of the circular aperture in mm.

required
focus_mm float

Axial distance from the rim to the line focus in mm. Must be >= 0.

required
no_sub_diameter int

Number of coarse patches across the diameter.

25
ratio_big_patches float

Fraction of the radius filled with coarse patches. Default 0.85.

0.85
refine_factor int

Subdivision factor for boundary patches. Default 3.

3
focus_axis (y, x)

Which axis carries the curvature. Default is 'y' (elevation).

'y'
frequency_Hz float

Centre frequency in Hz. Defaults to 1 MHz.

None

speed_of_sound_mps instance-attribute

speed_of_sound_mps: float = 1540.0

_apodization instance-attribute

_apodization: Optional[ndarray] = None

_delays instance-attribute

_delays: Optional[ndarray] = None

_elevation_lens_sag instance-attribute

_elevation_lens_sag: Optional[float] = None

apodization_type instance-attribute

apodization_type: Optional[str] = None

FoverD instance-attribute

FoverD: Optional[float] = None

_impulse_response instance-attribute

_impulse_response: Optional[ndarray] = None

_excitation instance-attribute

_excitation: Optional[ndarray] = None

_element_centers instance-attribute

_element_centers: Optional[ndarray] = None

_sub_quad_verts instance-attribute

_sub_quad_verts: Optional[List[ndarray]] = None

_sub_area instance-attribute

_sub_area: Optional[float] = None

_sub_el_idx instance-attribute

_sub_el_idx: Optional[List[int]] = None

_sub_patch_frames instance-attribute

_sub_patch_frames: Optional[Dict] = None

element_centers property

element_centers: ndarray

3-D element centre positions, shape (n_elements, 3) in metres.

Returns:

Type Description
ndarray

Array of shape (n_elements, 3) with element positions in metres.

elevation_lens_sag property writable

elevation_lens_sag: float

Depth (m) a cylindrical elevation lens dishes the surface back at its centre.

Zero for flat/unfocused apertures. For a lens of radius R and element height h the surface centre sits R − √(R² − (h/2)²) behind the rim. The pulse-echo time origin is referenced to the first-arriving edge (the rim), but a focused elevation aperture's echo peaks one lens transit later, so reception adds this sag — as a propagation time, once per aperture — to align the RF origin with a lens-focused reference.

Settable: assign a value in metres to override the geometric default — needed for imported geometries (e.g. a Field II xdc_focused_array probe) whose lens curvature is present in the patches but whose focal parameters are not known to eSDIva. Assign None to restore the default. Subclasses with a native lens supply the default via _default_elevation_lens_sag.

Returns:

Type Description
float

Lens sag in metres (0.0 for flat/unfocused apertures).

sub_quad_verts property

sub_quad_verts: List[ndarray]

List of quad-vertex arrays (4, 3) for every patch, in metres.

Returns:

Type Description
list of ndarray

Each element is a (4, 3) array of corner positions.

sub_area property

sub_area: float

Patch area in m² (same for all patches in a uniform grid).

Returns:

Type Description
float

Area of each sub-patch in square metres.

sub_el_idx property

sub_el_idx: List[int]

Element index for each patch; maps patch to parent element.

Returns:

Type Description
list of int

Index of the parent element for each sub-patch.

n_sub_patches property

n_sub_patches: int

Total number of rectangular sub-patches across all elements.

Returns:

Type Description
int

Number of sub-patches.

sub_patch_frames property

sub_patch_frames: Dict

Per-patch rigid-body frames used by the SIR kernel.

Returns a dict with keys centers, normals, tangents_u, tangents_v, wu, wv — all ndarrays indexed by patch.

For flat transducers the default implementation computes frames from the vertex edge vectors (v[1]-v[0] and v[3]-v[0]), which is exact for any flat, arbitrarily-oriented patch. Curved transducers override _build_patch_frames to return surface-accurate frames derived from the parametric surface equations.

Returns:

Type Description
dict

Patch-frame arrays keyed by centers, normals, etc.

apodization property writable

apodization: ndarray

Per-element apodization weights, shape (n_elements,).

Returns:

Type Description
ndarray

Apodization weights for each element.

delays property writable

delays: ndarray

Per-element delays in seconds, shape (n_elements,).

Returns:

Type Description
ndarray

Delay values for each element in seconds.

tx_N_active property

tx_N_active: int

Number of elements with non-zero apodization.

Returns:

Type Description
int

Count of active elements.

impulse_response property writable

impulse_response: Optional[ndarray]

Electromechanical impulse response of the transducer element.

1-D float32 array sampled at the simulation sampling frequency. Represents the electrical-to-acoustic (TX) or acoustic-to-electrical (RX) transfer function. Applied via convolution in the frequency domain.

None = ideal (delta function) — no filtering.

Returns:

Type Description
ndarray or None

Impulse response array of shape (L_ir,), or None.

excitation property writable

excitation: Optional[ndarray]

Excitation pulse for this transducer.

1-D float32 array sampled at the simulation sampling frequency. None = impulse (delta) excitation.

Returns:

Type Description
ndarray or None

Excitation array of shape (L_exc,), or None.

compute_delays

compute_delays(
    focus_mm=None,
    *,
    angle_steering_deg=None,
    c: Optional[float] = None,
    inline: bool = True,
    plot: bool = False,
) -> ndarray

Compute per-element time delays for electronic focusing or plane-wave steering.

Exactly one of focus_mm or angle_steering_deg must be provided.

Parameters:

Name Type Description Default
focus_mm (array - like, shape(2) or (3,))

Focal point in mm. If 2-D [x, z], y=0 is assumed. Mutually exclusive with angle_steering_deg.

None
angle_steering_deg float or (float, float)

Plane-wave steering angle(s) in degrees. A single float steers in the xz-plane only: (θ_x, θ_y=0). A tuple (θ_x, θ_y) steers in both xz and yz planes (matrix or 3-D arrays). Mutually exclusive with focus_mm.

None
c float

Speed of sound in m/s. Defaults to speed_of_sound_mps (1540).

None
inline bool

If True (default) store result in self.delays.

True
plot bool

If True, display a delay plot after computation.

False

Returns:

Type Description
ndarray

Delays in seconds, shape (n_elements,) (minimum delay is always 0).

Raises:

Type Description
ValueError

If both or neither of focus_mm / angle_steering_deg are given, or if the steering angles exceed the physical limit sin²θ_x + sin²θ_y > 1.

compute_apodization

compute_apodization(
    focus_mm=None,
    *,
    FoverD: Optional[float] = None,
    apodization_type: Optional[str] = None,
    plot: bool = False,
    inline: bool = True,
) -> ndarray

Return uniform full-aperture apodization (all ones).

Mono-element transducers use the full aperture by definition. Multi-element subclasses (linear, matrix) override this method with window-based aperture selection.

For mono-element transducers, patch-wise apodization can still be set directly via set_apodization().

Parameters:

Name Type Description Default
focus_mm array - like

Accepted for API consistency with multi-element subclasses.

None
FoverD float

Accepted for API consistency.

None
apodization_type str

Accepted for API consistency.

None
plot bool

Accepted for API consistency.

False
inline bool

If True (default), store result in self.apodization.

True

Returns:

Type Description
ndarray

Uniform apodization weights, shape (n_elements,).

set_apodization

set_apodization(weights: ndarray) -> None

Set per-element apodization weights directly.

Parameters:

Name Type Description Default
weights ndarray

Apodization weights, shape (n_elements,).

required

set_delays

set_delays(delays: ndarray) -> None

Set per-element delays directly (normalised so minimum = 0).

Parameters:

Name Type Description Default
delays ndarray

Delays in seconds, shape (n_elements,).

required

set_impulse_response

set_impulse_response(ir: Optional[ndarray]) -> None

Set the transducers impulse response.

Parameters:

Name Type Description Default
ir ndarray or None

Impulse response array. Converted to 1-D float32 and ravelled. None = ideal (delta) response.

required

set_excitation

set_excitation(exc: Optional[ndarray]) -> None

Set the transducers excitation pulse.

Parameters:

Name Type Description Default
exc ndarray or None

Excitation array. Converted to 1-D float32 and ravelled. None = impulse (delta) excitation.

required

get_mesh

get_mesh() -> PolyData

Build a PyVista surface mesh of the transducer.

Returns:

Type Description
PolyData

Mesh with 'Apodization' and 'Delays' as cell arrays.

show

show(
    *,
    window_size: Tuple[int, int] = (800, 600),
    scalars: str = "Apodization",
    notebook: bool = False,
    jupyter_backend: Optional[str] = None,
    colorbar_title: Optional[str] = None,
    **kwargs,
) -> None

Interactive 3-D visualisation of the transducer surface.

Parameters:

Name Type Description Default
window_size (int, int)

Pixel dimensions of the render window.

(800, 600)
scalars (Apodization, Delays)

Which cell array to colour by.

'Apodization'
notebook bool

Enable Jupyter notebook rendering.

False
jupyter_backend str

Backend string passed to PyVista ('static', 'trame' …).

None
colorbar_title str

Override the default colour-bar label.

None
**kwargs

Forwarded to plotter.add_mesh().

{}

plot_apodization

plot_apodization(
    apodization: Optional[ndarray] = None,
    *,
    figsize: Tuple[int, int] = (6, 5),
    ax=None,
)

Plot apodization weights as a line/stem chart.

For 2-D matrix transducers, override this method to produce an image.

Parameters:

Name Type Description Default
apodization ndarray

Weights to plot. Defaults to self.apodization.

None
figsize tuple of int

Figure size in inches (width, height).

(6, 5)
ax Axes

Axes to draw on. If None, a new figure is created.

None

Returns:

Type Description
Axes or None

The axes object if ax was provided, otherwise None.

plot_delays

plot_delays(
    delays: Optional[ndarray] = None,
    *,
    figsize: Tuple[int, int] = (6, 5),
    ax=None,
)

Plot per-element delays in microseconds.

Parameters:

Name Type Description Default
delays ndarray

Delays to plot. Defaults to self.delays.

None
figsize tuple of int

Figure size in inches (width, height).

(6, 5)
ax Axes

Axes to draw on. If None, a new figure is created.

None

Returns:

Type Description
Axes or None

The axes object if ax was provided, otherwise None.

plot_delays_apodization

plot_delays_apodization(
    figsize: Tuple[int, int] = (10, 4),
) -> None

Side-by-side delay and apodization plot.

Parameters:

Name Type Description Default
figsize tuple of int

Figure size in inches (width, height).

(10, 4)

transform

transform(T_matrix) -> None

Rigidly move the aperture in space (rotation then translation).

Applies the homogeneous transform to the computed geometry — patch vertices, patch frames (centres, normals, tangents) and element centres — so the SIR simulation and the visualisation both see the moved aperture. Patch widths are rotation-invariant and unchanged.

Delays and apodization are firing-time / weight state, not geometry, so they are untouched: a focus computed before the move still aims at the old global-frame target — call compute_delays / compute_apodization again after moving if the beam must follow.

Parameters:

Name Type Description Default
T_matrix (4, 4) array-like

Homogeneous rigid-body transform. The upper-left 3×3 block is the rotation (orthogonal, det +1); the last column is the translation in mm (user-facing unit).

required

Raises:

Type Description
ValueError

If T_matrix is not (4, 4) or its 3×3 block is not a proper rotation — scaling or reflection would corrupt the patch widths and normals the SIR kernel relies on.

Notes

Simulators snapshot the transducer geometry at construction: after transforming, refresh them with sim.set("transducer", tx) (Emission) or sim.set("tx", tx) / sim.set("rx", rx) (Reception). clean() discards cached geometry, so a rebuilt transducer returns to its canonical pose (the transform is not replayed).

clean

clean() -> None

Release cached geometry arrays to free memory.

copy

copy() -> TransducerBase

Return a deep copy of this transducer, including all state and cached geometry.

Returns:

Type Description
TransducerBase

Independent copy: mutating its delays/apodization/geometry leaves the original untouched.

get_state_dict

get_state_dict() -> Dict[str, Any]

Return a snapshot of the current apodization / delay state.

Returns:

Type Description
dict

Keys apodization, delays, apodization_type, FoverD.

set_state_dict

set_state_dict(state: Dict[str, Any]) -> None

Restore apodization / delay state from a dictionary.

Parameters:

Name Type Description Default
state dict

State dictionary as returned by get_state_dict().

required

Custom & imported

CustomTransducer

CustomTransducer(
    elements: List[TransducerBase],
    positions_mm,
    normals=None,
    *,
    frequency_Hz: Optional[float] = None,
)

Bases: TransducerBase

Multi-element array assembled from individual mono-element transducers.

Each element can be any TransducerBase subclass that represents a single physical source (FlatCircularTransducer, ConcaveCircularTransducer, FocusedCircularTransducer, or any custom subclass with n_elements == 1). The assembled array supports electronic delays and per-element apodization, enabling beam steering and focusing.

The patches of each element are rigidly transformed — rotated to align their normal axis with the provided direction, then translated to the given position. By default, all elements point in the +z direction (the eSDIva propagation axis).

Parameters:

Name Type Description Default
elements list of TransducerBase

Individual mono-element transducer objects. All must have n_elements == 1. They may be of different types or sizes, though sharing the same type is most common.

required
positions_mm (array - like, shape(N, 3))

3-D centre position of each element in mm.

required
normals (array - like, shape(N, 3))

Unit vectors pointing from each element toward the target medium (i.e. in the direction of wave propagation). Defaults to [0, 0, 1] for all elements (all elements flat, facing +z).

None
frequency_Hz float

Override the centre frequency reported to the simulator. If None (default) the frequency of the first element is used.

None

Raises:

Type Description
ValueError

If any element has n_elements != 1.

speed_of_sound_mps instance-attribute

speed_of_sound_mps: float = 1540.0

_apodization instance-attribute

_apodization: Optional[ndarray] = None

_delays instance-attribute

_delays: Optional[ndarray] = None

_elevation_lens_sag instance-attribute

_elevation_lens_sag: Optional[float] = None

apodization_type instance-attribute

apodization_type: Optional[str] = None

FoverD instance-attribute

FoverD: Optional[float] = None

_impulse_response instance-attribute

_impulse_response: Optional[ndarray] = None

_excitation instance-attribute

_excitation: Optional[ndarray] = None

_element_centers instance-attribute

_element_centers: Optional[ndarray] = None

_sub_quad_verts instance-attribute

_sub_quad_verts: Optional[List[ndarray]] = None

_sub_area instance-attribute

_sub_area: Optional[float] = None

_sub_el_idx instance-attribute

_sub_el_idx: Optional[List[int]] = None

_sub_patch_frames instance-attribute

_sub_patch_frames: Optional[Dict] = None

element_centers property

element_centers: ndarray

3-D element centre positions, shape (n_elements, 3) in metres.

Returns:

Type Description
ndarray

Array of shape (n_elements, 3) with element positions in metres.

elevation_lens_sag property writable

elevation_lens_sag: float

Depth (m) a cylindrical elevation lens dishes the surface back at its centre.

Zero for flat/unfocused apertures. For a lens of radius R and element height h the surface centre sits R − √(R² − (h/2)²) behind the rim. The pulse-echo time origin is referenced to the first-arriving edge (the rim), but a focused elevation aperture's echo peaks one lens transit later, so reception adds this sag — as a propagation time, once per aperture — to align the RF origin with a lens-focused reference.

Settable: assign a value in metres to override the geometric default — needed for imported geometries (e.g. a Field II xdc_focused_array probe) whose lens curvature is present in the patches but whose focal parameters are not known to eSDIva. Assign None to restore the default. Subclasses with a native lens supply the default via _default_elevation_lens_sag.

Returns:

Type Description
float

Lens sag in metres (0.0 for flat/unfocused apertures).

sub_quad_verts property

sub_quad_verts: List[ndarray]

List of quad-vertex arrays (4, 3) for every patch, in metres.

Returns:

Type Description
list of ndarray

Each element is a (4, 3) array of corner positions.

sub_area property

sub_area: float

Patch area in m² (same for all patches in a uniform grid).

Returns:

Type Description
float

Area of each sub-patch in square metres.

sub_el_idx property

sub_el_idx: List[int]

Element index for each patch; maps patch to parent element.

Returns:

Type Description
list of int

Index of the parent element for each sub-patch.

n_sub_patches property

n_sub_patches: int

Total number of rectangular sub-patches across all elements.

Returns:

Type Description
int

Number of sub-patches.

sub_patch_frames property

sub_patch_frames: Dict

Per-patch rigid-body frames used by the SIR kernel.

Returns a dict with keys centers, normals, tangents_u, tangents_v, wu, wv — all ndarrays indexed by patch.

For flat transducers the default implementation computes frames from the vertex edge vectors (v[1]-v[0] and v[3]-v[0]), which is exact for any flat, arbitrarily-oriented patch. Curved transducers override _build_patch_frames to return surface-accurate frames derived from the parametric surface equations.

Returns:

Type Description
dict

Patch-frame arrays keyed by centers, normals, etc.

apodization property writable

apodization: ndarray

Per-element apodization weights, shape (n_elements,).

Returns:

Type Description
ndarray

Apodization weights for each element.

delays property writable

delays: ndarray

Per-element delays in seconds, shape (n_elements,).

Returns:

Type Description
ndarray

Delay values for each element in seconds.

tx_N_active property

tx_N_active: int

Number of elements with non-zero apodization.

Returns:

Type Description
int

Count of active elements.

impulse_response property writable

impulse_response: Optional[ndarray]

Electromechanical impulse response of the transducer element.

1-D float32 array sampled at the simulation sampling frequency. Represents the electrical-to-acoustic (TX) or acoustic-to-electrical (RX) transfer function. Applied via convolution in the frequency domain.

None = ideal (delta function) — no filtering.

Returns:

Type Description
ndarray or None

Impulse response array of shape (L_ir,), or None.

excitation property writable

excitation: Optional[ndarray]

Excitation pulse for this transducer.

1-D float32 array sampled at the simulation sampling frequency. None = impulse (delta) excitation.

Returns:

Type Description
ndarray or None

Excitation array of shape (L_exc,), or None.

_default_elevation_lens_sag

_default_elevation_lens_sag() -> float

Geometric lens sag (m) of this transducer type; 0 for flat apertures.

_build_patch_frames

_build_patch_frames() -> Dict

Default patch-frame builder for flat transducers.

Computes each patch's local frame directly from its corner vertices:

  • tangent_u = normalised v[1] - v[0] (first edge)
  • tangent_v = v[3] - v[0] orthogonalised against tangent_u
  • normal = tangent_u × tangent_v
  • wu = ‖v[1] - v[0]‖
  • wv = ‖v[3] - v[0]‖

This is exact for truly flat patches and gives a good approximation for very gently curved surfaces. Subclasses whose geometry is significantly curved should override this method (or set _sub_patch_frames as a side-effect inside _build_subdivisions).

compute_delays

compute_delays(
    focus_mm=None,
    *,
    angle_steering_deg=None,
    c: Optional[float] = None,
    inline: bool = True,
    plot: bool = False,
) -> ndarray

Compute per-element time delays for electronic focusing or plane-wave steering.

Exactly one of focus_mm or angle_steering_deg must be provided.

Parameters:

Name Type Description Default
focus_mm (array - like, shape(2) or (3,))

Focal point in mm. If 2-D [x, z], y=0 is assumed. Mutually exclusive with angle_steering_deg.

None
angle_steering_deg float or (float, float)

Plane-wave steering angle(s) in degrees. A single float steers in the xz-plane only: (θ_x, θ_y=0). A tuple (θ_x, θ_y) steers in both xz and yz planes (matrix or 3-D arrays). Mutually exclusive with focus_mm.

None
c float

Speed of sound in m/s. Defaults to speed_of_sound_mps (1540).

None
inline bool

If True (default) store result in self.delays.

True
plot bool

If True, display a delay plot after computation.

False

Returns:

Type Description
ndarray

Delays in seconds, shape (n_elements,) (minimum delay is always 0).

Raises:

Type Description
ValueError

If both or neither of focus_mm / angle_steering_deg are given, or if the steering angles exceed the physical limit sin²θ_x + sin²θ_y > 1.

set_apodization

set_apodization(weights: ndarray) -> None

Set per-element apodization weights directly.

Parameters:

Name Type Description Default
weights ndarray

Apodization weights, shape (n_elements,).

required

set_delays

set_delays(delays: ndarray) -> None

Set per-element delays directly (normalised so minimum = 0).

Parameters:

Name Type Description Default
delays ndarray

Delays in seconds, shape (n_elements,).

required

set_impulse_response

set_impulse_response(ir: Optional[ndarray]) -> None

Set the transducers impulse response.

Parameters:

Name Type Description Default
ir ndarray or None

Impulse response array. Converted to 1-D float32 and ravelled. None = ideal (delta) response.

required

set_excitation

set_excitation(exc: Optional[ndarray]) -> None

Set the transducers excitation pulse.

Parameters:

Name Type Description Default
exc ndarray or None

Excitation array. Converted to 1-D float32 and ravelled. None = impulse (delta) excitation.

required

get_mesh

get_mesh() -> PolyData

Build a PyVista surface mesh of the transducer.

Returns:

Type Description
PolyData

Mesh with 'Apodization' and 'Delays' as cell arrays.

show

show(
    *,
    window_size: Tuple[int, int] = (800, 600),
    scalars: str = "Apodization",
    notebook: bool = False,
    jupyter_backend: Optional[str] = None,
    colorbar_title: Optional[str] = None,
    **kwargs,
) -> None

Interactive 3-D visualisation of the transducer surface.

Parameters:

Name Type Description Default
window_size (int, int)

Pixel dimensions of the render window.

(800, 600)
scalars (Apodization, Delays)

Which cell array to colour by.

'Apodization'
notebook bool

Enable Jupyter notebook rendering.

False
jupyter_backend str

Backend string passed to PyVista ('static', 'trame' …).

None
colorbar_title str

Override the default colour-bar label.

None
**kwargs

Forwarded to plotter.add_mesh().

{}

plot_apodization

plot_apodization(
    apodization: Optional[ndarray] = None,
    *,
    figsize: Tuple[int, int] = (6, 5),
    ax=None,
)

Plot apodization weights as a line/stem chart.

For 2-D matrix transducers, override this method to produce an image.

Parameters:

Name Type Description Default
apodization ndarray

Weights to plot. Defaults to self.apodization.

None
figsize tuple of int

Figure size in inches (width, height).

(6, 5)
ax Axes

Axes to draw on. If None, a new figure is created.

None

Returns:

Type Description
Axes or None

The axes object if ax was provided, otherwise None.

plot_delays

plot_delays(
    delays: Optional[ndarray] = None,
    *,
    figsize: Tuple[int, int] = (6, 5),
    ax=None,
)

Plot per-element delays in microseconds.

Parameters:

Name Type Description Default
delays ndarray

Delays to plot. Defaults to self.delays.

None
figsize tuple of int

Figure size in inches (width, height).

(6, 5)
ax Axes

Axes to draw on. If None, a new figure is created.

None

Returns:

Type Description
Axes or None

The axes object if ax was provided, otherwise None.

plot_delays_apodization

plot_delays_apodization(
    figsize: Tuple[int, int] = (10, 4),
) -> None

Side-by-side delay and apodization plot.

Parameters:

Name Type Description Default
figsize tuple of int

Figure size in inches (width, height).

(10, 4)

transform

transform(T_matrix) -> None

Rigidly move the aperture in space (rotation then translation).

Applies the homogeneous transform to the computed geometry — patch vertices, patch frames (centres, normals, tangents) and element centres — so the SIR simulation and the visualisation both see the moved aperture. Patch widths are rotation-invariant and unchanged.

Delays and apodization are firing-time / weight state, not geometry, so they are untouched: a focus computed before the move still aims at the old global-frame target — call compute_delays / compute_apodization again after moving if the beam must follow.

Parameters:

Name Type Description Default
T_matrix (4, 4) array-like

Homogeneous rigid-body transform. The upper-left 3×3 block is the rotation (orthogonal, det +1); the last column is the translation in mm (user-facing unit).

required

Raises:

Type Description
ValueError

If T_matrix is not (4, 4) or its 3×3 block is not a proper rotation — scaling or reflection would corrupt the patch widths and normals the SIR kernel relies on.

Notes

Simulators snapshot the transducer geometry at construction: after transforming, refresh them with sim.set("transducer", tx) (Emission) or sim.set("tx", tx) / sim.set("rx", rx) (Reception). clean() discards cached geometry, so a rebuilt transducer returns to its canonical pose (the transform is not replayed).

clean

clean() -> None

Release cached geometry arrays to free memory.

copy

copy() -> TransducerBase

Return a deep copy of this transducer, including all state and cached geometry.

Returns:

Type Description
TransducerBase

Independent copy: mutating its delays/apodization/geometry leaves the original untouched.

get_state_dict

get_state_dict() -> Dict[str, Any]

Return a snapshot of the current apodization / delay state.

Returns:

Type Description
dict

Keys apodization, delays, apodization_type, FoverD.

set_state_dict

set_state_dict(state: Dict[str, Any]) -> None

Restore apodization / delay state from a dictionary.

Parameters:

Name Type Description Default
state dict

State dictionary as returned by get_state_dict().

required

from_fieldii_rect_data

from_fieldii_rect_data(
    rect,
    *,
    frequency_hz: float = 1000000.0,
    elevation_focus_mm: Optional[float] = None,
) -> FieldIITransducer

Create a :class:FieldIITransducer from xdc_get(Th, 'rect') output.

xdc_get(Th, 'rect') returns a 26 × M matrix with one column per mathematical element (patch). Rows used here (0-indexed):

row 0     : physical element number
row 4     : apodization weight
rows 10-21: four corner vertices, each (x, y, z) in metres
row 22    : time delay [s]

Field II lists the corners walking the rectangle perimeter, which is NOT eSDIva's quad ordering (c1-c0 must be the u-tangent and c3-c0 the v-tangent). Each quad is therefore re-ordered from the corner positions themselves: the corner farthest from c0 is the diagonal, the two remaining corners give the u and v edges. This makes the import robust to any corner ordering Field II may produce.

Typical MATLAB export::

rect = xdc_get(Th, 'rect');
save('tx_rect.mat', 'rect');

Parameters:

Name Type Description Default
rect (26, M) array-like

The xdc_get(Th, 'rect') matrix (also accepted transposed).

required
frequency_hz float

Transducer centre frequency in Hz.

1e6
elevation_focus_mm float

Elevation-lens focal length in mm (Field II Rfocus); sets elevation_lens_sag so reception's RF time origin includes the lens transit. None for unlensed probes.

None

Returns:

Type Description
FieldIITransducer

An eSDIva transducer with one element per Field II mathematical element.

from_fieldii_xdc_data

from_fieldii_xdc_data(
    data,
    *,
    frequency_hz: Optional[float] = None,
    elevation_focus_mm: Optional[float] = None,
) -> FieldIITransducer

Create a :class:FieldIITransducer from xdc_get(Th, 'all') output.

Parameters:

Name Type Description Default
data dict or structured ndarray

Python representation of the MATLAB struct returned by xdc_get(Th, 'all'), typically loaded with scipy.io.loadmat(..., simplify_cells=True)['all_data'].

required
frequency_hz float

Transducer centre frequency in Hz. If None, the function tries to read data['f0']; falls back to 1 MHz if not present.

None
elevation_focus_mm float

Elevation-lens focal length in mm (Field II Rfocus of xdc_focused_array); sets elevation_lens_sag so reception's RF time origin includes the lens transit. None for unlensed probes.

None

Returns:

Type Description
FieldIITransducer

An eSDIva transducer with one element per Field II mathematical element.

Raises:

Type Description
KeyError

If data has no geometri field.

ValueError

If the geometri matrix does not have at least 17 columns.

Notes

The geometri column layout assumed here is the Field II v3.x format::

col 0   : element number (1-indexed, skipped)
col 1-3 : centre (x, y, z) [m]
col 4-6 : R[:,0] — global u-tangent direction
col 7-9 : R[:,1] — global v-tangent direction
col 10-12: R[:,2] — patch normal (unused directly)
col 13  : delay [s]
col 14  : half-width  [m] (along u-tangent)
col 15  : half-height [m] (along v-tangent)
col 16  : apodization weight

If the Field II version stores full widths in cols 14–15 instead of half-widths, pass the result through :func:from_fieldii_patch_arrays with half_widths=False.