-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into dependabot/pip/scipy-1.14.1
- Loading branch information
Showing
14 changed files
with
678 additions
and
144 deletions.
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
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 |
---|---|---|
|
@@ -10,7 +10,7 @@ jobs: | |
fetch-depth: 0 # otherwise, you will fail to push refs to dest repo | ||
- uses: actions/setup-python@v5 | ||
with: | ||
python-version: '3.9' | ||
python-version: '3.10' | ||
cache: 'pip' | ||
- name: Build and Commit | ||
uses: waltsims/[email protected] | ||
|
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
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 @@ | ||
# Modelling Sensor Directivity 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_directivity_modelling_2D/sd_directivity_modelling_2D.ipynb) | ||
|
||
This example demonstrates how the sensitivity of a large single element detector varies with the angular position of a point-like source. | ||
|
||
To read more, visit the [original example page](http://www.k-wave.org/documentation/example_sd_directivity_modelling_2D.php). |
244 changes: 244 additions & 0 deletions
244
examples/sd_directivity_modelling_2D/sd_directivity_modelling_2D.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,244 @@ | ||
{ | ||
"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": [ | ||
"# Modelling Sensor Directivity In 2D Example\n", | ||
"\n", | ||
"This example demonstrates how the sensitivity of a large single element detector varies with the angular position of a point-like source." | ||
] | ||
}, | ||
{ | ||
"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.ksensor import kSensor\n", | ||
"from kwave.ksource import kSource\n", | ||
"from kwave.kspaceFirstOrder2D import kspaceFirstOrder2DC\n", | ||
"from kwave.options.simulation_execution_options import SimulationExecutionOptions\n", | ||
"from kwave.options.simulation_options import SimulationOptions\n", | ||
"from kwave.utils.conversion import cart2grid\n", | ||
"from kwave.utils.filters import filter_time_series\n", | ||
"from kwave.utils.mapgen import make_cart_circle\n", | ||
"from kwave.utils.matlab import ind2sub, matlab_find, unflatten_matlab_mask\n", | ||
"from kwave.utils.colormap import get_color_map\n", | ||
"from kwave.utils.data import scale_SI" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Create the computational grid and medium" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"grid_size_points = Vector([128, 128]) # [grid points]\n", | ||
"grid_size_meters = Vector([50e-3, 50e-3]) # [m]\n", | ||
"grid_spacing_meters = grid_size_meters / grid_size_points # [m]\n", | ||
"kgrid = kWaveGrid(grid_size_points, grid_spacing_meters)\n", | ||
"\n", | ||
"# define the properties of the propagation medium\n", | ||
"medium = kWaveMedium(sound_speed=1500)\n", | ||
"\n", | ||
"# define the array of time points [s]\n", | ||
"Nt = 350\n", | ||
"dt = 7e-8 # [s]\n", | ||
"kgrid.setTime(Nt, dt)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Define a large area detector" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"sz = 20 # [grid points]\n", | ||
"sensor_mask = np.zeros(grid_size_points)\n", | ||
"sensor_mask[grid_size_points.x // 2, (grid_size_points.y // 2 - sz // 2) : (grid_size_points.y // 2 + sz // 2) + 1] = 1\n", | ||
"sensor = kSensor(sensor_mask)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Define a time varying sinusoidal source" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# define equally spaced point sources lying on a circle centred at the\n", | ||
"# centre of the detector face\n", | ||
"radius = 30 # [grid points]\n", | ||
"points = 11\n", | ||
"circle = make_cart_circle(radius * grid_spacing_meters.x, points, Vector([0, 0]), np.pi)\n", | ||
"\n", | ||
"# find the binary sensor mask most closely corresponding to the Cartesian\n", | ||
"# coordinates from makeCartCircle\n", | ||
"circle, _, _ = cart2grid(kgrid, circle)\n", | ||
"\n", | ||
"# find the indices of the sources in the binary source mask\n", | ||
"source_positions = matlab_find(circle, val=1, mode=\"eq\")\n", | ||
"\n", | ||
"source = kSource()\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", | ||
"\n", | ||
"# filter the source to remove high frequencies not supported by the grid\n", | ||
"source.p = filter_time_series(kgrid, medium, source.p)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Define simulation parameters and run simulations" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# pre-allocate array for storing the output time series\n", | ||
"single_element_data = np.zeros((Nt, points)) # noqa: F841\n", | ||
"\n", | ||
"# run a simulation for each of these sources to see the effect that the\n", | ||
"# angle from the detector has on the measured signal\n", | ||
"for source_loop in range(points):\n", | ||
" # select a point source\n", | ||
" source.p_mask = np.zeros(grid_size_points)\n", | ||
" source.p_mask[unflatten_matlab_mask(source.p_mask, source_positions[source_loop] - 1)] = 1\n", | ||
"\n", | ||
" # run the simulation\n", | ||
"\n", | ||
" input_filename = f\"example_input_{source_loop + 1}_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)\n", | ||
" # run the simulation\n", | ||
" sensor_data = kspaceFirstOrder2DC(\n", | ||
" medium=medium,\n", | ||
" kgrid=kgrid,\n", | ||
" source=deepcopy(source),\n", | ||
" sensor=deepcopy(sensor),\n", | ||
" simulation_options=simulation_options,\n", | ||
" execution_options=SimulationExecutionOptions(),\n", | ||
" )\n", | ||
" single_element_data[:, source_loop] = sensor_data['p'].sum(axis=1)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Visualize recorded data" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"plt.figure()\n", | ||
"plt.imshow(circle + sensor.mask, \n", | ||
" extent=[\n", | ||
" kgrid.y_vec.min() * 1e3, kgrid.y_vec.max() * 1e3, \n", | ||
" kgrid.x_vec.max() * 1e3, kgrid.x_vec.min() * 1e3], vmin=-1, vmax=1, cmap=get_color_map())\n", | ||
"plt.ylabel('x-position [mm]')\n", | ||
"plt.xlabel('y-position [mm]')\n", | ||
"plt.axis('image')\n", | ||
"\n", | ||
"_, t_scale, t_prefix, _ = scale_SI(kgrid.t_array[-1])\n", | ||
"\n", | ||
"# Plot the time series recorded for each of the sources\n", | ||
"plt.figure()\n", | ||
"# Loop through each source and plot individually\n", | ||
"for i in range(single_element_data.shape[1]):\n", | ||
" plt.plot((kgrid.t_array * t_scale).squeeze(), single_element_data[:, i], label=f'Source {i+1}')\n", | ||
"\n", | ||
"plt.xlabel(f'Time [{t_prefix}s]')\n", | ||
"plt.ylabel('Pressure [au]')\n", | ||
"plt.title('Time Series For Each Source Direction')\n", | ||
"\n", | ||
"\n", | ||
"# Calculate angle between source and center of detector face\n", | ||
"angles = []\n", | ||
"for source_position in source_positions:\n", | ||
" x, y = ind2sub(kgrid.y.shape, source_position)\n", | ||
" angles.append(np.arctan(kgrid.y[x, y] / kgrid.x[x, y]))\n", | ||
"\n", | ||
"# Plot the maximum amplitudes for each of the sources\n", | ||
"plt.figure()\n", | ||
"plt.plot(angles, np.max(single_element_data[200:350, :], axis=0), 'o', mfc='none')\n", | ||
"plt.xlabel('Angle Between Source and Centre of Detector Face [rad]')\n", | ||
"plt.ylabel('Maximum Detected Pressure [au]')\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.