Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor ktransducer #437

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
202 changes: 153 additions & 49 deletions kwave/ktransducer.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import Union

import numpy as np
import logging

Expand Down Expand Up @@ -25,6 +27,9 @@
element_spacing=0,
position=None,
radius=float("inf"),
active_elements=None,
receive_apodization="Rectangular",
transmit_apodization="Rectangular",
):
"""
Args:
Expand Down Expand Up @@ -69,6 +74,22 @@
elif self.position[0] > self.stored_grid_size[0]:
raise ValueError("The defined transducer is positioned outside the grid in the x-direction")

if active_elements is None:
active_elements = np.ones((self.number_elements, 1))
self.active_elements = active_elements

# check the length of the input
assert (
not is_number(receive_apodization) or len(receive_apodization) == self.number_active_elements
), "The length of the receive apodization input must match the number of active elements"
self.receive_apodization = receive_apodization

# check the length of the input
assert (
not is_number(transmit_apodization) or len(transmit_apodization) == self.number_active_elements
), "The length of the transmit apodization input must match the number of active elements"
self.transmit_apodization = transmit_apodization

@property
def element_pitch(self):
return (self.element_spacing + self.element_width) * self.grid_spacing[1]
Expand All @@ -85,6 +106,54 @@
"""
return self.number_elements * self.element_width + (self.number_elements - 1) * self.element_spacing

@property
def number_active_elements(self) -> int:
return int(self.active_elements.sum())

def get_receive_apodization(self):
"""
Get the current receive apodization setting.
"""
if is_number(self.receive_apodization):
assert (

Check warning on line 118 in kwave/ktransducer.py

View check run for this annotation

Codecov / codecov/patch

kwave/ktransducer.py#L118

Added line #L118 was not covered by tests
self.receive_apodization.size == self.number_active_elements
), "The length of the receive apodization input must match the number of active elements"
return self.receive_apodization

Check warning on line 121 in kwave/ktransducer.py

View check run for this annotation

Codecov / codecov/patch

kwave/ktransducer.py#L121

Added line #L121 was not covered by tests
else:
if self.number_active_elements > 1:
apodization, _ = get_win(int(self.number_active_elements), type_=self.receive_apodization)

Check warning on line 124 in kwave/ktransducer.py

View check run for this annotation

Codecov / codecov/patch

kwave/ktransducer.py#L124

Added line #L124 was not covered by tests
else:
apodization = 1
return np.array(apodization)

Check warning on line 127 in kwave/ktransducer.py

View check run for this annotation

Codecov / codecov/patch

kwave/ktransducer.py#L126-L127

Added lines #L126 - L127 were not covered by tests

def get_transmit_apodization(self):
"""
Returns:
return the transmit apodization, converting strings of window
type to actual numbers using getWin

"""

# check if a user defined apodization is given and whether this
# is still the correct size (in case the number of active
# elements has changed)
if is_number(self.transmit_apodization):
assert (

Check warning on line 141 in kwave/ktransducer.py

View check run for this annotation

Codecov / codecov/patch

kwave/ktransducer.py#L141

Added line #L141 was not covered by tests
self.transmit_apodization.size == self.number_active_elements
), "The length of the transmit apodization input must match the number of active elements"

# assign apodization
apodization = self.transmit_apodization

Check warning on line 146 in kwave/ktransducer.py

View check run for this annotation

Codecov / codecov/patch

kwave/ktransducer.py#L146

Added line #L146 was not covered by tests
else:
# if the number of active elements is greater than 1,
# create apodization using getWin, otherwise, assign 1
if self.number_active_elements > 1:
apodization, _ = get_win(int(self.number_active_elements), type_=self.transmit_apodization)
else:
apodization = 1

Check warning on line 153 in kwave/ktransducer.py

View check run for this annotation

Codecov / codecov/patch

kwave/ktransducer.py#L153

Added line #L153 was not covered by tests
apodization = np.array(apodization)
return apodization


