├── .github ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── code_enhancement.md │ ├── config.yml │ ├── example.md │ └── feature_request.md ├── codecov.yml ├── dependabot.yml └── workflows │ ├── codespell.yml │ ├── pytest.yml │ ├── ruff.yml │ ├── run-examples.yml │ ├── test_example.yml │ ├── test_optional_dependencies.yml │ └── test_pages.yml ├── .gitignore ├── .pre-commit-config.yaml ├── .readthedocs.yaml ├── CITATION.cff ├── Dockerfile ├── LICENSE ├── Makefile ├── docs ├── Makefile ├── README.md ├── _static │ └── example_bmode.png ├── conf.py ├── development │ └── development_environment.rst ├── get_started │ ├── contrib.rst │ ├── legacy_licenses │ │ ├── gpl-3.0.rst │ │ └── mit.rst │ └── license.rst ├── index.rst ├── kwave.data.rst ├── kwave.enums.rst ├── kwave.executor.rst ├── kwave.kWaveSimulation.rst ├── kwave.kWaveSimulation_helper.create_absorption_variables.rst ├── kwave.kWaveSimulation_helper.display_simulation_params.rst ├── kwave.kWaveSimulation_helper.expand_grid_matrices.rst ├── kwave.kWaveSimulation_helper.retract_transducer_grid_size.rst ├── kwave.kWaveSimulation_helper.rst ├── kwave.kWaveSimulation_helper.save_to_disk_func.rst ├── kwave.kWaveSimulation_helper.scale_source_terms_func.rst ├── kwave.kWaveSimulation_helper.set_sound_speed_ref.rst ├── kwave.kgrid.rst ├── kwave.kmedium.rst ├── kwave.ksensor.rst ├── kwave.ksource.rst ├── kwave.kspaceFirstOrder.rst ├── kwave.kspaceFirstOrder2D.rst ├── kwave.kspaceFirstOrder3D.rst ├── kwave.kspaceFirstOrderAS.rst ├── kwave.ktransducer.rst ├── kwave.options.rst ├── kwave.reconstruction.beamform.rst ├── kwave.reconstruction.converter.rst ├── kwave.reconstruction.rst ├── kwave.reconstruction.shifted_transform.rst ├── kwave.reconstruction.tools.rst ├── kwave.recorder.rst ├── kwave.rst ├── kwave.utils.checks.rst ├── kwave.utils.colormap.rst ├── kwave.utils.conversion.rst ├── kwave.utils.data.rst ├── kwave.utils.dotdictionary.rst ├── kwave.utils.filters.rst ├── kwave.utils.interp.rst ├── kwave.utils.io.rst ├── kwave.utils.mapgen.rst ├── kwave.utils.math.rst ├── kwave.utils.matrix.rst ├── kwave.utils.pml.rst ├── kwave.utils.rst ├── kwave.utils.signals.rst ├── kwave.utils.tictoc.rst ├── make.bat └── reconstruction │ ├── index.rst │ └── time_reversal.rst ├── examples ├── README.md ├── at_array_as_sensor │ ├── README.md │ ├── at_array_as_sensor.ipynb │ └── at_array_as_sensor.py ├── at_array_as_source │ ├── README.md │ ├── at_array_as_source.ipynb │ └── at_array_as_source.py ├── at_circular_piston_3D │ ├── README.md │ ├── at_circular_piston_3D.ipynb │ └── at_circular_piston_3D.py ├── at_circular_piston_AS │ ├── README.md │ ├── at_circular_piston_AS.ipynb │ └── at_circular_piston_AS.py ├── at_focused_annular_array_3D │ ├── README.md │ ├── at_focused_annular_array_3D.ipynb │ └── at_focused_annular_array_3D.py ├── at_focused_bowl_3D │ ├── README.md │ ├── at_focused_bowl_3D.ipynb │ └── at_focused_bowl_3D.py ├── at_focused_bowl_AS │ ├── README.md │ ├── at_focused_bowl_AS.ipynb │ └── at_focused_bowl_AS.py ├── at_linear_array_transducer │ ├── README.md │ ├── at_linear_array_transducer.ipynb │ └── at_linear_array_transducer.py ├── checkpointing │ ├── README.md │ └── checkpoint.py ├── ivp_photoacoustic_waveforms │ ├── README.md │ ├── ivp_photoacoustic_waveforms.ipynb │ └── ivp_photoacoustic_waveforms.py ├── na_controlling_the_pml │ ├── README.md │ ├── modified_matlab_example.m │ └── na_controlling_the_pml.ipynb ├── pr_2D_FFT_line_sensor │ ├── README.md │ ├── pr_2D_FFT_line_sensor.ipynb │ └── pr_2D_FFT_line_sensor.py ├── pr_2D_TR_line_sensor │ ├── README.md │ ├── pr_2D_TR_line_sensor.ipynb │ └── pr_2D_TR_line_sensor.py ├── pr_3D_FFT_planar_sensor │ ├── README.md │ ├── pr_3D_FFT_planar_sensor.ipynb │ └── pr_3D_FFT_planar_sensor.py ├── pr_3D_TR_planar_sensor │ ├── README.md │ ├── pr_3D_TR_planar_sensor.ipynb │ └── pr_3D_TR_planar_sensor.py ├── sd_directivity_modelling_2D │ ├── README.md │ ├── sd_directivity_modelling_2D.ipynb │ └── sd_directivity_modelling_2D.py ├── sd_focussed_detector_2D │ ├── README.md │ ├── sd_focussed_detector_2D.ipynb │ └── sd_focussed_detector_2D.py ├── sd_focussed_detector_3D │ ├── README.md │ ├── sd_focussed_detector_3D.ipynb │ └── sd_focussed_detector_3D.py ├── us_beam_patterns │ ├── README.md │ ├── us_beam_patterns.ipynb │ └── us_beam_patterns.py ├── us_bmode_linear_transducer │ ├── README.md │ ├── example_utils.py │ ├── us_bmode_linear_transducer.ipynb │ └── us_bmode_linear_transducer.py ├── us_bmode_phased_array │ ├── README.md │ ├── us_bmode_phased_array.ipynb │ └── us_bmode_phased_array.py └── us_defining_transducer │ ├── README.md │ ├── us_defining_transducer.ipynb │ └── us_defining_transducer.py ├── kwave ├── __init__.py ├── data.py ├── enums.py ├── executor.py ├── kWaveSimulation.py ├── kWaveSimulation_helper │ ├── __init__.py │ ├── create_absorption_variables.py │ ├── display_simulation_params.py │ ├── expand_grid_matrices.py │ ├── retract_transducer_grid_size.py │ ├── save_to_disk_func.py │ ├── scale_source_terms_func.py │ └── set_sound_speed_ref.py ├── kgrid.py ├── kmedium.py ├── ksensor.py ├── ksource.py ├── kspaceFirstOrder2D.py ├── kspaceFirstOrder3D.py ├── kspaceFirstOrderAS.py ├── kspaceLineRecon.py ├── kspacePlaneRecon.py ├── ktransducer.py ├── options │ ├── __init__.py │ ├── simulation_execution_options.py │ └── simulation_options.py ├── reconstruction │ ├── __init__.py │ ├── beamform.py │ ├── time_reversal.py │ └── tools.py ├── recorder.py └── utils │ ├── __init__.py │ ├── angular_spectrum.py │ ├── angular_spectrum_cw.py │ ├── atten_comp.py │ ├── checks.py │ ├── colormap.py │ ├── conversion.py │ ├── data.py │ ├── dotdictionary.py │ ├── filters.py │ ├── interp.py │ ├── io.py │ ├── kwave_array.py │ ├── mapgen.py │ ├── math.py │ ├── matlab.py │ ├── matrix.py │ ├── plot.py │ ├── pml.py │ ├── sharpness_filters.py │ ├── signals.py │ ├── tictoc.py │ └── typing.py ├── make_docs.sh ├── pyproject.toml ├── pytest.ini ├── run_examples.py ├── run_tests.sh └── tests ├── EXAMPLE_source_one.png ├── EXAMPLE_source_two.bmp ├── __init__.py ├── diff_utils.py ├── h5_summary.py ├── matlab_test_data_collectors ├── matlab_collectors │ ├── +private_kwave_functions │ │ └── tolStar.m │ ├── +utils │ │ ├── TestRecorder.m │ │ └── rand_vector_in_range.m │ ├── collect_FocusAnnulusONeil.m │ ├── collect_FocusBowlONeil.m │ ├── collect_angularSpectrum.m │ ├── collect_angularSpectrumCW.m │ ├── collect_at_linear_array_transducer.m │ ├── collect_attenComp.m │ ├── collect_brenner.m │ ├── collect_cart2grid.m │ ├── collect_checkStability.m │ ├── collect_computeLinearTransform.m │ ├── collect_createCWSignals.m │ ├── collect_expandMatrix.m │ ├── collect_fourierShift.m │ ├── collect_gaussian.m │ ├── collect_gaussianFilter.m │ ├── collect_getAffineMatrix.m │ ├── collect_getColorMap.m │ ├── collect_getWin.m │ ├── collect_get_delta_BLI.m │ ├── collect_gradientSpect.m │ ├── collect_hounsfield2density.m │ ├── collect_interpCartData.m │ ├── collect_kWaveArray.m │ ├── collect_kWaveGrid.m │ ├── collect_makeArc.m │ ├── collect_makeBall.m │ ├── collect_makeBowl.m │ ├── collect_makeCartArc.m │ ├── collect_makeCartBowl.m │ ├── collect_makeCartCircle.m │ ├── collect_makeCartDisc.m │ ├── collect_makeCartRect.m │ ├── collect_makeCartSphere.m │ ├── collect_makeCartSphericalSegment.m │ ├── collect_makeCircle.m │ ├── collect_makeDisc.m │ ├── collect_makeLine.m │ ├── collect_makeMultiArc.m │ ├── collect_makeMultiBowl.m │ ├── collect_makeSphere.m │ ├── collect_makeSphericalSection.m │ ├── collect_maxND.m │ ├── collect_minND.m │ ├── collect_normvar.m │ ├── collect_reorderBinarySensorData.m │ ├── collect_reorderSensorData.m │ ├── collect_resize.m │ ├── collect_revolve2D.m │ ├── collect_rotation_matrices.m │ ├── collect_scaleSI.m │ ├── collect_scaleTime.m │ ├── collect_scanConversion.m │ ├── collect_smooth.m │ ├── collect_tenenbaum.m │ ├── collect_tolStar.m │ ├── collect_toneBurst.m │ ├── collect_trimCartPoints.m │ ├── collect_unmaskSensorData.m │ ├── collect_writeAttributes.m │ ├── collect_writeFlags.m │ ├── collect_writeGrid.m │ └── collect_writeMatrix.m ├── python_testers │ ├── __init__.py │ ├── angularSpectrumCW_test.py │ ├── angularSpectrum_test.py │ ├── attenComp_test.py │ ├── cart2grid_test.py │ ├── computeLinearTransform_test.py │ ├── create_cw_signals_test.py │ ├── expandMatrix_test.py │ ├── focusBowlONeil_test.py │ ├── focusedAnnulusONeil_test.py │ ├── fourierShift_test.py │ ├── gaussianFilter_test.py │ ├── gaussian_test.py │ ├── getAffineMatrix_test.py │ ├── getColorMap_test.py │ ├── getDeltaBLI_test.py │ ├── getWin_test.py │ ├── h5io_test.py │ ├── hounsfield2density.py │ ├── kWaveArray_test.py │ ├── kWaveGrid_test.py │ ├── makeArc_test.py │ ├── makeBall_test.py │ ├── makeBowl_test.py │ ├── makeCartArc_test.py │ ├── makeCartBowl_test.py │ ├── makeCartCircle_test.py │ ├── makeCartRect_test.py │ ├── makeCartSphere_test.py │ ├── makeCartSphericalSegment_test.py │ ├── makeCircle_test.py │ ├── makeDisc_test.py │ ├── makeLine_test.py │ ├── makeMultiArc_test.py │ ├── makeMultiBowl_test.py │ ├── makeSphere_test.py │ ├── makeSphericalSection_test.py │ ├── maxND_test.py │ ├── minND_test.py │ ├── phase_shift_interpolate_test.py │ ├── reorderBinarySensorData_test.py │ ├── reorderSensorData_test.py │ ├── revolve2D_test.py │ ├── rotation_matrices_test.py │ ├── scaleSI_test.py │ ├── scaleTime_test.py │ ├── scanConversion_test.py │ ├── sharpness_test.py │ ├── smooth_test.py │ ├── test_check_stability.py │ ├── test_interpcartdata.py │ ├── test_linear_array_transducer.py │ ├── test_make_cart_disc.py │ ├── test_resize.py │ ├── tolStart_test.py │ ├── toneBurst_test.py │ ├── trimCartPoints_test.py │ ├── unmaskSensorData_test.py │ └── utils │ │ ├── __init__.py │ │ ├── check_equality.py │ │ └── record_reader.py └── run_all_collectors.m ├── reference_outputs ├── out_cpp_io_in_parts.json ├── out_cpp_running_simulations.json ├── out_ivp_3D_simulation.json ├── out_ivp_axisymmetric_simulation.json ├── out_ivp_binary_sensor_mask.json ├── out_ivp_comparison_modelling_functions │ ├── input_1.json │ └── input_2.json ├── out_ivp_heterogeneous_medium.json ├── out_ivp_homogeneous_medium.json ├── out_ivp_loading_external_image.json ├── out_ivp_opposing_corners_sensor_mask.json ├── out_ivp_photoacoustic_waveforms │ ├── input_1.json │ └── input_2.json ├── out_ivp_sensor_frequency_response │ ├── input_1.json │ └── input_2.json ├── out_na_controlling_the_PML │ ├── input_1.json │ ├── input_2.json │ ├── input_3.json │ └── input_4.json ├── out_na_optimising_performance │ ├── input_1.json │ ├── input_2.json │ └── input_3.json ├── out_pr_2D_FFT_line_sensor.json ├── out_pr_2D_TR_circular_sensor.json ├── out_pr_2D_TR_directional_sensors │ ├── input_1.json │ └── input_2.json ├── out_pr_2D_TR_line_sensor.json ├── out_pr_3D_FFT_planar_sensor.json ├── out_sd_directional_array_elements.json ├── out_sd_directivity_modelling_2D │ ├── input_1.json │ ├── input_10.json │ ├── input_11.json │ ├── input_2.json │ ├── input_3.json │ ├── input_4.json │ ├── input_5.json │ ├── input_6.json │ ├── input_7.json │ ├── input_8.json │ └── input_9.json ├── out_sd_directivity_modelling_3D │ ├── input_1.json │ ├── input_10.json │ ├── input_11.json │ ├── input_2.json │ ├── input_3.json │ ├── input_4.json │ ├── input_5.json │ ├── input_6.json │ ├── input_7.json │ ├── input_8.json │ └── input_9.json ├── out_sd_focussed_detector_2D.json ├── out_sd_sensor_directivity_2D.json ├── out_tvsp_3D_simulation.json ├── out_tvsp_doppler_effect.json ├── out_tvsp_homogeneous_medium_dipole.json ├── out_tvsp_homogeneous_medium_monopole.json ├── out_us_beam_patterns.json ├── out_us_bmode_linear_transducer │ ├── input_1.json │ ├── input_10.json │ ├── input_11.json │ ├── input_12.json │ ├── input_13.json │ ├── input_14.json │ ├── input_15.json │ ├── input_16.json │ ├── input_17.json │ ├── input_18.json │ ├── input_19.json │ ├── input_2.json │ ├── input_20.json │ ├── input_21.json │ ├── input_22.json │ ├── input_23.json │ ├── input_24.json │ ├── input_25.json │ ├── input_26.json │ ├── input_27.json │ ├── input_28.json │ ├── input_29.json │ ├── input_3.json │ ├── input_30.json │ ├── input_31.json │ ├── input_32.json │ ├── input_33.json │ ├── input_34.json │ ├── input_35.json │ ├── input_36.json │ ├── input_37.json │ ├── input_38.json │ ├── input_39.json │ ├── input_4.json │ ├── input_40.json │ ├── input_41.json │ ├── input_42.json │ ├── input_43.json │ ├── input_44.json │ ├── input_45.json │ ├── input_46.json │ ├── input_47.json │ ├── input_48.json │ ├── input_49.json │ ├── input_5.json │ ├── input_50.json │ ├── input_51.json │ ├── input_52.json │ ├── input_53.json │ ├── input_54.json │ ├── input_55.json │ ├── input_56.json │ ├── input_57.json │ ├── input_58.json │ ├── input_59.json │ ├── input_6.json │ ├── input_60.json │ ├── input_61.json │ ├── input_62.json │ ├── input_63.json │ ├── input_64.json │ ├── input_65.json │ ├── input_66.json │ ├── input_67.json │ ├── input_68.json │ ├── input_69.json │ ├── input_7.json │ ├── input_70.json │ ├── input_71.json │ ├── input_72.json │ ├── input_73.json │ ├── input_74.json │ ├── input_75.json │ ├── input_76.json │ ├── input_77.json │ ├── input_78.json │ ├── input_79.json │ ├── input_8.json │ ├── input_80.json │ ├── input_81.json │ ├── input_82.json │ ├── input_83.json │ ├── input_84.json │ ├── input_85.json │ ├── input_86.json │ ├── input_87.json │ ├── input_88.json │ ├── input_89.json │ ├── input_9.json │ ├── input_90.json │ ├── input_91.json │ ├── input_92.json │ ├── input_93.json │ ├── input_94.json │ ├── input_95.json │ └── input_96.json ├── out_us_bmode_phased_array │ ├── input_1.json │ ├── input_10.json │ ├── input_11.json │ ├── input_12.json │ ├── input_13.json │ ├── input_14.json │ ├── input_15.json │ ├── input_16.json │ ├── input_17.json │ ├── input_18.json │ ├── input_19.json │ ├── input_2.json │ ├── input_20.json │ ├── input_21.json │ ├── input_22.json │ ├── input_23.json │ ├── input_24.json │ ├── input_25.json │ ├── input_26.json │ ├── input_27.json │ ├── input_28.json │ ├── input_29.json │ ├── input_3.json │ ├── input_30.json │ ├── input_31.json │ ├── input_32.json │ ├── input_33.json │ ├── input_4.json │ ├── input_5.json │ ├── input_6.json │ ├── input_7.json │ ├── input_8.json │ └── input_9.json ├── out_us_defining_transducer.json └── out_us_transducer_as_sensor.json ├── setup_test.py ├── test__init__.py ├── test_checks.py ├── test_cpp_io_in_parts.py ├── test_cpp_running_simulations.py ├── test_create_pixel_dim.py ├── test_display_simulation_params.py ├── test_element.py ├── test_executor.py ├── test_filterutils.py ├── test_ivp_3D_simulation.py ├── test_ivp_axisymmetric_karray_simulation.py ├── test_ivp_axisymmetric_simulation.py ├── test_ivp_binary_sensor_mask.py ├── test_ivp_comparison_modelling_functions.py ├── test_ivp_heterogeneous_medium.py ├── test_ivp_homogeneous_medium.py ├── test_ivp_loading_external_image.py ├── test_ivp_opposing_corners_sensor_mask.py ├── test_ivp_photoacoustic_waveforms.py ├── test_ivp_sensor_frequency_response.py ├── test_ksource.py ├── test_kutils.py ├── test_math.py ├── test_misc.py ├── test_na_controlling_the_PML.py ├── test_na_optimising_performance.py ├── test_pmlutils.py ├── test_pr_2D_FFT_line_sensor.py ├── test_pr_2D_TR_circular_sensor.py ├── test_pr_2D_TR_directional_sensors.py ├── test_pr_2D_TR_line_sensor.py ├── test_pr_3D_FFT_planar_sensor.py ├── test_reconstruction.py ├── test_sd_directional_array_elements.py ├── test_sd_directivity_modelling_2D.py ├── test_sd_directivity_modelling_3D.py ├── test_sd_focussed_detector_2D.py ├── test_sd_sensor_directivity_2D.py ├── test_sharpness_filters.py ├── test_simulation.py ├── test_simulation_execution_options.py ├── test_time_reversal.py ├── test_tvsp_3D_simulation.py ├── test_tvsp_doppler_effect.py ├── test_tvsp_homogeneous_medium_dipole.py ├── test_tvsp_homogeneous_medium_monopole.py ├── test_us_beam_patterns.py ├── test_us_bmode_linear_transducer.py ├── test_us_bmode_phased_array.py ├── test_us_defining_transducer.py ├── test_us_transducer_as_sensor.py ├── test_utils.py └── test_water.py /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thanks for your interest in contributing an example to k-wave-python! 4 | 5 | ## Issues 6 | 7 | ### Create a new issue 8 | 9 | If you would like to contribute to this project, search to see if a related issue already exists. If a related issue doesn't exist, you can open a new issue using a relevant issue form. 10 | 11 | ### Solve an open issue 12 | 13 | Have a look through our existing issues to find one that interests you. 14 | You can narrow down the search using labels as filters. 15 | If you find an issue to work on, you are welcome to open a PR with a fix. 16 | 17 | ## Make changes 18 | 19 | Fork k-wave-python and make changes you would like to contribute to your fork. 20 | 21 | ## Open a Pull-Request 22 | 23 | * Complete the "Ready for review" template so that we can review your PR. This template helps reviewers understand your changes and the purpose of your pull request. 24 | 25 | * [Link PR to an issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) if you are solving one. 26 | 27 | * Don't forget to click the checkbox to [allow maintainer edits](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork) so you PR can be updated before a merge. 28 | 29 | 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG]" 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. Windows/Linux] 28 | - Version [e.g. 22] 29 | 30 | **Additional context** 31 | Add any other context about the problem here. 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/code_enhancement.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Code Enhancement 3 | about: Suggest changes to improve code quality, reduce complexity, and increase efficiency 4 | title: "[ENHANCE] Brief description of enhancement" 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Description of the Enhancement 11 | Provide a clear and concise description of what you want to happen. Explain the current state and the exact changes. 12 | 13 | ## Justification for the Enhancement 14 | 15 | 1. **Reduces Complexity**: Detail how the changes simplify the code, e.g. reducing the number of lines or eliminating redundant functions. 16 | 2. **Improves Efficiency**: Describe how the changes will enhance performance, e.g. decreasing execution time, or reducing memory consumption. 17 | 3. **Improve Readability**: Describe how readability benefits from changes. 18 | 19 | ## Impact of Changes 20 | 21 | List any other components or modules that might be affected by these changes. 22 | 23 | ## Screenshots/Examples 24 | 25 | If applicable, add screenshots, code snippets, or links to help illustrate the enhancement. 26 | 27 | ## Additional Context 28 | Add any other context or information about the enhancement here. 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/example.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Example 3 | about: Request an example to help others get started 4 | title: "[Example]" 5 | labels: example 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the example** 11 | What example do you wish was included in k-wave-python? What functionality of principle should it display? 12 | 13 | **Sources** 14 | If applicable, add sources of the example from literature or other projects. 15 | 16 | **Additional context** 17 | Add any other context about the example here. 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '[Feature]' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | status: 3 | project: 4 | default: 5 | threshold: 1% 6 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "pip" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "weekly" 12 | -------------------------------------------------------------------------------- /.github/workflows/codespell.yml: -------------------------------------------------------------------------------- 1 | name: Spell Check 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | spellcheck: 11 | name: Spell Check 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v3 15 | 16 | - name: Set up Python 17 | uses: actions/setup-python@v4 18 | with: 19 | python-version: '3.10' 20 | 21 | - name: Install codespell 22 | run: pip install codespell 23 | 24 | - name: Run codespell 25 | run: codespell --config .codespellrc -------------------------------------------------------------------------------- /.github/workflows/ruff.yml: -------------------------------------------------------------------------------- 1 | name: Ruff 2 | on: [push, pull_request] 3 | jobs: 4 | ruff: 5 | runs-on: ubuntu-latest 6 | continue-on-error: true 7 | steps: 8 | - uses: actions/checkout@v3 9 | - uses: astral-sh/ruff-action@v1 10 | -------------------------------------------------------------------------------- /.github/workflows/run-examples.yml: -------------------------------------------------------------------------------- 1 | name: Run K-Wave Examples 2 | 3 | on: 4 | schedule: 5 | - cron: '0 0 * * 1' # Every Monday at 00:00 UTC 6 | workflow_dispatch: # Manual trigger 7 | 8 | jobs: 9 | discover-examples: 10 | runs-on: ubuntu-latest 11 | outputs: 12 | example_paths: ${{ steps.find-examples.outputs.examples }} 13 | steps: 14 | - uses: actions/checkout@v4 15 | - id: find-examples 16 | run: | 17 | # Find all Python files in examples subdirectories 18 | EXAMPLES=$(find examples -name "*.py" -not -path "*/\.*" | jq -R -s -c 'split("\n")[:-1]') 19 | echo "examples=$EXAMPLES" >> "$GITHUB_OUTPUT" 20 | 21 | run-examples: 22 | needs: discover-examples 23 | runs-on: ubuntu-latest 24 | timeout-minutes: 60 # 1 hour timeout per example 25 | strategy: 26 | fail-fast: false # Continue running other examples even if one fails 27 | matrix: 28 | example: ${{ fromJson(needs.discover-examples.outputs.example_paths) }} 29 | 30 | steps: 31 | - name: Checkout repository 32 | uses: actions/checkout@v4 33 | 34 | - name: Install system dependencies 35 | run: | 36 | sudo apt-get update 37 | sudo apt-get install -y ffmpeg 38 | 39 | - name: Set up Python 40 | uses: actions/setup-python@v5 41 | with: 42 | python-version: '3.10' # Matches requires-python from pyproject.toml 43 | cache: 'pip' 44 | 45 | - name: Install dependencies 46 | run: | 47 | python -m pip install --upgrade pip 48 | # Install the package with example dependencies 49 | pip install -e ".[example]" 50 | 51 | - name: Run example 52 | env: 53 | KWAVE_FORCE_CPU: 1 54 | run: | 55 | echo "Running example: ${{ matrix.example }}" 56 | python "${{ matrix.example }}" 57 | -------------------------------------------------------------------------------- /.github/workflows/test_example.yml: -------------------------------------------------------------------------------- 1 | name: test_example 2 | 3 | on: [ push ] 4 | 5 | jobs: 6 | test_example: 7 | strategy: 8 | matrix: 9 | os: [ "windows-latest", "ubuntu-latest" , "macos-latest"] 10 | python-version: [ "3.10", "3.11", "3.12", "3.13" ] 11 | runs-on: ${{matrix.os}} 12 | steps: 13 | - uses: actions/checkout@v4 14 | - name: Set up Python ${{ matrix.python-version }} 15 | uses: actions/setup-python@v5 16 | with: 17 | python-version: ${{ matrix.python-version }} 18 | cache: 'pip' 19 | - name: Install dependencies 20 | run: | 21 | pip install -e '.[example]' 22 | - name: Run example script 23 | run: | 24 | python3 examples/us_bmode_linear_transducer/us_bmode_linear_transducer.py 25 | - name: Upload example results 26 | uses: actions/upload-artifact@v4 27 | with: 28 | name: example_bmode_reconstruction_results_${{ matrix.os }}_${{ matrix.python-version }} 29 | path: ${{ github.workspace }}/example_bmode.png 30 | -------------------------------------------------------------------------------- /.github/workflows/test_optional_dependencies.yml: -------------------------------------------------------------------------------- 1 | name: test_optional_requirements 2 | 3 | on: 4 | push: 5 | paths: 6 | - 'pyproject.toml' 7 | pull_request: 8 | paths: 9 | - 'pyproject.toml' 10 | 11 | jobs: 12 | test_install: 13 | strategy: 14 | matrix: 15 | os: [ "windows-latest", "ubuntu-latest" , "macos-latest"] 16 | python-version: [ "3.10", "3.11", "3.12", "3.13" ] 17 | extra_requirements: [ "test", "examples", "docs", "dev", "all" ] 18 | runs-on: ${{matrix.os}} 19 | steps: 20 | - uses: actions/checkout@v4 21 | # Pull the cache based on the hash value 22 | - name: Set up Python ${{ matrix.python-version }} 23 | uses: actions/setup-python@v5 24 | with: 25 | python-version: ${{ matrix.python-version }} 26 | cache: 'pip' 27 | - name: Install dependencies 28 | run: | 29 | pip install '.[${{ matrix.extra_requirements }}]' 30 | -------------------------------------------------------------------------------- /.github/workflows/test_pages.yml: -------------------------------------------------------------------------------- 1 | name: test_pages 2 | on: [push] 3 | 4 | jobs: 5 | build: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - uses: actions/checkout@master 9 | with: 10 | fetch-depth: 0 # otherwise, you will fail to push refs to dest repo 11 | - uses: actions/setup-python@v5 12 | with: 13 | python-version: '3.10' 14 | cache: 'pip' 15 | - name: Build and Commit 16 | uses: waltsims/pages@pyproject.toml-support 17 | with: 18 | pyproject_toml_deps: ".[docs]" 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # IDE specific files 2 | .idea/ 3 | .vscode/ 4 | 5 | # Virtual environments 6 | .venv/ 7 | venv/ 8 | 9 | # Compiled files 10 | *.pyc 11 | examples/__pycache__/ 12 | 13 | # System files 14 | .DS_Store 15 | 16 | # Python egg files 17 | /k_Wave_python.egg-info/ 18 | 19 | # Build directories 20 | build/ 21 | src/ 22 | transfer_temp/ 23 | docs/_build/ 24 | kwave/bin/ 25 | 26 | # Package manager files 27 | Pipfile.lock 28 | 29 | # Coverage reports 30 | /.coverage 31 | 32 | # Test and temporary files 33 | difference.py 34 | test_local.sh 35 | tests/reference_outputs 36 | 37 | # Data and output files 38 | *.mat 39 | *.mp4 40 | *.h5 41 | *.png 42 | *.tar.gz 43 | *.whl 44 | *.asv 45 | kspaceFirstOrder-*_metadata.json 46 | 47 | 48 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/srstevenson/nb-clean.git 3 | rev: 3.2.0 4 | hooks: 5 | - id: nb-clean 6 | name: nb-clean 7 | entry: nb-clean clean 8 | language: python 9 | types_or: [jupyter] 10 | minimum_pre_commit_version: 2.9.2 11 | - repo: https://github.com/astral-sh/ruff-pre-commit 12 | # Ruff version. 13 | rev: v0.2.2 14 | hooks: 15 | # Run the linter. 16 | - id: ruff 17 | args: [ --fix ] 18 | # Run the formatter. 19 | - id: ruff-format 20 | - repo: https://github.com/codespell-project/codespell 21 | rev: v2.2.6 22 | hooks: 23 | - id: codespell 24 | additional_dependencies: 25 | - tomli 26 | args: [--write-changes] 27 | # - repo: https://github.com/pre-commit/pre-commit-hooks 28 | # rev: v4.5.0 # Use the ref you want to point at 29 | # hooks: 30 | # - id: trailing-whitespace 31 | # - repo: https://github.com/nbQA-dev/nbQA 32 | # rev: 1.7.1 33 | # hooks: 34 | # - id: nbqa-ruff 35 | # name: nbqa-ruff 36 | # entry: nbqa ruff 37 | # language: python 38 | # types_or: [jupyter] 39 | # minimum_pre_commit_version: 2.9.2 -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | build: 4 | os: ubuntu-22.04 5 | tools: 6 | python: "3.11" 7 | sphinx: 8 | configuration: docs/conf.py 9 | python: 10 | install: 11 | - method: pip 12 | path: . 13 | extra_requirements: 14 | - docs 15 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | title: k-Wave-python 3 | type: software 4 | authors: 5 | - given-names: Farid 6 | family-names: Yagubbbayli 7 | email: farid.yagubbayli@tum.de 8 | - given-names: David 9 | family-names: Sinden 10 | affiliation: Fraunhofer Institute for Digital Medicine MEVIS 11 | orcid: 'https://orcid.org/0000-0002-8514-8279' 12 | - family-names: Simson 13 | given-names: Walter 14 | email: walter.a.simson@gmail.com 15 | orcid: 'https://orcid.org/0000-0002-2801-8646' 16 | identifiers: 17 | - type: doi 18 | value: 10.5281/zenodo.10719460 19 | description: Zenodo DOI 20 | repository-code: 'https://github.com/waltsims/k-wave-python' 21 | license: LGPL-3.0 22 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.9.0-slim 2 | 3 | RUN apt-get update 4 | RUN apt-get install -y gfortran libopenblas-dev liblapack-dev libgl1-mesa-glx libglib2.0-0 libgl1-mesa-glx libglib2.0-0 git 5 | RUN pip install --upgrade pip 6 | COPY pyproject.toml . 7 | #COPY README.md . 8 | COPY docs/ docs 9 | COPY LICENSE . 10 | COPY kwave/ kwave 11 | RUN pip install '.[test]' 12 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Define the Python interpreter and MATLAB command 2 | PYTHON = python 3 | MATLAB = matlab 4 | 5 | # Define the directories and files 6 | EXAMPLES_DIR = examples 7 | TESTS_DIR = tests 8 | MATLAB_SCRIPT = tests/matlab_test_data_collectors/run_all_collectors.m 9 | KWAVE_MATLAB_PATH = $(abspath ../k-wave) # Get absolute path of k-wave directory 10 | 11 | # Define the artifact directory 12 | COLLECTED_VALUES_DIR = $(abspath tests/matlab_test_data_collectors/python_testers/collectedValues) 13 | 14 | # Default target 15 | all: run-examples test 16 | 17 | # Target to run all examples 18 | run-examples: 19 | @echo "Running all examples..." 20 | @MPLBACKEND=Agg $(PYTHON) run_examples.py 21 | 22 | # Target to run pytest, which depends on running the MATLAB script first 23 | test: $(COLLECTED_VALUES_DIR) 24 | @echo "Running pytest..." 25 | @pytest $(TESTS_DIR) 26 | 27 | # Target to run the MATLAB script and create the artifact directory 28 | $(COLLECTED_VALUES_DIR): 29 | @echo "Running MATLAB script to collect values..."; \ 30 | $(MATLAB) -batch "run('$(MATLAB_SCRIPT)');"; \ 31 | # Clean target (optional) - cleans Python caches and collected values 32 | clean: clean-python clean-collected_values 33 | 34 | clean-python: 35 | @echo "Cleaning Python cache files..." 36 | @find . -name '*.pyc' -delete 37 | @find . -name '__pycache__' -delete 38 | 39 | # Clean collected values directory 40 | clean-collected_values: 41 | @echo "Cleaning collected values directory..." 42 | @rm -rf $(COLLECTED_VALUES_DIR) 43 | 44 | .PHONY: all run-examples run-tests clean-python clean-collected_values clean 45 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /docs/_static/example_bmode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waltsims/k-wave-python/51b2041523377c937f224c75cc771ec761ec975c/docs/_static/example_bmode.png -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # For the full list of built-in configuration values, see the documentation: 4 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 5 | 6 | # -- Project information ----------------------------------------------------- 7 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information 8 | 9 | project = "k-Wave-python" 10 | copyright = "2024, Walter Simson, Farid Yagubbayli" 11 | author = "Walter Simson, Farid Yagubbayli" 12 | version = "0.3.3" 13 | 14 | # -- General configuration --------------------------------------------------- 15 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration 16 | 17 | extensions = [ 18 | "sphinx.ext.autodoc", 19 | "sphinx.ext.githubpages", 20 | "sphinx_toolbox.code", 21 | "sphinx_copybutton", 22 | "sphinx.ext.coverage", 23 | "sphinx.ext.napoleon", 24 | "sphinx.ext.viewcode", 25 | "sphinx_mdinclude", 26 | ] 27 | 28 | source_suffix = [".rst", ".md"] 29 | templates_path = ["_templates"] 30 | exclude_patterns = ["README.md", "_build", "Thumbs.db", ".DS_Store"] 31 | 32 | language = "en" 33 | 34 | # -- Options for HTML output ------------------------------------------------- 35 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output 36 | html_theme = "furo" 37 | html_theme_options = { 38 | "source_repository": "https://github.com/waltsims/k-wave-python", 39 | "source_branch": "master", 40 | "source_directory": "docs/", 41 | } 42 | html_static_path = ["_static"] 43 | 44 | # -- Options for todo extension ---------------------------------------------- 45 | # https://www.sphinx-doc.org/en/master/usage/extensions/todo.html#configuration 46 | 47 | todo_include_todos = True 48 | 49 | # -- Options for autodoc ---------------------------------------------------- 50 | # https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#configuration 51 | 52 | # Automatically extract typehints when specified and place them in 53 | # descriptions of the relevant function/method. 54 | autodoc_typehints = "description" 55 | 56 | # Don't show class signature with the class' name. 57 | autodoc_class_signature = "separated" 58 | 59 | # Remove module name from object names 60 | add_module_names = False 61 | -------------------------------------------------------------------------------- /docs/get_started/contrib.rst: -------------------------------------------------------------------------------- 1 | Contribution 2 | ============ 3 | 4 | To contribute, please open a pull request with your changes. The project is still small and we look forward to all contributions. 5 | -------------------------------------------------------------------------------- /docs/get_started/legacy_licenses/mit.rst: -------------------------------------------------------------------------------- 1 | MIT License 2 | Copyright (c) 2022 Walter Simson 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | The above copyright notice and this permission notice shall be included in all 10 | copies or substantial portions of the Software. 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 14 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 15 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | SOFTWARE. -------------------------------------------------------------------------------- /docs/get_started/license.rst: -------------------------------------------------------------------------------- 1 | ======= 2 | License 3 | ======= 4 | 5 | Current License 6 | -------------------------------------- 7 | 8 | For past licenses, see `the Past Licenses section <#past-licenses-for-reference>`_. Migration was performed with approval of all contributors in `the public forum GitHub `_. 9 | 10 | .. include:: ../../LICENSE 11 | :literal: 12 | 13 | Past Licenses (for reference) 14 | ----------------------------- 15 | 16 | 17 | v0.2.0 - v0.4.0 18 | ------------ 19 | Between v0.2.0 and v0.4.0, the project was released under the GNU General Public License v3.0. 20 | 21 | .. include:: legacy_licenses/gpl-3.0.rst 22 | :literal: 23 | 24 | Pre v0.2.0 25 | ----------- 26 | The first release of v0.1.0 was under the MIT License. 27 | 28 | .. include:: legacy_licenses/mit.rst 29 | :literal: 30 | 31 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | Welcome to k-Wave-python's documentation! 2 | ========================================= 3 | 4 | k-Wave is an open source acoustics toolbox for MATLAB and C++ developed by Bradley Treeby and Ben Cox (University College London) and Jiri Jaros (Brno University of Technology). The software is designed for time domain acoustic and ultrasound simulations in complex and tissue-realistic media. The simulation functions are based on the k-space pseudospectral method and are both fast and easy to use. 5 | 6 | .. mdinclude:: README.md 7 | :start-line: 5 8 | :end-line: -3 9 | 10 | .. toctree:: 11 | :maxdepth: 2 12 | :caption: Getting Started 13 | :hidden: 14 | 15 | get_started/contrib 16 | get_started/license 17 | 18 | .. toctree:: 19 | :maxdepth: 2 20 | :caption: Development 21 | :hidden: 22 | 23 | development/development_environment 24 | 25 | .. toctree:: 26 | :caption: kwave 27 | :titlesonly: 28 | :maxdepth: 4 29 | :hidden: 30 | 31 | kwave.data 32 | kwave.enums 33 | kwave.executor 34 | kwave.kWaveSimulation 35 | kwave.kgrid 36 | kwave.kmedium 37 | kwave.ksensor 38 | kwave.ksource 39 | kwave.kspaceFirstOrder 40 | kwave.kspaceFirstOrder2D 41 | kwave.kspaceFirstOrder3D 42 | kwave.kspaceFirstOrderAS 43 | kwave.ktransducer 44 | kwave.options 45 | kwave.recorder 46 | kwave.utils 47 | kwave.kWaveSimulation_helper 48 | kwave.reconstruction 49 | 50 | -------------------------------------------------------------------------------- /docs/kwave.data.rst: -------------------------------------------------------------------------------- 1 | kwave.data module 2 | ================= 3 | 4 | .. automodule:: kwave.data 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.enums.rst: -------------------------------------------------------------------------------- 1 | kwave.enums module 2 | ================== 3 | 4 | .. automodule:: kwave.enums 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.executor.rst: -------------------------------------------------------------------------------- 1 | kwave.executor module 2 | ===================== 3 | 4 | .. automodule:: kwave.executor 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.kWaveSimulation.rst: -------------------------------------------------------------------------------- 1 | kwave.kWaveSimulation module 2 | ============================ 3 | 4 | .. automodule:: kwave.kWaveSimulation 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.kWaveSimulation_helper.create_absorption_variables.rst: -------------------------------------------------------------------------------- 1 | kwave.kWaveSimulation\_helper.create\_absorption\_variables module 2 | ================================================================== 3 | 4 | .. automodule:: kwave.kWaveSimulation_helper.create_absorption_variables 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.kWaveSimulation_helper.display_simulation_params.rst: -------------------------------------------------------------------------------- 1 | kwave.kWaveSimulation\_helper.display\_simulation\_params module 2 | ================================================================ 3 | 4 | .. automodule:: kwave.kWaveSimulation_helper.display_simulation_params 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.kWaveSimulation_helper.expand_grid_matrices.rst: -------------------------------------------------------------------------------- 1 | kwave.kWaveSimulation\_helper.expand\_grid\_matrices module 2 | =========================================================== 3 | 4 | .. automodule:: kwave.kWaveSimulation_helper.expand_grid_matrices 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.kWaveSimulation_helper.retract_transducer_grid_size.rst: -------------------------------------------------------------------------------- 1 | kwave.kWaveSimulation\_helper.retract\_transducer\_grid\_size module 2 | ==================================================================== 3 | 4 | .. automodule:: kwave.kWaveSimulation_helper.retract_transducer_grid_size 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.kWaveSimulation_helper.rst: -------------------------------------------------------------------------------- 1 | kwave.kWaveSimulation\_helper package 2 | ===================================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | kwave.kWaveSimulation_helper.create_absorption_variables 11 | kwave.kWaveSimulation_helper.display_simulation_params 12 | kwave.kWaveSimulation_helper.expand_grid_matrices 13 | kwave.kWaveSimulation_helper.retract_transducer_grid_size 14 | kwave.kWaveSimulation_helper.save_to_disk_func 15 | kwave.kWaveSimulation_helper.scale_source_terms_func 16 | kwave.kWaveSimulation_helper.set_sound_speed_ref 17 | 18 | Module contents 19 | --------------- 20 | 21 | .. automodule:: kwave.kWaveSimulation_helper 22 | :members: 23 | :undoc-members: 24 | :show-inheritance: 25 | -------------------------------------------------------------------------------- /docs/kwave.kWaveSimulation_helper.save_to_disk_func.rst: -------------------------------------------------------------------------------- 1 | kwave.kWaveSimulation\_helper.save\_to\_disk\_func module 2 | ========================================================= 3 | 4 | .. automodule:: kwave.kWaveSimulation_helper.save_to_disk_func 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.kWaveSimulation_helper.scale_source_terms_func.rst: -------------------------------------------------------------------------------- 1 | kwave.kWaveSimulation\_helper.scale\_source\_terms\_func module 2 | =============================================================== 3 | 4 | .. automodule:: kwave.kWaveSimulation_helper.scale_source_terms_func 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.kWaveSimulation_helper.set_sound_speed_ref.rst: -------------------------------------------------------------------------------- 1 | kwave.kWaveSimulation\_helper.set\_sound\_speed\_ref module 2 | =========================================================== 3 | 4 | .. automodule:: kwave.kWaveSimulation_helper.set_sound_speed_ref 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.kgrid.rst: -------------------------------------------------------------------------------- 1 | kwave.kgrid module 2 | ================== 3 | 4 | .. automodule:: kwave.kgrid 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.kmedium.rst: -------------------------------------------------------------------------------- 1 | kwave.kmedium module 2 | ==================== 3 | 4 | .. automodule:: kwave.kmedium 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.ksensor.rst: -------------------------------------------------------------------------------- 1 | kwave.ksensor module 2 | ==================== 3 | 4 | .. automodule:: kwave.ksensor 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.ksource.rst: -------------------------------------------------------------------------------- 1 | kwave.ksource module 2 | ==================== 3 | 4 | .. automodule:: kwave.ksource 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.kspaceFirstOrder.rst: -------------------------------------------------------------------------------- 1 | kwave.kspaceFirstOrder module 2 | ============================= 3 | 4 | .. automodule:: kwave.kspaceFirstOrder 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.kspaceFirstOrder2D.rst: -------------------------------------------------------------------------------- 1 | kwave.kspaceFirstOrder2D module 2 | =============================== 3 | 4 | .. automodule:: kwave.kspaceFirstOrder2D 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.kspaceFirstOrder3D.rst: -------------------------------------------------------------------------------- 1 | kwave.kspaceFirstOrder3D module 2 | =============================== 3 | 4 | .. automodule:: kwave.kspaceFirstOrder3D 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.kspaceFirstOrderAS.rst: -------------------------------------------------------------------------------- 1 | kwave.kspaceFirstOrderAS module 2 | =============================== 3 | 4 | .. automodule:: kwave.kspaceFirstOrderAS 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.ktransducer.rst: -------------------------------------------------------------------------------- 1 | kwave.ktransducer module 2 | ======================== 3 | 4 | .. automodule:: kwave.ktransducer 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.options.rst: -------------------------------------------------------------------------------- 1 | kwave.options module 2 | ==================== 3 | 4 | .. automodule:: kwave.options 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.reconstruction.beamform.rst: -------------------------------------------------------------------------------- 1 | kwave.reconstruction.beamform module 2 | ==================================== 3 | 4 | .. automodule:: kwave.reconstruction.beamform 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.reconstruction.converter.rst: -------------------------------------------------------------------------------- 1 | kwave.reconstruction.converter module 2 | ===================================== 3 | 4 | .. automodule:: kwave.reconstruction.converter 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.reconstruction.rst: -------------------------------------------------------------------------------- 1 | kwave.reconstruction package 2 | ============================ 3 | 4 | Submodules 5 | ---------- 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | kwave.reconstruction.beamform 11 | kwave.reconstruction.converter 12 | kwave.reconstruction.shifted_transform 13 | kwave.reconstruction.tools 14 | 15 | Module contents 16 | --------------- 17 | 18 | .. automodule:: kwave.reconstruction 19 | :members: 20 | :undoc-members: 21 | :show-inheritance: 22 | -------------------------------------------------------------------------------- /docs/kwave.reconstruction.shifted_transform.rst: -------------------------------------------------------------------------------- 1 | kwave.reconstruction.shifted\_transform module 2 | ============================================== 3 | 4 | .. automodule:: kwave.reconstruction.shifted_transform 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.reconstruction.tools.rst: -------------------------------------------------------------------------------- 1 | kwave.reconstruction.tools module 2 | ================================= 3 | 4 | .. automodule:: kwave.reconstruction.tools 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.recorder.rst: -------------------------------------------------------------------------------- 1 | kwave.recorder module 2 | ===================== 3 | 4 | .. automodule:: kwave.recorder 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.rst: -------------------------------------------------------------------------------- 1 | kwave package 2 | ============= 3 | 4 | Subpackages 5 | ----------- 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | kwave.kWaveSimulation_helper 11 | kwave.reconstruction 12 | kwave.utils 13 | 14 | Submodules 15 | ---------- 16 | 17 | .. toctree:: 18 | :maxdepth: 4 19 | 20 | kwave.data 21 | kwave.enums 22 | kwave.executor 23 | kwave.kWaveSimulation 24 | kwave.kgrid 25 | kwave.kmedium 26 | kwave.ksensor 27 | kwave.ksource 28 | kwave.kspaceFirstOrder 29 | kwave.kspaceFirstOrder2D 30 | kwave.kspaceFirstOrder3D 31 | kwave.kspaceFirstOrderAS 32 | kwave.ktransducer 33 | kwave.options 34 | kwave.recorder 35 | 36 | Module contents 37 | --------------- 38 | 39 | .. automodule:: kwave 40 | :members: 41 | :undoc-members: 42 | :show-inheritance: 43 | -------------------------------------------------------------------------------- /docs/kwave.utils.checks.rst: -------------------------------------------------------------------------------- 1 | kwave.utils.checks module 2 | ========================= 3 | 4 | .. automodule:: kwave.utils.checks 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.utils.colormap.rst: -------------------------------------------------------------------------------- 1 | kwave.utils.colormap module 2 | =========================== 3 | 4 | .. automodule:: kwave.utils.colormap 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.utils.conversion.rst: -------------------------------------------------------------------------------- 1 | kwave.utils.conversion module 2 | ============================= 3 | 4 | .. automodule:: kwave.utils.conversion 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.utils.data.rst: -------------------------------------------------------------------------------- 1 | kwave.utils.data module 2 | ======================= 3 | 4 | .. automodule:: kwave.utils.data 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.utils.dotdictionary.rst: -------------------------------------------------------------------------------- 1 | kwave.utils.dotdictionary module 2 | ================================ 3 | 4 | .. automodule:: kwave.utils.dotdictionary 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.utils.filters.rst: -------------------------------------------------------------------------------- 1 | kwave.utils.filters module 2 | ========================== 3 | 4 | .. automodule:: kwave.utils.filters 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.utils.interp.rst: -------------------------------------------------------------------------------- 1 | kwave.utils.interp module 2 | ========================= 3 | 4 | .. automodule:: kwave.utils.interp 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.utils.io.rst: -------------------------------------------------------------------------------- 1 | kwave.utils.io module 2 | ===================== 3 | 4 | .. automodule:: kwave.utils.io 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.utils.mapgen.rst: -------------------------------------------------------------------------------- 1 | kwave.utils.mapgen module 2 | ========================= 3 | 4 | .. automodule:: kwave.utils.mapgen 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.utils.math.rst: -------------------------------------------------------------------------------- 1 | kwave.utils.math module 2 | ======================= 3 | 4 | .. automodule:: kwave.utils.math 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.utils.matrix.rst: -------------------------------------------------------------------------------- 1 | kwave.utils.matrix module 2 | ========================= 3 | 4 | .. automodule:: kwave.utils.matrix 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.utils.pml.rst: -------------------------------------------------------------------------------- 1 | kwave.utils.pml module 2 | ====================== 3 | 4 | .. automodule:: kwave.utils.pml 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.utils.rst: -------------------------------------------------------------------------------- 1 | kwave.utils package 2 | =================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | kwave.utils.checks 11 | kwave.utils.colormap 12 | kwave.utils.conversion 13 | kwave.utils.data 14 | kwave.utils.dotdictionary 15 | kwave.utils.filters 16 | kwave.utils.interp 17 | kwave.utils.io 18 | kwave.utils.mapgen 19 | kwave.utils.math 20 | kwave.utils.matrix 21 | kwave.utils.pml 22 | kwave.utils.signals 23 | kwave.utils.tictoc 24 | 25 | Module contents 26 | --------------- 27 | 28 | .. automodule:: kwave.utils 29 | :members: 30 | :undoc-members: 31 | :show-inheritance: 32 | -------------------------------------------------------------------------------- /docs/kwave.utils.signals.rst: -------------------------------------------------------------------------------- 1 | kwave.utils.signals module 2 | ========================== 3 | 4 | .. automodule:: kwave.utils.signals 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/kwave.utils.tictoc.rst: -------------------------------------------------------------------------------- 1 | kwave.utils.tictoc module 2 | ========================= 3 | 4 | .. automodule:: kwave.utils.tictoc 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | 13 | %SPHINXBUILD% >NUL 2>NUL 14 | if errorlevel 9009 ( 15 | echo. 16 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 17 | echo.installed, then set the SPHINXBUILD environment variable to point 18 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 19 | echo.may add the Sphinx directory to PATH. 20 | echo. 21 | echo.If you don't have Sphinx installed, grab it from 22 | echo.https://www.sphinx-doc.org/ 23 | exit /b 1 24 | ) 25 | 26 | if "%1" == "" goto help 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /docs/reconstruction/index.rst: -------------------------------------------------------------------------------- 1 | Reconstruction 2 | ============= 3 | 4 | This module provides functionality for reconstructing acoustic fields from recorded sensor data. 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | time_reversal 10 | beamform 11 | converter 12 | shifted_transform 13 | tools 14 | 15 | Migration Notes 16 | ------------- 17 | 18 | The time reversal reconstruction functionality has been moved to the :class:`TimeReversal` class. 19 | See :doc:`time_reversal` for migration guidelines and examples. -------------------------------------------------------------------------------- /examples/at_array_as_sensor/README.md: -------------------------------------------------------------------------------- 1 | # Defining A Sensor Using An Array Transducer Example 2 | 3 | [![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_array_as_sensor/at_array_as_sensor.ipynb) 4 | 5 | This example provides a demonstration of using the kWaveArray class to define an array transducer with 20 arc-shaped elements which is then used as a receiver array. It builds on the Defining A Source Using An Array Transducer Example. 6 | 7 | To read more, visit the [original example page](http://www.k-wave.org/documentation/example_at_array_as_sensor.php) -------------------------------------------------------------------------------- /examples/at_array_as_source/README.md: -------------------------------------------------------------------------------- 1 | # Defining A Source Using An Array Transducer Example 2 | 3 | [![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_array_as_source/at_array_as_source.ipynb) 4 | 5 | This example provides a demonstration of using the kWaveArray class to define an array transducer with three arc-shaped elements without staircasing errors. 6 | 7 | For a more detailed discussion of this example and the underlying techniques, see E. S. Wise, B. T. Cox, J. Jaros, & B. E. Treeby (2019). Representing arbitrary acoustic source and sensor distributions in Fourier collocation methods. The Journal of the Acoustical Society of America, 146(1), 278-288. https://doi.org/10.1121/1.5116132. 8 | 9 | To read more, visit the [original example page](http://www.k-wave.org/documentation/example_at_array_as_source.php). 10 | -------------------------------------------------------------------------------- /examples/at_circular_piston_3D/README.md: -------------------------------------------------------------------------------- 1 | # Modelling A Circular Plane Piston Transducer Example 2 | 3 | This example models a circular plan piston transducer in 3D. The _on-axis_ pressure is compared with an analytical solution for a piston in an infinite baffle (Eq 5-7.3 in Allan Pierce's book on Acoustics). 4 | 5 | To read more, visit the [original example page](http://www.k-wave.org/documentation/example_at_piston_and_bowl_transducers.php#heading3) 6 | -------------------------------------------------------------------------------- /examples/at_circular_piston_AS/README.md: -------------------------------------------------------------------------------- 1 | # Modelling An Axisymmetric Circular Plane Piston Transducer Example 2 | 3 | This example models an axisymmetric circular plan piston transducer. The _on-axis_ pressure is compared with an analytical solution for a piston in an infinite baffle (Eq 5-7.3 in Allan Pierce's book on Acoustics). 4 | 5 | To read more, visit the [original example page](http://www.k-wave.org/documentation/example_at_piston_and_bowl_transducers.php#heading4) -------------------------------------------------------------------------------- /examples/at_focused_annular_array_3D/README.md: -------------------------------------------------------------------------------- 1 | # Modelling A Focused Annular Transducer Example 2 | 3 | This example models a focused annular transducer in 3D. The _on-axis_ pressure is compared with an analytical solution calculated using `focused_annulus_oneil`. 4 | 5 | To read more, visit the [original example page](http://www.k-wave.org/documentation/example_at_piston_and_bowl_transducers.php#heading7) -------------------------------------------------------------------------------- /examples/at_focused_bowl_3D/README.md: -------------------------------------------------------------------------------- 1 | # Modelling A Focused Bowl Transducer Example 2 | 3 | This example models a focused bowl transducer in 3D. The _on-axis_ pressure is compared with an analytical solution calculated using `focused_bowl_oneil`. 4 | 5 | To read more, visit the [original example page](http://www.k-wave.org/documentation/example_at_piston_and_bowl_transducers.php#heading5) -------------------------------------------------------------------------------- /examples/at_focused_bowl_AS/README.md: -------------------------------------------------------------------------------- 1 | # Modelling An Axisymmetric Focused Bowl Transducer Example 2 | 3 | This example models an axisymmetric focused bowl transducer. The _on-axis_ pressure is compared with an analytical solution calculated using `focused_bowl_oneil`. 4 | 5 | To read more, visit the [original example page](http://www.k-wave.org/documentation/example_at_piston_and_bowl_transducers.php#heading6) -------------------------------------------------------------------------------- /examples/at_linear_array_transducer/README.md: -------------------------------------------------------------------------------- 1 | # Modelling A Linear Array Transducer Example 2 | 3 | [![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_linear_array_transducer/at_linear_array_transducer.ipynb) 4 | 5 | This example provides a demonstration of using the kWaveArray class to define a linear array transducer with 15 rectangular elements. Electronic focusing is then used to transmit an ultrasound pulse. It builds on the [Defining A Source Using An Array Transducer Example](../at_array_as_source/). 6 | 7 | To read more, visit the [original example page](http://www.k-wave.org/documentation/example_at_linear_array_transducer.php). -------------------------------------------------------------------------------- /examples/checkpointing/README.md: -------------------------------------------------------------------------------- 1 | # Checkpointing 2 | 3 | This example demonstrates how to checkpoint simulations. 4 | 5 | It uses the same simulation parameters as found in "3D FFT Reconstruction For A Planar Sensor". -------------------------------------------------------------------------------- /examples/ivp_photoacoustic_waveforms/README.md: -------------------------------------------------------------------------------- 1 | # Initial Value Problem: Photoacoustic Waveforms in 2D and 3D 2 | 3 | [![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/ivp_photoacoustic_waveforms/ivp_photoacoustic_waveforms.ipynb) 4 | 5 | See the k-wave example [here](http://www.k-wave.org/documentation/example_ivp_photoacoustic_waveforms.php), which includes one-dimensional propagation as well. 6 | 7 | > [!WARNING] 8 | > As there is no one-dimensional simulation, the example does not fully recreate the k-wave example. It underable to show how a 1D wave is different from 2D and 3D waves. 9 | 10 | ## Rational 11 | 12 | The purpose of this example is to show that the dimensions of a system influence characteristics of the propagation. A point source in two-dimensions is represented by an infinite line source in three-dimensions. 13 | 14 | In two-dimensions there is cylindrical spreading, This means the acoustic energy is inversely proportional to radius, $r$, and the acoustic pressure decays as $1/\sqrt r$. In three-dimensions there is spherical spreading, so the energy is spread over $r^2$, and the pressure decays as ${1/r}$. 15 | 16 | Photoacoustic waves in 3D have [compact support](https://en.wikipedia.org/wiki/Support_(mathematics)#Compact_support). This means they decay to zero rapidly, whereas a waveform in 2D does not have this property. As an infinite line source in 3D, there will always be some signal arriving to the detector from some (increasingly distant) part of the line source. 17 | -------------------------------------------------------------------------------- /examples/na_controlling_the_pml/README.md: -------------------------------------------------------------------------------- 1 | # Using An Ultrasound Transducer As A Sensor Example 2 | 3 | 4 | Open In Colab 5 | 6 | 7 | # Running the example 8 | 9 | Please have a look at the `example_na_controlling_the_pml.ipynb` notebook file to see the example in action. 10 | 11 | ## Preparing the Matlab reference files 12 | 13 | We can verify the correctness of Python implementation by saving intermediate/final variable states from the Matlab script 14 | and comparing them against Python version. Saving the variable states can be done manually by running the Matlab script, 15 | pausing it in appropriate places and saving the variables using `save(...)` method. However, this is very involved process. 16 | To automate the process a bit, we followed the steps below. 17 | 18 | 1. Grab the original example file from K-wave repository (link: [example_na_controlling_the_PML.m](https://github.com/ucl-bug/k-wave/blob/main/k-Wave/examples/example_na_controlling_the_PML.m)) 19 | 2. Modify the file such that we are running for all scenarios (4 different simulation cases) and saving the output sensor data + visualized figures each time. We saved the modified script in the `modified_matlab_example.m` file. 20 | 3. Run the modified file from the step above. Now we should have 4x `.mat` and `.png` files for the captured sensor data and visualized figure, respectively. 21 | 4. We check against these files in the `example_na_controlling_the_pml.ipynb` notebook. 22 | -------------------------------------------------------------------------------- /examples/pr_2D_FFT_line_sensor/README.md: -------------------------------------------------------------------------------- 1 | # 2D FFT Reconstruction For A Line Sensor Example 2 | 3 | [![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/pr_2D_FFT_line_sensor/pr_2D_FFT_line_sensor.ipynb) 4 | 5 | This example demonstrates the use of k-Wave for the reconstruction of a two-dimensional photoacoustic wave-field recorded over a linear array of sensor elements. The sensor data is simulated using [kspaceFirstOrder2D](https://k-wave-python.readthedocs.io/en/latest/kwave.kspaceFirstOrder2D.html) and reconstructed using kspaceLineRecon. It builds on the Homogeneous Propagation Medium and Heterogeneous Propagation Medium examples. 6 | 7 | To read more, visit the [original example page](http://www.k-wave.org/documentation/example_pr_2D_fft_line_sensor.php) or its [implementation](https://github.com/ucl-bug/k-wave/blob/main/k-Wave/examples/example_pr_2D_FFT_line_sensor.m). -------------------------------------------------------------------------------- /examples/pr_2D_TR_line_sensor/README.md: -------------------------------------------------------------------------------- 1 | # 2D Time Reversal Reconstruction For A Line Sensor Example 2 | 3 | [![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/pr_2D_TR_line_sensor/pr_2D_TR_line_sensor.ipynb) 4 | 5 | This example demonstrates the use of k-Wave for the time-reversal reconstruction of a two-dimensional photoacoustic wave-field recorded over a linear array of sensor elements. The sensor data is simulated and then time-reversed using [kspaceFirstOrder2D](https://k-wave-python.readthedocs.io/en/latest/kwave.kspaceFirstOrder2D.html). It builds on the [2D FFT Reconstruction For A Line Sensor Example](../pr_2D_TR_line_sensor/). 6 | 7 | To read more, visit the [original example page](http://www.k-wave.org/documentation/example_pr_2D_tr_line_sensor.php) or its [implementation](https://github.com/ucl-bug/k-wave/blob/main/k-Wave/examples/example_pr_2D_TR_line_sensor.m). -------------------------------------------------------------------------------- /examples/pr_3D_FFT_planar_sensor/README.md: -------------------------------------------------------------------------------- 1 | # 3D FFT Reconstruction For A Planar Sensor Example 2 | 3 | [![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/pr_3D_FFT_planar_sensor/pr_3D_FFT_planar_sensor.ipynb) 4 | 5 | This example demonstrates the use of k-Wave for the reconstruction of a three-dimensional photoacoustic wave-field recorded over a planar array of sensor elements. The sensor data is simulated using [kspaceFirstOrder3D](https://k-wave-python.readthedocs.io/en/latest/kwave.kspaceFirstOrder3D.html) and reconstructed using kspacePlaneRecon. It builds on the Simulations In Three Dimensions and [2D FFT Reconstruction For A Line Sensor](../pr_3D_FFT_planar_sensor/) examples. 6 | 7 | To read more, visit the [original example page](http://www.k-wave.org/documentation/example_pr_3D_fft_planar_sensor.php) or its [implementation](https://github.com/ucl-bug/k-wave/blob/main/k-Wave/examples/example_pr_3D_FFT_planar_sensor.m). -------------------------------------------------------------------------------- /examples/pr_3D_TR_planar_sensor/README.md: -------------------------------------------------------------------------------- 1 | # 3D Time Reversal Reconstruction For A Planar Sensor Example 2 | 3 | [![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/pr_3D_TR_planar_sensor/pr_3D_TR_planar_sensor.ipynb) 4 | 5 | This example demonstrates the use of k-Wave for the reconstruction of a three-dimensional photoacoustic wave-field recorded over a planar array of sensor elements. The sensor data is simulated and then time-reversed using [kspaceFirstOrder3D](https://k-wave-python.readthedocs.io/en/latest/kwave.kspaceFirstOrder3D.html). It builds on the [3D FFT Reconstruction For A Planar Sensor](../pr_3D_FFT_planar_sensor/) and [2D Time Reversal Reconstruction For A Line Sensor](../pr_2D_TR_line_sensor) examples. 6 | 7 | To read more, visit the [original example page](http://www.k-wave.org/documentation/example_pr_3D_tr_planar_sensor.php) or its [implementation](https://github.com/ucl-bug/k-wave/blob/main/k-Wave/examples/example_pr_3D_TR_planar_sensor.m). -------------------------------------------------------------------------------- /examples/sd_directivity_modelling_2D/README.md: -------------------------------------------------------------------------------- 1 | # Modelling Sensor Directivity In 2D Example 2 | 3 | [![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) 4 | 5 | This example demonstrates how the sensitivity of a large single element detector varies with the angular position of a point-like source. 6 | 7 | To read more, visit the [original example page](http://www.k-wave.org/documentation/example_sd_directivity_modelling_2D.php). 8 | -------------------------------------------------------------------------------- /examples/sd_focussed_detector_2D/README.md: -------------------------------------------------------------------------------- 1 | # Focussed Detector In 2D Example 2 | 3 | [![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) 4 | 5 | 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. 6 | 7 | To read more, visit the [original example page](http://www.k-wave.org/documentation/example_sd_focussed_detector_2D.php). 8 | -------------------------------------------------------------------------------- /examples/sd_focussed_detector_3D/README.md: -------------------------------------------------------------------------------- 1 | # Focussed Detector In 3D Example 2 | 3 | [![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) 4 | 5 | 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. 6 | 7 | To read more, visit the [original example page](http://www.k-wave.org/documentation/example_sd_focussed_detector_3D.php). 8 | -------------------------------------------------------------------------------- /examples/us_beam_patterns/README.md: -------------------------------------------------------------------------------- 1 | # Simulating Ultrasound Beam Patterns Example 2 | 3 | [![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/us_beam_patterns/us_beam_patterns.ipynb) 4 | 5 | This example shows how the nonlinear beam pattern from an ultrasound transducer can be modelled. It builds on the Defining An Ultrasound Transducer and Simulating Transducer Field Patterns examples. 6 | 7 | To read more, visit the [original example page](http://www.k-wave.org/documentation/example_us_beam_patterns.php). -------------------------------------------------------------------------------- /examples/us_bmode_linear_transducer/README.md: -------------------------------------------------------------------------------- 1 | # Simulating B-mode Ultrasound Images Example 2 | 3 | [![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/us_bmode_linear_transducer/us_bmode_linear_transducer.ipynb) 4 | 5 | This example illustrates how k-wave-python can be used for the simulation of B-mode ultrasound images (including tissue harmonic imaging) analogous to those produced by a modern diagnostic ultrasound scanner. 6 | 7 | 8 | To read more, visit the [original example page](http://www.k-wave.org/documentation/example_us_bmode_linear_transducer.php). -------------------------------------------------------------------------------- /examples/us_bmode_linear_transducer/example_utils.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | def download_from_gdrive(file_id, output_path): 5 | try: 6 | import gdown 7 | except ModuleNotFoundError: 8 | raise AssertionError("This example requires `gdown` to be installed. Please install using `pip install gdown`") 9 | 10 | url = f"https://drive.google.com/uc?export=download&confirm=t&id={file_id}" 11 | gdown.download(url, output_path, quiet=False) 12 | 13 | 14 | def download_if_does_not_exist(file_id, output_path): 15 | if not os.path.exists(output_path): 16 | download_from_gdrive(file_id, output_path) 17 | -------------------------------------------------------------------------------- /examples/us_bmode_phased_array/README.md: -------------------------------------------------------------------------------- 1 | # Simulating B-mode Ultrasound Images From a Phased Array Transducer Example 2 | 3 | [![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/us_bmode_phased_array/us_bmode_phased_array.ipynb) 4 | 5 | This example illustrates how k-wave-python can be used for the simulation of B-mode ultrasound images (including tissue harmonic imaging) analogous to those produced by a modern diagnostic ultrasound scanner. 6 | Specifically, it demonstrates the usage of a phased array transducer. In this case, the entire medium should fit into the kgrid. 7 | 8 | 9 | To read more, visit the [original example page](http://www.k-wave.org/documentation/example_us_bmode_phased_array.php). -------------------------------------------------------------------------------- /examples/us_defining_transducer/README.md: -------------------------------------------------------------------------------- 1 | # Defining An Ultrasound Transducer Example 2 | 3 | [![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/us_defining_transducer/us_defining_transducer.ipynb) 4 | 5 | This example illustrates how kWaveTransducerSimple can be used to simulate the field produced by an ultrasound transducer. 6 | 7 | 8 | To read more, visit the [original example page](http://www.k-wave.org/documentation/example_us_defining_transducer.php). 9 | -------------------------------------------------------------------------------- /kwave/enums.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | 3 | ################################################################ 4 | # literals that link the discrete cosine and sine transform types with 5 | # their type definitions in the functions dtt1D, dtt2D, and dtt3D 6 | 7 | 8 | class DiscreteCosine(Enum): 9 | TYPE_1 = 1 10 | TYPE_2 = 2 11 | TYPE_3 = 3 12 | TYPE_4 = 4 13 | 14 | 15 | class DiscreteSine(Enum): 16 | TYPE_1 = 1 17 | TYPE_2 = 2 18 | TYPE_3 = 3 19 | TYPE_4 = 4 20 | 21 | 22 | ################################################################ 23 | -------------------------------------------------------------------------------- /kwave/kWaveSimulation_helper/__init__.py: -------------------------------------------------------------------------------- 1 | from kwave.kWaveSimulation_helper.create_absorption_variables import create_absorption_variables 2 | from kwave.kWaveSimulation_helper.display_simulation_params import display_simulation_params 3 | from kwave.kWaveSimulation_helper.expand_grid_matrices import expand_grid_matrices 4 | from kwave.kWaveSimulation_helper.retract_transducer_grid_size import retract_transducer_grid_size 5 | from kwave.kWaveSimulation_helper.save_to_disk_func import save_to_disk_func 6 | from kwave.kWaveSimulation_helper.scale_source_terms_func import scale_source_terms_func 7 | from kwave.kWaveSimulation_helper.set_sound_speed_ref import set_sound_speed_ref 8 | -------------------------------------------------------------------------------- /kwave/kWaveSimulation_helper/retract_transducer_grid_size.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from kwave.ktransducer import NotATransducer 4 | 5 | 6 | def retract_transducer_grid_size(source, sensor, retract_size, pml_inside: bool): 7 | # resize the transducer object if the grid has been expanded 8 | is_source_kwave_transducer = isinstance(source, NotATransducer) 9 | is_sensor_kwave_transducer = isinstance(sensor, NotATransducer) 10 | retract_size = np.array(retract_size) 11 | 12 | if not pml_inside and (is_source_kwave_transducer or is_sensor_kwave_transducer): 13 | # check if the sensor is a transducer 14 | if is_sensor_kwave_transducer: 15 | # retract the transducer mask 16 | sensor.retract_grid(retract_size) 17 | 18 | # check if the source is a transducer, and if so, and different 19 | # transducer to the sensor 20 | if is_source_kwave_transducer and not (is_sensor_kwave_transducer and sensor == source): 21 | # retract the transducer mask 22 | source.retract_grid(retract_size) 23 | -------------------------------------------------------------------------------- /kwave/options/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Simulation options module for k-Wave. 3 | 4 | This module provides classes for configuring simulation parameters and execution options 5 | for k-Wave simulations. 6 | """ 7 | 8 | from kwave.options.simulation_execution_options import SimulationExecutionOptions 9 | from kwave.options.simulation_options import SimulationOptions 10 | 11 | __all__ = ["SimulationOptions", "SimulationExecutionOptions"] 12 | -------------------------------------------------------------------------------- /kwave/reconstruction/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Time reversal reconstruction module for k-Wave. 3 | 4 | This module provides functionality for time reversal reconstruction in photoacoustic imaging. 5 | The main class is TimeReversal which handles the reconstruction process using time reversal 6 | of the acoustic wave equation. 7 | """ 8 | 9 | from kwave.reconstruction.time_reversal import TimeReversal 10 | 11 | __all__ = ["TimeReversal"] 12 | -------------------------------------------------------------------------------- /kwave/reconstruction/tools.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | 4 | def log_compression(signal, cf, normalize=False): 5 | """ 6 | Log compress an input signal. 7 | 8 | Args: 9 | signal: signal to be log compressed 10 | cf: compression factor 11 | normalize (bool): when true, signal is normalized before compression 12 | 13 | Returns: signal: log-compressed signal 14 | """ 15 | if normalize: 16 | ms = np.max(signal, axis=-1) 17 | if np.ndim(signal) == 2: 18 | ms = ms[:, np.newaxis] 19 | signal = ms * (np.log10(1 + cf * signal / ms) / np.log10(1 + cf)) 20 | else: 21 | signal = np.log10(1 + cf * signal) / np.log10(1 + cf) 22 | return signal 23 | 24 | 25 | def db(x): 26 | return 20 * np.log10(np.abs(x)) 27 | 28 | 29 | def apodize(distance, aperture, window): 30 | """ 31 | Function that assigns different apodization to a set of pixels and elements 32 | 33 | """ 34 | 35 | if window == "none": 36 | apod = np.ones(np.size(distance)) 37 | elif window == "boxcar": 38 | apod = np.double(distance <= aperture / 2.0) 39 | elif window == "hanning": 40 | apod = np.double(distance <= aperture / 2) * (0.5 + 0.5 * np.cos(2 * np.pi * distance / aperture)) 41 | elif window == "hamming": 42 | apod = np.double(distance <= aperture) / 2 * (0.53836 + 0.46164 * np.cos(2 * np.pi * distance / aperture)) 43 | elif window == "tukey25": 44 | roll = 0.25 45 | apod = (distance < (aperture / 2 * (1 - roll))) + (distance > (aperture / 2 * (1 - roll))) * (distance < (aperture / 2)) * 0.5 * ( 46 | 1 + np.cos(2 * np.pi / roll * (distance / aperture - roll / 2 - 1 / 2)) 47 | ) 48 | elif window == "tukey50": 49 | roll = 0.5 50 | apod = (distance < (aperture / 2 * (1 - roll))) + (distance > (aperture / 2 * (1 - roll))) * (distance < (aperture / 2)) * 0.5 * ( 51 | 1 + np.cos(2 * np.pi / roll * (distance / aperture - roll / 2 - 1 / 2)) 52 | ) 53 | elif window == "tukey75": 54 | roll = 0.75 55 | apod = (distance < (aperture / 2 * (1 - roll))) + (distance > (aperture / 2 * (1 - roll))) * (distance < (aperture / 2)) * 0.5 * ( 56 | 1 + np.cos(2 * np.pi / roll * (distance / aperture - roll / 2 - 1 / 2)) 57 | ) 58 | else: 59 | raise ValueError("Unknown window type. Known types are: boxcar, hamming, hanning, tukey25, tukey50, tukey75.") 60 | 61 | return apod 62 | 63 | 64 | def make_time_vector(num_samples, sampling_freq, time_offset): 65 | return np.linspace(start=0, num=num_samples, stop=num_samples / sampling_freq) + time_offset 66 | -------------------------------------------------------------------------------- /kwave/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waltsims/k-wave-python/51b2041523377c937f224c75cc771ec761ec975c/kwave/utils/__init__.py -------------------------------------------------------------------------------- /kwave/utils/dotdictionary.py: -------------------------------------------------------------------------------- 1 | from typing import Any 2 | 3 | 4 | class dotdict(dict): 5 | """ 6 | A dictionary supporting dot notation. 7 | 8 | This class extends the built-in `dict` type by adding support for accessing 9 | items using dot notation (e.g. `dotdict.a.b.c`) instead of square bracket 10 | notation (e.g. `dotdict['a']['b']['c']`). The class also provides a 11 | `lookup` method for looking up a value in a nested dictionary structure 12 | using a dot-separated path (e.g. "a.b.c"). 13 | 14 | Examples: 15 | >>> d = dotdict({'a': {'b': {'c': 1}}}) 16 | >>> d.a.b.c 17 | 1 18 | >>> d.lookup('a.b.c') 19 | 1 20 | 21 | """ 22 | 23 | __getattr__ = dict.get 24 | __setattr__ = dict.__setitem__ 25 | __delattr__ = dict.__delitem__ 26 | 27 | def __init__(self, *args: Any, **kwargs: Any) -> None: 28 | super().__init__(*args, **kwargs) 29 | for k, v in self.items(): 30 | if isinstance(v, dict): 31 | self[k] = dotdict(v) 32 | 33 | def lookup(self, dotkey: str) -> Any: 34 | """ 35 | Look up a value in a nested dictionary structure using a dot-separated path. 36 | 37 | Args: 38 | dotkey: A dot-separated path to the value, e.g. "a.b.c". 39 | 40 | Returns: 41 | The value at the specified path. 42 | 43 | Raises: 44 | KeyError: If the specified path does not exist in the dictionary. 45 | 46 | """ 47 | path = list(reversed(dotkey.split("."))) 48 | v = self 49 | while path: 50 | key = path.pop() 51 | if isinstance(v, dict): 52 | v = v[key] 53 | elif isinstance(v, list): 54 | v = v[int(key)] 55 | else: 56 | raise KeyError(key) 57 | return v 58 | -------------------------------------------------------------------------------- /kwave/utils/plot.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import numpy as np 3 | 4 | 5 | def voxel_plot(mat, axis_tight=False, color=(1, 1, 0.4), transparency=0.8): 6 | """ 7 | Generates a 3D voxel plot of a binary matrix. 8 | 9 | Args: 10 | mat (numpy.ndarray): Input 3D matrix in single or double precision. 11 | axis_tight (bool): Whether axis limits are set to only display the filled voxels (default = False). 12 | color (tuple): Three-element tuple specifying RGB color (default = (1, 1, 0.4)). 13 | transparency (float): Value between 0 and 1 specifying transparency where 1 gives no transparency (default = 0.8). 14 | 15 | Returns: 16 | None 17 | """ 18 | # Check input matrix is 3D and single or double precision 19 | if len(mat.shape) != 3 or not np.issubdtype(mat.dtype, np.floating): 20 | raise ValueError("Input must be a 3D matrix in single or double precision.") 21 | 22 | # Normalize the matrix 23 | mat = mat / np.max(mat) 24 | 25 | # Create 3D figure 26 | fig = plt.figure() 27 | ax = fig.add_subplot(111, projection="3d") 28 | ax.voxels(mat, facecolors=color, alpha=transparency, edgecolors=(0.5, 0.5, 0.5, 0.5)) 29 | 30 | # Set the axes properties and labels 31 | ax.view_init(elev=35, azim=-35) # Adjust viewing angles here 32 | ax.set_xlabel("x [voxels]") 33 | ax.set_ylabel("y [voxels]") 34 | ax.set_zlabel("z [voxels]") 35 | 36 | if not axis_tight: 37 | sz = mat.shape 38 | ax.set_xlim([0.5, sz[2] + 0.5]) 39 | ax.set_ylim([0.5, sz[1] + 0.5]) 40 | ax.set_zlim([0.5, sz[0] + 0.5]) 41 | 42 | # Show the plot 43 | plt.show() 44 | -------------------------------------------------------------------------------- /kwave/utils/tictoc.py: -------------------------------------------------------------------------------- 1 | from time import perf_counter 2 | 3 | 4 | class TicToc(object): 5 | """ 6 | A class for measuring the execution time of a code block. 7 | 8 | This class uses the perf_counter function from the time module to measure the 9 | execution time of a code block. It provides a simple interface with two methods: 10 | tic and toc. You can use the tic method to start the timer, and then use the 11 | toc method to stop the timer and get the elapsed time. 12 | """ 13 | 14 | start_time = -1 15 | 16 | @staticmethod 17 | def tic(): 18 | """ 19 | Start the timer. 20 | 21 | This method sets the start_time attribute to the current time, as measured 22 | by the perf_counter function from the time module. 23 | """ 24 | TicToc.start_time = perf_counter() 25 | 26 | @staticmethod 27 | def toc(reset: bool = False) -> float: 28 | """Stop the timer and return the elapsed time. 29 | 30 | This method calculates the elapsed time since the timer was started by 31 | subtracting the start_time attribute from the current time, as measured by 32 | the perf_counter function from the time module. If the reset argument is 33 | True, the timer will be restarted automatically. 34 | 35 | Args: 36 | reset: Whether to reset the timer after stopping it. 37 | 38 | Returns: 39 | The elapsed time in seconds. 40 | """ 41 | passed_time = perf_counter() - TicToc.start_time 42 | if reset: 43 | TicToc.tic() 44 | return passed_time 45 | -------------------------------------------------------------------------------- /kwave/utils/typing.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from beartype.typing import Union 3 | from jaxtyping import Bool, Complex, Float, Int, Shaped 4 | 5 | ArrayLike = Union[ 6 | np.ndarray, # NumPy array type 7 | np.bool_, 8 | np.number, # NumPy scalar types 9 | bool, 10 | int, 11 | float, 12 | complex, # Python scalar types 13 | ] 14 | 15 | ScalarLike = Shaped[ArrayLike, ""] 16 | 17 | 18 | INT = Union[Int, int] 19 | NUMERIC = Union[int, float, np.number] 20 | NUMERIC_WITH_COMPLEX = Union[int, float, complex, np.number] 21 | 22 | 23 | NP_ARRAY_INT_1D = Int[np.ndarray, "Dim1"] 24 | NP_ARRAY_FLOAT_1D = Float[np.ndarray, "Dim1"] 25 | NP_ARRAY_BOOL_1D = Bool[np.ndarray, "Dim1"] 26 | NP_ARRAY_COMPLEX_1D = Complex[np.ndarray, "Dim1"] 27 | NP_ARRAY_INT_2D = Int[np.ndarray, "Dim1 Dim2"] 28 | NP_ARRAY_BOOL_2D = Bool[np.ndarray, "Dim1 Dim2"] 29 | NP_ARRAY_FLOAT_2D = Float[np.ndarray, "Dim1 Dim2"] 30 | NP_ARRAY_INT_3D = Int[np.ndarray, "Dim1 Dim2 Dim3"] 31 | NP_ARRAY_BOOL_3D = Bool[np.ndarray, "Dim1 Dim2 Dim3"] 32 | NP_ARRAY_FLOAT_3D = Float[np.ndarray, "Dim1 Dim2 Dim3"] 33 | 34 | NP_DOMAIN = Union[Float[np.ndarray, "1"], Float[np.ndarray, "2"], Float[np.ndarray, "3"]] 35 | -------------------------------------------------------------------------------- /make_docs.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # sphinx-apidoc -o ./docs -efT $pwd 4 | sphinx-build -b html docs docs/_build 5 | -------------------------------------------------------------------------------- /pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | filterwarnings = 3 | ignore:The interactive_bk attribute was deprecated.*:matplotlib._api.deprecation.MatplotlibDeprecationWarning 4 | # Add any other warning filters you might need below 5 | -------------------------------------------------------------------------------- /run_examples.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | from pathlib import Path 4 | 5 | 6 | def run_python_files(directory): 7 | # Recursively walk through the directory 8 | for root, _, files in os.walk(directory): 9 | for file in files: 10 | # Check if it's a Python file 11 | if file.endswith(".py"): 12 | file_path = os.path.join(root, file) 13 | print(f"Running: {file_path}") 14 | try: 15 | # Use subprocess to run the Python file 16 | result = subprocess.run(["python", file_path], capture_output=True, text=True) 17 | print(f"Output:\n{result.stdout}") 18 | if result.stderr: 19 | print(f"Errors:\n{result.stderr}") 20 | except Exception as e: 21 | print(f"Failed to run {file_path}: {e}") 22 | 23 | 24 | if __name__ == "__main__": 25 | directory = Path("examples/") 26 | run_python_files(directory) 27 | -------------------------------------------------------------------------------- /run_tests.sh: -------------------------------------------------------------------------------- 1 | # Run tests inside a Docker image 2 | image_name='kwave-python-image' 3 | project_dir_in_container='/k-wave-python' 4 | 5 | docker build -t $image_name . 6 | 7 | docker run -it \ 8 | --volume "$(pwd)":$project_dir_in_container \ 9 | --workdir $project_dir_in_container \ 10 | $image_name \ 11 | pytest # run pytest 12 | -------------------------------------------------------------------------------- /tests/EXAMPLE_source_one.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waltsims/k-wave-python/51b2041523377c937f224c75cc771ec761ec975c/tests/EXAMPLE_source_one.png -------------------------------------------------------------------------------- /tests/EXAMPLE_source_two.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waltsims/k-wave-python/51b2041523377c937f224c75cc771ec761ec975c/tests/EXAMPLE_source_two.bmp -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | import sys 4 | 5 | PACKAGE_PARENT = ".." 6 | SCRIPT_DIR = os.path.dirname(os.path.realpath(os.path.join(os.getcwd(), os.path.expanduser(__file__)))) 7 | logging.log(logging.INFO, os.path.normpath(os.path.join(SCRIPT_DIR, PACKAGE_PARENT))) 8 | sys.path.append(os.path.normpath(os.path.join(SCRIPT_DIR, PACKAGE_PARENT))) 9 | -------------------------------------------------------------------------------- /tests/diff_utils.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from tests.h5_summary import H5Summary 4 | 5 | 6 | def compare_against_ref(reference: str, h5_path, eps=1e-8, precision=8): 7 | summary_ref = H5Summary.load(reference) 8 | summary_new = H5Summary.from_h5(h5_path) 9 | 10 | logging.log(logging.INFO, "Comparing Summary files ...") 11 | diff = summary_ref.get_diff(summary_new, eps=eps, precision=precision) 12 | if len(diff) != 0: 13 | logging.log(logging.WARN, "H5Summary files do not match! Printing the difference:") 14 | print(diff) 15 | return len(diff) == 0 16 | 17 | 18 | # Note: this is no longer used, but kept for reference 19 | # def check_h5_equality(path_a, path_b): 20 | # # H5DIFF doesn't support excluding attributes from comparison 21 | # # Therefore we remove them manually 22 | # # Don't apply this procedure in the final version! 23 | # for path in [path_a, path_b]: 24 | # with h5py.File(path, "a") as f: 25 | # for attr in ['creation_date', 'file_description', 'created_by', 'Nt']: 26 | # if attr in f.attrs: 27 | # del f.attrs[attr] 28 | # 29 | # cmd = f'h5diff -c -d 0.00000001 {path_a} {path_b}' 30 | # logging.log(logging.INFO, cmd) 31 | # res = os.system(cmd) 32 | # return res == 0 33 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/+utils/TestRecorder.m: -------------------------------------------------------------------------------- 1 | classdef TestRecorder < handle 2 | properties 3 | record_filename = "" 4 | records 5 | step = 0 6 | end 7 | methods 8 | 9 | function obj = TestRecorder(record_filename) 10 | obj.records = containers.Map; 11 | obj.record_filename = record_filename; 12 | end 13 | 14 | function obj = recordObject(obj, obj_name, obj_to_record) 15 | warning('off', 'MATLAB:structOnObject') 16 | key = ['step_' num2str(obj.step) '___' obj_name]; 17 | obj.records(key) = struct(obj_to_record); 18 | end 19 | 20 | function obj = recordVariable(obj, var_name, var_value) 21 | key = ['step_' num2str(obj.step) '___' var_name]; 22 | obj.records(key) = var_value; 23 | end 24 | 25 | function obj = increment(obj) 26 | obj.step = obj.step + 1; 27 | end 28 | 29 | function obj = saveRecordsToDisk(obj) 30 | k = keys(obj.records) ; 31 | val = values(obj.records) ; 32 | for i = 1:length(obj.records) 33 | curr_key = k{i}; 34 | curr_val = val{i}; 35 | eval([curr_key, '=curr_val;']); 36 | end 37 | total_steps = obj.step; 38 | save(obj.record_filename, k{:}, 'total_steps'); 39 | end 40 | 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/+utils/rand_vector_in_range.m: -------------------------------------------------------------------------------- 1 | function [vec] = rand_vector_in_range(min_bound, max_bound, num_points) 2 | vec = (max_bound-min_bound).*rand(num_points, 1) + min_bound; 3 | end 4 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_FocusAnnulusONeil.m: -------------------------------------------------------------------------------- 1 | output_file = 'collectedValues/focusAnnulusONeil.mat'; 2 | recorder = utils.TestRecorder(output_file); 3 | 4 | % define transducer parameters 5 | radius = 30e-3; % [m] 6 | % aperture diameters of the elements given an inner, outer pairs [m] 7 | diameters = [0 5; 10 15; 20 25].' .* 1e-3; 8 | amplitude = [0.5e6, 1e6, 0.75e6]; % source pressure [Pa] 9 | source_phase = deg2rad([0, 10, 20]); % phase [rad] 10 | frequency = 1e6; % [Hz] 11 | sound_speed = 1500; % [m/s] 12 | density = 1000; % [kg/m^3] 13 | 14 | % define position vectors 15 | axial_position = 0:1e-4:250e-3; % [m] 16 | 17 | % evaluate pressures 18 | p_axial = focusedAnnulusONeil(radius, diameters, ... 19 | amplitude / (sound_speed * density), source_phase, frequency, sound_speed, density, ... 20 | axial_position); 21 | 22 | recorder.recordVariable('radius', radius); 23 | recorder.recordVariable('diameters', diameters); 24 | recorder.recordVariable('amplitude', amplitude); 25 | recorder.recordVariable('source_phase', source_phase); 26 | recorder.recordVariable('frequency', frequency); 27 | recorder.recordVariable('sound_speed', sound_speed); 28 | recorder.recordVariable('density', density); 29 | recorder.recordVariable('axial_position', axial_position); 30 | recorder.recordVariable('p_axial', p_axial); 31 | 32 | recorder.saveRecordsToDisk(); -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_FocusBowlONeil.m: -------------------------------------------------------------------------------- 1 | output_file = 'collectedValues/focusBowlONeil.mat'; 2 | recorder = utils.TestRecorder(output_file); 3 | 4 | % define transducer parameters 5 | radius = 140e-3; % [m] 6 | diameter = 120e-3; % [m] 7 | velocity = 100e-3; % [m/s] 8 | frequency = 1e6; % [Hz] 9 | sound_speed = 1500; % [m/s] 10 | density = 1000; % [kg/m^3] 11 | 12 | % define position vectors 13 | axial_position = 0:1e-4:250e-3; % [m] 14 | lateral_position = -15e-3:1e-4:15e-3; % [m] 15 | 16 | % evaluate pressure 17 | [p_axial, p_lateral, p_axial_complex] = focusedBowlONeil(radius, diameter, ... 18 | velocity, frequency, sound_speed, density, ... 19 | axial_position, lateral_position); 20 | 21 | recorder.recordVariable('radius', radius); 22 | recorder.recordVariable('diameter', diameter); 23 | recorder.recordVariable('velocity', velocity); 24 | recorder.recordVariable('frequency', frequency); 25 | recorder.recordVariable('sound_speed', sound_speed); 26 | recorder.recordVariable('density', density); 27 | recorder.recordVariable('axial_position', axial_position); 28 | recorder.recordVariable('lateral_position', lateral_position); 29 | recorder.recordVariable('p_axial', p_axial); 30 | recorder.recordVariable('p_lateral', p_lateral); 31 | recorder.recordVariable('p_axial_complex', p_axial_complex); 32 | 33 | recorder.saveRecordsToDisk(); 34 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_angularSpectrum.m: -------------------------------------------------------------------------------- 1 | output_file = 'collectedValues/angularSpectrum.mat'; 2 | recorder = utils.TestRecorder(output_file); 3 | 4 | input_plane = rand(44, 44, 255); 5 | dx = 1.0000e-04; 6 | dt = 2.0059e-08; 7 | z_pos = 0.0034; 8 | c0 = 1500; 9 | grid_expansion = 50; 10 | 11 | [pressure_max, pressure_time] = angularSpectrum(input_plane, dx, ... 12 | dt, z_pos, c0, 'GridExpansion', grid_expansion); 13 | 14 | recorder.recordVariable('input_plane', input_plane); 15 | recorder.recordVariable('dx', dx); 16 | recorder.recordVariable('dt', dt); 17 | recorder.recordVariable('z_pos', z_pos); 18 | recorder.recordVariable('c0', c0); 19 | recorder.recordVariable('grid_expansion', grid_expansion); 20 | 21 | recorder.recordVariable('pressure_max', pressure_max); 22 | recorder.recordVariable('pressure_time', pressure_time); 23 | 24 | recorder.saveRecordsToDisk(); 25 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_angularSpectrumCW.m: -------------------------------------------------------------------------------- 1 | output_file = 'collectedValues/angularSpectrumCW.mat'; 2 | 3 | 4 | recorder = utils.TestRecorder(output_file); 5 | 6 | input_plane = rand(44, 100); 7 | dx = 1.0000e-04; 8 | z_pos = 0.0034; 9 | f0 = 300000; 10 | c0 = 1500; 11 | grid_expansion = 50; 12 | 13 | pressure = angularSpectrumCW(input_plane, dx, ... 14 | z_pos, f0, c0, 'GridExpansion', grid_expansion); 15 | 16 | recorder.recordVariable('input_plane', input_plane); 17 | recorder.recordVariable('dx', dx); 18 | recorder.recordVariable('z_pos', z_pos); 19 | recorder.recordVariable('f0', f0); 20 | recorder.recordVariable('c0', c0); 21 | recorder.recordVariable('grid_expansion', grid_expansion); 22 | 23 | recorder.recordVariable('pressure', pressure); 24 | 25 | recorder.saveRecordsToDisk(); 26 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_attenComp.m: -------------------------------------------------------------------------------- 1 | output_file = 'collectedValues/attenComp.mat'; 2 | recorder = utils.TestRecorder(output_file); 3 | 4 | inp_signal = rand(44, 100); 5 | dt = 0.0001; 6 | c = 1500; 7 | alpha_0 = 0.1; 8 | y = 0.5; 9 | fit_type = 'mav'; 10 | 11 | [out_signal, tfd, cutoff_freq] = attenComp(inp_signal, dt, c, alpha_0, y, 'FitType', fit_type); 12 | 13 | recorder.recordVariable('inp_signal', inp_signal); 14 | recorder.recordVariable('dt', dt); 15 | recorder.recordVariable('c', c); 16 | recorder.recordVariable('alpha_0', alpha_0); 17 | recorder.recordVariable('y', y); 18 | 19 | recorder.recordVariable('out_signal', out_signal); 20 | recorder.recordVariable('tfd', tfd); 21 | recorder.recordVariable('cutoff_freq', cutoff_freq); 22 | recorder.recordVariable('fit_type', fit_type); 23 | 24 | recorder.saveRecordsToDisk(); 25 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_brenner.m: -------------------------------------------------------------------------------- 1 | output_file = 'collectedValues/brenner.mat'; 2 | recorder = utils.TestRecorder(output_file); 3 | 4 | img2 = rand([5,5]); 5 | out2 = sharpness(img2, 'Brenner'); 6 | recorder.recordVariable('img2', img2); 7 | recorder.recordVariable('out2', out2); 8 | 9 | img3 = rand([5,5,5]); 10 | out3 = sharpness(img3, 'Brenner'); 11 | recorder.recordVariable('img3', img3); 12 | recorder.recordVariable('out3', out3); 13 | recorder.saveRecordsToDisk(); 14 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_checkStability.m: -------------------------------------------------------------------------------- 1 | recorder = utils.TestRecorder("collectedValues/checkstability.mat"); 2 | 3 | c_min = 1500; 4 | rho_min = 1000; 5 | alpha_coeff_min = 4; 6 | ppw = 3; 7 | freq = 500e3; 8 | 9 | Nx = 128; 10 | Ny = 128; 11 | Nz = 128; 12 | 13 | dx = c_min / (ppw * freq); 14 | 15 | sound = ones(Nx, Ny, Nz) * c_min; 16 | density = ones(Nx, Ny, Nz) * rho_min; 17 | alpha_coeff = ones(Nx, Ny, Nz) * alpha_coeff_min; 18 | alpha_power = 1.43; 19 | 20 | medium.density = density; 21 | medium.sound_speed = sound; 22 | medium.alpha_coeff = alpha_coeff; 23 | medium.alpha_power = alpha_power; 24 | 25 | kgrid = kWaveGrid(Nx, dx, Ny, dx, Nz, dx); 26 | 27 | dt_stability_limit = checkStability(kgrid, medium); 28 | recorder.recordObject('kgrid', kgrid); 29 | recorder.recordObject('medium', medium); 30 | recorder.recordVariable('dt', dt_stability_limit); 31 | recorder.increment(); 32 | medium.alpha_mode = 'no_dispersion'; 33 | medium.sound_speed_ref = 'mean'; 34 | dt_stability_limit = checkStability(kgrid, medium); 35 | recorder.recordObject('kgrid', kgrid); 36 | recorder.recordObject('medium', medium); 37 | recorder.recordVariable('dt', dt_stability_limit); 38 | recorder.increment(); 39 | medium.alpha_mode = 'no_absorption'; 40 | medium.sound_speed_ref = 'min'; 41 | dt_stability_limit = checkStability(kgrid, medium); 42 | recorder.recordObject('kgrid', kgrid); 43 | recorder.recordObject('medium', medium); 44 | recorder.recordVariable('dt', dt_stability_limit); 45 | recorder.increment(); 46 | 47 | 48 | 49 | recorder.saveRecordsToDisk(); 50 | 51 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_computeLinearTransform.m: -------------------------------------------------------------------------------- 1 | all_params = { ... 2 | {[20, 30, 10], [5, 50, 10], 3}, ... 3 | {[0, 0, 0], [5, 50, 10]}, ... 4 | {[0, 0, 0], [5, 50, 10], -5}, ... 5 | {[0, 0, 0], [0, 0, 0], -5}, ... 6 | {[0, 0, 0], [0, 0, 0], 0}, ... 7 | {[15, 16, 17], [15, 16, 17]}, ... 8 | }; 9 | 10 | output_file = 'collectedValues/computeLinearTransform.mat'; 11 | recorder = utils.TestRecorder(output_file); 12 | 13 | for idx=1:length(all_params) 14 | disp(idx); 15 | params = all_params{idx}; 16 | 17 | [rotMat, offsetPos] = computeLinearTransform(params{:}); 18 | 19 | recorder.recordVariable('params', params); 20 | recorder.recordVariable('rotMat', rotMat); 21 | recorder.recordVariable('offsetPos', offsetPos); 22 | recorder.increment(); 23 | end 24 | 25 | recorder.saveRecordsToDisk(); 26 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_createCWSignals.m: -------------------------------------------------------------------------------- 1 | output_file = 'collectedValues/createCWSignals.mat'; 2 | recorder = utils.TestRecorder(output_file); 3 | 4 | % define sampling parameters 5 | f = 5e6; 6 | T = 1/f; 7 | Fs = 100e6; 8 | dt = 1/Fs; 9 | t_array = 0:dt:10*T; 10 | 11 | % define amplitude and phase 12 | amp = getWin(9, 'Gaussian'); 13 | phase = linspace(0, 2*pi, 9).'; 14 | signal = createCWSignals(t_array, f, amp, phase); 15 | 16 | recorder.recordVariable('t_array', t_array); 17 | recorder.recordVariable('f', f); 18 | recorder.recordVariable('amp', amp); 19 | recorder.recordVariable('phase', phase); 20 | recorder.recordVariable('signal', signal); 21 | 22 | recorder.saveRecordsToDisk(); 23 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_expandMatrix.m: -------------------------------------------------------------------------------- 1 | dims = [1, 2, 3]; 2 | 3 | 4 | idx = 0; 5 | 6 | for dim = dims 7 | if dim == 1 8 | matrices = {rand(30, 1), rand(4, 1)}; 9 | exp_coeffs = {[20, 3], [3, 0], [0, 2]}; 10 | is_edge_val = {false, true}; 11 | edge_vals = {0, 10}; 12 | elseif dim == 2 13 | matrices = {rand(30, 10), rand(8, 5)}; 14 | exp_coeffs = {[20, 3, 0, 4], [3, 4, 1, 2]}; 15 | is_edge_val = {true, true}; 16 | edge_vals = {3, 5}; 17 | elseif dim == 3 18 | matrices = {rand(30, 10, 8), rand(4, 5, 6)}; 19 | exp_coeffs = {[20, 3, 0, 4, 2, 1], [3, 4, 1, 0, 12, 0]}; 20 | is_edge_val = {true, false}; 21 | edge_vals = {30, 0}; 22 | end 23 | 24 | for i=1:length(matrices) 25 | for j=1:length(exp_coeffs) 26 | for k=1:length(is_edge_val) 27 | 28 | matrix = matrices{i}; 29 | exp_coeff = exp_coeffs{j}; 30 | 31 | input_args = { ... 32 | exp_coeff ... 33 | }; 34 | 35 | if is_edge_val{k} 36 | input_args{end+1} = edge_vals{k}; 37 | end 38 | 39 | expanded_matrix = expandMatrix(matrix, input_args{:}); 40 | 41 | disp(size(matrix)) 42 | disp(size(expanded_matrix)) 43 | 44 | idx_padded = sprintf('%06d', idx); 45 | filename = ['collectedValues/expandMatrix/' idx_padded '.mat']; 46 | save(filename, 'matrix', 'input_args', 'expanded_matrix'); 47 | 48 | idx = idx + 1; 49 | end 50 | end 51 | end 52 | end 53 | disp('Done.') 54 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_fourierShift.m: -------------------------------------------------------------------------------- 1 | 2 | % fourierShift does not support more than 4 dims 3 | dims = [1, 2, 3, 4]; 4 | data_dims = { ... 5 | [7,], ... # 1D 6 | [8, 2], ... # 2D 7 | [4, 8, 3], ... # 3D 8 | [5, 10, 5, 4] ... # 4D 9 | }; 10 | shifts = [0, 0.12, 0.29, 0.5, 0.52, 0.85, 1.0]; 11 | output_file = 'collectedValues/fourierShift.mat'; 12 | idx = 0; 13 | recorder = utils.TestRecorder(output_file); 14 | for data_dim_idx=1:size(dims, 2) 15 | data_dim = data_dims{data_dim_idx}; 16 | data = rand(data_dim); 17 | 18 | for shift=shifts 19 | shifted_data = fourierShift(data, shift); 20 | 21 | % Save output 22 | recorder.recordVariable('data', data); 23 | recorder.recordVariable('shift', shift); 24 | recorder.recordVariable('shifted_data', shifted_data); 25 | recorder.increment(); 26 | 27 | for shift_dim=1:size(data_dim, 2) 28 | shifted_data = fourierShift(data, shift, shift_dim); 29 | recorder.recordVariable('data', data); 30 | recorder.recordVariable('shift', shift); 31 | recorder.recordVariable('shift_dim', shift_dim); 32 | recorder.recordVariable('shifted_data', shifted_data); 33 | recorder.increment(); 34 | end 35 | 36 | end 37 | 38 | end 39 | 40 | recorder.saveRecordsToDisk(); 41 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_gaussian.m: -------------------------------------------------------------------------------- 1 | output_file = 'collectedValues/gaussian.mat'; 2 | recorder = utils.TestRecorder(output_file); 3 | 4 | 5 | x = (-3 : 0.05 : 3); 6 | 7 | y = gaussian(x); 8 | 9 | recorder.recordVariable('x', x); 10 | recorder.recordVariable('y', y); 11 | 12 | recorder.saveRecordsToDisk(); 13 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_gaussianFilter.m: -------------------------------------------------------------------------------- 1 | params = { ... 2 | [40e6, 5e6, 4, 50], ... 3 | [80e6, 20e6, 2, 80], ... 4 | [10e6, 0.5e6, 1, 100], ... 5 | }; 6 | 7 | recorder = utils.TestRecorder('collectedValues/gaussianFilter.mat'); 8 | for param_idx = 1:length(params) 9 | fs = params{param_idx}(1); 10 | fc = params{param_idx}(2); 11 | n_cycles = params{param_idx}(3); 12 | bw = params{param_idx}(4); 13 | input_signal = toneBurst(fs, fc, n_cycles); 14 | output_signal = gaussianFilter(input_signal, fs, fc, bw); 15 | recorder.recordVariable('input_signal', input_signal); 16 | recorder.recordVariable('output_signal', output_signal); 17 | recorder.recordVariable('fs', fs); 18 | recorder.recordVariable('fc', fc); 19 | recorder.recordVariable('bw', bw); 20 | recorder.increment(); 21 | end 22 | recorder.saveRecordsToDisk(); 23 | disp('Done.') 24 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_getAffineMatrix.m: -------------------------------------------------------------------------------- 1 | all_params = { ... 2 | {[20, 30], [5]}, ... 3 | {[-1.5, -12.3], [182]}, ... 4 | {[-1.5, -12.3], [0]}, ... 5 | {[0, 0, 0], [0, 0, 0]}, ... 6 | {[5, 5, 5], [0, 90, 180]}, ... 7 | {[50, 12, -5], [-13, 27, -180]}, ... 8 | }; 9 | 10 | output_file = 'collectedValues/getAffineMatrix.mat'; 11 | recorder = utils.TestRecorder(output_file); 12 | 13 | for idx=1:length(all_params) 14 | disp(idx); 15 | params = all_params{idx}; 16 | 17 | affine_matrix = getAffineMatrix(params{:}); 18 | 19 | recorder.recordVariable('params', params); 20 | recorder.recordVariable('affine_matrix', affine_matrix); 21 | recorder.increment(); 22 | 23 | end 24 | 25 | recorder.saveRecordsToDisk(); 26 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_getColorMap.m: -------------------------------------------------------------------------------- 1 | list_num_colors = [12, 36, 256]; 2 | output_file = 'collectedValues/getColorMap.mat'; 3 | 4 | recorder = utils.TestRecorder(output_file); 5 | 6 | for num_colors=list_num_colors 7 | color_map = getColorMap(num_colors); 8 | 9 | recorder.recordVariable('color_map', color_map); 10 | recorder.recordVariable('num_colors', num_colors); 11 | recorder.increment(); 12 | end 13 | recorder.saveRecordsToDisk(); 14 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_get_delta_BLI.m: -------------------------------------------------------------------------------- 1 | % adapted from getDelteaBLI_test_bli.m in k-wave toolbox v1.4.0 2 | 3 | output_file = 'collectedValues/getDeltaBLI.mat'; 4 | recorder = utils.TestRecorder(output_file); 5 | % set the number of upsampled points 6 | NN = 10002; 7 | 8 | % include the imaginary component of the off-grid delta function 9 | include_imag = true; 10 | 11 | % run test for both even and odd off-grid deltas 12 | for loop_index = 1:2 13 | 14 | % specify the computational grid 15 | Nx = 30 + loop_index; 16 | dx = 2/Nx; 17 | x_grid = linspace(-1, 1, Nx+1); 18 | x_grid = x_grid(1:end-1); 19 | 20 | % create a list of delta function positions 21 | positions = linspace(0, dx, 7); 22 | 23 | % loop through positions 24 | for position_index = 1:length(positions) 25 | position = positions(position_index); 26 | f_grid = getDeltaBLI(Nx, dx, x_grid, position, include_imag); 27 | recorder.recordVariable('Nx', Nx); 28 | recorder.recordVariable('dx', dx); 29 | recorder.recordVariable('x_grid', x_grid); 30 | recorder.recordVariable('position', position); 31 | recorder.recordVariable('include_imag', include_imag); 32 | recorder.recordVariable('f_grid', f_grid); 33 | recorder.increment(); 34 | end 35 | end 36 | recorder.saveRecordsToDisk(); 37 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_gradientSpect.m: -------------------------------------------------------------------------------- 1 | output_file = 'collectedValues/gradientSpect.mat'; 2 | recorder = utils.TestRecorder(output_file); 3 | 4 | x = (pi / 20 : pi / 20 : 4 * pi); 5 | y = (pi / 20 : pi / 20 : 4 * pi); 6 | 7 | [X, Y] = meshgrid(x, y); 8 | 9 | z = sin(X) * sin(Y); 10 | 11 | [dy, dx] = gradientSpect(z, [pi/20 pi/20]); 12 | 13 | recorder.recordVariable('X', X); 14 | recorder.recordVariable('Y', Y); 15 | recorder.recordVariable('z', z); 16 | recorder.recordVariable('dy', dy); 17 | recorder.recordVariable('dx', dx); 18 | 19 | recorder.saveRecordsToDisk(); 20 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_hounsfield2density.m: -------------------------------------------------------------------------------- 1 | output_file = 'collectedValues/hounsfield2density.mat'; 2 | recorder = utils.TestRecorder(output_file); 3 | 4 | p = phantom('Modified Shepp-Logan',200); 5 | out = hounsfield2density(p); 6 | recorder.recordVariable('out', out); 7 | recorder.recordVariable('p', p); 8 | 9 | recorder.saveRecordsToDisk(); -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_makeArc.m: -------------------------------------------------------------------------------- 1 | % makeArc([40, 40], [10, 10], 20, 39, [1, 30], 'Plot', true); 2 | % makeArc([40, 30], [10, 10], 20, 39, [1, 30], 'Plot', true); 3 | % makeArc([40, 30], [20, 15], 20, 39, [37, 12], 'Plot', true); 4 | % makeArc([40, 30], [20, 15], 20, 3, [37, 12], 'Plot', true); 5 | % makeArc([40, 30], [20, 15], 21, 21, [24, 24], 'Plot', true); 6 | 7 | 8 | all_params = { ... 9 | {[40, 40], [10, 10], 20, 39, [1, 30]}, ... 10 | {[40, 30], [10, 10], 20, 39, [1, 30]}, ... 11 | {[40, 30], [20, 15], 20, 39, [37, 12]}, ... 12 | {[40, 30], [20, 15], 20, 3, [37, 12]}, ... 13 | {[40, 30], [20, 15], 21, 21, [24, 24]}, ... 14 | {[40, 40], [10, 10], inf, 39, [1, 30]}, ... 15 | {[40, 30], [10, 10], inf, 39, [1, 30]}, ... 16 | {[40, 30], [20, 15], inf, 39, [37, 12]}, ... 17 | {[40, 30], [20, 15], inf, 3, [37, 12]}, ... 18 | {[40, 30], [20, 15], inf, 21, [24, 24]}, ... 19 | }; 20 | 21 | recorder = utils.TestRecorder('collectedValues/makeArc.mat'); 22 | for idx=1:length(all_params) 23 | disp(idx); 24 | 25 | params = all_params{idx}; 26 | 27 | recorder.recordVariable('params', params); 28 | 29 | arc = makeArc(params{:}); 30 | 31 | recorder.recordVariable('arc', arc); 32 | 33 | recorder.increment() 34 | end 35 | 36 | recorder.saveRecordsToDisk(); -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_makeBall.m: -------------------------------------------------------------------------------- 1 | all_params = { ... 2 | {20, 20, 20, 10, 10, 10, 5, false, false}, ... 3 | {20, 20, 20, 10, 10, 10, 5, false, true}, ... 4 | {20, 20, 20, 10, 10, 10, 5, false, false}, ... 5 | {40, 20, 15, 10, 15, 12, 2, false, false}, ... 6 | {40, 50, 60, 27, 33, 20, 13, false, true}, ... 7 | }; 8 | 9 | recorder = utils.TestRecorder('collectedValues/makeBall.mat'); 10 | 11 | for idx=1:length(all_params) 12 | disp(idx); 13 | params = all_params{idx}; 14 | 15 | ball = makeBall(params{:}); 16 | 17 | recorder.recordVariable('ball', ball); 18 | recorder.recordVariable('params', params); 19 | recorder.increment() 20 | 21 | end 22 | 23 | recorder.saveRecordsToDisk(); -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_makeBowl.m: -------------------------------------------------------------------------------- 1 | all_params = { ... 2 | {[40, 40, 40], [20, 20, 20], 5, 7, [23, 23, 23], 'Binary', false, 'RemoveOverlap', false}, ... 3 | {[40, 40, 40], [20, 20, 20], 5, 7, [23, 23, 23], 'Binary', true, 'RemoveOverlap', false}, ... 4 | {[40, 40, 40], [20, 20, 20], inf, 7, [23, 23, 23], 'Binary', true, 'RemoveOverlap', false}, ... 5 | {[40, 40, 40], [20, 20, 20], inf, 7, [23, 23, 23], 'Binary', true, 'RemoveOverlap', true}, ... 6 | {[40, 40, 40], [30, 35, 38], 3, 5, [17, 18, 5], 'Binary', false, 'RemoveOverlap', true}, ... 7 | {[40, 40, 40], [32, 35, 38], 10, 11, [17, 18, 5], 'Binary', false, 'RemoveOverlap', true}, ... 8 | {[40, 40, 40], [5, 35, 38], 10, 11, [17, 18, 5], 'Binary', false, 'RemoveOverlap', true}, ... 9 | {[40, 40, 40], [32, 2, 3], 10, 11, [17, 18, 5], 'Binary', false, 'RemoveOverlap', true}, ... 10 | }; 11 | 12 | recorder = utils.TestRecorder('collectedValues/makeBowl.mat'); 13 | for idx=1:length(all_params) 14 | disp(idx); 15 | params = all_params{idx}; 16 | 17 | bowl = makeBowl(params{:}); 18 | 19 | recorder.recordVariable('bowl', bowl); 20 | recorder.recordVariable('params', params); 21 | recorder.increment() 22 | end 23 | recorder.saveRecordsToDisk(); 24 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_makeCartArc.m: -------------------------------------------------------------------------------- 1 | % radius, num_points, center_pos 2 | all_params = { 3 | {[0,0], 5.0, 7.0, [2,5], 50}, ... 4 | {[2,2], 5.0, 7.0, [8,5], 5}, ... 5 | {[2,9], 8.0, 13.0, [8,5], 5} 6 | }; 7 | output_file = 'collectedValues/make_cart_arc.mat'; 8 | 9 | recorder = utils.TestRecorder(output_file); 10 | 11 | for idx=1:length(all_params) 12 | 13 | params = all_params{idx}; 14 | cart_arc = makeCartArc(params{1}, params{2}, params{3}, params{4}, params{5}); 15 | 16 | recorder.recordVariable('params', params); 17 | recorder.recordVariable('cart_arc', cart_arc); 18 | 19 | recorder.increment(); 20 | 21 | end 22 | recorder.saveRecordsToDisk(); 23 | disp('Done.') 24 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_makeCartBowl.m: -------------------------------------------------------------------------------- 1 | all_params = { ... 2 | {[20, 20, 30], 1, 2, [70, 50, 20], 2, false}, ... 3 | {[20, 10, 30], 2, 3, [30, 50, 10], 3, false}, ... 4 | {[20, 40, 30], 5, 3, [50, 20, 20], 1, false}, ... 5 | {[10, 20, 30], 2, 1, [40, 30, 20], 2, false}, ... 6 | }; 7 | 8 | output_file = 'collectedValues/makeCartBowl.mat'; 9 | recorder = utils.TestRecorder(output_file); 10 | 11 | for idx = 1:length(all_params) 12 | disp(idx); 13 | params = all_params{idx}; 14 | 15 | coordinates = makeCartBowl(params{:}); 16 | 17 | recorder.recordVariable('params', params); 18 | recorder.recordVariable('coordinates', coordinates); 19 | recorder.increment(); 20 | end 21 | 22 | recorder.saveRecordsToDisk(); 23 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_makeCartCircle.m: -------------------------------------------------------------------------------- 1 | % radius, num_points, center_pos 2 | all_params = { 3 | {5, 100, [1,1], 2*pi}, ... 4 | {1, 10, [5,5], pi/4}, ... 5 | {0.5, 10, [0,0], 2*pi}, ... 6 | {0.05, 20, [0 0]} 7 | }; 8 | output_file = 'collectedValues/makeCartCircle.mat'; 9 | recorder = utils.TestRecorder(output_file); 10 | 11 | for idx=1:length(all_params) 12 | params = all_params{idx}; 13 | if length(all_params{idx}) < 4 14 | circle = makeCartCircle(params{1}, params{2}, params{3}); 15 | params = {params{1}, params{2}, params{3}}; 16 | else 17 | circle = makeCartCircle(params{1}, params{2}, params{3}, params{4}); 18 | params = {params{1}, params{2}, params{3}, params{4}}; 19 | end 20 | recorder.recordVariable('params', params); 21 | recorder.recordVariable('circle', circle); 22 | recorder.increment() 23 | 24 | end 25 | recorder.saveRecordsToDisk(); 26 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_makeCartDisc.m: -------------------------------------------------------------------------------- 1 | all_params = { ... 2 | {[20, 20], 1, [70, 50], 2, false, false}, ... 3 | {[20, 10, 30], 2, [30, 50, 10], 3, false, false}, ... 4 | {[20, 40, 30], 5,[50, 20, 20], 1, false, false}, ... 5 | {[10, 20, 30], 2, [40, 30, 20], 2, false, true}, ... 6 | }; 7 | 8 | output_file = 'collectedValues/makeCartDisc.mat'; 9 | recorder = utils.TestRecorder(output_file); 10 | 11 | for idx = 1:length(all_params) 12 | disp(idx); 13 | params = all_params{idx}; 14 | 15 | coordinates = makeCartDisc(params{:}); 16 | 17 | recorder.recordVariable('params', params); 18 | recorder.recordVariable('coordinates', coordinates); 19 | recorder.increment(); 20 | end 21 | 22 | recorder.saveRecordsToDisk(); 23 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_makeCartRect.m: -------------------------------------------------------------------------------- 1 | % rect_pos, Lx, Ly, theta, num_points, plot_rect 2 | all_params = { ... 3 | {[20, 20, 30], 10, 10, [70, 50, 20], 500, false}, ... 4 | {[20, 70], 10, 10, -15, 500, false}, ... 5 | {[-20, -30], 15, 30, -5.3, 72, false}, ... 6 | {[-20, -30], 15, 30, -5.3, 72, false}, ... 7 | }; 8 | output_file = 'collectedValues/makeCartRect.mat'; 9 | recorder = utils.TestRecorder(output_file); 10 | 11 | for idx=1:length(all_params) 12 | disp(idx); 13 | params = all_params{idx}; 14 | 15 | coordinates = makeCartRect(params{:}); 16 | 17 | recorder.recordVariable('params', params); 18 | recorder.recordVariable('coordinates', coordinates); 19 | recorder.increment(); 20 | end 21 | recorder.saveRecordsToDisk(); 22 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_makeCartSphere.m: -------------------------------------------------------------------------------- 1 | % radius, num_points, center_pos 2 | all_params = { 3 | {5, 100, [1,1,8]}, ... 4 | {1, 10, [5,5,0]}, ... 5 | {0.5, 10, [0,0,0]}, ... 6 | {4e-3, 100, [0, 0, 0]} % Case from interpCartData 7 | }; 8 | output_file = 'collectedValues/make_cart_sphere.mat'; 9 | 10 | recorder = utils.TestRecorder(output_file); 11 | 12 | for idx=1:length(all_params) 13 | params = all_params{idx}; 14 | cart_sphere = makeCartSphere(params{1}, params{2}, params{3}); 15 | 16 | recorder.recordVariable('params', params); 17 | recorder.recordVariable('cart_sphere', cart_sphere); 18 | 19 | recorder.increment(); 20 | end 21 | recorder.saveRecordsToDisk(); 22 | disp('Done.') 23 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_makeCartSphericalSegment.m: -------------------------------------------------------------------------------- 1 | all_params = make_params(); 2 | 3 | 4 | 5 | output_file = 'collectedValues/makeCartSphericalSegment.mat'; 6 | recorder = utils.TestRecorder(output_file); 7 | 8 | for idx = 1:length(all_params) 9 | disp(idx); 10 | params = all_params{idx}; 11 | 12 | coordinates = makeCartSphericalSegment(params{:}); 13 | 14 | recorder.recordVariable('params', params); 15 | recorder.recordVariable('coordinates', coordinates); 16 | recorder.increment(); 17 | end 18 | 19 | recorder.saveRecordsToDisk(); 20 | 21 | function all_params = make_params() 22 | %% parameters taken from k-wave testing 23 | bowl_pos = [0.5, 0.5, 0.5]; 24 | focus_pos = [0.5, 0.5, 1.5]; 25 | num_points_vec = [69, 70, 200, 1000]; 26 | radius = 65e-3; 27 | ap_diam1 = 30e-3; 28 | ap_diam2 = 45e-3; 29 | ap_diam3 = 60e-3; 30 | 31 | % find position where to split the bowl 32 | bowl_height1 = radius - sqrt(radius^2 - (ap_diam1/2)^2); 33 | bowl_height2 = radius - sqrt(radius^2 - (ap_diam2/2)^2); 34 | all_params = {}; 35 | % loop over some different numbers of points 36 | for points_ind = 1:length(num_points_vec) 37 | 38 | num_points = num_points_vec(points_ind); 39 | 40 | % make regular bowl 41 | bowl_points = makeCartBowl(bowl_pos, radius, ap_diam3, focus_pos, num_points); 42 | 43 | % split array 44 | bowl_points_ann1 = bowl_points(:, bowl_points(3, :) <= bowl_height1); 45 | bowl_points_ann2 = bowl_points(:, (bowl_points(3, :) <= bowl_height2) & (bowl_points(3, :) > bowl_height1)); 46 | bowl_points_ann3 = bowl_points(:, bowl_points(3, :) > bowl_height2); 47 | 48 | % count points 49 | num_points_ann1 = size(bowl_points_ann1, 2); 50 | num_points_ann2 = size(bowl_points_ann2, 2); 51 | num_points_ann3 = size(bowl_points_ann3, 2); 52 | 53 | % (bowl_pos, radius, inner_diameter, outer_diameter, focus_pos, num_points, plot_bowl, num_points_inner 54 | 55 | all_params{end+1} = {bowl_pos, radius, 0, ap_diam1, focus_pos, num_points_ann1, false, 0}; 56 | all_params{end+1} = {bowl_pos, radius, ap_diam1, ap_diam2, focus_pos, num_points_ann2, [], num_points_ann1}; 57 | all_params{end+1} = {bowl_pos, radius, ap_diam2, ap_diam3, focus_pos, num_points_ann3, [], num_points_ann1 + num_points_ann2}; 58 | 59 | end 60 | end -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_makeCircle.m: -------------------------------------------------------------------------------- 1 | params = { ... 2 | [20, 20, 5, 5, 2, 2*pi], ... 3 | [100, 40, 15, 8, 4, 2*pi], ... 4 | [50, 50, 25, 25, 10, 2*pi], ... 5 | [50, 50, 25, 25, 10, pi], ... 6 | [50, 50, 25, 25, 10, 0.75 * pi], ... 7 | [10, 8, 3, 4, 10, 0.1 * pi], ... 8 | [20, 20, 0, 5, 2, 2*pi], ... 9 | [20, 20, 5, 0, 2, 2*pi], ... 10 | [20.3, 19.7, 5, 4, 2, 2*pi], ... 11 | }; 12 | 13 | recorder = utils.TestRecorder('collectedValues/makeCircle.mat'); 14 | 15 | for idx=1:length(params) 16 | disp(idx); 17 | param = params{idx}; 18 | 19 | Nx = param(1); 20 | Ny = param(2); 21 | cx = param(3); 22 | cy = param(4); 23 | radius = param(5); 24 | arc_angle = param(6); 25 | recorder.recordVariable('param', param); 26 | circle = makeCircle(Nx, Ny, cx, cy, radius, arc_angle); 27 | recorder.recordVariable('circle', circle); 28 | recorder.increment() 29 | 30 | end 31 | recorder.saveRecordsToDisk(); 32 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_makeDisc.m: -------------------------------------------------------------------------------- 1 | all_params = { ... 2 | {20, 20, 10, 10, 5, false}, ... 3 | {20, 20, 10, 10, 5, false}, ... 4 | {20, 20, 10, 10, 5, false}, ... 5 | {40, 20, 10, 15, 2, false}, ... 6 | {17, 33, 8, 9, 7, false}, ... 7 | {17, 38, 5, 12, 4, false}, ... 8 | }; 9 | 10 | recorder = utils.TestRecorder('collectedValues/makeDisc.mat'); 11 | for idx=1:length(all_params) 12 | disp(idx); 13 | params = all_params{idx}; 14 | 15 | recorder.recordVariable('params', params); 16 | 17 | disc = makeDisc(params{:}); 18 | recorder.recordVariable('disc', disc); 19 | recorder.increment(); 20 | 21 | end 22 | recorder.saveRecordsToDisk(); -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_makeLine.m: -------------------------------------------------------------------------------- 1 | 2 | all_params = { ... 3 | {20, 20, [1, 1], [19, 19]}, ... 4 | {20, 20, [1, 1], [5, 5]}, ... 5 | {10, 20, [4, 15], [10, 1]}, ... 6 | {20, 20, [15, 15], 0.75 * pi, 5}, ... 7 | {20, 20, [15, 15], 0.75 * pi, -5}, ... 8 | {20, 10, [15, 10], 0.1 * pi, 5}, ... 9 | }; 10 | 11 | % 12 | 13 | for idx=1:length(all_params) 14 | disp(idx); 15 | params = all_params{idx}; 16 | 17 | if idx == 4 18 | disp('aaa'); 19 | end 20 | 21 | line = makeLine(params{:}); 22 | 23 | idx_padded = sprintf('%06d', idx - 1); 24 | filename = ['collectedValues/makeLine/' idx_padded '.mat']; 25 | save(filename, 'params', 'line'); 26 | end 27 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_makeMultiArc.m: -------------------------------------------------------------------------------- 1 | all_params = { ... 2 | { ... 3 | [40, 30], ... 4 | [[10, 10]; [20, 15]; [15, 17]; [37, 2]; [1, 27]], ... 5 | [20, 21, inf, 9, 5], ... 6 | [39, 3, 21, 13, 1], ... 7 | [[1, 30]; [37, 12]; [24, 24]; [5, 17]; [8, 8]], ... 8 | } ... 9 | }; 10 | 11 | for idx=1:length(all_params) 12 | disp(idx); 13 | params = all_params{idx}; 14 | 15 | multi_arc = makeMultiArc(params{:}); 16 | 17 | idx_padded = sprintf('%06d', idx - 1); 18 | filename = ['collectedValues/makeMultiArc/' idx_padded '.mat']; 19 | save(filename, 'params', 'multi_arc'); 20 | end 21 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_makeMultiBowl.m: -------------------------------------------------------------------------------- 1 | all_params = { ... 2 | { ... 3 | [40, 40, 40], ... 4 | [[20, 20, 20]; [10, 15, 20]; [8, 13, 27]; [5, 35, 38]; [32, 2, 3]], ... 5 | [5, inf, 30, 10, 10], ... 6 | [7, 7, 13, 11, 11], ... 7 | [[23, 23, 23]; [23, 23, 23]; [17, 18, 5]; [17, 18, 5]; [17, 18, 5]], ... 8 | 'Binary', false, ... 9 | 'RemoveOverlap', false, ... 10 | }, ... 11 | }; 12 | 13 | for idx=1:length(all_params) 14 | disp(idx); 15 | params = all_params{idx}; 16 | 17 | multiBowl = makeMultiBowl(params{:}); 18 | 19 | idx_padded = sprintf('%06d', idx - 1); 20 | filename = ['collectedValues/makeMultiBowl/' idx_padded '.mat']; 21 | save(filename, 'params', 'multiBowl'); 22 | end 23 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_makeSphere.m: -------------------------------------------------------------------------------- 1 | all_params = { ... 2 | {40, 30, 36, 10, false, false}, ... 3 | {17, 23, 10, 4, false, false}, ... 4 | {3, 4, 5, 1, false, true}, ... 5 | }; 6 | output_file = 'collectedValues/makeSphere.mat'; 7 | 8 | recorder = utils.TestRecorder(output_file); 9 | 10 | for idx=1:length(all_params) 11 | disp(idx); 12 | params = all_params{idx}; 13 | 14 | sphere = makeSphere(params{:}); 15 | 16 | recorder.recordVariable('params', params); 17 | recorder.recordVariable('sphere', sphere); 18 | recorder.increment(); 19 | 20 | end 21 | recorder.saveRecordsToDisk(); 22 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_makeSphericalSection.m: -------------------------------------------------------------------------------- 1 | all_params = { ... 2 | {36, 13}, ... 3 | {36, 13, 21, false, true}, ... 4 | {28, 13, 5, false, false}, ... 5 | }; 6 | output_folder = 'collectedValues/makeSphericalSection/'; 7 | 8 | for idx=1:length(all_params) 9 | disp(idx); 10 | params = all_params{idx}; 11 | 12 | [spherical_section, distance_map] = makeSphericalSection(params{:}); 13 | 14 | idx_padded = sprintf('%06d', idx - 1); 15 | if ~exist(output_folder, 'dir') 16 | mkdir(output_folder); 17 | end 18 | filename = [output_folder idx_padded '.mat']; 19 | save(filename, 'params', 'spherical_section', 'distance_map'); 20 | end 21 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_maxND.m: -------------------------------------------------------------------------------- 1 | matrix_sizes = { ... 2 | [12, 7], ... 3 | [12, 7, 5], ... 4 | [2, 8, 56], ... 5 | [5, 10, 10], ... 6 | [8, 3, 6, 9, 5], ... 7 | }; 8 | 9 | % 10 | recorder = utils.TestRecorder('collectedValues/maxND.mat'); 11 | for idx=1:length(matrix_sizes) 12 | matrix_size = matrix_sizes{idx}; 13 | matrix = rand(matrix_size); 14 | 15 | [max_val, ind] = maxND(matrix); 16 | 17 | recorder.recordVariable('matrix', matrix); 18 | recorder.recordVariable('max_val', max_val); 19 | recorder.recordVariable('ind', ind); 20 | recorder.increment(); 21 | 22 | end 23 | 24 | recorder.saveRecordsToDisk(); 25 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_minND.m: -------------------------------------------------------------------------------- 1 | matrix_sizes = { ... 2 | [12, 7], ... 3 | [12, 7, 5], ... 4 | [1], ... 5 | [5], ... 6 | [8, 3, 6, 1, 5], ... 7 | }; 8 | 9 | % 10 | output_file = 'collectedValues/minND.mat'; 11 | recorder = utils.TestRecorder(output_file); 12 | 13 | for idx=1:length(matrix_sizes) 14 | matrix_size = matrix_sizes{idx}; 15 | matrix = rand(matrix_size); 16 | 17 | [min_val, ind] = minND(matrix); 18 | 19 | recorder.recordVariable('matrix', matrix); 20 | recorder.recordVariable('min_val', min_val); 21 | recorder.recordVariable('ind', ind); 22 | recorder.increment(); 23 | end 24 | recorder.saveRecordsToDisk(); 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_normvar.m: -------------------------------------------------------------------------------- 1 | output_file = 'collectedValues/normvar.mat'; 2 | recorder = utils.TestRecorder(output_file); 3 | 4 | img2 = rand([5,5]); 5 | out2 = sharpness(img2, 'NormVariance'); 6 | recorder.recordVariable('img2', img2); 7 | recorder.recordVariable('out2', out2); 8 | 9 | img3 = rand([5,5,5]); 10 | out3 = sharpness(img3, 'NormVariance'); 11 | recorder.recordVariable('img3', img3); 12 | recorder.recordVariable('out3', out3); 13 | recorder.saveRecordsToDisk(); 14 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_reorderBinarySensorData.m: -------------------------------------------------------------------------------- 1 | sensor_data_size = [32, 4]; 2 | 3 | sensor_data = rand(sensor_data_size); 4 | reorder_index = rand(sensor_data_size(1), 1); 5 | 6 | reordered_data = reorderBinarySensorData(sensor_data, reorder_index); 7 | 8 | 9 | idx = 0; 10 | idx_padded = sprintf('%06d', idx); 11 | filename = ['collectedValues/reorderBinarySensorData/' idx_padded '.mat']; 12 | save(filename, 'sensor_data', 'reorder_index', 'reordered_data'); 13 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_reorderSensorData.m: -------------------------------------------------------------------------------- 1 | mask_size = [16, 23]; 2 | kgrid_size = [16, 23]; 3 | kgrid_dx_dy = 0.1; 4 | sensor_data_size = [32, 4]; 5 | 6 | mask = zeros(mask_size(1), mask_size(2)); 7 | 8 | for i=1:20 9 | mask(randi(mask_size(1)), randi(mask_size(2))) = 1; 10 | end 11 | sensor = struct('mask', mask); 12 | sensor_data = rand(sensor_data_size); 13 | kgrid = kWaveGrid(kgrid_size(1), kgrid_dx_dy, kgrid_size(2), kgrid_dx_dy); 14 | reordered_sensor_data = reorderSensorData(kgrid, sensor, sensor_data); 15 | 16 | idx = 0; 17 | idx_padded = sprintf('%06d', idx); 18 | filename = ['collectedValues/reorderSensorData/' idx_padded '.mat']; 19 | save(filename, 'mask_size', 'kgrid_size', 'kgrid_dx_dy', ... 20 | 'sensor_data_size', 'mask', 'sensor_data', 'reordered_sensor_data'); 21 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_resize.m: -------------------------------------------------------------------------------- 1 | % Generate a list of interpolation methods 2 | 3 | output_file = 'collectedValues/resize.mat'; 4 | recorder = utils.TestRecorder(output_file); 5 | 6 | interp_methods = {'nearest', 'linear'}; 7 | 8 | % Generate a random 3D volume with dimensions Nx x Ny x Nz 9 | sizes = [32, 32, 32; 48, 48, 48; 56, 56, 56]; 10 | new_sizes = [16, 16, 16; 32, 32, 32; 48, 48, 48]; 11 | 12 | 13 | for i = length(sizes) 14 | new_size = new_sizes(i,:); 15 | volume = rand(sizes(i,:)); 16 | % Loop through each interpolation method 17 | for method = interp_methods 18 | % Use the current interpolation method to resize the volume 19 | resized_volume = resize(volume, new_size, char(method)); 20 | 21 | recorder.recordVariable('volume', volume); 22 | recorder.recordVariable('resized_volume', resized_volume); 23 | recorder.recordVariable('new_size', new_size); 24 | recorder.recordVariable('method', method) 25 | recorder.increment(); 26 | 27 | end 28 | end 29 | recorder.saveRecordsToDisk(); 30 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_revolve2D.m: -------------------------------------------------------------------------------- 1 | all_params = { ... 2 | {rand(4)}, ... 3 | {rand(8)}, ... 4 | {rand(7, 12)}, ... 5 | {rand(8, 6)}, ... 6 | }; 7 | output_folder = 'collectedValues/revolve2D/'; 8 | 9 | for idx=1:length(all_params) 10 | disp(idx); 11 | params = all_params{idx}; 12 | 13 | mat3D = revolve2D(params{:}); 14 | 15 | idx_padded = sprintf('%06d', idx - 1); 16 | if ~exist(output_folder, 'dir') 17 | mkdir(output_folder); 18 | end 19 | filename = [output_folder idx_padded '.mat']; 20 | save(filename, 'params', 'mat3D'); 21 | end 22 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_rotation_matrices.m: -------------------------------------------------------------------------------- 1 | function collect_rotation_matrices() 2 | % Test angles 3 | angles = [-180, -90, -45, 0, 45, 90, 180]; 4 | 5 | output_file = 'collectedValues/rotation_matrices.mat'; 6 | recorder = utils.TestRecorder(output_file); 7 | 8 | % Test all angles 9 | for i = 1:length(angles) 10 | theta = angles(i); 11 | 12 | % Record angle and matrices 13 | recorder.recordVariable('theta', theta); 14 | recorder.recordVariable('Rx_matrix', Rx(theta)); 15 | recorder.recordVariable('Ry_matrix', Ry(theta)); 16 | recorder.recordVariable('Rz_matrix', Rz(theta)); 17 | recorder.increment(); 18 | end 19 | 20 | recorder.saveRecordsToDisk(); 21 | end 22 | 23 | % generate 3D rotation matrices 24 | function R = Rx(theta) 25 | R = [1, 0, 0; 0, cosd(theta), -sind(theta); 0, sind(theta), cosd(theta)]; 26 | end 27 | 28 | function R = Ry(theta) 29 | R = [cosd(theta), 0, sind(theta); 0, 1, 0; -sind(theta), 0, cosd(theta)]; 30 | end 31 | 32 | function R = Rz(theta) 33 | R = [cosd(theta), -sind(theta), 0; sind(theta), cosd(theta), 0; 0, 0, 1]; 34 | end -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_scaleSI.m: -------------------------------------------------------------------------------- 1 | list_of_x = { ... 2 | [20, 30, 12], .... % should take the max 3 | -5, ... 4 | -0.3, ... 5 | 0, ... 6 | 1e-3, 3e-5, 6e-9, 2e-12, 2e-18, 2e-21, 2e-23, 2e-25, 3e-29, ... 7 | 1e4, 3e7, 6e9, 2e12, 2e18, 2e21, 2e23, 2e25, 3e29, 4e32, ... 8 | }; 9 | 10 | 11 | idx = 0; 12 | 13 | for i=1:length(list_of_x) 14 | x = list_of_x{i}; 15 | 16 | [x_sc, scale, prefix, prefix_fullname] = scaleSI(x); 17 | 18 | 19 | idx_padded = sprintf('%06d', idx); 20 | filename = ['collectedValues/scaleSI/' idx_padded '.mat']; 21 | save(filename, 'x', 'x_sc', 'scale', 'prefix', 'prefix_fullname'); 22 | 23 | idx = idx + 1; 24 | end 25 | disp('Done.') 26 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_scaleTime.m: -------------------------------------------------------------------------------- 1 | list_of_seconds = { ... 2 | 10, 300, 5000, 12000, ... 3 | 5^4, 12^10, 8.3^4, ... 4 | 0.23^8, ... 5 | -3, -3.5 ... 6 | }; 7 | 8 | 9 | idx = 0; 10 | 11 | for i=1:length(list_of_seconds) 12 | seconds = list_of_seconds{i}; 13 | 14 | time = scaleTime(seconds); 15 | 16 | 17 | idx_padded = sprintf('%06d', idx); 18 | filename = ['collectedValues/scaleTime/' idx_padded '.mat']; 19 | save(filename, 'seconds', 'time'); 20 | 21 | idx = idx + 1; 22 | end 23 | disp('Done.') 24 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_scanConversion.m: -------------------------------------------------------------------------------- 1 | scan_lines = rand(5, 618); 2 | steering_angles = -4:2:4; 3 | image_size = [0.0500, 0.0522]; 4 | c0 = 1540; 5 | dt = 4.3098e-08; 6 | resolution = [128, 128]; 7 | 8 | recorder = utils.TestRecorder('collectedValues/scanConversion.mat'); 9 | 10 | recorder.recordVariable('scan_lines', scan_lines); 11 | recorder.recordVariable('steering_angles', steering_angles); 12 | recorder.recordVariable('image_size', image_size); 13 | recorder.recordVariable('c0', c0); 14 | recorder.recordVariable('dt', dt); 15 | recorder.recordVariable('resolution', resolution); 16 | 17 | 18 | b_mode = scanConversion(scan_lines, steering_angles, image_size, c0, dt, resolution); 19 | recorder.recordVariable('b_mode', b_mode); 20 | 21 | recorder.increment() 22 | 23 | recorder.saveRecordsToDisk(); 24 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_smooth.m: -------------------------------------------------------------------------------- 1 | output_file = 'collectedValues/smooth.mat'; 2 | recorder = utils.TestRecorder(output_file); 3 | 4 | img = rand([20, 20]); 5 | out = smooth(img); 6 | recorder.recordVariable('img', img); 7 | recorder.recordVariable('out', out); 8 | 9 | recorder.saveRecordsToDisk(); -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_tenenbaum.m: -------------------------------------------------------------------------------- 1 | output_file = 'collectedValues/tenenbaum.mat'; 2 | recorder = utils.TestRecorder(output_file); 3 | 4 | img2 = ones([5,5]); 5 | out2 = sharpness(img2, 'Tenenbaum'); 6 | recorder.recordVariable('img2', img2); 7 | recorder.recordVariable('out2', out2); 8 | 9 | 10 | img3 = ones([5,5,5]); 11 | out3 = sharpness(img3, 'Tenenbaum'); 12 | recorder.recordVariable('img3', img3); 13 | recorder.recordVariable('out3', out3); 14 | recorder.saveRecordsToDisk(); -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_tolStar.m: -------------------------------------------------------------------------------- 1 | % NOTE: it is very important to alternate kgrid.dim between each test case 2 | % because tolStar has internal state. We want tests to be independent 3 | % of each other. Alternating the kgrid.dim between test cases will 4 | % reset the state. 5 | params = { ... 6 | { 7 | 0.005, ... 8 | struct('dx', 0.5, 'dim', 3, 'x_vec', 0.5:0.5:50, 'y_vec', 0.5:0.5:50, 'z_vec', 0.5:0.5:50, 'Nx', 100, 'Ny', 100, 'Nz', 100), ... 9 | [25.0, 25, 25] ... 10 | }, ... 11 | { 12 | 0.01, ... 13 | struct('dx', 1.0, 'dim', 1, 'x_vec', 1:100, 'Nx', 100), ... 14 | [50.0, 129.0] ... 15 | }, ... 16 | { 17 | 0.01, ... 18 | struct('dx', 1.0, 'dim', 2, 'x_vec', 1:100, 'y_vec', 1:100, 'Nx', 100, 'Ny', 100), ... 19 | [50.0, 50.0] ... 20 | }, ... 21 | { 22 | 0.05, ... 23 | struct('dx', 1.0, 'dim', 1, 'x_vec', 1:5, 'Nx', 19), ... 24 | 12.0 ... 25 | }, ... 26 | { 27 | 0.01, ... 28 | struct('dx', 1.0, 'dim', 3, 'x_vec', 1:100, 'y_vec', 1:100, 'z_vec', 1:100, 'Nx', 100, 'Ny', 100, 'Nz', 100), ... 29 | [-5, 50.0, 50] ... 30 | }, ... 31 | { 32 | 0.005, ... 33 | struct('dx', 0.5, 'dim', 1, 'x_vec', 0.5:0.5:50, 'Nx', 100), ... 34 | 25.0 ... 35 | }, ... 36 | { 37 | 0.005, ... 38 | struct('dx', 0.5, 'dim', 2, 'x_vec', 0.5:0.5:50, 'y_vec', 0.5:0.5:50, 'Nx', 100, 'Ny', 100), ... 39 | [25.0, 25.0] ... 40 | }, ... 41 | { 42 | 0.005, ... 43 | struct('dx', 0.5, 'dim', 2, 'x_vec', 0.5:0.3:19, 'y_vec', 0.5:0.49:27, 'Nx', 12, 'Ny', 17), ... 44 | [-45.0, 12] ... 45 | }, ... 46 | }; 47 | 48 | output_file = 'collectedValues/tolStar.mat'; 49 | recorder = utils.TestRecorder(output_file); 50 | for param_idx = 1:length(params) 51 | 52 | [lin_ind, is, js, ks] = private_kwave_functions.tolStar(params{param_idx}{:}, false); 53 | 54 | recorder.recordVariable('params', params{param_idx}); 55 | recorder.recordVariable('lin_ind', lin_ind); 56 | recorder.recordVariable('is', is); 57 | recorder.recordVariable('js', js); 58 | recorder.recordVariable('ks', ks); 59 | recorder.increment(); 60 | 61 | end 62 | recorder.saveRecordsToDisk(); 63 | disp('Done.') 64 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_toneBurst.m: -------------------------------------------------------------------------------- 1 | params = { ... 2 | {40e6, 5e6, 4, 'Envelope','Gaussian'}, ... 3 | {80e6, 20e6, 2,'Envelope', 'Gaussian'}, ... 4 | {10e6, 0.5e6, 1, 'Envelope', 'Gaussian'}, ... 5 | {40e6, 5e6, 4, 'Envelope', 'Rectangular'}, ... 6 | {80e6, 20e6, 2, 'Envelope', 'Rectangular'}, ... 7 | {10e6, 0.5e6, 1, 'Envelope', 'Rectangular'}, ... 8 | {40e6, 5e6, 7, 'Envelope', [3, 2]}, ... 9 | {80e6, 20e6, 2, 'Envelope', 'Gaussian', 'SignalOffset', 200}, ... 10 | {10e6, 0.5e6, 200, 'Envelope', [40, 90], 'SignalLength', 8000} ... 11 | {10e6, 0.5e6, 200, 'Envelope', [40, 90], 'SignalLength', 8000, 'SignalOffset', 200}, ... 12 | {10e6, 0.5e6, 200, 'Envelope', [40, 90], 'SignalLength', 80, 'SignalOffset', 200} ... 13 | }; 14 | 15 | output_file = 'collectedValues/tone_burst.mat'; 16 | recorder = utils.TestRecorder(output_file); 17 | for param_idx = 1:length(params) 18 | 19 | input_signal = toneBurst(params{param_idx}{:}); 20 | 21 | recorder.recordVariable('params', params{param_idx}); 22 | recorder.recordVariable('input_signal', input_signal); 23 | recorder.increment(); 24 | 25 | end 26 | recorder.saveRecordsToDisk(); 27 | disp('Done.') 28 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_trimCartPoints.m: -------------------------------------------------------------------------------- 1 | % Define kgrids with different parameters 2 | kgrid1 = struct('x_vec', [1,2,3], 'y_vec', [1,2,3], 'z_vec', [1,2,3], 'dim', 1); 3 | kgrid2 = struct('x_vec', [1,2,3,4,5], 'y_vec', [1,2,3,4,5], 'z_vec', [1,2,3,4,5], 'dim', 2); 4 | kgrid3 = struct('x_vec', [1,2,3,4,5,6], 'y_vec', [1,2,3,4,5,6], 'z_vec', [1,2,3,4,5,6], 'dim', 3); 5 | 6 | % Define sets of points to trim 7 | pointsSet1 = [1,2,3,4,5,6; 1,2,3,4,5,6; 1,2,3,4,5,6]; % 3 rows of x,y,z values 8 | pointsSet2 = [1,2; 1,2; 1,2]; % 3 rows of x,y,z values with fewer columns 9 | pointsSet3 = [1,2,3,4; 1,2,3,4; 1,2,3,4]; % 3 rows of x,y,z values with different number of columns 10 | 11 | % Define kgrids and points arrays for looping 12 | kgrids = {kgrid1, kgrid2, kgrid3}; 13 | pointsSets = {pointsSet1, pointsSet2, pointsSet3}; 14 | 15 | output_file = 'collectedValues/trimCartPoints.mat'; 16 | recorder = utils.TestRecorder(output_file); 17 | 18 | recorder.recordVariable('kgrid1', kgrid1); 19 | recorder.recordVariable('kgrid2', kgrid1); 20 | recorder.recordVariable('kgrid3', kgrid1); 21 | 22 | recorder.recordVariable('pointsSet1', pointsSet1); 23 | recorder.recordVariable('pointsSet2', pointsSet1); 24 | recorder.recordVariable('pointsSet3', pointsSet1); 25 | 26 | recorder.increment(); 27 | 28 | % Loop over each combination of kgrid and points set 29 | for i = 1:length(kgrids) 30 | for j = 1:length(pointsSets) 31 | % Call the function with current parameters 32 | trimmed_points = trimCartPoints(kgrids{i}, pointsSets{j}); 33 | 34 | recorder.recordVariable('i', i); 35 | recorder.recordVariable('j', j); 36 | recorder.recordVariable('trimmed_points', trimmed_points); 37 | recorder.increment(); 38 | end 39 | end 40 | 41 | recorder.saveRecordsToDisk(); 42 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_unmaskSensorData.m: -------------------------------------------------------------------------------- 1 | dims = [1, 2, 3]; 2 | data_dims = { ... 3 | [12], ... 4 | [20, 40], ... 5 | [16, 24, 32], ... 6 | }; 7 | d_xyz = -1; % not important 8 | num_pts_per_dim = 9; 9 | output_folder = 'collectedValues/unmaskSensorData'; 10 | idx = 0; 11 | 12 | 13 | for dim=dims 14 | data_dim = data_dims{dim}; 15 | 16 | switch dim 17 | case 1 18 | kgrid = kWaveGrid( ... 19 | data_dim(1), d_xyz ... 20 | ); 21 | mask_points_x = uint8(utils.rand_vector_in_range(1, data_dim(1)-1, num_pts_per_dim)); 22 | 23 | sensor_mask = zeros(1, data_dim); 24 | sensor_mask(mask_points_x) = 1; 25 | case 2 26 | kgrid = kWaveGrid( ... 27 | data_dim(1), d_xyz, ... 28 | data_dim(2), d_xyz ... 29 | ); 30 | mask_points_x = uint8(utils.rand_vector_in_range(1, data_dim(1)-1, num_pts_per_dim)); 31 | mask_points_y = uint8(utils.rand_vector_in_range(1, data_dim(2)-1, num_pts_per_dim)); 32 | 33 | sensor_mask = zeros(data_dim); 34 | sensor_mask(mask_points_x, mask_points_y) = 1; 35 | case 3 36 | kgrid = kWaveGrid( ... 37 | data_dim(1), d_xyz, ... 38 | data_dim(2), d_xyz, ... 39 | data_dim(3), d_xyz ... 40 | ); 41 | mask_points_x = uint8(utils.rand_vector_in_range(1, data_dim(1)-1, num_pts_per_dim)); 42 | mask_points_y = uint8(utils.rand_vector_in_range(1, data_dim(2)-1, num_pts_per_dim)); 43 | mask_points_z = uint8(utils.rand_vector_in_range(1, data_dim(3)-1, num_pts_per_dim)); 44 | 45 | sensor_mask = zeros(data_dim); 46 | sensor_mask(mask_points_x, mask_points_y, mask_points_z) = 1; 47 | end 48 | 49 | sensor.mask = sensor_mask; 50 | num_ones_in_mask = sum(sensor_mask, 'all'); 51 | sensor_data = rand(1, num_ones_in_mask); 52 | 53 | unmasked_sensor_data = unmaskSensorData(kgrid, sensor, sensor_data); 54 | disp(size(unmasked_sensor_data)); 55 | 56 | % Save output 57 | idx_padded = sprintf('%06d', idx); 58 | filename = [output_folder '/' idx_padded '.mat']; 59 | save(filename, 'data_dim', 'sensor_mask', ... 60 | 'sensor_data', 'unmasked_sensor_data'); 61 | idx = idx + 1; 62 | 63 | end 64 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_writeAttributes.m: -------------------------------------------------------------------------------- 1 | rel_path = "collectedValues/writeAttributes"; 2 | idx = 0; 3 | 4 | matrix_name = 'test'; 5 | filename = rel_path + "/" + num2str(idx) + ".h5"; 6 | matrix = single(10.0 * ones([1,1])); 7 | writeMatrix(filename,matrix, matrix_name); 8 | 9 | writeAttributes(filename) 10 | 11 | disp('Done.') 12 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_writeFlags.m: -------------------------------------------------------------------------------- 1 | rel_path = "collectedValues/writeFlags"; 2 | idx = 0; 3 | for dim=1:3 4 | filename = rel_path + "/" + num2str(idx) + ".h5"; 5 | grid_size = 10 * ones([3,1]); 6 | grid_spacing = 0.1 * ones([3,1]); 7 | pml_size = 2 * ones([3,1]); 8 | pml_alpha = 0.5 * ones([3,1]); 9 | 10 | writeGrid(filename,grid_size, grid_spacing, pml_size, pml_alpha, 5, 0.5, 1540) 11 | writeMatrix(filename,single([0]),'sensor_mask_index') 12 | writeFlags(filename) 13 | idx = idx + 1; 14 | end 15 | disp('Done.') 16 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_writeGrid.m: -------------------------------------------------------------------------------- 1 | rel_path = "collectedValues/writeGrid"; 2 | idx = 0; 3 | % TODO: assert the dimension number works correctly 4 | for dim=1:3 5 | filename = rel_path + "/" + num2str(idx) + ".h5"; 6 | grid_size = 10 * ones([3,1]); 7 | grid_spacing = 0.1 * ones([3,1]); 8 | pml_size = 2 * ones([3,1]); 9 | pml_alpha = 0.5 * ones([3,1]); 10 | 11 | writeGrid(filename,grid_size, grid_spacing, pml_size, pml_alpha, 5, 0.5, 1540) 12 | idx = idx + 1; 13 | end 14 | disp('Done.') 15 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/matlab_collectors/collect_writeMatrix.m: -------------------------------------------------------------------------------- 1 | rel_path = "collectedValues/writeMatrix"; 2 | idx = 0; 3 | for dim=1:3 4 | for compression_level=1:9 5 | matrix_name = 'test'; 6 | filename = rel_path + "/" + num2str(idx) + ".h5"; 7 | matrix = single(10.0 * ones([1,dim])); 8 | writeMatrix(filename,matrix, matrix_name,compression_level); 9 | idx = idx + 1; 10 | end 11 | end 12 | disp('Done.') 13 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waltsims/k-wave-python/51b2041523377c937f224c75cc771ec761ec975c/tests/matlab_test_data_collectors/python_testers/__init__.py -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/angularSpectrumCW_test.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pathlib import Path 3 | 4 | import numpy as np 5 | 6 | from kwave.utils.angular_spectrum_cw import angular_spectrum_cw 7 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 8 | 9 | 10 | def test_angular_spectrum_cw(): 11 | test_record_path = os.path.join(Path(__file__).parent, "collectedValues/angularSpectrumCW.mat") 12 | reader = TestRecordReader(test_record_path) 13 | 14 | input_plane = reader.expected_value_of("input_plane") 15 | dx = reader.expected_value_of("dx") 16 | z_pos = reader.expected_value_of("z_pos") 17 | f0 = reader.expected_value_of("f0") 18 | c0 = reader.expected_value_of("c0") 19 | grid_expansion = reader.expected_value_of("grid_expansion") 20 | 21 | expected_pressure = reader.expected_value_of("pressure") 22 | 23 | pressure = angular_spectrum_cw(input_plane, dx, z_pos, f0, c0, grid_expansion=grid_expansion) 24 | assert np.allclose(pressure.squeeze(), expected_pressure) 25 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/angularSpectrum_test.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pathlib import Path 3 | 4 | import numpy as np 5 | 6 | from kwave.utils.angular_spectrum import angular_spectrum 7 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 8 | 9 | 10 | def test_angular_spectrum(): 11 | test_record_path = os.path.join(Path(__file__).parent, "collectedValues/angularSpectrum.mat") 12 | reader = TestRecordReader(test_record_path) 13 | 14 | input_plane = reader.expected_value_of("input_plane") 15 | dx = reader.expected_value_of("dx") 16 | dt = reader.expected_value_of("dt") 17 | z_pos = reader.expected_value_of("z_pos") 18 | c0 = reader.expected_value_of("c0") 19 | grid_expansion = reader.expected_value_of("grid_expansion") 20 | 21 | expected_pressure_max = reader.expected_value_of("pressure_max") 22 | expected_pressure_time = reader.expected_value_of("pressure_time") 23 | 24 | pressure_max, pressure_time = angular_spectrum(input_plane, dx, dt, z_pos, c0, grid_expansion=grid_expansion, record_time_series=True) 25 | 26 | assert np.allclose(pressure_time.squeeze(), expected_pressure_time) 27 | assert np.allclose(pressure_max.squeeze(), expected_pressure_max) 28 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/attenComp_test.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pathlib import Path 3 | 4 | import numpy as np 5 | 6 | from kwave.utils.atten_comp import atten_comp 7 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 8 | 9 | 10 | def test_atten_comp(): 11 | test_record_path = os.path.join(Path(__file__).parent, "collectedValues/attenComp.mat") 12 | reader = TestRecordReader(test_record_path) 13 | 14 | inp_signal = reader.expected_value_of("inp_signal") 15 | dt = reader.expected_value_of("dt") 16 | c = reader.expected_value_of("c") 17 | alpha_0 = reader.expected_value_of("alpha_0") 18 | y = reader.expected_value_of("y") 19 | 20 | expected_out_signal = reader.expected_value_of("out_signal") 21 | expected_tfd = reader.expected_value_of("tfd") 22 | expected_cutoff_freq = reader.expected_value_of("cutoff_freq") 23 | fit_type = reader.expected_value_of("fit_type") 24 | 25 | out_signal, tfd, cutoff_freq = atten_comp(inp_signal, dt, c, alpha_0, y, fit_type=fit_type) 26 | 27 | assert np.allclose(out_signal, expected_out_signal) 28 | assert np.allclose(tfd, expected_tfd) 29 | assert np.allclose(cutoff_freq, expected_cutoff_freq) 30 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/cart2grid_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | import typing 4 | from pathlib import Path 5 | from unittest.mock import Mock 6 | 7 | import numpy as np 8 | 9 | from kwave.kgrid import kWaveGrid 10 | from kwave.utils.conversion import cart2grid 11 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 12 | 13 | 14 | class kGridMock(Mock): 15 | @property 16 | def __class__(self) -> type: 17 | return kWaveGrid 18 | 19 | def set_props(self, props): 20 | self.kprops = props 21 | 22 | def __getattr__(self, name: str) -> typing.Any: 23 | if name in self.kprops.keys(): 24 | return self.kprops[name] 25 | return super().__getattr__(name) 26 | 27 | 28 | def test_cart2grid(): 29 | collected_values_file = os.path.join(Path(__file__).parent, "collectedValues/cart2grid.mat") 30 | record_reader = TestRecordReader(collected_values_file) 31 | 32 | for i in range(len(record_reader)): 33 | # 'kgrid', 'cart_data', 'grid_data', ... 34 | # 'order_index', 'reorder_index' 35 | kgrid = kGridMock() 36 | kgrid_props = record_reader.expected_value_of("kgrid") 37 | kgrid.set_props(kgrid_props) 38 | 39 | cart_data = record_reader.expected_value_of("cart_data") 40 | if cart_data.ndim == 1: 41 | cart_data = np.expand_dims(cart_data, axis=0) 42 | expected_grid_data = record_reader.expected_value_of("grid_data") 43 | expected_order_index = record_reader.expected_value_of("order_index") 44 | expected_reorder_index = record_reader.expected_value_of("reorder_index") 45 | is_axisymmetric = bool(record_reader.expected_value_of("is_axisymmetric")) 46 | 47 | logging.log(logging.INFO, is_axisymmetric) 48 | 49 | if kgrid.dim == 3: 50 | expected_reorder_index = np.reshape(expected_reorder_index, (-1, 1, 1)) 51 | 52 | grid_data, order_index, reorder_index = cart2grid(kgrid, cart_data, axisymmetric=is_axisymmetric) 53 | 54 | assert len(expected_order_index) == len(order_index), f"Failed on example {i}" 55 | assert np.allclose(expected_order_index, order_index.squeeze()), f"Failed on example {i}" 56 | assert np.allclose(expected_reorder_index, reorder_index.squeeze()), f"Failed on example {i}" 57 | assert np.allclose(expected_grid_data, grid_data.squeeze()), f"Failed on example {i}" 58 | 59 | logging.log(logging.INFO, "cart2grid(..) works as expected!") 60 | 61 | 62 | if __name__ == "__main__": 63 | test_cart2grid() 64 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/computeLinearTransform_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | 7 | from kwave.utils.math import compute_rotation_between_vectors 8 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 9 | 10 | 11 | def test_compute_linear_transform(): 12 | test_record_path = os.path.join(Path(__file__).parent, "collectedValues/computeLinearTransform.mat") 13 | reader = TestRecordReader(test_record_path) 14 | 15 | for i in range(len(reader)): 16 | params = reader.expected_value_of("params") 17 | if len(params) == 2: 18 | pos1, pos2 = params 19 | pos1, pos2 = pos1.astype(float), pos2.astype(float) 20 | 21 | rot_mat, direction = compute_rotation_between_vectors(pos1, pos2) 22 | offset_pos = 0 23 | 24 | else: 25 | pos1, pos2, offset = params 26 | pos1, pos2, offset = pos1.astype(float), pos2.astype(float), float(offset) 27 | rot_mat, direction = compute_rotation_between_vectors(pos1, pos2) 28 | offset_pos = pos1 + offset * direction 29 | 30 | if not np.any(np.isnan(reader.expected_value_of("rotMat"))): 31 | assert np.allclose(rot_mat, reader.expected_value_of("rotMat")) 32 | assert np.allclose(offset_pos, reader.expected_value_of("offsetPos")) 33 | reader.increment() 34 | 35 | logging.log(logging.INFO, "compute_rotation_between_vectors(..) works as expected!") 36 | 37 | 38 | if __name__ == "__main__": 39 | test_compute_linear_transform() 40 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/create_cw_signals_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | 7 | from kwave.utils.signals import create_cw_signals 8 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 9 | 10 | 11 | def test_create_cw_signals(): 12 | test_record_path = os.path.join(Path(__file__).parent, Path("collectedValues/createCWSignals.mat")) 13 | reader = TestRecordReader(test_record_path) 14 | amp = reader.expected_value_of("amp") 15 | phase = reader.expected_value_of("phase") 16 | f = reader.expected_value_of("f") 17 | t_array = reader.expected_value_of("t_array") 18 | signal_prime = reader.expected_value_of("signal") 19 | 20 | signal = create_cw_signals(t_array=t_array, amp=amp, phase=phase, freq=f) 21 | 22 | # compare signal and signal_prime element-wise 23 | difference = signal - signal_prime 24 | tolerance = 1e-6 25 | is_close = np.allclose(signal, signal_prime, atol=tolerance, rtol=tolerance) 26 | 27 | if not is_close: 28 | logging.log(logging.INFO, "signal and signal_prime are not equal") 29 | logging.log(logging.INFO, "difference =", difference) 30 | else: 31 | logging.log(logging.INFO, "signal and signal_prime are equal within the specified tolerance") 32 | assert is_close, "signal did not match expected signal" 33 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/expandMatrix_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | from scipy.io import loadmat 7 | 8 | from kwave.utils.matrix import expand_matrix 9 | 10 | 11 | def test_expand_matrix_test(): 12 | collected_values_folder = os.path.join(Path(__file__).parent, "collectedValues/expandMatrix") 13 | num_collected_values = len(os.listdir(collected_values_folder)) 14 | for i in range(num_collected_values): 15 | filepath = os.path.join(collected_values_folder, f"{i:06d}.mat") 16 | recorded_data = loadmat(filepath, simplify_cells=True) 17 | 18 | matrix = recorded_data["matrix"] 19 | matrix = np.squeeze(matrix) 20 | input_args = recorded_data["input_args"] 21 | exp_coeff = input_args 22 | if isinstance(input_args[0], np.ndarray): 23 | edge_val = float(input_args[1]) 24 | exp_coeff = input_args[0] 25 | else: 26 | edge_val = None 27 | expected_expanded_matrix = recorded_data["expanded_matrix"] 28 | 29 | expanded_matrix = expand_matrix(matrix, exp_coeff=exp_coeff, edge_val=edge_val) 30 | 31 | logging.log(logging.INFO, i) 32 | assert np.allclose(expected_expanded_matrix, expanded_matrix, equal_nan=True) 33 | 34 | logging.log(logging.INFO, "expanded_matrix(..) works as expected!") 35 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/focusBowlONeil_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | 7 | from kwave.utils.mapgen import focused_bowl_oneil 8 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 9 | 10 | 11 | def test_focused_bowl_oneil(): 12 | test_record_path = os.path.join(Path(__file__).parent, "collectedValues/focusBowlONeil.mat") 13 | reader = TestRecordReader(test_record_path) 14 | 15 | radius = reader.expected_value_of("radius") 16 | diameter = reader.expected_value_of("diameter") 17 | velocity = reader.expected_value_of("velocity") 18 | frequency = reader.expected_value_of("frequency") 19 | sound_speed = reader.expected_value_of("sound_speed") 20 | density = reader.expected_value_of("density") 21 | axial_positions = reader.expected_value_of("axial_position") 22 | lateral_positions = reader.expected_value_of("lateral_position") 23 | 24 | p_axial, p_lateral, p_axial_complex = focused_bowl_oneil( 25 | radius, diameter, velocity, frequency, sound_speed, density, axial_positions=axial_positions, lateral_positions=lateral_positions 26 | ) 27 | 28 | assert np.allclose(p_axial, reader.expected_value_of("p_axial")) 29 | assert np.allclose(p_lateral, reader.expected_value_of("p_lateral")) 30 | assert np.allclose(p_axial_complex, reader.expected_value_of("p_axial_complex")) 31 | 32 | _, p_lateral, _ = focused_bowl_oneil(radius, diameter, velocity, frequency, sound_speed, density, axial_positions=axial_positions) 33 | 34 | assert p_lateral is None 35 | 36 | p_axial, _, p_axial_complex = focused_bowl_oneil( 37 | radius, diameter, velocity, frequency, sound_speed, density, lateral_positions=lateral_positions 38 | ) 39 | 40 | assert p_axial is None 41 | assert p_axial_complex is None 42 | 43 | logging.log(logging.INFO, "focused_bowl_oneil(..) works as expected!") 44 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/fourierShift_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | import pytest 7 | 8 | from kwave.utils.math import fourier_shift 9 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 10 | 11 | 12 | def test_fourier_shift(): 13 | collected_values_file = os.path.join(Path(__file__).parent, "collectedValues/fourierShift.mat") 14 | reader = TestRecordReader(collected_values_file) 15 | 16 | for i in range(len(reader)): 17 | # Read recorded data 18 | 19 | data = reader.expected_value_of("data") 20 | shift = reader.expected_value_of("shift") 21 | try: 22 | # - 1 TODO: subtract 1 from dimension here to make fourier_shift use python dimensions 23 | shift_dim = reader.expected_value_of("shift_dim") 24 | except KeyError: 25 | shift_dim = None 26 | expected_shifted_data = reader.expected_value_of("shifted_data") 27 | 28 | # Execute implementation 29 | shifted_data = fourier_shift(data, shift, shift_dim) 30 | 31 | # Check correctness 32 | assert np.allclose(shifted_data, expected_shifted_data) 33 | 34 | reader.increment() 35 | 36 | logging.log(logging.INFO, "fourier_shift(..) works as expected!") 37 | 38 | 39 | if __name__ == "__main__": 40 | pytest.main([__file__]) 41 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/gaussianFilter_test.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pathlib import Path 3 | 4 | import numpy as np 5 | 6 | from kwave.utils.filters import gaussian_filter 7 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 8 | 9 | 10 | def test_gaussianFilter(): 11 | collected_values_file = os.path.join(Path(__file__).parent, "collectedValues/gaussianFilter.mat") 12 | 13 | record_reader = TestRecordReader(collected_values_file) 14 | 15 | for _ in range(len(record_reader)): 16 | fs = record_reader.expected_value_of("fs") 17 | fc = record_reader.expected_value_of("fc") 18 | bw = record_reader.expected_value_of("bw") 19 | input_signal = record_reader.expected_value_of("input_signal") 20 | output_signal = record_reader.expected_value_of("output_signal") 21 | local_output = gaussian_filter(input_signal, fs, fc, bw) 22 | 23 | assert np.allclose(output_signal, local_output) 24 | record_reader.increment() 25 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/gaussian_test.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pathlib import Path 3 | 4 | import numpy as np 5 | 6 | from kwave.utils.filters import gaussian 7 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 8 | 9 | 10 | def test_gaussian(): 11 | test_record_path = os.path.join(Path(__file__).parent, Path("collectedValues/gaussian.mat")) 12 | reader = TestRecordReader(test_record_path) 13 | x = reader.expected_value_of("x") 14 | 15 | y = gaussian(x) 16 | y_prime = reader.expected_value_of("y") 17 | assert np.allclose(y, y_prime), "Gaussian distribution did not match expected distribution" 18 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/getAffineMatrix_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | 7 | from kwave.utils.math import make_affine 8 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 9 | 10 | 11 | def test_get_affine_matrix(): 12 | test_record_path = os.path.join(Path(__file__).parent, "collectedValues/getAffineMatrix.mat") 13 | reader = TestRecordReader(test_record_path) 14 | 15 | for i in range(len(reader)): 16 | params = reader.expected_value_of("params") 17 | translation, rotation = params 18 | affine_matrix = make_affine(translation, rotation) 19 | assert np.allclose(affine_matrix, reader.expected_value_of("affine_matrix")) 20 | reader.increment() 21 | 22 | logging.log(logging.INFO, "make_affine(..) works as expected!") 23 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/getColorMap_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import matplotlib 6 | import matplotlib.pyplot as plt 7 | import numpy as np 8 | 9 | from kwave.utils.colormap import get_color_map 10 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 11 | 12 | 13 | def test_get_color_map(): 14 | matplotlib.use("Agg") 15 | 16 | collected_values_file = os.path.join(Path(__file__).parent, "collectedValues/getColorMap.mat") 17 | reader = TestRecordReader(collected_values_file) 18 | 19 | for i in range(len(reader)): 20 | logging.log(logging.INFO, i) 21 | # Read recorded data 22 | 23 | num_colors = reader.expected_value_of("num_colors") 24 | expected_color_map = reader.expected_value_of("color_map") 25 | 26 | # Execute implementation 27 | color_map = get_color_map(num_colors) 28 | 29 | # Check correctness 30 | assert np.allclose(color_map.colors, expected_color_map) 31 | 32 | plt.imshow(np.random.rand(5, 5), cmap=color_map) 33 | plt.show() 34 | 35 | logging.log(logging.INFO, "get_color_map(..) works as expected!") 36 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/getDeltaBLI_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | 7 | from kwave.utils.interp import get_delta_bli 8 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 9 | 10 | 11 | def test_get_delta_bli(): 12 | test_record_path = os.path.join(Path(__file__).parent, "collectedValues/getDeltaBLI.mat") 13 | reader = TestRecordReader(test_record_path) 14 | 15 | for i in range(len(reader)): 16 | Nx = reader.expected_value_of("Nx") 17 | dx = reader.expected_value_of("dx") 18 | xgrid = reader.expected_value_of("x_grid") 19 | position = reader.expected_value_of("position") 20 | include_imag = reader.expected_value_of("include_imag") == 1 21 | f_grid = get_delta_bli(Nx, dx, xgrid, position, include_imag) 22 | 23 | assert np.allclose(f_grid, reader.expected_value_of("f_grid")) 24 | reader.increment() 25 | 26 | logging.log(logging.INFO, "get_delta_bli(..) works as expected!") 27 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/getWin_test.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pathlib import Path 3 | 4 | import numpy as np 5 | import pytest 6 | 7 | from kwave.utils.filters import get_win 8 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 9 | 10 | 11 | def test_get_win(): 12 | test_data_file = os.path.join(Path(__file__).parent, "collectedValues/getWin.mat") 13 | reader = TestRecordReader(test_data_file) 14 | for i in range(len(reader)): 15 | # logging.log(logging.INFO, "i: => %d", i) 16 | 17 | N = reader.expected_value_of("N") 18 | input_args = reader.expected_value_of("input_args") 19 | type_ = reader.expected_value_of("type_") 20 | 21 | rotation = bool(input_args[1]) 22 | symmetric = bool(input_args[3]) 23 | square = bool(input_args[5]) 24 | 25 | if len(input_args) == 8: 26 | param = float(input_args[7]) 27 | else: 28 | param = None 29 | assert len(input_args) == 6 30 | 31 | N = np.squeeze(N) 32 | 33 | # logging.log(logging.INFO, N, type_, param, rotation, symmetric, square, win) 34 | 35 | win_py, cg_py = get_win(N, type_, param=param, rotation=rotation, symmetric=symmetric, square=square) 36 | 37 | cg = reader.expected_value_of("cg") 38 | win = reader.expected_value_of("win") 39 | win_py = np.squeeze(win_py) 40 | assert np.shape(win_py) == np.shape(win) 41 | assert np.allclose(win_py, win, equal_nan=True) 42 | assert np.allclose(cg_py, cg, equal_nan=True) 43 | 44 | reader.increment() 45 | 46 | 47 | if __name__ == "__main__": 48 | pytest.main([__file__]) 49 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/hounsfield2density.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pathlib import Path 3 | 4 | import numpy as np 5 | 6 | from kwave.utils.conversion import hounsfield2density 7 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 8 | 9 | 10 | def test_hounsfield2density(): 11 | test_record_path = os.path.join(Path(__file__).parent, Path("collectedValues/hounsfield2density.mat")) 12 | reader = TestRecordReader(test_record_path) 13 | p = reader.expected_value_of("p") 14 | 15 | out = hounsfield2density(p) 16 | 17 | out_prime = reader.expected_value_of("out") 18 | assert np.allclose(out, out_prime), "hounsfield2density did not match expected hounsfield2density" 19 | 20 | 21 | test_hounsfield2density() 22 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/makeArc_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | import pytest 7 | 8 | from kwave.data import Vector 9 | from kwave.utils.mapgen import make_arc 10 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 11 | 12 | 13 | def test_makeArc(): 14 | reader = TestRecordReader(os.path.join(Path(__file__).parent, "collectedValues/makeArc.mat")) 15 | 16 | for i in range(len(reader)): 17 | logging.log(logging.INFO, i) 18 | 19 | grid_size, arc_pos, radius, diameter, focus_pos = reader.expected_value_of("params") 20 | grid_size, arc_pos, diameter, focus_pos = grid_size, arc_pos, int(diameter), focus_pos 21 | try: 22 | radius = int(radius) 23 | except OverflowError: 24 | radius = float(radius) 25 | expected_arc = reader.expected_value_of("arc") 26 | 27 | grid_size = Vector(grid_size) 28 | arc_pos = Vector(arc_pos) 29 | focus_pos = Vector(focus_pos) 30 | arc = make_arc(grid_size, arc_pos, radius, diameter, focus_pos) 31 | 32 | assert np.allclose(expected_arc, arc) 33 | reader.increment() 34 | logging.log(logging.INFO, "make_arc(..) works as expected!") 35 | 36 | 37 | if __name__ == "__main__": 38 | pytest.main([__file__]) 39 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/makeBall_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | import pytest 7 | 8 | from kwave.data import Vector 9 | from kwave.utils.mapgen import make_ball 10 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 11 | 12 | 13 | def test_makeBall(): 14 | reader = TestRecordReader(os.path.join(Path(__file__).parent, "collectedValues/makeBall.mat")) 15 | 16 | for i in range(len(reader)): 17 | logging.log(logging.INFO, i) 18 | 19 | Nx, Ny, Nz, cx, cy, cz, radius, plot_ball, binary = reader.expected_value_of("params") 20 | grid_size = Vector([int(Nx), int(Ny), int(Nz)]) 21 | ball_center = Vector([int(cx), int(cy), int(cz)]) 22 | radius, plot_ball, binary = int(radius), bool(plot_ball), bool(binary) 23 | 24 | expected_ball = reader.expected_value_of("ball") 25 | 26 | ball = make_ball(grid_size, ball_center, radius, plot_ball, binary) 27 | 28 | reader.increment() 29 | 30 | assert np.allclose(expected_ball, ball) 31 | 32 | logging.log(logging.INFO, "make_ball(..) works as expected!") 33 | 34 | 35 | if __name__ == "__main__": 36 | pytest.main([__file__]) 37 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/makeBowl_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | import pytest 7 | 8 | from kwave.data import Vector 9 | from kwave.utils.mapgen import make_bowl 10 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 11 | 12 | 13 | def test_makeBowl(): 14 | collected_values_file = os.path.join(Path(__file__).parent, "collectedValues/makeBowl.mat") 15 | reader = TestRecordReader(collected_values_file) 16 | 17 | for i in range(len(reader)): 18 | params = reader.expected_value_of("params") 19 | grid_size, bowl_pos, radius, diameter, focus_pos = params[:5] 20 | grid_size, bowl_pos, diameter, focus_pos = grid_size, bowl_pos, int(diameter), focus_pos 21 | grid_size = Vector(grid_size) 22 | bowl_pos = Vector(bowl_pos) 23 | focus_pos = Vector(focus_pos) 24 | 25 | try: 26 | radius = int(radius) 27 | except OverflowError: 28 | radius = float(radius) 29 | 30 | binary = bool(params[6]) 31 | remove_overlap = bool(params[8]) 32 | expected_bowl = reader.expected_value_of("bowl") 33 | 34 | bowl = make_bowl(grid_size, bowl_pos, radius, diameter, focus_pos, binary=binary, remove_overlap=remove_overlap) 35 | 36 | assert np.allclose(expected_bowl, bowl) 37 | reader.increment() 38 | 39 | logging.log(logging.INFO, "make_bowl(..) works as expected!") 40 | 41 | 42 | if __name__ == "__main__": 43 | pytest.main([__file__]) 44 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/makeCartArc_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | import pytest 7 | 8 | from kwave.data import Vector 9 | from kwave.utils.mapgen import make_cart_arc 10 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 11 | 12 | 13 | def test_makeCartArc(): 14 | collected_values_file = os.path.join(Path(__file__).parent, "collectedValues/make_cart_arc.mat") 15 | 16 | record_reader = TestRecordReader(collected_values_file) 17 | 18 | for i in range(len(record_reader)): 19 | params = record_reader.expected_value_of("params") 20 | 21 | arc_pos, radius, diameter, focus_pos, num_points = params 22 | arc_pos = Vector(arc_pos.astype(float)) 23 | focus_pos = Vector(focus_pos.astype(float)) 24 | expected_value = record_reader.expected_value_of("cart_arc") 25 | 26 | cart_arc = make_cart_arc(arc_pos, radius, diameter, focus_pos, num_points) 27 | record_reader.increment() 28 | 29 | # if radius of curvature is negative 30 | with pytest.raises(ValueError): 31 | _ = make_cart_arc(arc_pos, -radius, diameter, focus_pos, num_points) 32 | # if diameter of arc is negative 33 | with pytest.raises(ValueError): 34 | _ = make_cart_arc(arc_pos, radius, -diameter, focus_pos, num_points) 35 | # if diameter of arc is unphysical 36 | with pytest.raises(ValueError): 37 | _ = make_cart_arc(arc_pos, radius, int(np.ceil(2.1 * radius)), focus_pos, num_points) 38 | # if focus is at same place as middle of arc 39 | with pytest.raises(ValueError): 40 | _ = make_cart_arc(arc_pos, radius, diameter, arc_pos, num_points) 41 | 42 | # test floating point diameter 43 | _ = make_cart_arc(arc_pos, radius, float(diameter), focus_pos, num_points) 44 | 45 | assert np.allclose(expected_value, cart_arc), "Step {} of {} failed!".format(i, collected_values_file) 46 | 47 | logging.log(logging.INFO, "makeCartArc(..) works as expected!") 48 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/makeCartBowl_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | 7 | from kwave.utils.mapgen import make_cart_bowl 8 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 9 | 10 | 11 | def test_make_cart_bowl(): 12 | test_record_path = os.path.join(Path(__file__).parent, "collectedValues/makeCartBowl.mat") 13 | reader = TestRecordReader(test_record_path) 14 | 15 | for i in range(len(reader)): 16 | params = reader.expected_value_of("params") 17 | bowl_pos, radius, diameter, focus_pos, num_points, plot_bowl = params 18 | focus_pos = focus_pos.astype(np.float64) 19 | bowl_pos = bowl_pos.astype(np.float64) 20 | radius = float(radius) 21 | diameter = float(diameter) 22 | plot_bowl = plot_bowl == 1 23 | coordinates = make_cart_bowl(bowl_pos, radius, diameter, focus_pos, num_points, plot_bowl) 24 | assert np.allclose(coordinates, reader.expected_value_of("coordinates"), equal_nan=True) 25 | reader.increment() 26 | 27 | logging.log(logging.INFO, "make_cart_bowl(..) works as expected!") 28 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/makeCartCircle_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | from scipy.io import loadmat 7 | 8 | from kwave.data import Vector 9 | from kwave.utils.mapgen import make_cart_circle 10 | 11 | 12 | def test_makeCartCircle(): 13 | collected_values_folder = os.path.join(Path(__file__).parent, "collectedValues/makeCartCircle") 14 | num_collected_values = len(os.listdir(collected_values_folder)) 15 | 16 | for i in range(num_collected_values): 17 | filepath = os.path.join(collected_values_folder, f"{i:06d}.mat") 18 | recorded_data = loadmat(filepath) 19 | params = recorded_data["params"][0] 20 | 21 | if len(params) == 4: 22 | radius, num_points, center, arc_angle = params 23 | center = Vector(center[0]) 24 | num_points = num_points[0][0] 25 | radius = radius[0][0] 26 | arc_angle = arc_angle[0][0] 27 | if np.isclose(arc_angle, 2 * np.pi): 28 | arc_angle = 2 * np.pi 29 | 30 | circle = make_cart_circle(radius, num_points, center, arc_angle) 31 | else: 32 | radius, num_points, center = params 33 | center = Vector(center[0]) 34 | num_points = num_points[0][0] 35 | radius = radius[0][0] 36 | circle = make_cart_circle(radius, num_points, center) 37 | expected_value = recorded_data["circle"] 38 | 39 | assert np.allclose(expected_value, circle) 40 | 41 | logging.log(logging.INFO, "makeCartCircle(..) works as expected!") 42 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/makeCartRect_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | from scipy.spatial.transform import Rotation 7 | 8 | from kwave.utils.mapgen import make_cart_rect 9 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 10 | 11 | 12 | def test_make_cart_rect(): 13 | test_record_path = os.path.join(Path(__file__).parent, "collectedValues/makeCartRect.mat") 14 | reader = TestRecordReader(test_record_path) 15 | 16 | for i in range(len(reader)): 17 | params = reader.expected_value_of("params") 18 | rect_pos, Lx, Ly, theta, num_points, plot_rect = params 19 | if theta is not None and isinstance(theta, np.ndarray) and theta.size == 1: 20 | theta = float(theta) 21 | plot_rect = plot_rect == 1 22 | coordinates = make_cart_rect(rect_pos, Lx, Ly, theta, num_points, plot_rect) 23 | assert np.allclose(coordinates, reader.expected_value_of("coordinates")) 24 | reader.increment() 25 | 26 | logging.log(logging.INFO, "make_cart_rect(..) works as expected!") 27 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/makeCartSphere_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | 7 | from kwave.data import Vector 8 | from kwave.utils.mapgen import make_cart_sphere 9 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 10 | 11 | 12 | def test_makeCartSphere(): 13 | collected_values_file = os.path.join(Path(__file__).parent, "collectedValues/make_cart_sphere.mat") 14 | reader = TestRecordReader(collected_values_file) 15 | 16 | for i in range(len(reader)): 17 | logging.log(logging.INFO, i) 18 | params = reader.expected_value_of("params") 19 | radius = params[0] 20 | num_points = params[1] 21 | center = params[2] 22 | center = Vector(center.astype(int)) 23 | expected_value = reader.expected_value_of("cart_sphere") 24 | 25 | sphere = make_cart_sphere(radius, num_points, center) 26 | 27 | assert np.allclose(expected_value, sphere) 28 | reader.increment() 29 | 30 | logging.log(logging.INFO, "makeCartSphere(..) works as expected!") 31 | 32 | if __name__ == "__main__": 33 | test_makeCartSphere() 34 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/makeCircle_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | import pytest 7 | 8 | from kwave.data import Vector 9 | from kwave.utils.mapgen import make_circle 10 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 11 | 12 | 13 | def test_makeCircle(): 14 | reader = TestRecordReader(os.path.join(Path(__file__).parent, "collectedValues/makeCircle.mat")) 15 | 16 | for i in range(len(reader)): 17 | logging.log(logging.INFO, i) 18 | 19 | Nx, Ny, cx, cy, radius, arc_angle = reader.expected_value_of("param") 20 | 21 | grid_size = Vector([Nx, Ny]) 22 | center = Vector([cx, cy]) 23 | circle = make_circle(grid_size, center, radius, arc_angle) 24 | 25 | expected_circle = reader.expected_value_of("circle") 26 | 27 | assert np.allclose(expected_circle, circle) 28 | 29 | reader.increment() 30 | 31 | logging.log(logging.INFO, "make_circle(..) works as expected!") 32 | 33 | 34 | if __name__ == "__main__": 35 | pytest.main([__file__]) 36 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/makeDisc_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | 7 | from kwave.data import Vector 8 | from kwave.utils.mapgen import make_disc 9 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 10 | 11 | 12 | def test_makeDisc(): 13 | collected_values_file = os.path.join(Path(__file__).parent, "collectedValues/makeDisc.mat") 14 | reader = TestRecordReader(collected_values_file) 15 | 16 | for i in range(len(reader)): 17 | logging.log(logging.INFO, i) 18 | 19 | Nx, Ny, cx, cy, radius, plot_disc = reader.expected_value_of("params") 20 | Nx, Ny, cx, cy, radius, plot_disc = int(Nx), int(Ny), int(cx), int(cy), int(radius), bool(plot_disc) 21 | expected_disc = reader.expected_value_of("disc") 22 | 23 | grid_size = Vector([Nx, Ny]) 24 | center = Vector([cx, cy]) 25 | disc = make_disc(grid_size, center, radius, plot_disc) 26 | 27 | assert np.allclose(expected_disc, disc) 28 | 29 | logging.log(logging.INFO, "make_disc(..) works as expected!") 30 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/makeLine_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | from scipy.io import loadmat 7 | 8 | from kwave.data import Vector 9 | from kwave.utils.mapgen import make_line 10 | 11 | 12 | def test_makeLine(): 13 | collected_values_folder = os.path.join(Path(__file__).parent, "collectedValues/makeLine") 14 | 15 | num_collected_values = len(os.listdir(collected_values_folder)) 16 | 17 | for i in range(num_collected_values): 18 | logging.log(logging.INFO, i) 19 | 20 | filepath = os.path.join(collected_values_folder, f"{i:06d}.mat") 21 | recorded_data = loadmat(filepath, simplify_cells=True) 22 | 23 | params = recorded_data["params"] 24 | if len(params) == 4: 25 | Nx, Ny, startpoint, endpoint = params 26 | Nx, Ny = int(Nx), int(Ny) 27 | startpoint = tuple(startpoint.astype(np.int32)) 28 | endpoint = tuple(endpoint.astype(int)) 29 | grid_size = Vector([Nx, Ny]) 30 | line = make_line(grid_size, startpoint, endpoint) 31 | else: 32 | Nx, Ny, startpoint, angle, length = params 33 | Nx, Ny, angle, length = int(Nx), int(Ny), float(angle), int(length) 34 | startpoint = tuple(startpoint.astype(np.int32)) 35 | grid_size = Vector([Nx, Ny]) 36 | line = make_line(grid_size, startpoint, endpoint=None, angle=angle, length=length) 37 | 38 | expected_line = recorded_data["line"] 39 | 40 | if i == 3: 41 | logging.log(logging.INFO, "here") 42 | 43 | assert np.allclose(expected_line, line) 44 | 45 | logging.log(logging.INFO, "make_line(..) works as expected!") 46 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/makeMultiArc_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | from scipy.io import loadmat 7 | 8 | from kwave.data import Vector 9 | from kwave.utils.mapgen import make_multi_arc 10 | 11 | 12 | def test_makeMultiArc(): 13 | collected_values_folder = os.path.join(Path(__file__).parent, "collectedValues/makeMultiArc") 14 | 15 | num_collected_values = len(os.listdir(collected_values_folder)) 16 | 17 | for i in range(num_collected_values): 18 | logging.log(logging.INFO, i) 19 | filepath = os.path.join(collected_values_folder, f"{i:06d}.mat") 20 | recorded_data = loadmat(filepath, simplify_cells=True) 21 | 22 | grid_size, arc_pos, radius, diameter, focus_pos = recorded_data["params"] 23 | expected_multi_arc = recorded_data["multi_arc"] 24 | 25 | grid_size = Vector(grid_size) 26 | multi_arc, _ = make_multi_arc(grid_size, arc_pos, radius, diameter, focus_pos) 27 | 28 | assert np.allclose(expected_multi_arc, multi_arc) 29 | 30 | logging.log(logging.INFO, "make_multi_arc(..) works as expected!") 31 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/makeMultiBowl_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | from scipy.io import loadmat 7 | 8 | from kwave.data import Vector 9 | from kwave.utils.mapgen import make_multi_bowl 10 | 11 | 12 | def test_makeMultiBowl(): 13 | collected_values_folder = os.path.join(Path(__file__).parent, "collectedValues/makeMultiBowl") 14 | num_collected_values = len(os.listdir(collected_values_folder)) 15 | 16 | for i in range(num_collected_values): 17 | logging.log(logging.INFO, i) 18 | filepath = os.path.join(collected_values_folder, f"{i:06d}.mat") 19 | recorded_data = loadmat(filepath, simplify_cells=True) 20 | 21 | params = recorded_data["params"] 22 | grid_size, bowl_pos, radius, diameter, focus_pos = params[:5] 23 | grid_size = Vector(grid_size) 24 | 25 | binary = bool(params[6]) 26 | remove_overlap = bool(params[8]) 27 | expected_multi_bowl = recorded_data["multiBowl"] 28 | 29 | multi_bowl, _ = make_multi_bowl(grid_size, bowl_pos, radius, diameter, focus_pos, binary=binary, remove_overlap=remove_overlap) 30 | 31 | assert np.allclose(expected_multi_bowl, multi_bowl) 32 | 33 | logging.log(logging.INFO, "make_multi_bowl(..) works as expected!") 34 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/makeSphere_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | 7 | from kwave.data import Vector 8 | from kwave.utils.mapgen import make_sphere 9 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 10 | 11 | 12 | def test_makeSphere(): 13 | collected_values_file = os.path.join(Path(__file__).parent, "collectedValues/makeSphere.mat") 14 | reader = TestRecordReader(collected_values_file) 15 | 16 | for i in range(len(reader)): 17 | logging.log(logging.INFO, i) 18 | 19 | Nx, Ny, Nz, radius, plot_sphere, binary = reader.expected_value_of("params") 20 | Nx, Ny, Nz, radius, plot_sphere, binary = int(Nx), int(Ny), int(Nz), int(radius), bool(plot_sphere), bool(binary) 21 | expected_sphere = reader.expected_value_of("sphere") 22 | 23 | grid_size = Vector([Nx, Ny, Nz]) 24 | sphere = make_sphere(grid_size, radius, plot_sphere, binary) 25 | 26 | assert np.allclose(expected_sphere, sphere) 27 | reader.increment() 28 | 29 | logging.log(logging.INFO, "make_sphere(..) works as expected!") 30 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/makeSphericalSection_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | from scipy.io import loadmat 7 | 8 | from kwave.utils.mapgen import make_spherical_section 9 | 10 | 11 | def test_makeSphericalSection(): 12 | collected_values_folder = os.path.join(Path(__file__).parent, "collectedValues/makeSphericalSection") 13 | 14 | num_collected_values = len(os.listdir(collected_values_folder)) 15 | 16 | for i in range(num_collected_values): 17 | logging.log(logging.INFO, i) 18 | filepath = os.path.join(collected_values_folder, f"{i:06d}.mat") 19 | recorded_data = loadmat(filepath, simplify_cells=True) 20 | 21 | params = recorded_data["params"] 22 | if len(params) == 2: 23 | radius, height = params 24 | radius, height = int(radius), int(height) 25 | width, plot_section, binary = None, False, False 26 | else: 27 | radius, height, width, plot_section, binary = recorded_data["params"] 28 | radius, height, width, plot_section, binary = int(radius), int(height), int(width), bool(plot_section), bool(binary) 29 | expected_spherical_section = recorded_data["spherical_section"] 30 | expected_distance_map = recorded_data["distance_map"] 31 | 32 | spherical_section, distance_map = make_spherical_section(radius, height, width, plot_section, binary) 33 | 34 | assert np.allclose(expected_spherical_section, spherical_section) 35 | assert np.allclose(expected_distance_map, distance_map) 36 | 37 | logging.log(logging.INFO, "make_spherical_section(..) works as expected!") 38 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/maxND_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | 7 | from kwave.utils.matrix import max_nd 8 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 9 | 10 | 11 | def test_maxND(): 12 | reader = TestRecordReader(os.path.join(Path(__file__).parent, "collectedValues/maxND.mat")) 13 | 14 | for _ in range(len(reader)): 15 | matrix = reader.expected_value_of("matrix") 16 | expected_max_val = reader.expected_value_of("max_val") 17 | expected_ind = reader.expected_value_of("ind") 18 | 19 | max_val, ind = max_nd(matrix) 20 | 21 | assert np.allclose(expected_max_val, max_val, equal_nan=True) 22 | assert np.allclose(expected_ind, ind) 23 | 24 | reader.increment() 25 | 26 | logging.log(logging.INFO, "max_nd(..) works as expected!") 27 | 28 | 29 | if __name__ == "__main__": 30 | test_maxND() 31 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/minND_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | 7 | from kwave.utils.matrix import min_nd 8 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 9 | 10 | 11 | def test_minND(): 12 | test_record_path = os.path.join(Path(__file__).parent, "collectedValues/minND.mat") 13 | reader = TestRecordReader(test_record_path) 14 | 15 | for i in range(len(reader)): 16 | matrix = reader.expected_value_of("matrix") 17 | expected_min_val = reader.expected_value_of("min_val") 18 | expected_ind = reader.expected_value_of("ind") 19 | 20 | min_val, ind = min_nd(matrix) 21 | 22 | assert np.allclose(expected_min_val, min_val, equal_nan=True) 23 | assert np.allclose(expected_ind, ind) 24 | 25 | logging.log(logging.INFO, "min_nd(..) works as expected!") 26 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/phase_shift_interpolate_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | import warnings 4 | from pathlib import Path 5 | 6 | import numpy as np 7 | import pytest 8 | 9 | from kwave.utils.math import fourier_shift, phase_shift_interpolate 10 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 11 | 12 | 13 | def test_phase_shift_interpolate(): 14 | """Test that phase_shift_interpolate works as expected""" 15 | collected_values_file = os.path.join(Path(__file__).parent, "collectedValues/fourierShift.mat") 16 | reader = TestRecordReader(collected_values_file) 17 | 18 | for i in range(len(reader)): 19 | # Read recorded data 20 | data = reader.expected_value_of("data") 21 | shift = reader.expected_value_of("shift") 22 | try: 23 | shift_dim = reader.expected_value_of("shift_dim") 24 | except KeyError: 25 | shift_dim = None 26 | expected_shifted_data = reader.expected_value_of("shifted_data") 27 | 28 | # Execute implementation with new function 29 | shifted_data = phase_shift_interpolate(data, shift, shift_dim) 30 | 31 | # Check correctness 32 | assert np.allclose(shifted_data, expected_shifted_data) 33 | 34 | reader.increment() 35 | 36 | logging.log(logging.INFO, "phase_shift_interpolate works as expected!") 37 | 38 | 39 | def test_fourier_shift_deprecation(): 40 | """Test that the old fourier_shift function works and raises deprecation warning""" 41 | collected_values_file = os.path.join(Path(__file__).parent, "collectedValues/fourierShift.mat") 42 | reader = TestRecordReader(collected_values_file) 43 | 44 | # Get first test case 45 | data = reader.expected_value_of("data") 46 | shift = reader.expected_value_of("shift") 47 | try: 48 | shift_dim = reader.expected_value_of("shift_dim") 49 | except KeyError: 50 | shift_dim = None 51 | expected_shifted_data = reader.expected_value_of("shifted_data") 52 | 53 | # Test that old function raises deprecation warning but still works 54 | with pytest.warns(DeprecationWarning, match="Call to deprecated function.*fourier_shift") as warns: 55 | shifted_data = fourier_shift(data, shift, shift_dim) 56 | assert len(warns) == 1 57 | assert "has been renamed to phase_shift_interpolate" in str(warns[0].message) 58 | assert "Deprecated since version 0.4.1" in str(warns[0].message) 59 | assert np.allclose(shifted_data, expected_shifted_data) 60 | 61 | logging.log(logging.INFO, "fourier_shift deprecation works as expected!") 62 | 63 | 64 | if __name__ == "__main__": 65 | pytest.main([__file__]) 66 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/reorderBinarySensorData_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | from scipy.io import loadmat 7 | 8 | from kwave.utils.signals import reorder_binary_sensor_data 9 | 10 | 11 | def test_binary_sensor_data(): 12 | collected_values_folder = os.path.join(Path(__file__).parent, "collectedValues/reorderBinarySensorData") 13 | num_collected_values = len(os.listdir(collected_values_folder)) 14 | 15 | for i in range(num_collected_values): 16 | filepath = os.path.join(collected_values_folder, f"{i:06d}.mat") 17 | recorded_data = loadmat(filepath) 18 | 19 | sensor_data = recorded_data["sensor_data"] 20 | reorder_index = recorded_data["reorder_index"] 21 | expected_reordered_data = recorded_data["reordered_data"] 22 | 23 | calculated_reordered_data = reorder_binary_sensor_data(sensor_data, reorder_index) 24 | assert np.allclose(expected_reordered_data, calculated_reordered_data, equal_nan=True) 25 | 26 | logging.log(logging.INFO, "reorder_binary_sensor_data(..) works as expected!") 27 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/reorderSensorData_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | from scipy.io import loadmat 7 | 8 | from kwave.kgrid import kWaveGrid 9 | from kwave.utils.dotdictionary import dotdict 10 | from kwave.utils.signals import reorder_sensor_data 11 | 12 | 13 | def test_reorder_sensor_data(): 14 | collected_values_folder = os.path.join(Path(__file__).parent, "collectedValues/reorderSensorData") 15 | num_collected_values = len(os.listdir(collected_values_folder)) 16 | 17 | for i in range(num_collected_values): 18 | filepath = os.path.join(collected_values_folder, f"{i:06d}.mat") 19 | recorded_data = loadmat(filepath) 20 | 21 | mask_size = np.squeeze(recorded_data["mask_size"]) # noqa: F841 22 | kgrid_size = np.squeeze(recorded_data["kgrid_size"]) 23 | kgrid_dx_dy = np.squeeze(recorded_data["kgrid_dx_dy"]) 24 | 25 | sensor_data_size = np.squeeze(recorded_data["sensor_data_size"]) # noqa: F841 26 | mask = recorded_data["mask"] 27 | sensor_data = recorded_data["sensor_data"] 28 | expected_reordered_sensor_data = recorded_data["reordered_sensor_data"] 29 | 30 | sensor = dotdict() 31 | sensor.mask = mask 32 | 33 | kgrid = kWaveGrid(kgrid_size, [kgrid_dx_dy, kgrid_dx_dy]) 34 | 35 | calculated_reordered_sensor_data = reorder_sensor_data(kgrid, sensor, sensor_data) 36 | 37 | assert np.allclose(expected_reordered_sensor_data, calculated_reordered_sensor_data, equal_nan=True) 38 | 39 | logging.log(logging.INFO, "reorder_sensor_data(..) works as expected!") 40 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/revolve2D_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | from scipy.io import loadmat 7 | 8 | from kwave.utils.matrix import revolve2d 9 | 10 | 11 | def test_revolve2D(): 12 | collected_values_folder = os.path.join(Path(__file__).parent, "collectedValues/revolve2D") 13 | 14 | num_collected_values = len(os.listdir(collected_values_folder)) 15 | 16 | for i in range(num_collected_values): 17 | logging.log(logging.INFO, i) 18 | filepath = os.path.join(collected_values_folder, f"{i:06d}.mat") 19 | recorded_data = loadmat(filepath) 20 | 21 | params = recorded_data["params"][0] 22 | mat2D = params[0] 23 | 24 | expected_mat3D = recorded_data["mat3D"] 25 | 26 | mat3D = revolve2d(mat2D) 27 | 28 | assert np.allclose(expected_mat3D, mat3D) 29 | 30 | logging.log(logging.INFO, "revolve2d(..) works as expected!") 31 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/rotation_matrices_test.py: -------------------------------------------------------------------------------- 1 | import os 2 | import warnings 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | 7 | from kwave.utils.math import Rx, Ry, Rz 8 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 9 | 10 | 11 | def test_rotation_matrices(): 12 | """Test that Python rotation matrices match MATLAB output""" 13 | # Ignore deprecation warnings for these functions 14 | with warnings.catch_warnings(): 15 | warnings.filterwarnings("ignore", category=DeprecationWarning) 16 | 17 | # Test 3D rotations against MATLAB output 18 | reader = TestRecordReader(os.path.join(Path(__file__).parent, "collectedValues/rotation_matrices.mat")) 19 | for _ in range(len(reader)): 20 | theta = reader.expected_value_of("theta") 21 | 22 | # Test Rx 23 | result = Rx(theta) # Default 3D 24 | expected_matrix = reader.expected_value_of("Rx_matrix") 25 | np.testing.assert_allclose(result, expected_matrix, rtol=1e-15, atol=1e-15, err_msg=f"Rx matrix mismatch for angle {theta}") 26 | 27 | # Test Ry 28 | result = Ry(theta) # Default 3D 29 | expected_matrix = reader.expected_value_of("Ry_matrix") 30 | np.testing.assert_allclose(result, expected_matrix, rtol=1e-15, atol=1e-15, err_msg=f"Ry matrix mismatch for angle {theta}") 31 | 32 | # Test Rz 33 | result = Rz(theta) # Default 3D 34 | expected_matrix = reader.expected_value_of("Rz_matrix") 35 | np.testing.assert_allclose(result, expected_matrix, rtol=1e-15, atol=1e-15, err_msg=f"Rz matrix mismatch for angle {theta}") 36 | 37 | reader.increment() 38 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/scaleSI_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | from scipy.io import loadmat 7 | 8 | from kwave.utils.data import scale_SI 9 | 10 | 11 | def test_scale_si(): 12 | collected_values_folder = os.path.join(Path(__file__).parent, "collectedValues/scaleSI") 13 | num_collected_values = len(os.listdir(collected_values_folder)) 14 | 15 | for i in range(num_collected_values): 16 | filepath = os.path.join(collected_values_folder, f"{i:06d}.mat") 17 | recorded_data = loadmat(filepath) 18 | 19 | x = np.squeeze(recorded_data["x"]) 20 | expected_x_sc = recorded_data["x_sc"][0] 21 | expected_scale = recorded_data["scale"][0][0] 22 | expected_prefix = recorded_data["prefix"] 23 | if len(expected_prefix) == 0: 24 | expected_prefix = "" 25 | else: 26 | expected_prefix = str(expected_prefix[0]) 27 | 28 | expected_prefix_fullname = np.squeeze(recorded_data["prefix_fullname"]) 29 | if expected_prefix_fullname.size == 0: 30 | expected_prefix_fullname = "" 31 | else: 32 | expected_prefix_fullname = str(expected_prefix_fullname) 33 | 34 | [x_sc, scale, prefix, prefix_fullname] = scale_SI(x) 35 | 36 | assert x_sc == expected_x_sc 37 | assert scale == expected_scale 38 | assert prefix == expected_prefix 39 | assert prefix_fullname == expected_prefix_fullname 40 | 41 | # calculated_reordered_data = reorder_binary_sensor_data(sensor_data, reorder_index) 42 | # assert np.allclose(expected_reordered_data, calculated_reordered_data, equal_nan=True) 43 | 44 | logging.log(logging.INFO, "scale_si(..) works as expected!") 45 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/scaleTime_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | from scipy.io import loadmat 7 | 8 | from kwave.utils.data import scale_time 9 | 10 | 11 | def test_scale_time(): 12 | collected_values_folder = os.path.join(Path(__file__).parent, "collectedValues/scaleTime") 13 | num_collected_values = len(os.listdir(collected_values_folder)) 14 | 15 | for i in range(num_collected_values): 16 | filepath = os.path.join(collected_values_folder, f"{i:06d}.mat") 17 | recorded_data = loadmat(filepath) 18 | 19 | seconds = np.squeeze(recorded_data["seconds"]) 20 | if seconds.dtype == np.uint8: 21 | seconds = int(seconds) 22 | else: 23 | seconds = float(seconds) 24 | expected_time = str(recorded_data["time"][0]) 25 | 26 | time = scale_time(seconds) 27 | assert time == expected_time 28 | 29 | logging.log(logging.INFO, "scale_time(..) works as expected!") 30 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/scanConversion_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | 7 | from kwave.reconstruction.beamform import scan_conversion 8 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 9 | 10 | 11 | def test_scanConversion(): 12 | collected_values_file = os.path.join(Path(__file__).parent, "collectedValues/scanConversion.mat") 13 | reader = TestRecordReader(collected_values_file) 14 | 15 | for _ in range(len(reader)): 16 | scan_lines = reader.expected_value_of("scan_lines") 17 | steering_angles = reader.expected_value_of("steering_angles") 18 | image_size = reader.expected_value_of("image_size") 19 | c0 = reader.expected_value_of("c0") 20 | dt = reader.expected_value_of("dt") 21 | resolution = reader.expected_value_of("resolution") 22 | expected_b_mode = reader.expected_value_of("b_mode") 23 | 24 | calculated_b_mode = scan_conversion(scan_lines, steering_angles, image_size, c0, dt, resolution) 25 | 26 | assert np.allclose(expected_b_mode, calculated_b_mode, equal_nan=True) 27 | 28 | reader.increment() 29 | 30 | logging.log(logging.INFO, "scan_conversion(..) works as expected!") 31 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/smooth_test.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pathlib import Path 3 | 4 | import numpy as np 5 | 6 | from kwave.utils.filters import smooth 7 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 8 | 9 | 10 | def test_smooth(): 11 | test_record_path = os.path.join(Path(__file__).parent, Path("collectedValues/smooth.mat")) 12 | reader = TestRecordReader(test_record_path) 13 | img = reader.expected_value_of("img") 14 | 15 | out = smooth(img) 16 | 17 | out_prime = reader.expected_value_of("out") 18 | assert np.allclose(out, out_prime), "Smooth did not match expected smooth" 19 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/test_interpcartdata.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | import typing 4 | from pathlib import Path 5 | from unittest.mock import Mock 6 | 7 | import numpy as np 8 | import pytest 9 | 10 | from kwave.kgrid import kWaveGrid 11 | from kwave.utils.interp import interp_cart_data 12 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 13 | 14 | 15 | class kGridMock(Mock): 16 | @property 17 | def __class__(self) -> type: 18 | return kWaveGrid 19 | 20 | def set_props(self, props): 21 | self.kprops = props 22 | 23 | def __getattr__(self, name: str) -> typing.Any: 24 | if name in self.kprops.keys(): 25 | return self.kprops[name] 26 | return super().__getattr__(name) 27 | 28 | 29 | def test_interpcartdata(): 30 | reader = TestRecordReader(os.path.join(Path(__file__).parent, "collectedValues/interpCartData.mat")) 31 | 32 | for _ in range(len(reader)): 33 | # 'params', 'kgrid', 'sensor_data', 'sensor_mask', 'binary_sensor_mask', 'trbd' 34 | trbd = reader.expected_value_of("trbd") 35 | kgrid_props = reader.expected_value_of("kgrid") 36 | sensor_data = reader.expected_value_of("sensor_data") 37 | sensor_mask = reader.expected_value_of("sensor_mask") 38 | binary_sensor_mask = reader.expected_value_of("binary_sensor_mask") 39 | interp_method = reader.expected_value_of("interp_method") 40 | 41 | kgrid = kGridMock() 42 | kgrid.set_props(kgrid_props) 43 | 44 | trbd_py = interp_cart_data( 45 | kgrid, cart_sensor_data=sensor_data, cart_sensor_mask=sensor_mask, binary_sensor_mask=binary_sensor_mask, interp=interp_method 46 | ) 47 | 48 | assert np.allclose(trbd, trbd_py) 49 | reader.increment() 50 | 51 | logging.log(logging.INFO, "cart2grid(..) works as expected!") 52 | 53 | 54 | def test_unknown_interp_method(): 55 | with pytest.raises(ValueError): 56 | reader = TestRecordReader(os.path.join(Path(__file__).parent, "collectedValues/interpCartData.mat")) 57 | kprops = reader.expected_value_of("kgrid") 58 | kgrid = kGridMock() 59 | kgrid.set_props(kprops) 60 | interp_cart_data( 61 | kgrid, 62 | cart_sensor_data=reader.expected_value_of("sensor_data"), 63 | cart_sensor_mask=reader.expected_value_of("sensor_mask"), 64 | binary_sensor_mask=reader.expected_value_of("binary_sensor_mask"), 65 | interp="unknown", 66 | ) 67 | 68 | 69 | if __name__ == "__main__": 70 | pytest.main([__file__]) 71 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/test_linear_array_transducer.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pathlib import Path 3 | 4 | import numpy as np 5 | 6 | import kwave.data 7 | from kwave.kgrid import kWaveGrid 8 | from kwave.utils.kwave_array import kWaveArray 9 | from tests.matlab_test_data_collectors.python_testers.utils.check_equality import check_kgrid_equality, check_kwave_array_equality 10 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 11 | 12 | 13 | def test_linear_array_transducer(): 14 | test_record_path = os.path.join(Path(__file__).parent, "collectedValues/linear_array_transducer.mat") 15 | reader = TestRecordReader(test_record_path) 16 | 17 | c0 = 1500 18 | source_f0 = 1e6 19 | source_focus = 20e-3 20 | element_num = 15 21 | element_width = 1e-3 22 | element_length = 10e-3 23 | element_pitch = 2e-3 24 | translation = kwave.data.Vector([5e-3, 0, 8e-3]) 25 | rotation = kwave.data.Vector([0, 20, 0]) 26 | grid_size_x = 40e-3 27 | grid_size_y = 20e-3 28 | grid_size_z = 40e-3 29 | ppw = 3 30 | t_end = 35e-6 31 | cfl = 0.5 32 | bli_tolerance = 0.05 33 | upsampling_rate = 10 34 | 35 | # GRID 36 | dx = c0 / (ppw * source_f0) 37 | Nx = round(grid_size_x / dx) 38 | Ny = round(grid_size_y / dx) 39 | Nz = round(grid_size_z / dx) 40 | kgrid = kWaveGrid([Nx, Ny, Nz], [dx, dx, dx]) 41 | kgrid.makeTime(c0, cfl, t_end) 42 | 43 | check_kgrid_equality(kgrid, reader.expected_value_of("kgrid")) 44 | # SOURCE 45 | if element_num % 2 != 0: 46 | centering_offset = np.ceil(element_num / 2) 47 | else: 48 | centering_offset = (element_num + 1) / 2 49 | 50 | positional_basis = np.arange(1, element_num + 1) - centering_offset 51 | 52 | time_delays = -(np.sqrt((positional_basis * element_pitch) ** 2 + source_focus**2) - source_focus) / c0 53 | time_delays = time_delays - min(time_delays) 54 | 55 | karray = kWaveArray(bli_tolerance=bli_tolerance, upsampling_rate=upsampling_rate) 56 | 57 | for ind in range(1, element_num + 1): 58 | x_pos = 0 - (element_num * element_pitch / 2 - element_pitch / 2) + (ind - 1) * element_pitch 59 | karray.add_rect_element([x_pos, 0, kgrid.z_vec.flat[0]], element_width, element_length, rotation) 60 | 61 | karray.set_array_position(translation, rotation) 62 | 63 | check_kwave_array_equality(karray, reader.expected_value_of("karray")) 64 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/test_make_cart_disc.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | 7 | from kwave.utils.mapgen import make_cart_disc 8 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 9 | 10 | 11 | def test_make_cart_disc(): 12 | test_record_path = os.path.join(Path(__file__).parent, "collectedValues/makeCartDisc.mat") 13 | reader = TestRecordReader(test_record_path) 14 | 15 | for i in range(len(reader)): 16 | params = reader.expected_value_of("params") 17 | disc_pos, radius, focus_pos, num_points, plot_disc, use_spiral = params 18 | focus_pos = focus_pos.astype(np.float64) 19 | disc_pos = disc_pos.astype(np.float64) 20 | radius = float(radius) 21 | coordinates = make_cart_disc(disc_pos, radius, focus_pos, num_points, plot_disc, use_spiral) 22 | assert np.allclose(coordinates, reader.expected_value_of("coordinates"), equal_nan=True) 23 | reader.increment() 24 | 25 | logging.log(logging.INFO, "make_cart_disc(..) works as expected!") 26 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/test_resize.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | 7 | from kwave.utils.matrix import resize 8 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 9 | 10 | 11 | def test_resize(): 12 | test_record_path = os.path.join(Path(__file__).parent, "collectedValues/resize.mat") 13 | reader = TestRecordReader(test_record_path) 14 | 15 | for i in range(len(reader)): 16 | volume = reader.expected_value_of("volume") 17 | expected_resized_volume = reader.expected_value_of("resized_volume") 18 | new_size = reader.expected_value_of("new_size") 19 | method = reader.expected_value_of("method") # TODO: does not work for spline cases 20 | 21 | resized_volume = resize(volume, new_size, interp_mode=method) 22 | 23 | assert np.allclose(expected_resized_volume, resized_volume), f"Results do not match for {i + 1} dimensional case." 24 | reader.increment() 25 | 26 | logging.log(logging.INFO, "resize(..) works as expected!") 27 | 28 | 29 | if __name__ == "__main__": 30 | test_resize() 31 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/tolStart_test.py: -------------------------------------------------------------------------------- 1 | import os 2 | import typing 3 | from pathlib import Path 4 | from unittest.mock import Mock 5 | 6 | import numpy as np 7 | 8 | from kwave.kgrid import kWaveGrid 9 | from kwave.utils.conversion import tol_star 10 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 11 | 12 | 13 | class kGridMock(Mock): 14 | @property 15 | def __class__(self) -> type: 16 | return kWaveGrid 17 | 18 | def set_props(self, props): 19 | self.kprops = props 20 | 21 | def __getattr__(self, name: str) -> typing.Any: 22 | if name in vars(self.kprops)["_fieldnames"]: 23 | return self.kprops.__getattribute__(name) 24 | return super().__getattr__(name) 25 | 26 | 27 | def test_tol_star(): 28 | reader = TestRecordReader(os.path.join(Path(__file__).parent, "collectedValues/tolStar.mat")) 29 | 30 | for i in range(len(reader)): 31 | tolerance, kgrid_props, point = reader.expected_value_of("params") 32 | 33 | kgrid = kGridMock() 34 | kgrid.set_props(kgrid_props) 35 | 36 | if not isinstance(point, np.ndarray): 37 | point = np.array([float(point)]) 38 | else: 39 | point = point.astype(float) 40 | 41 | lin_ind, is_, js, ks = tol_star(tolerance, kgrid, point, debug=False) 42 | 43 | expected_lin_ind = reader.expected_value_of("lin_ind") 44 | expected_is = reader.expected_value_of("is") 45 | expected_js = reader.expected_value_of("js") 46 | expected_ks = reader.expected_value_of("ks") 47 | 48 | assert np.allclose(lin_ind, expected_lin_ind), "lin_ind did not match expected lin_ind" 49 | assert np.allclose(is_, expected_is - 1), "is_ did not match expected is" 50 | assert np.allclose(js, expected_js - 1), "js did not match expected js" 51 | assert np.allclose(ks, expected_ks - 1), "ks did not match expected ks" 52 | reader.increment() 53 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/trimCartPoints_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | import numpy as np 6 | 7 | from kwave.utils.dotdictionary import dotdict 8 | from kwave.utils.mapgen import trim_cart_points 9 | from tests.matlab_test_data_collectors.python_testers.utils.record_reader import TestRecordReader 10 | 11 | 12 | def test_trim_cart_points(): 13 | test_record_path = os.path.join(Path(__file__).parent, "collectedValues/trimCartPoints.mat") 14 | reader = TestRecordReader(test_record_path) 15 | 16 | kgrids = [reader.expected_value_of(f"kgrid{i}") for i in range(1, 4)] 17 | kgrids = [dotdict(kgrid) for kgrid in kgrids] 18 | point_sets = [reader.expected_value_of(f"pointsSet{i}") for i in range(1, 4)] 19 | reader.increment() 20 | 21 | for i in range(len(kgrids)): 22 | for j in range(len(point_sets)): 23 | trimmed_points = trim_cart_points(kgrids[i], point_sets[j]) 24 | expected_trimmed_points = reader.expected_value_of("trimmed_points") 25 | 26 | assert np.allclose(expected_trimmed_points, trimmed_points) 27 | 28 | logging.log(logging.INFO, "trim_cart_points(..) works as expected!") 29 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/unmaskSensorData_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | from unittest.mock import Mock 5 | 6 | import numpy as np 7 | from scipy.io import loadmat 8 | 9 | from kwave.utils.signals import unmask_sensor_data 10 | 11 | 12 | def test_unmask_sensor_data(): 13 | collected_values_folder = os.path.join(Path(__file__).parent, "collectedValues/unmaskSensorData") 14 | num_collected_values = len(os.listdir(collected_values_folder)) 15 | 16 | for i in range(num_collected_values): 17 | logging.log(logging.INFO, i) 18 | # Read recorded data 19 | filepath = os.path.join(collected_values_folder, f"{i:06d}.mat") 20 | recorded_data = loadmat(filepath) 21 | 22 | data_dim = recorded_data["data_dim"][0] 23 | sensor_mask = recorded_data["sensor_mask"] 24 | sensor_data = recorded_data["sensor_data"] 25 | expected_unmasked_sensor_data = recorded_data["unmasked_sensor_data"] 26 | 27 | kgrid = Mock() 28 | kgrid.Nx = data_dim[0] 29 | kgrid.k = data_dim.size 30 | 31 | if data_dim.size in [2, 3]: 32 | kgrid.Ny = data_dim[1] 33 | 34 | if data_dim.size == 3: 35 | kgrid.Nz = data_dim[2] 36 | 37 | sensor = Mock() 38 | sensor.mask = sensor_mask 39 | 40 | unmasked_sensor_data = unmask_sensor_data(kgrid, sensor, sensor_data) 41 | 42 | assert np.allclose(unmasked_sensor_data, expected_unmasked_sensor_data) 43 | 44 | logging.log(logging.INFO, "unmask_sensor_data(..) works as expected!") 45 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waltsims/k-wave-python/51b2041523377c937f224c75cc771ec761ec975c/tests/matlab_test_data_collectors/python_testers/utils/__init__.py -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/python_testers/utils/record_reader.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from scipy.io import loadmat 3 | 4 | 5 | class TestRecordReader(object): 6 | # Will make `pytest` to ignore this class as a test class 7 | __test__ = False 8 | 9 | def __init__(self, record_filename): 10 | recorded_data = loadmat(record_filename, simplify_cells=True) 11 | self._records = recorded_data 12 | self._total_steps = recorded_data["total_steps"] 13 | self._step = 0 14 | 15 | def expected_value_of(self, name, squeeze=False): 16 | record_key = f"step_{self._step}___{name}" 17 | value = self._records[record_key] 18 | if squeeze: 19 | value = np.squeeze(value) 20 | return value 21 | 22 | def increment(self): 23 | self._step += 1 24 | if self._step > self._total_steps: 25 | raise ValueError("Exceeded total recorded steps. Perhaps something is wrong with logic?") 26 | 27 | def __len__(self): 28 | return self._total_steps 29 | -------------------------------------------------------------------------------- /tests/matlab_test_data_collectors/run_all_collectors.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | % ensure k-wave is on the path 3 | addpath(genpath('../../../k-wave')); 4 | directory = pwd + "/matlab_collectors"; 5 | files = getListOfFiles(directory); 6 | 7 | for idx=1:length(files) 8 | % ensure collected value directory has been created 9 | file_parts = split(files(idx),["_","."]); 10 | collected_value_dir = pwd + ... 11 | "/matlab_collectors/collectedValues/" + file_parts(2); 12 | mkdir(collected_value_dir) 13 | % run value collector 14 | run(fullfile(directory, files{idx})); 15 | clearvars -except idx files directory 16 | end 17 | 18 | if ~isRunningInCI() 19 | updatePythonCollectedValues(directory); 20 | end 21 | 22 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 23 | function is_running_in_ci = isRunningInCI() 24 | is_running_in_ci = ~isempty(getenv('CI')); 25 | end 26 | 27 | function updatePythonCollectedValues(directory) 28 | target = pwd + "/python_testers/collectedValues"; 29 | if exist(target, 'dir') 30 | rmdir(target, 's') 31 | end 32 | movefile(directory + "/collectedValues", target) 33 | end 34 | 35 | function files = getListOfFiles(directory) 36 | list = dir(fullfile(directory, '*.m')); 37 | files = {list.name}; 38 | end -------------------------------------------------------------------------------- /tests/setup_test.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | import sys 4 | 5 | PACKAGE_PARENT = ".." 6 | SCRIPT_DIR = os.path.dirname(os.path.realpath(os.path.join(os.getcwd(), os.path.expanduser(__file__)))) 7 | logging.log(logging.INFO, os.path.normpath(os.path.join(SCRIPT_DIR, PACKAGE_PARENT))) 8 | sys.path.append(os.path.normpath(os.path.join(SCRIPT_DIR, PACKAGE_PARENT))) 9 | -------------------------------------------------------------------------------- /tests/test__init__.py: -------------------------------------------------------------------------------- 1 | import importlib 2 | from unittest.mock import patch 3 | 4 | import pytest 5 | 6 | 7 | def test__init(): 8 | with pytest.raises(NotImplementedError): 9 | with patch("platform.system", lambda: "Unknown"): 10 | import kwave 11 | 12 | importlib.reload(kwave) 13 | 14 | 15 | if __name__ == "__main__": 16 | pytest.main([__file__]) 17 | -------------------------------------------------------------------------------- /tests/test_create_pixel_dim.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pytest 3 | 4 | from kwave.utils.mapgen import create_pixel_dim 5 | 6 | 7 | def test_even_single_shift0(): 8 | Nx = 4 9 | origin_size = "single" 10 | shift = 0 11 | 12 | result = create_pixel_dim(Nx, origin_size, shift) 13 | expected = np.array([-1, 0, 1, 2]) # from the code path 14 | np.testing.assert_array_equal(result, expected) 15 | 16 | 17 | def test_even_single_shift1(): 18 | Nx = 4 19 | origin_size = "single" 20 | shift = 1 21 | 22 | result = create_pixel_dim(Nx, origin_size, shift) 23 | expected = np.array([-2, -1, 0, 1]) # from code path 24 | np.testing.assert_array_equal(result, expected) 25 | 26 | 27 | def test_even_double_shift_any(): 28 | Nx = 4 29 | origin_size = "double" 30 | shift = 999 # any shift, code doesn't branch on shift for Nx even 31 | 32 | result = create_pixel_dim(Nx, origin_size, shift) 33 | expected = np.array([-1, 0, 0, 1]) # based on code as-is 34 | np.testing.assert_array_equal(result, expected) 35 | 36 | 37 | def test_odd_single(): 38 | Nx = 5 39 | origin_size = "single" 40 | shift = 0 # or shift=1 doesn't matter for this branch 41 | 42 | result = create_pixel_dim(Nx, origin_size, shift) 43 | expected = np.array([-2, -1, 0, 1, 2]) 44 | np.testing.assert_array_equal(result, expected) 45 | 46 | 47 | def test_odd_double_shift0(): 48 | Nx = 5 49 | origin_size = "double" 50 | shift = 0 51 | 52 | result = create_pixel_dim(Nx, origin_size, shift) 53 | expected = np.array([-1, 0, 0, 1, 2]) # consistent with code 54 | np.testing.assert_array_equal(result, expected) 55 | 56 | 57 | def test_odd_double_shift1(): 58 | Nx = 5 59 | origin_size = "double" 60 | shift = 1 61 | 62 | result = create_pixel_dim(Nx, origin_size, shift) 63 | expected = np.array([-2, -1, 0, 0, 1]) 64 | np.testing.assert_array_equal(result, expected) 65 | -------------------------------------------------------------------------------- /tests/test_ksource.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import numpy as np 4 | 5 | from kwave.ksource import kSource 6 | 7 | 8 | class TestKSource(unittest.TestCase): 9 | def setUp(self): 10 | self.source = kSource() 11 | 12 | def test_p0_setter_empty_array(self): 13 | """Test that p0 is set to None when given an empty array""" 14 | self.source.p0 = np.array([]) 15 | self.assertIsNone(self.source.p0) 16 | 17 | def test_p0_setter_non_empty_array(self): 18 | """Test that p0 is set correctly for non-empty array""" 19 | test_array = np.array([1.0, 2.0, 3.0]) 20 | self.source.p0 = test_array 21 | np.testing.assert_array_equal(self.source.p0, test_array) 22 | 23 | def test_p0_setter_zero_array(self): 24 | """Test that p0 is set correctly for array of zeros (should not be set to None)""" 25 | test_array = np.zeros(5) 26 | self.source.p0 = test_array 27 | np.testing.assert_array_equal(self.source.p0, test_array) 28 | 29 | def test_is_p0_empty(self): 30 | """Test the is_p0_empty method""" 31 | # Test with None 32 | self.assertTrue(self.source.is_p0_empty()) 33 | 34 | # Test with empty array 35 | self.source.p0 = np.array([]) 36 | self.assertTrue(self.source.is_p0_empty()) 37 | 38 | # Test with non-empty array 39 | self.source.p0 = np.array([1.0, 2.0]) 40 | self.assertFalse(self.source.is_p0_empty()) 41 | 42 | # Test with zero array 43 | self.source.p0 = np.zeros(5) 44 | self.assertTrue(self.source.is_p0_empty()) 45 | -------------------------------------------------------------------------------- /tests/test_misc.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from kwave.utils.math import find_closest, round_even, round_odd 4 | 5 | 6 | def test_round_odd_down(): 7 | assert round_odd(3.9) == 3 8 | 9 | 10 | def test_round_odd_up(): 11 | assert round_odd(2.1) == 3 12 | 13 | 14 | def test_round_even_up(): 15 | assert round_even(21.1) == 22 16 | 17 | 18 | def test_round_even_down(): 19 | assert round_even(22.9) == 22 20 | 21 | 22 | def test_find_closest(): 23 | a = np.array([1, 2, 3, 4, 5, 6]) 24 | a_close, idx_close = find_closest(a, 2.1) 25 | assert a_close == 2 26 | assert idx_close == (1,) 27 | --------------------------------------------------------------------------------