diff --git a/examples/README.md b/examples/README.md index 5f426cc6..6927bfac 100644 --- a/examples/README.md +++ b/examples/README.md @@ -26,9 +26,10 @@ Every example has a short readme.md file which briefly describes the purpose of - [Focused bowl transducer (axisymmetric)](at_focused_bowl_AS/) ([original example](http://www.k-wave.org/documentation/example_at_piston_and_bowl_transducers.php#heading6), [![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/at_focused_bowl_AS/at_focused_bowl_AS.ipynb)) - - [Focused annular array](at_focused_annular_array_3D/) ([original example](http://www.k-wave.org/documentation/example_at_piston_and_bowl_transducers.php#heading7), [![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/at_focused_annular_array_3D/at_focused_annular_array_3D.ipynb)) +- [Focussed Detector In 2D Example](at_focused_annular_array_3D/) ([original example](http://www.k-wave.org/documentation/example_sd_focussed_detector_2D.php), [![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_2D/sd_focussed_detector_2D.ipynb)) + ## Contributing new examples diff --git a/examples/sd_focussed_detector_2D/README.md b/examples/sd_focussed_detector_2D/README.md new file mode 100644 index 00000000..9a05f008 --- /dev/null +++ b/examples/sd_focussed_detector_2D/README.md @@ -0,0 +1,7 @@ +# Focussed Detector In 2D 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_2D/sd_focussed_detector_2D.ipynb) + +This example shows how k-Wave-python can be used to model the output of a focussed semicircular 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_2D.php). diff --git a/examples/sd_focussed_detector_2D/sd_focussed_detector_2D.ipynb b/examples/sd_focussed_detector_2D/sd_focussed_detector_2D.ipynb new file mode 100644 index 00000000..648339ae --- /dev/null +++ b/examples/sd_focussed_detector_2D/sd_focussed_detector_2D.ipynb @@ -0,0 +1,199 @@ +{ + "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 2D Example\n", + "\n", + "This example shows how k-Wave-python can be used to model the output of a focussed semicircular 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.kspaceFirstOrder2D import kspaceFirstOrder2DC\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_disc, make_circle\n", + "from kwave.utils.data import scale_SI\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# create the computational grid\n", + "grid_size = Vector([180, 180]) # [grid points]\n", + "grid_spacing = Vector([0.1e-3, 0.1e-3]) # [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 a sensor as part of a circle centred on the grid\n", + "sensor_radius = 65 # [grid points]\n", + "arc_angle = np.pi # [rad]\n", + "sensor_mask = make_circle(grid_size, grid_size // 2 + 1, sensor_radius, arc_angle)\n", + "sensor = kSensor(sensor_mask)\n", + "\n", + "# define the array of temporal points\n", + "t_end = 11e-6 # [s]\n", + "_ = kgrid.makeTime(medium.sound_speed, t_end=t_end)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Define simulation parameters" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "input_filename = \"example_sd_focused_2d_input.h5\"\n", + "pathname = gettempdir()\n", + "input_file_full_path = os.path.join(pathname, input_filename)\n", + "simulation_options = SimulationOptions(save_to_disk=True, input_filename=input_filename, data_path=pathname)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Run simulation with first source" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# place a disc-shaped source near the focus of the detector\n", + "source = kSource()\n", + "source.p0 = 2 * make_disc(grid_size, grid_size / 2, 4)\n", + "\n", + "# run the simulation\n", + "sensor_data1 = kspaceFirstOrder2DC(\n", + " medium=medium,\n", + " kgrid=kgrid,\n", + " source=deepcopy(source),\n", + " sensor=sensor,\n", + " simulation_options=simulation_options,\n", + " execution_options=SimulationExecutionOptions(),\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Run simulation with second source" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# place a disc-shaped source horizontally shifted from the focus of the detector\n", + "source.p0 = 2 * make_disc(grid_size, grid_size / 2 + [0, 20], 4)\n", + "\n", + "sensor_data2 = kspaceFirstOrder2DC(\n", + " medium=medium,\n", + " kgrid=kgrid,\n", + " source=deepcopy(source),\n", + " sensor=sensor,\n", + " simulation_options=simulation_options,\n", + " execution_options=SimulationExecutionOptions(),\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Visualize recorded data" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sensor_output1 = np.sum(sensor_data1['p'], axis=1) / np.sum(sensor.mask)\n", + "sensor_output2 = np.sum(sensor_data2['p'], axis=1) / np.sum(sensor.mask)\n", + "\n", + "t_sc, t_scale, t_prefix, _ = scale_SI(t_end)\n", + "t_array = kgrid.t_array.squeeze() * t_scale\n", + "\n", + "plt.plot(t_array, sensor_output1, 'k')\n", + "plt.plot(t_array, sensor_output2, 'r')\n", + "\n", + "plt.xlabel('Time [' + t_prefix + 's]')\n", + "plt.ylabel('Average Pressure Measured Over Detector [au]')\n", + "plt.legend([\n", + " f\"Source on focus, sum(output^2) = {round(np.sum(sensor_output1**2) * 100) / 100}\",\n", + " f\"Source off focus, sum(output^2) = {round(np.sum(sensor_output2**2) * 100) / 100}\"\n", + "])\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 +}