class NotATransducer(kSensor):
def __init__(
Expand All @@ -94,8 +163,8 @@
active_elements=None,
focus_distance=float("inf"),
elevation_focus_distance=float("inf"),
receive_apodization="Rectangular",
transmit_apodization="Rectangular",
receive_apodization=None,
transmit_apodization=None,
sound_speed=1540,
input_signal=None,
steering_angle_max=None,
Expand Down Expand Up @@ -150,23 +219,37 @@
else:
raise ValueError("kgrid.dt or kgrid.t_array must be explicitly defined")

if active_elements is None:
active_elements = np.ones((transducer.number_elements, 1))
self.active_elements = active_elements
if active_elements is not None:
logging.log(
logging.WARN,
f"{DeprecationWarning.__name__}: active_elements should not be set "
f"in the {NotATransducer.__name__} class anymore. "
f"Please use the {kWaveTransducerSimple.__name__} class to set this property. "
f"For now, the functionality will be the same for backwards compatibility.",
)
self.transducer.active_elements = active_elements

self.elevation_focus_distance = elevation_focus_distance

# check the length of the input
assert (
not is_number(receive_apodization) or len(receive_apodization) == self.number_active_elements
), "The length of the receive apodization input must match the number of active elements"
self.receive_apodization = receive_apodization

# check the length of the input
assert (
not is_number(transmit_apodization) or len(transmit_apodization) == self.number_active_elements
), "The length of the transmit apodization input must match the number of active elements"
self.transmit_apodization = transmit_apodization
if receive_apodization is not None:
logging.log(
logging.WARN,
f"{DeprecationWarning.__name__}: receive_apodization should not be set "
f"in the {NotATransducer.__name__} class anymore. "
f"Please use the {kWaveTransducerSimple.__name__} class to set this property. "
f"For now, the functionality will be the same for backwards compatibility.",
)
self.transducer.receive_apodization = receive_apodization

if transmit_apodization is not None:
logging.log(
logging.WARN,
f"{DeprecationWarning.__name__}: transmit_apodization should not be set "
f"in the {NotATransducer.__name__} class anymore. "
f"Please use the {kWaveTransducerSimple.__name__} class to set this property. "
f"For now, the functionality will be the same for backwards compatibility.",
)
self.transducer.transmit_apodization = transmit_apodization

# check to see the sound_speed is positive
assert sound_speed > 0, "transducer.sound_speed must be greater than 0"
Expand Down Expand Up @@ -477,8 +560,46 @@
return signal

@property
def number_active_elements(self):
return int(self.active_elements.sum())
def number_active_elements(self) -> int:
logging.log(
logging.WARN,
f"{DeprecationWarning.__name__}: {NotATransducer.__name__}.number_active_elements "
f"is deprecated and will be removed in the future. "
f"Please use {kWaveTransducerSimple.__name__}.number_active_elements instead.",
)

return self.transducer.number_active_elements

@property
def active_elements(self) -> np.ndarray:
logging.log(
logging.WARN,
f"{DeprecationWarning.__name__}: {NotATransducer.__name__}.active_elements "
f"is deprecated and will be removed in the future. "
f"Please use {kWaveTransducerSimple.__name__}.active_elements instead.",
)

return self.transducer.active_elements

@property
def receive_apodization(self) -> Union[np.ndarray, str]:
logging.log(

Check warning on line 586 in kwave/ktransducer.py

View check run for this annotation

Codecov / codecov/patch

kwave/ktransducer.py#L586

Added line #L586 was not covered by tests
logging.WARN,
f"{DeprecationWarning.__name__}: {NotATransducer.__name__}.receive_apodization "
f"is deprecated and will be removed in the future. "
f"Please use {kWaveTransducerSimple.__name__}.receive_apodization instead.",
)
return self.transducer.receive_apodization

Check warning on line 592 in kwave/ktransducer.py

View check run for this annotation

Codecov / codecov/patch

kwave/ktransducer.py#L592

Added line #L592 was not covered by tests

@property
def transmit_apodization(self) -> Union[np.ndarray, str]:
logging.log(
logging.WARN,
f"{DeprecationWarning.__name__}: {NotATransducer.__name__}.transmit_apodization "
f"is deprecated and will be removed in the future. "
f"Please use {kWaveTransducerSimple.__name__}.transmit_apodization instead.",
)
return self.transducer.transmit_apodization

@property
def appended_zeros(self):
Expand Down Expand Up @@ -577,25 +698,13 @@

"""

# check if a user defined apodization is given and whether this
# is still the correct size (in case the number of active
# elements has changed)
if is_number(self.transmit_apodization):
assert (
self.transmit_apodization.size == self.number_active_elements
), "The length of the transmit apodization input must match the number of active elements"

# assign apodization
apodization = self.transmit_apodization
else:
# if the number of active elements is greater than 1,
# create apodization using getWin, otherwise, assign 1
if self.number_active_elements > 1:
apodization, _ = get_win(int(self.number_active_elements), type_=self.transmit_apodization)
else:
apodization = 1
apodization = np.array(apodization)
return apodization
logging.log(
logging.WARN,
f"{DeprecationWarning.__name__}: {NotATransducer.__name__}.get_transmit_apodization() "
f"is deprecated and will be removed in the future. "
f"Please use {kWaveTransducerSimple.__name__}.get_transmit_apodization() instead.",
)
return self.transducer.get_transmit_apodization()

def delay_mask(self, mode=None):
"""
Expand Down Expand Up @@ -675,18 +784,13 @@
"""
Get the current receive apodization setting.
"""
# Example implementation, adjust based on actual logic
if is_number(self.receive_apodization):
assert (
self.receive_apodization.size == self.number_active_elements
), "The length of the receive apodization input must match the number of active elements"
return self.receive_apodization
else:
if self.number_active_elements > 1:
apodization, _ = get_win(int(self.number_active_elements), type_=self.receive_apodization)
else:
apodization = 1
return np.array(apodization)
logging.log(

Check warning on line 787 in kwave/ktransducer.py

View check run for this annotation

Codecov / codecov/patch

kwave/ktransducer.py#L787

Added line #L787 was not covered by tests
logging.WARN,
f"{DeprecationWarning.__name__}: {NotATransducer.__name__}.get_receive_apodization() "
f"is deprecated and will be removed in the future. "
f"Please use {kWaveTransducerSimple.__name__}.get_receive_apodization instead.",
)
return self.transducer.get_receive_apodization()

Check warning on line 793 in kwave/ktransducer.py

View check run for this annotation

Codecov / codecov/patch

kwave/ktransducer.py#L793

Added line #L793 was not covered by tests

def scan_line(self, sensor_data):
"""
Expand Down
Loading