-
Notifications
You must be signed in to change notification settings - Fork 19
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
includes cup array PType307 #178
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
# SPDX-FileCopyrightText: 2021 Division of Intelligent Medical Systems, DKFZ | ||
# SPDX-FileCopyrightText: 2021 Janek Groehl | ||
# SPDX-License-Identifier: MIT | ||
import numpy as np | ||
|
||
from simpa.core.device_digital_twins import DetectionGeometryBase | ||
import os | ||
|
||
|
||
class CupArrayDetectionGeometry(DetectionGeometryBase): | ||
""" | ||
This class represents a digital twin of a ultrasound detection device | ||
with a cup detection geometry. The origin for this device is the center (focus) of the cup array. | ||
""" | ||
|
||
def __init__(self, radius_mm=30, | ||
pitch_mm=None, | ||
number_detector_elements=384, | ||
detector_element_width_mm=None, | ||
detector_element_length_mm=None, | ||
center_frequency_hz=8e6, | ||
bandwidth_percent=50, | ||
sampling_frequency_mhz=40, | ||
angular_origin_offset=None, | ||
device_position_mm=None, | ||
field_of_view_extent_mm=None): | ||
""" | ||
:param pitch_mm: In-plane distance between the beginning of one detector element to the next detector element. | ||
:param radius_mm: | ||
:param number_detector_elements: | ||
:param detector_element_width_mm: | ||
:param detector_element_length_mm: | ||
:param center_frequency_hz: | ||
:param bandwidth_percent: | ||
:param sampling_frequency_mhz: | ||
:param angular_origin_offset: | ||
:param device_position_mm: Center (focus) of the curved array. | ||
""" | ||
|
||
super(CupArrayDetectionGeometry, self).__init__( | ||
number_detector_elements=number_detector_elements, | ||
detector_element_width_mm=detector_element_width_mm, | ||
detector_element_length_mm=detector_element_length_mm, | ||
center_frequency_hz=center_frequency_hz, | ||
bandwidth_percent=bandwidth_percent, | ||
sampling_frequency_mhz=sampling_frequency_mhz, | ||
device_position_mm=device_position_mm) | ||
|
||
self.pitch_mm = pitch_mm | ||
self.radius_mm = radius_mm | ||
self.angular_origin_offset = angular_origin_offset | ||
|
||
if field_of_view_extent_mm is None: | ||
self.logger.warning("Set field_of_view_extend_mm, while looping over first or second dimension - otherwise " | ||
"memory issues could arise. Default FOV is 4mm*4mm*8.5mm, hence very small.") | ||
self.field_of_view_extent_mm = np.asarray([-2., 2., -2., 2., -6.5, 2.]) # -6.5 mm is level of membrane | ||
else: | ||
self.field_of_view_extent_mm = field_of_view_extent_mm | ||
|
||
def check_settings_prerequisites(self, global_settings) -> bool: | ||
pass | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Like in the other detection geometries we could also check here if the volume size is large enough to encompass this device and log an error if this is not the case. For example, we could determine the width and length of the device and see if this is smaller than the corresponding volume dimensions |
||
|
||
def update_settings_for_use_of_model_based_volume_creator(self, global_settings): | ||
pass | ||
|
||
def get_detector_element_positions_base_mm(self) -> np.ndarray: | ||
py_file_path = os.path.dirname(os.path.realpath(__file__)).replace("\\", "/") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do you need to replace There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As there are not backward slashes in Linux paths this line still works fine, because nothing will be replaced as everything is already correct. Nevertheless, I'm not sure if it is the best idea to search for a relative path from this file instead of from the simpa directory. |
||
detector_positions = np.load(f'{py_file_path}/cup_positions_PType307', allow_pickle=True) * 1000 # m -> mm | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason, why the detector positions are saved in a pickled file? Wouldn't it be cool if it was saved in a human readable format? |
||
return detector_positions | ||
|
||
def get_detector_element_orientations(self) -> np.ndarray: | ||
detector_positions = self.get_detector_element_positions_base_mm() | ||
detector_orientations = np.subtract(0, detector_positions) | ||
norm = np.linalg.norm(detector_orientations, axis=-1) | ||
for dim in range(3): | ||
detector_orientations[:, dim] = detector_orientations[:, dim] / norm | ||
Comment on lines
+75
to
+76
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can achieve the same result much cleaner and probably also faster with the following code detector_orientations /= norm[:,None] |
||
return detector_orientations | ||
|
||
def serialize(self) -> dict: | ||
serialized_device = self.__dict__ | ||
return {"CupArrayDetectionGeometry": serialized_device} | ||
|
||
@staticmethod | ||
def deserialize(dictionary_to_deserialize): | ||
deserialized_device = CupArrayDetectionGeometry() | ||
for key, value in dictionary_to_deserialize.items(): | ||
deserialized_device.__dict__[key] = value | ||
return deserialized_device |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you don't need these variables than there is no need to define them, I guess. The super constructor of the detection geometry has all relevant variables a detection geometry requires and the cup array doesn't seem to need the pitch, radius and angular origin offset so I would leave them out