-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1a4bba9
commit 1001de4
Showing
4 changed files
with
420 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Focussed Detector In 3D Example | ||
|
||
[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/waltsims/k-wave-python/blob/master/examples/sd_focussed_detector_3D/sd_focussed_detector_3D.ipynb) | ||
|
||
This example shows how k-Wave can be used to model the output of a focussed bowl detector where the directionality arises from spatially averaging across the detector surface. | ||
|
||
To read more, visit the [original example page](http://www.k-wave.org/documentation/example_sd_focussed_detector_3D.php). |
276 changes: 276 additions & 0 deletions
276
examples/sd_focussed_detector_3D/sd_focussed_detector_3D.ipynb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,276 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"%pip install git+https://github.com/waltsims/k-wave-python " | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"# Focussed Detector In 3D Example\n", | ||
"This example shows how k-Wave can be used to model the output of a focussed bowl detector where the directionality arises from spatially averaging across the detector surface." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"%matplotlib inline\n", | ||
"\n", | ||
"import os\n", | ||
"from copy import deepcopy\n", | ||
"from tempfile import gettempdir\n", | ||
"\n", | ||
"import numpy as np\n", | ||
"import matplotlib.pyplot as plt\n", | ||
"\n", | ||
"from kwave.data import Vector\n", | ||
"from kwave.kgrid import kWaveGrid\n", | ||
"from kwave.kmedium import kWaveMedium\n", | ||
"from kwave.ksource import kSource\n", | ||
"from kwave.ktransducer import kSensor\n", | ||
"from kwave.options.simulation_execution_options import SimulationExecutionOptions\n", | ||
"from kwave.options.simulation_options import SimulationOptions\n", | ||
"from kwave.utils.mapgen import make_bowl\n", | ||
"from kwave.utils.data import scale_SI\n", | ||
"\n", | ||
"from kwave.kspaceFirstOrder3D import kspaceFirstOrder3D\n", | ||
"from kwave.utils.filters import filter_time_series" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# create the computational grid\n", | ||
"grid_size = Vector([64, 64, 64]) # [grid points]\n", | ||
"grid_spacing_single = 100e-3 / grid_size.x\n", | ||
"grid_spacing = Vector([grid_spacing_single, grid_spacing_single, grid_spacing_single]) # [m]\n", | ||
"kgrid = kWaveGrid(grid_size, grid_spacing)\n", | ||
"\n", | ||
"# define the properties of the propagation medium\n", | ||
"medium = kWaveMedium(sound_speed=1500)\n", | ||
"\n", | ||
"# define the array of temporal points\n", | ||
"_ = kgrid.makeTime(medium.sound_speed)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Define simulation parameters" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"input_filename = \"example_sd_focused_3d_input.h5\"\n", | ||
"pathname = gettempdir()\n", | ||
"input_file_full_path = os.path.join(pathname, input_filename)\n", | ||
"simulation_options = SimulationOptions(\n", | ||
" save_to_disk=True, \n", | ||
" input_filename=input_filename, \n", | ||
" data_path=pathname, \n", | ||
" pml_size=10, \n", | ||
" data_cast='single'\n", | ||
")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Define a concave sensor" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# create a concave sensor\n", | ||
"sphere_offset = 10\n", | ||
"diameter = grid_size.x / 2 + 1\n", | ||
"radius = grid_size.x / 2\n", | ||
"bowl_pos = Vector([1 + sphere_offset, grid_size.y / 2, grid_size.z / 2])\n", | ||
"focus_pos = grid_size / 2\n", | ||
"\n", | ||
"sensor_mask = make_bowl(grid_size, bowl_pos, radius, diameter, focus_pos)\n", | ||
"sensor = kSensor(sensor_mask)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Run simulation with first source" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# define a time varying sinusoidal source\n", | ||
"source = kSource()\n", | ||
"\n", | ||
"source_freq = 0.25e6 # [Hz]\n", | ||
"source_mag = 1 # [Pa]\n", | ||
"source.p = source_mag * np.sin(2 * np.pi * source_freq * kgrid.t_array)\n", | ||
"source.p = filter_time_series(kgrid, medium, source.p)\n", | ||
"\n", | ||
"# place the first point source near the focus of the detector\n", | ||
"source1 = np.zeros(grid_size)\n", | ||
"source1[int(sphere_offset + radius), grid_size.y // 2 - 1, grid_size.z // 2 - 1] = 1\n", | ||
"\n", | ||
"# run the first simulation\n", | ||
"source.p_mask = source1\n", | ||
"\n", | ||
"sensor_data1 = kspaceFirstOrder3D(\n", | ||
" medium=medium,\n", | ||
" kgrid=kgrid,\n", | ||
" source=deepcopy(source),\n", | ||
" sensor=deepcopy(sensor),\n", | ||
" simulation_options=simulation_options,\n", | ||
" execution_options=SimulationExecutionOptions(is_gpu_simulation=False),\n", | ||
")\n", | ||
"\n", | ||
"# average the data recorded at each grid point to simulate the measured signal from a single element focused detector\n", | ||
"sensor_data1 = np.sum(sensor_data1['p'], axis=1)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Run simulation with second source" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# place the second point source off axis\n", | ||
"source2 = np.zeros(grid_size)\n", | ||
"source2[int(1 + sphere_offset + radius), grid_size.y // 2 + 5, grid_size.z // 2 + 5] = 1\n", | ||
"\n", | ||
"\n", | ||
"# run the second simulation\n", | ||
"source.p_mask = source2\n", | ||
"sensor_data2 = kspaceFirstOrder3D(\n", | ||
" medium=medium,\n", | ||
" kgrid=kgrid,\n", | ||
" source=source,\n", | ||
" sensor=sensor,\n", | ||
" simulation_options=simulation_options,\n", | ||
" execution_options=SimulationExecutionOptions(is_gpu_simulation=False),\n", | ||
")\n", | ||
"\n", | ||
"# average the data recorded at each grid point to simulate the measured signal from a single element focused detector\n", | ||
"sensor_data2 = np.sum(sensor_data2['p'], axis=1)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Visualize detector and sources" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# Combine arrays as in MATLAB: sensor.mask + source1 + source2\n", | ||
"combined_array = sensor_mask + source1 + source2\n", | ||
"\n", | ||
"# Find the indices of non-zero elements\n", | ||
"x, y, z = np.nonzero(combined_array)\n", | ||
"\n", | ||
"# Enable interactive mode\n", | ||
"plt.ion()\n", | ||
"\n", | ||
"# Create an interactive 3D plot with matplotlib\n", | ||
"fig = plt.figure(figsize=(8, 6))\n", | ||
"ax = fig.add_subplot(111, projection='3d')\n", | ||
"sc = ax.scatter(x, y, z, c='blue', marker='s', s=100, depthshade=True) # 's' for square-like markers\n", | ||
"\n", | ||
"# Set the view angle to mimic MATLAB's `view([130, 40])`\n", | ||
"ax.view_init(elev=40, azim=130)\n", | ||
"\n", | ||
"# Customize the axes\n", | ||
"ax.set_xlabel('X')\n", | ||
"ax.set_ylabel('Y')\n", | ||
"ax.set_zlabel('Z')\n", | ||
"ax.set_title('Interactive 3D Voxel Plot')" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Visualize recorded data" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"t_sc, t_scale, t_prefix, _ = scale_SI(kgrid.t_array[-1])\n", | ||
"t_array = kgrid.t_array.squeeze() * t_scale\n", | ||
"\n", | ||
"plt.figure()\n", | ||
"plt.plot(t_array, sensor_data1)\n", | ||
"plt.plot(t_array, sensor_data2, 'r')\n", | ||
"\n", | ||
"plt.xlabel('Time [' + t_prefix + 's]')\n", | ||
"plt.ylabel('Average Pressure Measured By Focussed Detector [Pa]')\n", | ||
"plt.legend(['Source on axis', 'Source off axis'])\n", | ||
"\n", | ||
"plt.show()" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "env_kwave", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |
Oops, something went wrong.