From ea8bfd71c120e669bcddd902f1f3943fef3eaa1f Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Mon, 28 Jul 2025 12:30:11 +0100 Subject: [PATCH 01/38] change workflow settings for testing --- .github/workflows/unit_tests.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index a9e66f8..f7cdd0b 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -2,11 +2,6 @@ name: Run unit tests on: push: - branches: - - main - pull_request: - branches: - - main jobs: unit-tests: @@ -28,7 +23,7 @@ jobs: command: | addpath("${{ github.workspace }}/k-Wave"); cd("${{ github.workspace }}/k-Wave/testing/unit"); - test_struct = runUnitTests("",false); + test_struct = runUnitTests("save",false); save('test_struct.mat', 'test_struct'); startup-options: -nojvm -logfile output.log From abbfda7f48a7e98b67d91364aa26330a303ae712 Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Mon, 28 Jul 2025 12:33:44 +0100 Subject: [PATCH 02/38] remove test info for failed tests --- k-Wave/testing/unit/runUnitTests_show_results.m | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/k-Wave/testing/unit/runUnitTests_show_results.m b/k-Wave/testing/unit/runUnitTests_show_results.m index f27ce9e..2e6e845 100644 --- a/k-Wave/testing/unit/runUnitTests_show_results.m +++ b/k-Wave/testing/unit/runUnitTests_show_results.m @@ -49,9 +49,9 @@ function runUnitTests_show_results(test_struct) % append the test result if results(i).pass - disp([' ' fn 'passed']); + disp(['✅ ' fn 'passed']); else - disp([' ' fn 'failed']); + disp(['❌ ' fn 'failed']); end end @@ -73,9 +73,5 @@ function runUnitTests_show_results(test_struct) fn = results(i).test; fn = fn(1:end - 2); disp(fn); - if ~isempty(results(i).test_info) - fprintf('%s\n', results(i).test_info); - disp(' '); - end end end \ No newline at end of file From 5d90eaedd4ed69ca707f77fbd3e88f89aa621ba1 Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Mon, 28 Jul 2025 12:46:51 +0100 Subject: [PATCH 03/38] run workflow on all tests --- .github/workflows/unit_tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index f7cdd0b..3a5aed2 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -23,7 +23,7 @@ jobs: command: | addpath("${{ github.workspace }}/k-Wave"); cd("${{ github.workspace }}/k-Wave/testing/unit"); - test_struct = runUnitTests("save",false); + test_struct = runUnitTests("",false); save('test_struct.mat', 'test_struct'); startup-options: -nojvm -logfile output.log From aff0b7e907e83235274b84d240a51ad7caf60218 Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Tue, 29 Jul 2025 16:15:33 +0100 Subject: [PATCH 04/38] refactor workflow: separate show test results and create artifact steps --- .github/workflows/unit_tests.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 3a5aed2..db63a1c 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -27,7 +27,7 @@ jobs: save('test_struct.mat', 'test_struct'); startup-options: -nojvm -logfile output.log - - name: Show test results & create artifact + - name: Show test results uses: matlab-actions/run-command@v2 with: command: | @@ -35,6 +35,15 @@ jobs: cd("${{ github.workspace }}/k-Wave/testing/unit"); load('test_struct.mat', 'test_struct'); runUnitTests_show_results(test_struct); + startup-options: -nojvm + + - name: Create artifact + uses: matlab-actions/run-command@v2 + with: + command: | + addpath("${{ github.workspace }}/k-Wave"); + cd("${{ github.workspace }}/k-Wave/testing/unit"); + load('test_struct.mat', 'test_struct'); runUnitTests_artifact(test_struct); startup-options: -nojvm From 7d4678caf58c1471f8a74a6da74bc38662290e3d Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Tue, 29 Jul 2025 16:26:56 +0100 Subject: [PATCH 05/38] enhance display of results --- .../testing/unit/runUnitTests_show_results.m | 45 ++++++++++--------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/k-Wave/testing/unit/runUnitTests_show_results.m b/k-Wave/testing/unit/runUnitTests_show_results.m index 2e6e845..42af529 100644 --- a/k-Wave/testing/unit/runUnitTests_show_results.m +++ b/k-Wave/testing/unit/runUnitTests_show_results.m @@ -2,11 +2,8 @@ function runUnitTests_show_results(test_struct) %RUNUNITTESTS_SHOW_RESULTS Display MATLAB unit test results in a formatted summary. % % DESCRIPTION: -% runUnitTests_show_results displays the results from the provided test_struct -% in a formatted summary, including test details, individual test outcomes, -% and a summary of passed and failed tests. +% runUnitTests_show_results displays the results from the provided test_struct. % - % ========================================================================= % DISPLAY SUMMARY % ========================================================================= @@ -35,6 +32,25 @@ function runUnitTests_show_results(test_struct) disp(['TESTS COMPLETED IN: ' info.completion_time]); disp(' '); +% display test summary +disp(' '); +num_passed = sum([results.pass]); +num_failed = numel(results) - num_passed; +disp(['✅ Number of tests passed: ' num2str(num_passed)]); +disp(['❌ Number of tests failed: ' num2str(num_failed)]); +disp(' '); + +% Show failed tests using test_struct +failed_idx = find(~[results.pass]); +if ~isempty(failed_idx) + disp('FAILED TESTS:'); + for i = failed_idx + fn = results(i).test; + fn = fn(1:end - 2); + disp(['❌ ' fn 'failed']); + end +end + % display individual test results disp('UNIT TEST RESULTS:'); @@ -57,21 +73,6 @@ function runUnitTests_show_results(test_struct) end % display test summary -disp(' '); -disp('UNIT TEST SUMMARY:'); -num_passed = sum([results.pass]); -num_failed = numel(results) - num_passed; -disp(['✅ Number of tests passed: ' num2str(num_passed)]); -disp(['❌ Number of tests failed: ' num2str(num_failed)]); -disp(' '); - -% Show failed tests using test_struct -failed_idx = find(~[results.pass]); -if ~isempty(failed_idx) - disp('❌ FAILED TESTS:'); - for i = failed_idx - fn = results(i).test; - fn = fn(1:end - 2); - disp(fn); - end -end \ No newline at end of file +disp('NOTE:'); +disp('Test output details are in the "Run unit tests" section of the workflow.'); +disp('You can also download a JSON summary from the "Upload Artifact" section in your CI logs or dashboard.'); From cf0fc46de5119b72d556ed883cee397dad4ccd34 Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Tue, 29 Jul 2025 16:43:15 +0100 Subject: [PATCH 06/38] exit if test fails --- .github/workflows/unit_tests.yml | 19 ++++++++++--------- .../testing/unit/runUnitTests_show_results.m | 5 +++++ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index db63a1c..716fd53 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -27,28 +27,29 @@ jobs: save('test_struct.mat', 'test_struct'); startup-options: -nojvm -logfile output.log - - name: Show test results + - name: Create artifact uses: matlab-actions/run-command@v2 with: command: | addpath("${{ github.workspace }}/k-Wave"); cd("${{ github.workspace }}/k-Wave/testing/unit"); load('test_struct.mat', 'test_struct'); - runUnitTests_show_results(test_struct); + runUnitTests_artifact(test_struct); startup-options: -nojvm - - name: Create artifact + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: unit_test_results + path: ${{ github.workspace }}/k-Wave/testing/unit/test_results.json + + - name: Test results uses: matlab-actions/run-command@v2 with: command: | addpath("${{ github.workspace }}/k-Wave"); cd("${{ github.workspace }}/k-Wave/testing/unit"); load('test_struct.mat', 'test_struct'); - runUnitTests_artifact(test_struct); + runUnitTests_show_results(test_struct); startup-options: -nojvm - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: unit_test_results - path: ${{ github.workspace }}/k-Wave/testing/unit/test_results.json diff --git a/k-Wave/testing/unit/runUnitTests_show_results.m b/k-Wave/testing/unit/runUnitTests_show_results.m index 42af529..9e873f6 100644 --- a/k-Wave/testing/unit/runUnitTests_show_results.m +++ b/k-Wave/testing/unit/runUnitTests_show_results.m @@ -76,3 +76,8 @@ function runUnitTests_show_results(test_struct) disp('NOTE:'); disp('Test output details are in the "Run unit tests" section of the workflow.'); disp('You can also download a JSON summary from the "Upload Artifact" section in your CI logs or dashboard.'); + +% Fail if any tests failed (for CI integration) +if num_failed > 0 + exit(1); +end From 9aac0c4192e038d6f8c11177c8eaf533c296f08d Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Tue, 29 Jul 2025 16:45:28 +0100 Subject: [PATCH 07/38] run kWaveDiffusion_compare_3D_heterog tests --- .github/workflows/unit_tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 716fd53..b914b24 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -23,7 +23,7 @@ jobs: command: | addpath("${{ github.workspace }}/k-Wave"); cd("${{ github.workspace }}/k-Wave/testing/unit"); - test_struct = runUnitTests("",false); + test_struct = runUnitTests("kWaveDiffusion_compare_3D_heterog",false); save('test_struct.mat', 'test_struct'); startup-options: -nojvm -logfile output.log From d30bac8ef0e9984b16b74ffa3ddb817dd36880c0 Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Tue, 29 Jul 2025 16:48:42 +0100 Subject: [PATCH 08/38] replace exit with error for failed unit tests in CI integration --- k-Wave/testing/unit/runUnitTests_show_results.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/k-Wave/testing/unit/runUnitTests_show_results.m b/k-Wave/testing/unit/runUnitTests_show_results.m index 9e873f6..1fdf3e1 100644 --- a/k-Wave/testing/unit/runUnitTests_show_results.m +++ b/k-Wave/testing/unit/runUnitTests_show_results.m @@ -79,5 +79,5 @@ function runUnitTests_show_results(test_struct) % Fail if any tests failed (for CI integration) if num_failed > 0 - exit(1); + error('Some unit tests failed. See above for details.'); end From 6196596c2668307af705000306b20193d8c76196 Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Tue, 29 Jul 2025 16:49:29 +0100 Subject: [PATCH 09/38] add spacing before error message for failed unit tests in CI integration --- k-Wave/testing/unit/runUnitTests_show_results.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/k-Wave/testing/unit/runUnitTests_show_results.m b/k-Wave/testing/unit/runUnitTests_show_results.m index 1fdf3e1..0bcec88 100644 --- a/k-Wave/testing/unit/runUnitTests_show_results.m +++ b/k-Wave/testing/unit/runUnitTests_show_results.m @@ -71,6 +71,7 @@ function runUnitTests_show_results(test_struct) end end +disp(' '); % display test summary disp('NOTE:'); @@ -79,5 +80,6 @@ function runUnitTests_show_results(test_struct) % Fail if any tests failed (for CI integration) if num_failed > 0 + disp(' '); error('Some unit tests failed. See above for details.'); end From d46e93415efdd0be8cf58ec6590eb0fb0989ce21 Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Tue, 29 Jul 2025 16:52:00 +0100 Subject: [PATCH 10/38] remove unnecessary display messages after saving unit test results --- k-Wave/testing/unit/runUnitTests_artifact.m | 3 --- 1 file changed, 3 deletions(-) diff --git a/k-Wave/testing/unit/runUnitTests_artifact.m b/k-Wave/testing/unit/runUnitTests_artifact.m index d62ae52..d346a3e 100644 --- a/k-Wave/testing/unit/runUnitTests_artifact.m +++ b/k-Wave/testing/unit/runUnitTests_artifact.m @@ -14,6 +14,3 @@ function runUnitTests_artifact(test_struct) fclose(fid); end -disp(' '); -disp('UNIT TEST RESULTS SAVED TO test_results.json'); -disp(' '); From 094d8900aeda9a4d064b41eb9cb927fb454d46e9 Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Tue, 29 Jul 2025 16:55:02 +0100 Subject: [PATCH 11/38] add failure messages and change exit to error for failed unit tests in CI integration --- k-Wave/testing/unit/runUnitTests_show_results.m | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/k-Wave/testing/unit/runUnitTests_show_results.m b/k-Wave/testing/unit/runUnitTests_show_results.m index 0bcec88..5ca52f6 100644 --- a/k-Wave/testing/unit/runUnitTests_show_results.m +++ b/k-Wave/testing/unit/runUnitTests_show_results.m @@ -78,8 +78,12 @@ function runUnitTests_show_results(test_struct) disp('Test output details are in the "Run unit tests" section of the workflow.'); disp('You can also download a JSON summary from the "Upload Artifact" section in your CI logs or dashboard.'); +disp(' '); % Fail if any tests failed (for CI integration) if num_failed > 0 + disp('Some of the tests have failed.'); + disp('For details see the above.'); disp(' '); - error('Some unit tests failed. See above for details.'); + exit(0); +end end From 4764e9f070907ef435557ea602dea54405a728c0 Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Tue, 29 Jul 2025 17:00:32 +0100 Subject: [PATCH 12/38] non zero exit status --- k-Wave/testing/unit/runUnitTests_show_results.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/k-Wave/testing/unit/runUnitTests_show_results.m b/k-Wave/testing/unit/runUnitTests_show_results.m index 5ca52f6..06b78a0 100644 --- a/k-Wave/testing/unit/runUnitTests_show_results.m +++ b/k-Wave/testing/unit/runUnitTests_show_results.m @@ -84,6 +84,6 @@ function runUnitTests_show_results(test_struct) disp('Some of the tests have failed.'); disp('For details see the above.'); disp(' '); - exit(0); + exit(1); end end From ceed84b796868f546b216dfdbbefdd46255ea2ba Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Tue, 29 Jul 2025 17:05:18 +0100 Subject: [PATCH 13/38] add message before exit to indicate CI detection of failed tests --- k-Wave/testing/unit/runUnitTests_show_results.m | 1 + 1 file changed, 1 insertion(+) diff --git a/k-Wave/testing/unit/runUnitTests_show_results.m b/k-Wave/testing/unit/runUnitTests_show_results.m index 06b78a0..91dc35d 100644 --- a/k-Wave/testing/unit/runUnitTests_show_results.m +++ b/k-Wave/testing/unit/runUnitTests_show_results.m @@ -84,6 +84,7 @@ function runUnitTests_show_results(test_struct) disp('Some of the tests have failed.'); disp('For details see the above.'); disp(' '); + disp('Exiting so that CI detects failed tests.'); exit(1); end end From 78621de691638e2f96ae90dbc19648990bda1892 Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Tue, 29 Jul 2025 17:05:48 +0100 Subject: [PATCH 14/38] run on all tests --- .github/workflows/unit_tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index b914b24..716fd53 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -23,7 +23,7 @@ jobs: command: | addpath("${{ github.workspace }}/k-Wave"); cd("${{ github.workspace }}/k-Wave/testing/unit"); - test_struct = runUnitTests("kWaveDiffusion_compare_3D_heterog",false); + test_struct = runUnitTests("",false); save('test_struct.mat', 'test_struct'); startup-options: -nojvm -logfile output.log From 1e0aeeffa396725a498de0cbbc9c2f702c5f540b Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Wed, 30 Jul 2025 08:12:09 +0100 Subject: [PATCH 15/38] adjust formatting --- k-Wave/testing/unit/runUnitTests_show_results.m | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/k-Wave/testing/unit/runUnitTests_show_results.m b/k-Wave/testing/unit/runUnitTests_show_results.m index 91dc35d..2ca553e 100644 --- a/k-Wave/testing/unit/runUnitTests_show_results.m +++ b/k-Wave/testing/unit/runUnitTests_show_results.m @@ -49,6 +49,7 @@ function runUnitTests_show_results(test_struct) fn = fn(1:end - 2); disp(['❌ ' fn 'failed']); end + disp(' '); end % display individual test results @@ -81,10 +82,8 @@ function runUnitTests_show_results(test_struct) disp(' '); % Fail if any tests failed (for CI integration) if num_failed > 0 - disp('Some of the tests have failed.'); - disp('For details see the above.'); disp(' '); - disp('Exiting so that CI detects failed tests.'); + disp('Exiting so that CI detects test failure.'); exit(1); end end From 0fb5149be21de42d084814ed63d385e6e4b1e903 Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Wed, 30 Jul 2025 08:42:28 +0100 Subject: [PATCH 16/38] correct workflow triggers --- .github/workflows/unit_tests.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 716fd53..0ff941c 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -2,6 +2,11 @@ name: Run unit tests on: push: + branches: + - main + pull_request: + branches: + - main jobs: unit-tests: From c808a3daa68dffb74b5b104a97fa6cdbe42c9ebc Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Wed, 30 Jul 2025 10:32:37 +0100 Subject: [PATCH 17/38] add regression tests workflow --- .github/workflows/regression_tests.yml | 37 ++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .github/workflows/regression_tests.yml diff --git a/.github/workflows/regression_tests.yml b/.github/workflows/regression_tests.yml new file mode 100644 index 0000000..e5c1828 --- /dev/null +++ b/.github/workflows/regression_tests.yml @@ -0,0 +1,37 @@ +name: Run regression tests + +on: + push: + +jobs: + regression-tests: + name: Run regression tests + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Set up MATLAB + uses: matlab-actions/setup-matlab@v2 + with: + products: Signal_Processing_Toolbox + cache: true + + - name: Generate data + uses: matlab-actions/run-command@v2 + with: + command: | + addpath("${{ github.workspace }}/k-Wave"); + cd("${{ github.workspace }}/k-Wave/testing/regression"); + generateRegressionData + startup-options: -nojvm + + - name: Test results + uses: matlab-actions/run-command@v2 + with: + command: | + addpath("${{ github.workspace }}/k-Wave"); + cd("${{ github.workspace }}/k-Wave/testing/regression"); + runRegressionTests("${{ github.workspace }}/k-Wave/testing/regression") + startup-options: -nojvm + From 9fcad9cf32face18c163d46a0a51f95c307a0758 Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Wed, 30 Jul 2025 10:53:17 +0100 Subject: [PATCH 18/38] only do the first regression test For testing the workflow --- .../regression/generateRegressionData.m | 655 +++++++++--------- 1 file changed, 328 insertions(+), 327 deletions(-) diff --git a/k-Wave/testing/regression/generateRegressionData.m b/k-Wave/testing/regression/generateRegressionData.m index 26ed406..586b955 100644 --- a/k-Wave/testing/regression/generateRegressionData.m +++ b/k-Wave/testing/regression/generateRegressionData.m @@ -35,333 +35,333 @@ test_examples{index}.outputs = {'sensor_data'}; test_examples{index}.precision = 'double'; -index = index + 1; -test_examples{index}.name = 'example_ivp_binary_sensor_mask'; -test_examples{index}.outputs = {'sensor_data', 'sensor_data_reordered'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_ivp_opposing_corners_sensor_mask'; -test_examples{index}.outputs = {'sensor_data'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_ivp_loading_external_image'; -test_examples{index}.outputs = {'sensor_data'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_ivp_heterogeneous_medium'; -test_examples{index}.outputs = {'sensor_data'}; -test_examples{index}.precision = 'double'; - -% NOT TESTED: example_ivp_saving_movie_files (no sensor data) - -index = index + 1; -test_examples{index}.name = 'example_ivp_recording_particle_velocity'; -test_examples{index}.outputs = {'sensor_data'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_ivp_sensor_frequency_response'; -test_examples{index}.outputs = {'sensor_data', 'sensor_data_filtered'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_ivp_comparison_modelling_functions'; -test_examples{index}.outputs = {'sensor_data_first_order', 'sensor_data_second_order'}; -test_examples{index}.precision = 'double'; - -% NOT TESTED: example_ivp_setting_initial_gradient (no sensor data) - -index = index + 1; -test_examples{index}.name = 'example_ivp_1D_simulation'; -test_examples{index}.outputs = {'sensor_data'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_ivp_3D_simulation'; -test_examples{index}.outputs = {'sensor_data'}; -test_examples{index}.precision = 'single'; - -index = index + 1; -test_examples{index}.name = 'example_ivp_axisymmetric_simulation'; -test_examples{index}.outputs = {'sensor_data'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_ivp_photoacoustic_waveforms'; -test_examples{index}.outputs = {'sensor_data_1D', 'sensor_data_2D', 'sensor_data_3D'}; -test_examples{index}.precision = 'single'; - -% ========================================================================= -% TIME VARYING SOURCE PROBLEMS -% ========================================================================= - -index = index + 1; -test_examples{index}.name = 'example_tvsp_homogeneous_medium_monopole'; -test_examples{index}.outputs = {'sensor_data'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_tvsp_homogeneous_medium_dipole'; -test_examples{index}.outputs = {'sensor_data'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_tvsp_transducer_field_patterns'; -test_examples{index}.outputs = {'sensor_data'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_tvsp_steering_linear_array'; -test_examples{index}.outputs = {'source'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_tvsp_snells_law'; -test_examples{index}.outputs = {'source'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_tvsp_doppler_effect'; -test_examples{index}.outputs = {'sensor_data', 'approach_as', 'retreat_as'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_tvsp_slit_diffraction'; -test_examples{index}.outputs = {'sensor_data'}; -test_examples{index}.precision = 'single'; - -index = index + 1; -test_examples{index}.name = 'example_tvsp_3D_simulation'; -test_examples{index}.outputs = {'sensor_data'}; -test_examples{index}.precision = 'single'; - -index = index + 1; -test_examples{index}.name = 'example_tvsp_acoustic_field_propagator'; -test_examples{index}.outputs = {'amp_out', 'phase_out'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_tvsp_angular_spectrum'; -test_examples{index}.outputs = {'plane_2_kw', 'plane_2_as'}; -test_examples{index}.precision = 'single'; - -index = index + 1; -test_examples{index}.name = 'example_tvsp_equivalent_source_holography'; -test_examples{index}.outputs = {'sensor_data', 'source_estimate', 'proj_asm', 'proj_dirch', 'proj_eqs'}; -test_examples{index}.precision = 'single'; - -% ========================================================================= -% SENSOR DIRECTIVITY -% ========================================================================= - -index = index + 1; -test_examples{index}.name = 'example_sd_focussed_detector_2D'; -test_examples{index}.outputs = {'sensor_data1', 'sensor_data2'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_sd_focussed_detector_3D'; -test_examples{index}.outputs = {'sensor_data1', 'sensor_data2'}; -test_examples{index}.precision = 'single'; - -index = index + 1; -test_examples{index}.name = 'example_sd_directivity_modelling_2D'; -test_examples{index}.outputs = {'sensor_data', 'single_element_data'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_sd_directivity_modelling_3D'; -test_examples{index}.outputs = {'sensor_data', 'single_element_data'}; -test_examples{index}.precision = 'single'; - -index = index + 1; -test_examples{index}.name = 'example_sd_sensor_directivity_2D'; -test_examples{index}.outputs = {'sensor_data1', 'sensor_data2'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_sd_directional_array_elements'; -test_examples{index}.outputs = {'sensor_data', 'element_data'}; -test_examples{index}.precision = 'double'; - -% ========================================================================= -% PHOTOACOUSTIC IMAGE RECONSTRUCTION -% ========================================================================= - -index = index + 1; -test_examples{index}.name = 'example_pr_2D_FFT_line_sensor'; -test_examples{index}.outputs = {'sensor_data', 'p_xy', 'p_xy_rs'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_pr_3D_FFT_planar_sensor'; -test_examples{index}.outputs = {'sensor_data', 'p_xyz', 'p_xyz_rs'}; -test_examples{index}.precision = 'single'; - -index = index + 1; -test_examples{index}.name = 'example_pr_2D_TR_line_sensor'; -test_examples{index}.outputs = {'sensor_data', 'p0_recon', 'p_xy', 'p_xy_rs'}; -test_examples{index}.precision = 'double'; - -% NOT TESTED: example_pr_2D_TR_circular_sensor (random noise added) - -index = index + 1; -test_examples{index}.name = 'example_pr_3D_TR_planar_sensor'; -test_examples{index}.outputs = {'sensor_data', 'p0_recon'}; -test_examples{index}.precision = 'single'; - -index = index + 1; -test_examples{index}.name = 'example_pr_3D_TR_spherical_sensor'; -test_examples{index}.outputs = {'sensor_data', 'p0_recon', 'p0_recon_interp'}; -test_examples{index}.precision = 'single'; - -index = index + 1; -test_examples{index}.name = 'example_pr_2D_TR_directional_sensors'; -test_examples{index}.outputs = {'sensor_data', 'p0_recon', 'p0_recon_directional'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_pr_2D_TR_bandlimited_sensors'; -test_examples{index}.outputs = {'sensor_data', 'p0_recon', 'p0_recon_high_pass', 'p0_recon_low_pass', 'p0_recon_gaussian'}; -test_examples{index}.precision = 'double'; - -% NOT TESTED: example_pr_2D_TR_absorption_compensation (random noise added) -% NOT TESTED: example_pr_2D_TR_time_variant_filtering (random noise added) - -index = index + 1; -test_examples{index}.name = 'example_pr_2D_TR_autofocus'; -test_examples{index}.outputs = {'sensor_data', 'focus_func'}; -test_examples{index}.precision = 'single'; - -index = index + 1; -test_examples{index}.name = 'example_pr_2D_TR_iterative'; -test_examples{index}.outputs = {'sensor_data', 'p0_estimate'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_pr_2D_adjoint'; -test_examples{index}.outputs = {'sensor_data', 'p0', 'p0_1', 'p0_2', 'p0_3', 'p0_4', 'p0_5'}; -test_examples{index}.precision = 'double'; - -% ========================================================================= -% DIAGNOSTIC ULTRASOUND SIMULATION -% ========================================================================= - -index = index + 1; -test_examples{index}.name = 'example_us_defining_transducer'; -test_examples{index}.outputs = {'sensor_data', 'as_1', 'as_2', 'as_3'}; -test_examples{index}.precision = 'single'; - -index = index + 1; -test_examples{index}.name = 'example_us_beam_patterns'; -test_examples{index}.outputs = {'sensor_data'}; -test_examples{index}.precision = 'single'; - -index = index + 1; -test_examples{index}.name = 'example_us_transducer_as_sensor'; -test_examples{index}.outputs = {'sensor_data', 'scan_line'}; -test_examples{index}.precision = 'single'; - -% NOT TESTED: example_us_bmode_linear_transducer (random noise added) -% NOT TESTED: example_us_bmode_phased_array (random noise added) - -% ========================================================================= -% NUMERICAL ANALYSIS -% ========================================================================= - -index = index + 1; -test_examples{index}.name = 'example_na_controlling_the_PML'; -test_examples{index}.outputs = {'sensor_data'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_na_source_smoothing'; -test_examples{index}.outputs = {'sensor_data'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_na_filtering_part_1'; -test_examples{index}.outputs = {'sensor_data', 'output_as'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_na_filtering_part_2'; -test_examples{index}.outputs = {'sensor_data', 'output_as'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_na_filtering_part_3'; -test_examples{index}.outputs = {'source_func_as', 'source_func_filtered_as', 'sensor_data', 'output_as'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_na_modelling_absorption'; -test_examples{index}.outputs = {'attenuation', 'attenuation_th', 'cp', 'cp_kk'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_na_modelling_nonlinearity'; -test_examples{index}.outputs = {'sensor_data', 'p_mendousse'}; -test_examples{index}.precision = 'double'; - -% NOT TESTED: example_na_optimising_performance (no output) - -% ========================================================================= -% USING THE C++ CODE -% ========================================================================= - -% NOT TESTED - -% ========================================================================= -% ELASTIC WAVE PROPAGATION -% ========================================================================= - -index = index + 1; -test_examples{index}.name = 'example_ewp_layered_medium'; -test_examples{index}.outputs = {'sensor_data', 'sensor_data_reordered'}; -test_examples{index}.precision = 'single'; - -index = index + 1; -test_examples{index}.name = 'example_ewp_plane_wave_absorption'; -test_examples{index}.outputs = {'sensor_data_comp', 'attenuation_comp', 'sensor_data_shear', 'attenuation_shear'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_ewp_shear_wave_snells_law'; -test_examples{index}.outputs = {'sensor_data_fluid', 'sensor_data_elastic'}; -test_examples{index}.precision = 'single'; - -index = index + 1; -test_examples{index}.name = 'example_ewp_3D_simulation'; -test_examples{index}.outputs = {'sensor_data'}; -test_examples{index}.precision = 'single'; - -% ========================================================================= -% THERMAL DIFFUSION -% ========================================================================= - -index = index + 1; -test_examples{index}.name = 'example_diff_homogeneous_medium_diffusion'; -test_examples{index}.outputs = {'T_exact', 'kdiff'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_diff_homogeneous_medium_source'; -test_examples{index}.outputs = {'T_exact', 'kdiff'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_diff_binary_sensor_mask'; -test_examples{index}.outputs = {'kdiff'}; -test_examples{index}.precision = 'double'; - -index = index + 1; -test_examples{index}.name = 'example_diff_focused_ultrasound_heating'; -test_examples{index}.outputs = {'sensor_data', 'source', 'T1', 'T2', 'kdiff'}; -test_examples{index}.precision = 'double'; +% index = index + 1; +% test_examples{index}.name = 'example_ivp_binary_sensor_mask'; +% test_examples{index}.outputs = {'sensor_data', 'sensor_data_reordered'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_ivp_opposing_corners_sensor_mask'; +% test_examples{index}.outputs = {'sensor_data'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_ivp_loading_external_image'; +% test_examples{index}.outputs = {'sensor_data'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_ivp_heterogeneous_medium'; +% test_examples{index}.outputs = {'sensor_data'}; +% test_examples{index}.precision = 'double'; + +% % NOT TESTED: example_ivp_saving_movie_files (no sensor data) + +% index = index + 1; +% test_examples{index}.name = 'example_ivp_recording_particle_velocity'; +% test_examples{index}.outputs = {'sensor_data'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_ivp_sensor_frequency_response'; +% test_examples{index}.outputs = {'sensor_data', 'sensor_data_filtered'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_ivp_comparison_modelling_functions'; +% test_examples{index}.outputs = {'sensor_data_first_order', 'sensor_data_second_order'}; +% test_examples{index}.precision = 'double'; + +% % NOT TESTED: example_ivp_setting_initial_gradient (no sensor data) + +% index = index + 1; +% test_examples{index}.name = 'example_ivp_1D_simulation'; +% test_examples{index}.outputs = {'sensor_data'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_ivp_3D_simulation'; +% test_examples{index}.outputs = {'sensor_data'}; +% test_examples{index}.precision = 'single'; + +% index = index + 1; +% test_examples{index}.name = 'example_ivp_axisymmetric_simulation'; +% test_examples{index}.outputs = {'sensor_data'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_ivp_photoacoustic_waveforms'; +% test_examples{index}.outputs = {'sensor_data_1D', 'sensor_data_2D', 'sensor_data_3D'}; +% test_examples{index}.precision = 'single'; + +% % ========================================================================= +% % TIME VARYING SOURCE PROBLEMS +% % ========================================================================= + +% index = index + 1; +% test_examples{index}.name = 'example_tvsp_homogeneous_medium_monopole'; +% test_examples{index}.outputs = {'sensor_data'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_tvsp_homogeneous_medium_dipole'; +% test_examples{index}.outputs = {'sensor_data'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_tvsp_transducer_field_patterns'; +% test_examples{index}.outputs = {'sensor_data'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_tvsp_steering_linear_array'; +% test_examples{index}.outputs = {'source'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_tvsp_snells_law'; +% test_examples{index}.outputs = {'source'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_tvsp_doppler_effect'; +% test_examples{index}.outputs = {'sensor_data', 'approach_as', 'retreat_as'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_tvsp_slit_diffraction'; +% test_examples{index}.outputs = {'sensor_data'}; +% test_examples{index}.precision = 'single'; + +% index = index + 1; +% test_examples{index}.name = 'example_tvsp_3D_simulation'; +% test_examples{index}.outputs = {'sensor_data'}; +% test_examples{index}.precision = 'single'; + +% index = index + 1; +% test_examples{index}.name = 'example_tvsp_acoustic_field_propagator'; +% test_examples{index}.outputs = {'amp_out', 'phase_out'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_tvsp_angular_spectrum'; +% test_examples{index}.outputs = {'plane_2_kw', 'plane_2_as'}; +% test_examples{index}.precision = 'single'; + +% index = index + 1; +% test_examples{index}.name = 'example_tvsp_equivalent_source_holography'; +% test_examples{index}.outputs = {'sensor_data', 'source_estimate', 'proj_asm', 'proj_dirch', 'proj_eqs'}; +% test_examples{index}.precision = 'single'; + +% % ========================================================================= +% % SENSOR DIRECTIVITY +% % ========================================================================= + +% index = index + 1; +% test_examples{index}.name = 'example_sd_focussed_detector_2D'; +% test_examples{index}.outputs = {'sensor_data1', 'sensor_data2'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_sd_focussed_detector_3D'; +% test_examples{index}.outputs = {'sensor_data1', 'sensor_data2'}; +% test_examples{index}.precision = 'single'; + +% index = index + 1; +% test_examples{index}.name = 'example_sd_directivity_modelling_2D'; +% test_examples{index}.outputs = {'sensor_data', 'single_element_data'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_sd_directivity_modelling_3D'; +% test_examples{index}.outputs = {'sensor_data', 'single_element_data'}; +% test_examples{index}.precision = 'single'; + +% index = index + 1; +% test_examples{index}.name = 'example_sd_sensor_directivity_2D'; +% test_examples{index}.outputs = {'sensor_data1', 'sensor_data2'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_sd_directional_array_elements'; +% test_examples{index}.outputs = {'sensor_data', 'element_data'}; +% test_examples{index}.precision = 'double'; + +% % ========================================================================= +% % PHOTOACOUSTIC IMAGE RECONSTRUCTION +% % ========================================================================= + +% index = index + 1; +% test_examples{index}.name = 'example_pr_2D_FFT_line_sensor'; +% test_examples{index}.outputs = {'sensor_data', 'p_xy', 'p_xy_rs'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_pr_3D_FFT_planar_sensor'; +% test_examples{index}.outputs = {'sensor_data', 'p_xyz', 'p_xyz_rs'}; +% test_examples{index}.precision = 'single'; + +% index = index + 1; +% test_examples{index}.name = 'example_pr_2D_TR_line_sensor'; +% test_examples{index}.outputs = {'sensor_data', 'p0_recon', 'p_xy', 'p_xy_rs'}; +% test_examples{index}.precision = 'double'; + +% % NOT TESTED: example_pr_2D_TR_circular_sensor (random noise added) + +% index = index + 1; +% test_examples{index}.name = 'example_pr_3D_TR_planar_sensor'; +% test_examples{index}.outputs = {'sensor_data', 'p0_recon'}; +% test_examples{index}.precision = 'single'; + +% index = index + 1; +% test_examples{index}.name = 'example_pr_3D_TR_spherical_sensor'; +% test_examples{index}.outputs = {'sensor_data', 'p0_recon', 'p0_recon_interp'}; +% test_examples{index}.precision = 'single'; + +% index = index + 1; +% test_examples{index}.name = 'example_pr_2D_TR_directional_sensors'; +% test_examples{index}.outputs = {'sensor_data', 'p0_recon', 'p0_recon_directional'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_pr_2D_TR_bandlimited_sensors'; +% test_examples{index}.outputs = {'sensor_data', 'p0_recon', 'p0_recon_high_pass', 'p0_recon_low_pass', 'p0_recon_gaussian'}; +% test_examples{index}.precision = 'double'; + +% % NOT TESTED: example_pr_2D_TR_absorption_compensation (random noise added) +% % NOT TESTED: example_pr_2D_TR_time_variant_filtering (random noise added) + +% index = index + 1; +% test_examples{index}.name = 'example_pr_2D_TR_autofocus'; +% test_examples{index}.outputs = {'sensor_data', 'focus_func'}; +% test_examples{index}.precision = 'single'; + +% index = index + 1; +% test_examples{index}.name = 'example_pr_2D_TR_iterative'; +% test_examples{index}.outputs = {'sensor_data', 'p0_estimate'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_pr_2D_adjoint'; +% test_examples{index}.outputs = {'sensor_data', 'p0', 'p0_1', 'p0_2', 'p0_3', 'p0_4', 'p0_5'}; +% test_examples{index}.precision = 'double'; + +% % ========================================================================= +% % DIAGNOSTIC ULTRASOUND SIMULATION +% % ========================================================================= + +% index = index + 1; +% test_examples{index}.name = 'example_us_defining_transducer'; +% test_examples{index}.outputs = {'sensor_data', 'as_1', 'as_2', 'as_3'}; +% test_examples{index}.precision = 'single'; + +% index = index + 1; +% test_examples{index}.name = 'example_us_beam_patterns'; +% test_examples{index}.outputs = {'sensor_data'}; +% test_examples{index}.precision = 'single'; + +% index = index + 1; +% test_examples{index}.name = 'example_us_transducer_as_sensor'; +% test_examples{index}.outputs = {'sensor_data', 'scan_line'}; +% test_examples{index}.precision = 'single'; + +% % NOT TESTED: example_us_bmode_linear_transducer (random noise added) +% % NOT TESTED: example_us_bmode_phased_array (random noise added) + +% % ========================================================================= +% % NUMERICAL ANALYSIS +% % ========================================================================= + +% index = index + 1; +% test_examples{index}.name = 'example_na_controlling_the_PML'; +% test_examples{index}.outputs = {'sensor_data'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_na_source_smoothing'; +% test_examples{index}.outputs = {'sensor_data'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_na_filtering_part_1'; +% test_examples{index}.outputs = {'sensor_data', 'output_as'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_na_filtering_part_2'; +% test_examples{index}.outputs = {'sensor_data', 'output_as'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_na_filtering_part_3'; +% test_examples{index}.outputs = {'source_func_as', 'source_func_filtered_as', 'sensor_data', 'output_as'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_na_modelling_absorption'; +% test_examples{index}.outputs = {'attenuation', 'attenuation_th', 'cp', 'cp_kk'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_na_modelling_nonlinearity'; +% test_examples{index}.outputs = {'sensor_data', 'p_mendousse'}; +% test_examples{index}.precision = 'double'; + +% % NOT TESTED: example_na_optimising_performance (no output) + +% % ========================================================================= +% % USING THE C++ CODE +% % ========================================================================= + +% % NOT TESTED + +% % ========================================================================= +% % ELASTIC WAVE PROPAGATION +% % ========================================================================= + +% index = index + 1; +% test_examples{index}.name = 'example_ewp_layered_medium'; +% test_examples{index}.outputs = {'sensor_data', 'sensor_data_reordered'}; +% test_examples{index}.precision = 'single'; + +% index = index + 1; +% test_examples{index}.name = 'example_ewp_plane_wave_absorption'; +% test_examples{index}.outputs = {'sensor_data_comp', 'attenuation_comp', 'sensor_data_shear', 'attenuation_shear'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_ewp_shear_wave_snells_law'; +% test_examples{index}.outputs = {'sensor_data_fluid', 'sensor_data_elastic'}; +% test_examples{index}.precision = 'single'; + +% index = index + 1; +% test_examples{index}.name = 'example_ewp_3D_simulation'; +% test_examples{index}.outputs = {'sensor_data'}; +% test_examples{index}.precision = 'single'; + +% % ========================================================================= +% % THERMAL DIFFUSION +% % ========================================================================= + +% index = index + 1; +% test_examples{index}.name = 'example_diff_homogeneous_medium_diffusion'; +% test_examples{index}.outputs = {'T_exact', 'kdiff'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_diff_homogeneous_medium_source'; +% test_examples{index}.outputs = {'T_exact', 'kdiff'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_diff_binary_sensor_mask'; +% test_examples{index}.outputs = {'kdiff'}; +% test_examples{index}.precision = 'double'; + +% index = index + 1; +% test_examples{index}.name = 'example_diff_focused_ultrasound_heating'; +% test_examples{index}.outputs = {'sensor_data', 'source', 'T1', 'T2', 'kdiff'}; +% test_examples{index}.precision = 'double'; % ========================================================================= % GENERATE REGRESSION DATA @@ -410,6 +410,7 @@ load([tempdir 'generate_regression_data_TEMP_VARS']); % move to the testing directory + if ~exist(testing_dir, 'dir'), mkdir(testing_dir); end cd(testing_dir); % generate computer info and add precision From 7c0c9bcf9671fed2c8d193776fd8b1ba1843f978 Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Wed, 30 Jul 2025 11:02:58 +0100 Subject: [PATCH 19/38] add optional argument to display results in runRegressionTests function --- .../testing/regression/runRegressionTests.m | 79 ++++++------------- 1 file changed, 22 insertions(+), 57 deletions(-) diff --git a/k-Wave/testing/regression/runRegressionTests.m b/k-Wave/testing/regression/runRegressionTests.m index f2233b7..a05d464 100644 --- a/k-Wave/testing/regression/runRegressionTests.m +++ b/k-Wave/testing/regression/runRegressionTests.m @@ -1,4 +1,4 @@ -function runRegressionTests(data_folder) +function runRegressionTests(data_folder, show_results) %RUNREGRESSIONTESTS Run MATLAB regression tests. % % DESCRIPTION: @@ -18,6 +18,7 @@ function runRegressionTests(data_folder) % % INPUTS: % data_folder - string of folder containing regression data +% show_results - logical flag to display results (default: true) % % ABOUT: % author - Bradley Treeby @@ -44,6 +45,11 @@ function runRegressionTests(data_folder) %#ok<*NASGU> %#ok<*IDISVAR> +% Set defaults for optional arguments +if nargin < 2 || isempty(show_results) + show_results = true; +end + % start the timer regression_start_time = datetime('now'); @@ -260,65 +266,24 @@ function runRegressionTests(data_folder) end % ========================================================================= -% DISPLAY SUMMARY +% CREATE OUTPUT % ========================================================================= -% get information about PC +completion_time = scaleTime(seconds(datetime('now') - regression_start_time)); comp_info = getComputerInfo; +info = comp_info; +info.completion_time = completion_time; -% get k-Wave version -eval('cur_dir = pwd; cd(getkWavePath(''private'')); kwave_ver = getkWaveVersion; cd(cur_dir);'); - -% display test header -disp(' '); -disp('-------------------------------------------------------------------------------------'); -disp(' _ __ __ _____ _ '); -disp(' | | __ \ \ / /_ ___ _____ |_ _|__ ___| |_ ___ _ __ '); -disp(' | |/ /___\ \ /\ / / _` \ \ / / _ \ | |/ _ \/ __| __/ _ \ ''__|'); -disp(' | <_____\ V V / (_| |\ V / __/ | | __/\__ \ || __/ | '); -disp(' |_|\_\ \_/\_/ \__,_| \_/ \___| |_|\___||___/\__\___|_| '); -disp(' '); -disp('-------------------------------------------------------------------------------------'); -disp(' '); -disp(['DATE: ' comp_info.date]); -disp(['HOST NAME: ' comp_info.computer_name]); -disp(['USER NAME: ' comp_info.user_name]); -disp(['O/S TYPE: ' comp_info.operating_system_type]); -disp(['O/S: ' comp_info.operating_system]); -disp(['MATLAB VERSION: ' comp_info.matlab_version]); -disp(['TESTED K-WAVE VERSION: ' kwave_ver]); -disp(['TESTS COMPLETED IN: ' scaleTime(seconds(datetime('now') - regression_start_time))]); -disp(' '); - -% display individual test results -disp('REGRESSION TEST RESULTS:'); -for filename_index = 1:length(filenames) - - % trim the filename and add number - fn = filenames{filename_index}; - fn = [num2str(filename_index, '%02.f') ' ' fn(1:end - 4), ':']; - - % add some spaces to align results - fn = sprintf('%-50s', fn); - - % append the test result - if test_result(filename_index) - disp([' ' fn 'passed']); - else - disp([' ' fn 'failed']); - end -end - -% display test summary -disp(' '); -if all(test_result) - disp('ALL REGRESSION TESTS PASSED!'); -else - disp('REGRESSION TEST FAILED...'); -end +% create results struct +test_struct = struct( ... + 'info', info, ... + 'results', struct('test', filenames(:), 'pass', num2cell(test_result(:)), 'test_info', test_info(:)) ... +); -disp(' '); -disp('-------------------------------------------------------------------------------------'); +% ========================================================================= +% SHOW RESULTS +% ========================================================================= -% remove temp data -delete(temp_var_filename); \ No newline at end of file +if show_results + runUnitTests_show_results(test_struct); +end From 959d80eb811d7d4ea23de454218a14a9e72560e6 Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Wed, 30 Jul 2025 11:26:58 +0100 Subject: [PATCH 20/38] add test_info array and save error strings for regression tests --- k-Wave/testing/regression/runRegressionTests.m | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/k-Wave/testing/regression/runRegressionTests.m b/k-Wave/testing/regression/runRegressionTests.m index a05d464..f71ea8e 100644 --- a/k-Wave/testing/regression/runRegressionTests.m +++ b/k-Wave/testing/regression/runRegressionTests.m @@ -83,6 +83,9 @@ function runRegressionTests(data_folder, show_results) % keep a list of whether the test passed or failed test_result = false(num_files, 1); +% preallocate cell array for test_info with empty strings by default +test_info = repmat({''}, num_files, 1); + % ========================================================================= % RUN TESTS % ========================================================================= @@ -244,10 +247,14 @@ function runRegressionTests(data_folder, show_results) test_pass = true; fprintf('passed'); end + % save the error string + error_str = sprintf(' (L_inf = %e)\n', L_inf); % display the error - fprintf(' (L_inf = %e)\n', L_inf); - + fprintf('%s', error_str); + + % save L_inf as test_info + test_info{filename_index} = error_str; end % clear the variables just in case @@ -262,7 +269,6 @@ function runRegressionTests(data_folder, show_results) % store test result test_result(filename_index) = test_pass_overall; - end % ========================================================================= From e6477316fb23360b1f33afc5b534b97f77a576b2 Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Wed, 30 Jul 2025 11:33:39 +0100 Subject: [PATCH 21/38] add show_results to saved variables in runRegressionTests function --- k-Wave/testing/regression/runRegressionTests.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/k-Wave/testing/regression/runRegressionTests.m b/k-Wave/testing/regression/runRegressionTests.m index f71ea8e..ba342f5 100644 --- a/k-Wave/testing/regression/runRegressionTests.m +++ b/k-Wave/testing/regression/runRegressionTests.m @@ -102,7 +102,7 @@ function runRegressionTests(data_folder, show_results) save(temp_var_filename, ... 'DOUBLE_COMPARISON_THRESHOLD', 'SINGLE_COMPARISON_THRESHOLD', ... 'regression_test_folder', 'temp_var_filename', 'regression_start_time', ... - 'filename_index', 'filenames', 'fn', 'num_files', 'test_result'); + 'filename_index', 'filenames', 'fn', 'num_files', 'test_result', 'show_results'); % display the filename disp(' '); From d69208e92e6cc7278d201ed877c66bd5fd842d1b Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Wed, 30 Jul 2025 11:45:16 +0100 Subject: [PATCH 22/38] refactor: update regression test functions and add artifact saving --- .github/workflows/unit_tests.yml | 18 ++-- .../testing/regression/runRegressionTests.m | 2 +- k-Wave/testing/save_artifact.m | 16 ++++ k-Wave/testing/show_test_results.m | 83 +++++++++++++++++++ 4 files changed, 111 insertions(+), 8 deletions(-) create mode 100644 k-Wave/testing/save_artifact.m create mode 100644 k-Wave/testing/show_test_results.m diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 0ff941c..28395f5 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -2,11 +2,11 @@ name: Run unit tests on: push: - branches: - - main - pull_request: - branches: - - main + # branches: + # - main + # pull_request: + # branches: + # - main jobs: unit-tests: @@ -28,7 +28,7 @@ jobs: command: | addpath("${{ github.workspace }}/k-Wave"); cd("${{ github.workspace }}/k-Wave/testing/unit"); - test_struct = runUnitTests("",false); + test_struct = runUnitTests("spaceFirstOrder_check_plane_wave_intensity",false); save('test_struct.mat', 'test_struct'); startup-options: -nojvm -logfile output.log @@ -55,6 +55,10 @@ jobs: addpath("${{ github.workspace }}/k-Wave"); cd("${{ github.workspace }}/k-Wave/testing/unit"); load('test_struct.mat', 'test_struct'); - runUnitTests_show_results(test_struct); + show_results(test_struct); + disp(' '); + disp('NOTE:'); + disp('Test output details are in the "Run unit tests" section of the workflow.'); + disp('You can also download a JSON summary from the "Upload Artifact" section in your CI logs or dashboard.'); startup-options: -nojvm diff --git a/k-Wave/testing/regression/runRegressionTests.m b/k-Wave/testing/regression/runRegressionTests.m index ba342f5..9ad52e2 100644 --- a/k-Wave/testing/regression/runRegressionTests.m +++ b/k-Wave/testing/regression/runRegressionTests.m @@ -291,5 +291,5 @@ function runRegressionTests(data_folder, show_results) % ========================================================================= if show_results - runUnitTests_show_results(test_struct); + show_test_results(test_struct); end diff --git a/k-Wave/testing/save_artifact.m b/k-Wave/testing/save_artifact.m new file mode 100644 index 0000000..a48cea3 --- /dev/null +++ b/k-Wave/testing/save_artifact.m @@ -0,0 +1,16 @@ +function save_artifact(test_struct) +%SAVE_ARTIFACT +% +% DESCRIPTION: +% save_artifact processes the provided test_struct, saves the results +% as a test_results.json artifact. +% + +fid = fopen('test_results.json', 'w'); +if fid == -1 + warning('Could not open test_results.json for writing.'); +else + fwrite(fid, jsonencode(test_struct), 'char'); + fclose(fid); +end + diff --git a/k-Wave/testing/show_test_results.m b/k-Wave/testing/show_test_results.m new file mode 100644 index 0000000..a8fd425 --- /dev/null +++ b/k-Wave/testing/show_test_results.m @@ -0,0 +1,83 @@ +function show_results(test_struct) +%SHOW_RESULTS Display MATLAB test results in a formatted summary. +% +% DESCRIPTION: +% show_results displays the results from the provided test_struct. +% +% ========================================================================= +% DISPLAY SUMMARY +% ========================================================================= + +info = test_struct.info; +results = test_struct.results; + +% display test header +disp(' '); +disp('-------------------------------------------------------------------------------------'); +disp(' _ __ __ _____ _ '); +disp(' | | __ \ \ / /_ ___ _____ |_ _|__ ___| |_ ___ _ __ '); +disp(' | |/ /___\ \ /\ / / _` \ \ / / _ \ | |/ _ \/ __| __/ _ \ ''__|'); +disp(' | <_____\ V V / (_| |\ V / __/ | | __/\__ \ || __/ | '); +disp(' |_|\_\ \_/\_/ \__,_| \_/ \___| |_|\___||___/\__\___|_| '); +disp(' '); +disp('-------------------------------------------------------------------------------------'); +disp(' '); +disp(['DATE: ' info.date]); +disp(['HOST NAME: ' info.computer_name]); +disp(['USER NAME: ' info.user_name]); +disp(['O/S TYPE: ' info.operating_system_type]); +disp(['O/S: ' info.operating_system]); +disp(['MATLAB VERSION: ' info.matlab_version]); +disp(['TESTED K-WAVE VERSION: ' info.kwave_version]); +disp(['TESTS COMPLETED IN: ' info.completion_time]); +disp(' '); + +% display test summary +disp(' '); +num_passed = sum([results.pass]); +num_failed = numel(results) - num_passed; +disp(['✅ Number of tests passed: ' num2str(num_passed)]); +disp(['❌ Number of tests failed: ' num2str(num_failed)]); +disp(' '); + +% Show failed tests using test_struct +failed_idx = find(~[results.pass]); +if ~isempty(failed_idx) + disp('FAILED TESTS:'); + for i = failed_idx + fn = results(i).test; + fn = fn(1:end - 2); + disp(['❌ ' fn 'failed']); + end + disp(' '); +end + +% display individual test results +disp('TEST RESULTS:'); + +for i = 1:length(results) + + % trim the filename + fn = results(i).test; + fn = [fn(1:end - 2), ':']; + + % add some spaces to align results + fn = sprintf('%-70s', fn); + + % append the test result + if results(i).pass + disp(['✅ ' fn 'passed']); + else + disp(['❌ ' fn 'failed']); + end + +end + +disp(' '); +% Fail if any tests failed (for CI integration) +if num_failed > 0 + disp(' '); + disp('Exiting so that CI detects test failure.'); + exit(1); +end +end From b6927b07239a0cb0af16e5bd278533c373cc94b6 Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Wed, 30 Jul 2025 11:50:33 +0100 Subject: [PATCH 23/38] fix: correct function name to show_test_results in unit tests workflow --- .github/workflows/unit_tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 28395f5..618ba32 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -55,7 +55,7 @@ jobs: addpath("${{ github.workspace }}/k-Wave"); cd("${{ github.workspace }}/k-Wave/testing/unit"); load('test_struct.mat', 'test_struct'); - show_results(test_struct); + show_test_results(test_struct); disp(' '); disp('NOTE:'); disp('Test output details are in the "Run unit tests" section of the workflow.'); From 5875b422fdca8e28afa239809600566a87f6964a Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Wed, 30 Jul 2025 11:53:53 +0100 Subject: [PATCH 24/38] reorganize regression test workflow --- .github/workflows/regression_tests.yml | 33 ++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/.github/workflows/regression_tests.yml b/.github/workflows/regression_tests.yml index e5c1828..b670399 100644 --- a/.github/workflows/regression_tests.yml +++ b/.github/workflows/regression_tests.yml @@ -26,12 +26,41 @@ jobs: generateRegressionData startup-options: -nojvm - - name: Test results + - name: Run regression tests + uses: matlab-actions/run-command@v2 + with: + command: | + addpath("${{ github.workspace }}/k-Wave"); + cd("${{ github.workspace }}/k-Wave/testing/regression"); + runRegressionTests("${{ github.workspace }}/k-Wave/testing/regression", false) + startup-options: -nojvm + + - name: Create artifact uses: matlab-actions/run-command@v2 with: command: | addpath("${{ github.workspace }}/k-Wave"); cd("${{ github.workspace }}/k-Wave/testing/regression"); - runRegressionTests("${{ github.workspace }}/k-Wave/testing/regression") + load('test_struct.mat', 'test_struct'); + runUnitTests_artifact(test_struct); startup-options: -nojvm + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: unit_test_results + path: ${{ github.workspace }}/k-Wave/testing/regression/test_results.json + + - name: Test results + uses: matlab-actions/run-command@v2 + with: + command: | + addpath("${{ github.workspace }}/k-Wave"); + cd("${{ github.workspace }}/k-Wave/testing/regression"); + load('test_struct.mat', 'test_struct'); + show_test_results(test_struct); + disp(' '); + disp('NOTE:'); + disp('Test output details are in the "Run regression tests" section of the workflow.'); + disp('You can also download a JSON summary from the "Upload Artifact" section in your CI logs or dashboard.'); + startup-options: -nojvm \ No newline at end of file From e4b39eae490d807aedee6323279f4fdbeb5545b7 Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Wed, 30 Jul 2025 11:59:18 +0100 Subject: [PATCH 25/38] update runRegressionTests function to return test_struct --- k-Wave/testing/regression/runRegressionTests.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/k-Wave/testing/regression/runRegressionTests.m b/k-Wave/testing/regression/runRegressionTests.m index 9ad52e2..266b6c7 100644 --- a/k-Wave/testing/regression/runRegressionTests.m +++ b/k-Wave/testing/regression/runRegressionTests.m @@ -1,4 +1,4 @@ -function runRegressionTests(data_folder, show_results) +function test_struct = runRegressionTests(data_folder, show_results) %RUNREGRESSIONTESTS Run MATLAB regression tests. % % DESCRIPTION: From ccaa55e93914d8e9dacfb02f3b553f43cb5342dd Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Wed, 30 Jul 2025 12:13:41 +0100 Subject: [PATCH 26/38] add path for show_test_results --- .github/workflows/regression_tests.yml | 1 + .github/workflows/unit_tests.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/regression_tests.yml b/.github/workflows/regression_tests.yml index b670399..594a18c 100644 --- a/.github/workflows/regression_tests.yml +++ b/.github/workflows/regression_tests.yml @@ -56,6 +56,7 @@ jobs: with: command: | addpath("${{ github.workspace }}/k-Wave"); + addpath("${{ github.workspace }}/k-Wave/testing"); cd("${{ github.workspace }}/k-Wave/testing/regression"); load('test_struct.mat', 'test_struct'); show_test_results(test_struct); diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 618ba32..c3a071c 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -36,7 +36,7 @@ jobs: uses: matlab-actions/run-command@v2 with: command: | - addpath("${{ github.workspace }}/k-Wave"); + addpath("${{ github.workspace }}/k-Wave/testing"); cd("${{ github.workspace }}/k-Wave/testing/unit"); load('test_struct.mat', 'test_struct'); runUnitTests_artifact(test_struct); From 9163567ab6c0d1ef8acecc825811843e5beb1a7a Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Wed, 30 Jul 2025 12:18:20 +0100 Subject: [PATCH 27/38] save artifact for regression tests --- .github/workflows/regression_tests.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/regression_tests.yml b/.github/workflows/regression_tests.yml index 594a18c..b488c33 100644 --- a/.github/workflows/regression_tests.yml +++ b/.github/workflows/regression_tests.yml @@ -40,15 +40,16 @@ jobs: with: command: | addpath("${{ github.workspace }}/k-Wave"); + addpath("${{ github.workspace }}/k-Wave/testing"); cd("${{ github.workspace }}/k-Wave/testing/regression"); load('test_struct.mat', 'test_struct'); - runUnitTests_artifact(test_struct); + save_artifact(test_struct); startup-options: -nojvm - name: Upload artifact uses: actions/upload-artifact@v4 with: - name: unit_test_results + name: regression_test_results path: ${{ github.workspace }}/k-Wave/testing/regression/test_results.json - name: Test results From 988ff7faf650daee216ca738fbd35a16f915e036 Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Wed, 30 Jul 2025 12:23:19 +0100 Subject: [PATCH 28/38] add show_test_results path --- .github/workflows/unit_tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index c3a071c..506620b 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -53,6 +53,7 @@ jobs: with: command: | addpath("${{ github.workspace }}/k-Wave"); + addpath("${{ github.workspace }}/k-Wave/testing"); cd("${{ github.workspace }}/k-Wave/testing/unit"); load('test_struct.mat', 'test_struct'); show_test_results(test_struct); From 3e9172942c2a75a3ecac5eeef63d32fea5b2c283 Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Wed, 30 Jul 2025 12:30:16 +0100 Subject: [PATCH 29/38] save regression test results in test_struct.mat --- .github/workflows/regression_tests.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/regression_tests.yml b/.github/workflows/regression_tests.yml index b488c33..8d40425 100644 --- a/.github/workflows/regression_tests.yml +++ b/.github/workflows/regression_tests.yml @@ -32,7 +32,8 @@ jobs: command: | addpath("${{ github.workspace }}/k-Wave"); cd("${{ github.workspace }}/k-Wave/testing/regression"); - runRegressionTests("${{ github.workspace }}/k-Wave/testing/regression", false) + test_struct = runRegressionTests("spaceFirstOrder_check_plane_wave_intensity",false); + save('test_struct.mat', 'test_struct'); startup-options: -nojvm - name: Create artifact From c96528402f95730f86411c6217154b6b5a8225db Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Wed, 30 Jul 2025 12:36:49 +0100 Subject: [PATCH 30/38] fix runRegressionTests input --- .github/workflows/regression_tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/regression_tests.yml b/.github/workflows/regression_tests.yml index 8d40425..443c82e 100644 --- a/.github/workflows/regression_tests.yml +++ b/.github/workflows/regression_tests.yml @@ -32,7 +32,7 @@ jobs: command: | addpath("${{ github.workspace }}/k-Wave"); cd("${{ github.workspace }}/k-Wave/testing/regression"); - test_struct = runRegressionTests("spaceFirstOrder_check_plane_wave_intensity",false); + test_struct = runRegressionTests("${{ github.workspace }}/k-Wave/testing/regression",false); save('test_struct.mat', 'test_struct'); startup-options: -nojvm From b59cde1849e4b128ef4c4105e57234c84f0454da Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Wed, 30 Jul 2025 12:41:47 +0100 Subject: [PATCH 31/38] add all tests to one workflow --- .github/workflows/unit_tests.yml | 67 +++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 506620b..4463bec 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -1,4 +1,4 @@ -name: Run unit tests +name: Run Tests on: push: @@ -10,7 +10,7 @@ on: jobs: unit-tests: - name: Run unit tests + name: Unit tests runs-on: ubuntu-latest steps: - name: Check out repository @@ -63,3 +63,66 @@ jobs: disp('You can also download a JSON summary from the "Upload Artifact" section in your CI logs or dashboard.'); startup-options: -nojvm + regression-tests: + name: Regression tests + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Set up MATLAB + uses: matlab-actions/setup-matlab@v2 + with: + products: Signal_Processing_Toolbox + cache: true + + - name: Generate data + uses: matlab-actions/run-command@v2 + with: + command: | + addpath("${{ github.workspace }}/k-Wave"); + cd("${{ github.workspace }}/k-Wave/testing/regression"); + generateRegressionData + startup-options: -nojvm + + - name: Run regression tests + uses: matlab-actions/run-command@v2 + with: + command: | + addpath("${{ github.workspace }}/k-Wave"); + cd("${{ github.workspace }}/k-Wave/testing/regression"); + test_struct = runRegressionTests("${{ github.workspace }}/k-Wave/testing/regression",false); + save('test_struct.mat', 'test_struct'); + startup-options: -nojvm + + - name: Create artifact + uses: matlab-actions/run-command@v2 + with: + command: | + addpath("${{ github.workspace }}/k-Wave"); + addpath("${{ github.workspace }}/k-Wave/testing"); + cd("${{ github.workspace }}/k-Wave/testing/regression"); + load('test_struct.mat', 'test_struct'); + save_artifact(test_struct); + startup-options: -nojvm + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: regression_test_results + path: ${{ github.workspace }}/k-Wave/testing/regression/test_results.json + + - name: Test results + uses: matlab-actions/run-command@v2 + with: + command: | + addpath("${{ github.workspace }}/k-Wave"); + addpath("${{ github.workspace }}/k-Wave/testing"); + cd("${{ github.workspace }}/k-Wave/testing/regression"); + load('test_struct.mat', 'test_struct'); + show_test_results(test_struct); + disp(' '); + disp('NOTE:'); + disp('Test output details are in the "Run regression tests" section of the workflow.'); + disp('You can also download a JSON summary from the "Upload Artifact" section in your CI logs or dashboard.'); + startup-options: -nojvm \ No newline at end of file From 5a0c32ac6074bd8c3a7c587e491980e3d03cae5a Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Wed, 30 Jul 2025 12:49:32 +0100 Subject: [PATCH 32/38] remove addpath --- .github/workflows/unit_tests.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 4463bec..6a30756 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -26,7 +26,6 @@ jobs: uses: matlab-actions/run-command@v2 with: command: | - addpath("${{ github.workspace }}/k-Wave"); cd("${{ github.workspace }}/k-Wave/testing/unit"); test_struct = runUnitTests("spaceFirstOrder_check_plane_wave_intensity",false); save('test_struct.mat', 'test_struct'); @@ -36,7 +35,6 @@ jobs: uses: matlab-actions/run-command@v2 with: command: | - addpath("${{ github.workspace }}/k-Wave/testing"); cd("${{ github.workspace }}/k-Wave/testing/unit"); load('test_struct.mat', 'test_struct'); runUnitTests_artifact(test_struct); @@ -52,7 +50,6 @@ jobs: uses: matlab-actions/run-command@v2 with: command: | - addpath("${{ github.workspace }}/k-Wave"); addpath("${{ github.workspace }}/k-Wave/testing"); cd("${{ github.workspace }}/k-Wave/testing/unit"); load('test_struct.mat', 'test_struct'); @@ -80,7 +77,6 @@ jobs: uses: matlab-actions/run-command@v2 with: command: | - addpath("${{ github.workspace }}/k-Wave"); cd("${{ github.workspace }}/k-Wave/testing/regression"); generateRegressionData startup-options: -nojvm @@ -89,7 +85,6 @@ jobs: uses: matlab-actions/run-command@v2 with: command: | - addpath("${{ github.workspace }}/k-Wave"); cd("${{ github.workspace }}/k-Wave/testing/regression"); test_struct = runRegressionTests("${{ github.workspace }}/k-Wave/testing/regression",false); save('test_struct.mat', 'test_struct'); @@ -99,7 +94,6 @@ jobs: uses: matlab-actions/run-command@v2 with: command: | - addpath("${{ github.workspace }}/k-Wave"); addpath("${{ github.workspace }}/k-Wave/testing"); cd("${{ github.workspace }}/k-Wave/testing/regression"); load('test_struct.mat', 'test_struct'); @@ -116,7 +110,6 @@ jobs: uses: matlab-actions/run-command@v2 with: command: | - addpath("${{ github.workspace }}/k-Wave"); addpath("${{ github.workspace }}/k-Wave/testing"); cd("${{ github.workspace }}/k-Wave/testing/regression"); load('test_struct.mat', 'test_struct'); From df789bc3bbb1f33ad03fb43eee55f85dc7707fe3 Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Wed, 30 Jul 2025 12:59:21 +0100 Subject: [PATCH 33/38] rename test workflow and add paths --- .github/workflows/regression_tests.yml | 69 ------------------- .../{unit_tests.yml => run_tests.yml} | 2 + 2 files changed, 2 insertions(+), 69 deletions(-) delete mode 100644 .github/workflows/regression_tests.yml rename .github/workflows/{unit_tests.yml => run_tests.yml} (97%) diff --git a/.github/workflows/regression_tests.yml b/.github/workflows/regression_tests.yml deleted file mode 100644 index 443c82e..0000000 --- a/.github/workflows/regression_tests.yml +++ /dev/null @@ -1,69 +0,0 @@ -name: Run regression tests - -on: - push: - -jobs: - regression-tests: - name: Run regression tests - runs-on: ubuntu-latest - steps: - - name: Check out repository - uses: actions/checkout@v4 - - - name: Set up MATLAB - uses: matlab-actions/setup-matlab@v2 - with: - products: Signal_Processing_Toolbox - cache: true - - - name: Generate data - uses: matlab-actions/run-command@v2 - with: - command: | - addpath("${{ github.workspace }}/k-Wave"); - cd("${{ github.workspace }}/k-Wave/testing/regression"); - generateRegressionData - startup-options: -nojvm - - - name: Run regression tests - uses: matlab-actions/run-command@v2 - with: - command: | - addpath("${{ github.workspace }}/k-Wave"); - cd("${{ github.workspace }}/k-Wave/testing/regression"); - test_struct = runRegressionTests("${{ github.workspace }}/k-Wave/testing/regression",false); - save('test_struct.mat', 'test_struct'); - startup-options: -nojvm - - - name: Create artifact - uses: matlab-actions/run-command@v2 - with: - command: | - addpath("${{ github.workspace }}/k-Wave"); - addpath("${{ github.workspace }}/k-Wave/testing"); - cd("${{ github.workspace }}/k-Wave/testing/regression"); - load('test_struct.mat', 'test_struct'); - save_artifact(test_struct); - startup-options: -nojvm - - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: regression_test_results - path: ${{ github.workspace }}/k-Wave/testing/regression/test_results.json - - - name: Test results - uses: matlab-actions/run-command@v2 - with: - command: | - addpath("${{ github.workspace }}/k-Wave"); - addpath("${{ github.workspace }}/k-Wave/testing"); - cd("${{ github.workspace }}/k-Wave/testing/regression"); - load('test_struct.mat', 'test_struct'); - show_test_results(test_struct); - disp(' '); - disp('NOTE:'); - disp('Test output details are in the "Run regression tests" section of the workflow.'); - disp('You can also download a JSON summary from the "Upload Artifact" section in your CI logs or dashboard.'); - startup-options: -nojvm \ No newline at end of file diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/run_tests.yml similarity index 97% rename from .github/workflows/unit_tests.yml rename to .github/workflows/run_tests.yml index 6a30756..f2b3bd1 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/run_tests.yml @@ -26,6 +26,7 @@ jobs: uses: matlab-actions/run-command@v2 with: command: | + addpath("${{ github.workspace }}/k-Wave"); cd("${{ github.workspace }}/k-Wave/testing/unit"); test_struct = runUnitTests("spaceFirstOrder_check_plane_wave_intensity",false); save('test_struct.mat', 'test_struct'); @@ -85,6 +86,7 @@ jobs: uses: matlab-actions/run-command@v2 with: command: | + addpath("${{ github.workspace }}/k-Wave"); cd("${{ github.workspace }}/k-Wave/testing/regression"); test_struct = runRegressionTests("${{ github.workspace }}/k-Wave/testing/regression",false); save('test_struct.mat', 'test_struct'); From 6f7748551ee99d9e6e3c248b689c49778bd8fc15 Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Wed, 30 Jul 2025 13:01:55 +0100 Subject: [PATCH 34/38] add path for Generate data (regression tests) --- .github/workflows/run_tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index f2b3bd1..dd1f591 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -78,6 +78,7 @@ jobs: uses: matlab-actions/run-command@v2 with: command: | + addpath("${{ github.workspace }}/k-Wave"); cd("${{ github.workspace }}/k-Wave/testing/regression"); generateRegressionData startup-options: -nojvm From a77812133d2a7b45244afb5fd1ef813c7f7e778a Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Wed, 30 Jul 2025 13:05:56 +0100 Subject: [PATCH 35/38] run on all regression and unit tests --- .github/workflows/run_tests.yml | 2 +- .../regression/generateRegressionData.m | 654 +++++++++--------- 2 files changed, 328 insertions(+), 328 deletions(-) diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index dd1f591..ee73466 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -28,7 +28,7 @@ jobs: command: | addpath("${{ github.workspace }}/k-Wave"); cd("${{ github.workspace }}/k-Wave/testing/unit"); - test_struct = runUnitTests("spaceFirstOrder_check_plane_wave_intensity",false); + test_struct = runUnitTests("",false); save('test_struct.mat', 'test_struct'); startup-options: -nojvm -logfile output.log diff --git a/k-Wave/testing/regression/generateRegressionData.m b/k-Wave/testing/regression/generateRegressionData.m index 586b955..fbbfeb6 100644 --- a/k-Wave/testing/regression/generateRegressionData.m +++ b/k-Wave/testing/regression/generateRegressionData.m @@ -35,333 +35,333 @@ test_examples{index}.outputs = {'sensor_data'}; test_examples{index}.precision = 'double'; -% index = index + 1; -% test_examples{index}.name = 'example_ivp_binary_sensor_mask'; -% test_examples{index}.outputs = {'sensor_data', 'sensor_data_reordered'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_ivp_opposing_corners_sensor_mask'; -% test_examples{index}.outputs = {'sensor_data'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_ivp_loading_external_image'; -% test_examples{index}.outputs = {'sensor_data'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_ivp_heterogeneous_medium'; -% test_examples{index}.outputs = {'sensor_data'}; -% test_examples{index}.precision = 'double'; - -% % NOT TESTED: example_ivp_saving_movie_files (no sensor data) - -% index = index + 1; -% test_examples{index}.name = 'example_ivp_recording_particle_velocity'; -% test_examples{index}.outputs = {'sensor_data'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_ivp_sensor_frequency_response'; -% test_examples{index}.outputs = {'sensor_data', 'sensor_data_filtered'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_ivp_comparison_modelling_functions'; -% test_examples{index}.outputs = {'sensor_data_first_order', 'sensor_data_second_order'}; -% test_examples{index}.precision = 'double'; - -% % NOT TESTED: example_ivp_setting_initial_gradient (no sensor data) - -% index = index + 1; -% test_examples{index}.name = 'example_ivp_1D_simulation'; -% test_examples{index}.outputs = {'sensor_data'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_ivp_3D_simulation'; -% test_examples{index}.outputs = {'sensor_data'}; -% test_examples{index}.precision = 'single'; - -% index = index + 1; -% test_examples{index}.name = 'example_ivp_axisymmetric_simulation'; -% test_examples{index}.outputs = {'sensor_data'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_ivp_photoacoustic_waveforms'; -% test_examples{index}.outputs = {'sensor_data_1D', 'sensor_data_2D', 'sensor_data_3D'}; -% test_examples{index}.precision = 'single'; - -% % ========================================================================= -% % TIME VARYING SOURCE PROBLEMS -% % ========================================================================= - -% index = index + 1; -% test_examples{index}.name = 'example_tvsp_homogeneous_medium_monopole'; -% test_examples{index}.outputs = {'sensor_data'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_tvsp_homogeneous_medium_dipole'; -% test_examples{index}.outputs = {'sensor_data'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_tvsp_transducer_field_patterns'; -% test_examples{index}.outputs = {'sensor_data'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_tvsp_steering_linear_array'; -% test_examples{index}.outputs = {'source'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_tvsp_snells_law'; -% test_examples{index}.outputs = {'source'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_tvsp_doppler_effect'; -% test_examples{index}.outputs = {'sensor_data', 'approach_as', 'retreat_as'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_tvsp_slit_diffraction'; -% test_examples{index}.outputs = {'sensor_data'}; -% test_examples{index}.precision = 'single'; - -% index = index + 1; -% test_examples{index}.name = 'example_tvsp_3D_simulation'; -% test_examples{index}.outputs = {'sensor_data'}; -% test_examples{index}.precision = 'single'; - -% index = index + 1; -% test_examples{index}.name = 'example_tvsp_acoustic_field_propagator'; -% test_examples{index}.outputs = {'amp_out', 'phase_out'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_tvsp_angular_spectrum'; -% test_examples{index}.outputs = {'plane_2_kw', 'plane_2_as'}; -% test_examples{index}.precision = 'single'; - -% index = index + 1; -% test_examples{index}.name = 'example_tvsp_equivalent_source_holography'; -% test_examples{index}.outputs = {'sensor_data', 'source_estimate', 'proj_asm', 'proj_dirch', 'proj_eqs'}; -% test_examples{index}.precision = 'single'; - -% % ========================================================================= -% % SENSOR DIRECTIVITY -% % ========================================================================= - -% index = index + 1; -% test_examples{index}.name = 'example_sd_focussed_detector_2D'; -% test_examples{index}.outputs = {'sensor_data1', 'sensor_data2'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_sd_focussed_detector_3D'; -% test_examples{index}.outputs = {'sensor_data1', 'sensor_data2'}; -% test_examples{index}.precision = 'single'; - -% index = index + 1; -% test_examples{index}.name = 'example_sd_directivity_modelling_2D'; -% test_examples{index}.outputs = {'sensor_data', 'single_element_data'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_sd_directivity_modelling_3D'; -% test_examples{index}.outputs = {'sensor_data', 'single_element_data'}; -% test_examples{index}.precision = 'single'; - -% index = index + 1; -% test_examples{index}.name = 'example_sd_sensor_directivity_2D'; -% test_examples{index}.outputs = {'sensor_data1', 'sensor_data2'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_sd_directional_array_elements'; -% test_examples{index}.outputs = {'sensor_data', 'element_data'}; -% test_examples{index}.precision = 'double'; - -% % ========================================================================= -% % PHOTOACOUSTIC IMAGE RECONSTRUCTION -% % ========================================================================= - -% index = index + 1; -% test_examples{index}.name = 'example_pr_2D_FFT_line_sensor'; -% test_examples{index}.outputs = {'sensor_data', 'p_xy', 'p_xy_rs'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_pr_3D_FFT_planar_sensor'; -% test_examples{index}.outputs = {'sensor_data', 'p_xyz', 'p_xyz_rs'}; -% test_examples{index}.precision = 'single'; - -% index = index + 1; -% test_examples{index}.name = 'example_pr_2D_TR_line_sensor'; -% test_examples{index}.outputs = {'sensor_data', 'p0_recon', 'p_xy', 'p_xy_rs'}; -% test_examples{index}.precision = 'double'; - -% % NOT TESTED: example_pr_2D_TR_circular_sensor (random noise added) - -% index = index + 1; -% test_examples{index}.name = 'example_pr_3D_TR_planar_sensor'; -% test_examples{index}.outputs = {'sensor_data', 'p0_recon'}; -% test_examples{index}.precision = 'single'; - -% index = index + 1; -% test_examples{index}.name = 'example_pr_3D_TR_spherical_sensor'; -% test_examples{index}.outputs = {'sensor_data', 'p0_recon', 'p0_recon_interp'}; -% test_examples{index}.precision = 'single'; - -% index = index + 1; -% test_examples{index}.name = 'example_pr_2D_TR_directional_sensors'; -% test_examples{index}.outputs = {'sensor_data', 'p0_recon', 'p0_recon_directional'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_pr_2D_TR_bandlimited_sensors'; -% test_examples{index}.outputs = {'sensor_data', 'p0_recon', 'p0_recon_high_pass', 'p0_recon_low_pass', 'p0_recon_gaussian'}; -% test_examples{index}.precision = 'double'; - -% % NOT TESTED: example_pr_2D_TR_absorption_compensation (random noise added) -% % NOT TESTED: example_pr_2D_TR_time_variant_filtering (random noise added) - -% index = index + 1; -% test_examples{index}.name = 'example_pr_2D_TR_autofocus'; -% test_examples{index}.outputs = {'sensor_data', 'focus_func'}; -% test_examples{index}.precision = 'single'; - -% index = index + 1; -% test_examples{index}.name = 'example_pr_2D_TR_iterative'; -% test_examples{index}.outputs = {'sensor_data', 'p0_estimate'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_pr_2D_adjoint'; -% test_examples{index}.outputs = {'sensor_data', 'p0', 'p0_1', 'p0_2', 'p0_3', 'p0_4', 'p0_5'}; -% test_examples{index}.precision = 'double'; - -% % ========================================================================= -% % DIAGNOSTIC ULTRASOUND SIMULATION -% % ========================================================================= - -% index = index + 1; -% test_examples{index}.name = 'example_us_defining_transducer'; -% test_examples{index}.outputs = {'sensor_data', 'as_1', 'as_2', 'as_3'}; -% test_examples{index}.precision = 'single'; - -% index = index + 1; -% test_examples{index}.name = 'example_us_beam_patterns'; -% test_examples{index}.outputs = {'sensor_data'}; -% test_examples{index}.precision = 'single'; - -% index = index + 1; -% test_examples{index}.name = 'example_us_transducer_as_sensor'; -% test_examples{index}.outputs = {'sensor_data', 'scan_line'}; -% test_examples{index}.precision = 'single'; - -% % NOT TESTED: example_us_bmode_linear_transducer (random noise added) -% % NOT TESTED: example_us_bmode_phased_array (random noise added) - -% % ========================================================================= -% % NUMERICAL ANALYSIS -% % ========================================================================= - -% index = index + 1; -% test_examples{index}.name = 'example_na_controlling_the_PML'; -% test_examples{index}.outputs = {'sensor_data'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_na_source_smoothing'; -% test_examples{index}.outputs = {'sensor_data'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_na_filtering_part_1'; -% test_examples{index}.outputs = {'sensor_data', 'output_as'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_na_filtering_part_2'; -% test_examples{index}.outputs = {'sensor_data', 'output_as'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_na_filtering_part_3'; -% test_examples{index}.outputs = {'source_func_as', 'source_func_filtered_as', 'sensor_data', 'output_as'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_na_modelling_absorption'; -% test_examples{index}.outputs = {'attenuation', 'attenuation_th', 'cp', 'cp_kk'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_na_modelling_nonlinearity'; -% test_examples{index}.outputs = {'sensor_data', 'p_mendousse'}; -% test_examples{index}.precision = 'double'; - -% % NOT TESTED: example_na_optimising_performance (no output) - -% % ========================================================================= -% % USING THE C++ CODE -% % ========================================================================= - -% % NOT TESTED - -% % ========================================================================= -% % ELASTIC WAVE PROPAGATION -% % ========================================================================= - -% index = index + 1; -% test_examples{index}.name = 'example_ewp_layered_medium'; -% test_examples{index}.outputs = {'sensor_data', 'sensor_data_reordered'}; -% test_examples{index}.precision = 'single'; - -% index = index + 1; -% test_examples{index}.name = 'example_ewp_plane_wave_absorption'; -% test_examples{index}.outputs = {'sensor_data_comp', 'attenuation_comp', 'sensor_data_shear', 'attenuation_shear'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_ewp_shear_wave_snells_law'; -% test_examples{index}.outputs = {'sensor_data_fluid', 'sensor_data_elastic'}; -% test_examples{index}.precision = 'single'; - -% index = index + 1; -% test_examples{index}.name = 'example_ewp_3D_simulation'; -% test_examples{index}.outputs = {'sensor_data'}; -% test_examples{index}.precision = 'single'; - -% % ========================================================================= -% % THERMAL DIFFUSION -% % ========================================================================= - -% index = index + 1; -% test_examples{index}.name = 'example_diff_homogeneous_medium_diffusion'; -% test_examples{index}.outputs = {'T_exact', 'kdiff'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_diff_homogeneous_medium_source'; -% test_examples{index}.outputs = {'T_exact', 'kdiff'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_diff_binary_sensor_mask'; -% test_examples{index}.outputs = {'kdiff'}; -% test_examples{index}.precision = 'double'; - -% index = index + 1; -% test_examples{index}.name = 'example_diff_focused_ultrasound_heating'; -% test_examples{index}.outputs = {'sensor_data', 'source', 'T1', 'T2', 'kdiff'}; -% test_examples{index}.precision = 'double'; +index = index + 1; +test_examples{index}.name = 'example_ivp_binary_sensor_mask'; +test_examples{index}.outputs = {'sensor_data', 'sensor_data_reordered'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_ivp_opposing_corners_sensor_mask'; +test_examples{index}.outputs = {'sensor_data'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_ivp_loading_external_image'; +test_examples{index}.outputs = {'sensor_data'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_ivp_heterogeneous_medium'; +test_examples{index}.outputs = {'sensor_data'}; +test_examples{index}.precision = 'double'; + +% NOT TESTED: example_ivp_saving_movie_files (no sensor data) + +index = index + 1; +test_examples{index}.name = 'example_ivp_recording_particle_velocity'; +test_examples{index}.outputs = {'sensor_data'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_ivp_sensor_frequency_response'; +test_examples{index}.outputs = {'sensor_data', 'sensor_data_filtered'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_ivp_comparison_modelling_functions'; +test_examples{index}.outputs = {'sensor_data_first_order', 'sensor_data_second_order'}; +test_examples{index}.precision = 'double'; + +% NOT TESTED: example_ivp_setting_initial_gradient (no sensor data) + +index = index + 1; +test_examples{index}.name = 'example_ivp_1D_simulation'; +test_examples{index}.outputs = {'sensor_data'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_ivp_3D_simulation'; +test_examples{index}.outputs = {'sensor_data'}; +test_examples{index}.precision = 'single'; + +index = index + 1; +test_examples{index}.name = 'example_ivp_axisymmetric_simulation'; +test_examples{index}.outputs = {'sensor_data'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_ivp_photoacoustic_waveforms'; +test_examples{index}.outputs = {'sensor_data_1D', 'sensor_data_2D', 'sensor_data_3D'}; +test_examples{index}.precision = 'single'; + +% ========================================================================= +% TIME VARYING SOURCE PROBLEMS +% ========================================================================= + +index = index + 1; +test_examples{index}.name = 'example_tvsp_homogeneous_medium_monopole'; +test_examples{index}.outputs = {'sensor_data'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_tvsp_homogeneous_medium_dipole'; +test_examples{index}.outputs = {'sensor_data'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_tvsp_transducer_field_patterns'; +test_examples{index}.outputs = {'sensor_data'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_tvsp_steering_linear_array'; +test_examples{index}.outputs = {'source'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_tvsp_snells_law'; +test_examples{index}.outputs = {'source'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_tvsp_doppler_effect'; +test_examples{index}.outputs = {'sensor_data', 'approach_as', 'retreat_as'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_tvsp_slit_diffraction'; +test_examples{index}.outputs = {'sensor_data'}; +test_examples{index}.precision = 'single'; + +index = index + 1; +test_examples{index}.name = 'example_tvsp_3D_simulation'; +test_examples{index}.outputs = {'sensor_data'}; +test_examples{index}.precision = 'single'; + +index = index + 1; +test_examples{index}.name = 'example_tvsp_acoustic_field_propagator'; +test_examples{index}.outputs = {'amp_out', 'phase_out'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_tvsp_angular_spectrum'; +test_examples{index}.outputs = {'plane_2_kw', 'plane_2_as'}; +test_examples{index}.precision = 'single'; + +index = index + 1; +test_examples{index}.name = 'example_tvsp_equivalent_source_holography'; +test_examples{index}.outputs = {'sensor_data', 'source_estimate', 'proj_asm', 'proj_dirch', 'proj_eqs'}; +test_examples{index}.precision = 'single'; + +% ========================================================================= +% SENSOR DIRECTIVITY +% ========================================================================= + +index = index + 1; +test_examples{index}.name = 'example_sd_focussed_detector_2D'; +test_examples{index}.outputs = {'sensor_data1', 'sensor_data2'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_sd_focussed_detector_3D'; +test_examples{index}.outputs = {'sensor_data1', 'sensor_data2'}; +test_examples{index}.precision = 'single'; + +index = index + 1; +test_examples{index}.name = 'example_sd_directivity_modelling_2D'; +test_examples{index}.outputs = {'sensor_data', 'single_element_data'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_sd_directivity_modelling_3D'; +test_examples{index}.outputs = {'sensor_data', 'single_element_data'}; +test_examples{index}.precision = 'single'; + +index = index + 1; +test_examples{index}.name = 'example_sd_sensor_directivity_2D'; +test_examples{index}.outputs = {'sensor_data1', 'sensor_data2'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_sd_directional_array_elements'; +test_examples{index}.outputs = {'sensor_data', 'element_data'}; +test_examples{index}.precision = 'double'; + +% ========================================================================= +% PHOTOACOUSTIC IMAGE RECONSTRUCTION +% ========================================================================= + +index = index + 1; +test_examples{index}.name = 'example_pr_2D_FFT_line_sensor'; +test_examples{index}.outputs = {'sensor_data', 'p_xy', 'p_xy_rs'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_pr_3D_FFT_planar_sensor'; +test_examples{index}.outputs = {'sensor_data', 'p_xyz', 'p_xyz_rs'}; +test_examples{index}.precision = 'single'; + +index = index + 1; +test_examples{index}.name = 'example_pr_2D_TR_line_sensor'; +test_examples{index}.outputs = {'sensor_data', 'p0_recon', 'p_xy', 'p_xy_rs'}; +test_examples{index}.precision = 'double'; + +% NOT TESTED: example_pr_2D_TR_circular_sensor (random noise added) + +index = index + 1; +test_examples{index}.name = 'example_pr_3D_TR_planar_sensor'; +test_examples{index}.outputs = {'sensor_data', 'p0_recon'}; +test_examples{index}.precision = 'single'; + +index = index + 1; +test_examples{index}.name = 'example_pr_3D_TR_spherical_sensor'; +test_examples{index}.outputs = {'sensor_data', 'p0_recon', 'p0_recon_interp'}; +test_examples{index}.precision = 'single'; + +index = index + 1; +test_examples{index}.name = 'example_pr_2D_TR_directional_sensors'; +test_examples{index}.outputs = {'sensor_data', 'p0_recon', 'p0_recon_directional'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_pr_2D_TR_bandlimited_sensors'; +test_examples{index}.outputs = {'sensor_data', 'p0_recon', 'p0_recon_high_pass', 'p0_recon_low_pass', 'p0_recon_gaussian'}; +test_examples{index}.precision = 'double'; + +% NOT TESTED: example_pr_2D_TR_absorption_compensation (random noise added) +% NOT TESTED: example_pr_2D_TR_time_variant_filtering (random noise added) + +index = index + 1; +test_examples{index}.name = 'example_pr_2D_TR_autofocus'; +test_examples{index}.outputs = {'sensor_data', 'focus_func'}; +test_examples{index}.precision = 'single'; + +index = index + 1; +test_examples{index}.name = 'example_pr_2D_TR_iterative'; +test_examples{index}.outputs = {'sensor_data', 'p0_estimate'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_pr_2D_adjoint'; +test_examples{index}.outputs = {'sensor_data', 'p0', 'p0_1', 'p0_2', 'p0_3', 'p0_4', 'p0_5'}; +test_examples{index}.precision = 'double'; + +% ========================================================================= +% DIAGNOSTIC ULTRASOUND SIMULATION +% ========================================================================= + +index = index + 1; +test_examples{index}.name = 'example_us_defining_transducer'; +test_examples{index}.outputs = {'sensor_data', 'as_1', 'as_2', 'as_3'}; +test_examples{index}.precision = 'single'; + +index = index + 1; +test_examples{index}.name = 'example_us_beam_patterns'; +test_examples{index}.outputs = {'sensor_data'}; +test_examples{index}.precision = 'single'; + +index = index + 1; +test_examples{index}.name = 'example_us_transducer_as_sensor'; +test_examples{index}.outputs = {'sensor_data', 'scan_line'}; +test_examples{index}.precision = 'single'; + +% NOT TESTED: example_us_bmode_linear_transducer (random noise added) +% NOT TESTED: example_us_bmode_phased_array (random noise added) + +% ========================================================================= +% NUMERICAL ANALYSIS +% ========================================================================= + +index = index + 1; +test_examples{index}.name = 'example_na_controlling_the_PML'; +test_examples{index}.outputs = {'sensor_data'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_na_source_smoothing'; +test_examples{index}.outputs = {'sensor_data'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_na_filtering_part_1'; +test_examples{index}.outputs = {'sensor_data', 'output_as'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_na_filtering_part_2'; +test_examples{index}.outputs = {'sensor_data', 'output_as'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_na_filtering_part_3'; +test_examples{index}.outputs = {'source_func_as', 'source_func_filtered_as', 'sensor_data', 'output_as'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_na_modelling_absorption'; +test_examples{index}.outputs = {'attenuation', 'attenuation_th', 'cp', 'cp_kk'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_na_modelling_nonlinearity'; +test_examples{index}.outputs = {'sensor_data', 'p_mendousse'}; +test_examples{index}.precision = 'double'; + +% NOT TESTED: example_na_optimising_performance (no output) + +% ========================================================================= +% USING THE C++ CODE +% ========================================================================= + +% NOT TESTED + +% ========================================================================= +% ELASTIC WAVE PROPAGATION +% ========================================================================= + +index = index + 1; +test_examples{index}.name = 'example_ewp_layered_medium'; +test_examples{index}.outputs = {'sensor_data', 'sensor_data_reordered'}; +test_examples{index}.precision = 'single'; + +index = index + 1; +test_examples{index}.name = 'example_ewp_plane_wave_absorption'; +test_examples{index}.outputs = {'sensor_data_comp', 'attenuation_comp', 'sensor_data_shear', 'attenuation_shear'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_ewp_shear_wave_snells_law'; +test_examples{index}.outputs = {'sensor_data_fluid', 'sensor_data_elastic'}; +test_examples{index}.precision = 'single'; + +index = index + 1; +test_examples{index}.name = 'example_ewp_3D_simulation'; +test_examples{index}.outputs = {'sensor_data'}; +test_examples{index}.precision = 'single'; + +% ========================================================================= +% THERMAL DIFFUSION +% ========================================================================= + +index = index + 1; +test_examples{index}.name = 'example_diff_homogeneous_medium_diffusion'; +test_examples{index}.outputs = {'T_exact', 'kdiff'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_diff_homogeneous_medium_source'; +test_examples{index}.outputs = {'T_exact', 'kdiff'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_diff_binary_sensor_mask'; +test_examples{index}.outputs = {'kdiff'}; +test_examples{index}.precision = 'double'; + +index = index + 1; +test_examples{index}.name = 'example_diff_focused_ultrasound_heating'; +test_examples{index}.outputs = {'sensor_data', 'source', 'T1', 'T2', 'kdiff'}; +test_examples{index}.precision = 'double'; % ========================================================================= % GENERATE REGRESSION DATA From 5931aac0f168b7bbfc5b5933a030143fa2b357d0 Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Wed, 30 Jul 2025 13:26:28 +0100 Subject: [PATCH 36/38] replace runUnitTests_artifact with save_artifact and remove unused result display functions --- .github/workflows/run_tests.yml | 3 +- k-Wave/testing/unit/runUnitTests_artifact.m | 16 ---- .../testing/unit/runUnitTests_show_results.m | 89 ------------------- 3 files changed, 2 insertions(+), 106 deletions(-) delete mode 100644 k-Wave/testing/unit/runUnitTests_artifact.m delete mode 100644 k-Wave/testing/unit/runUnitTests_show_results.m diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index ee73466..8f21852 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -36,9 +36,10 @@ jobs: uses: matlab-actions/run-command@v2 with: command: | + addpath("${{ github.workspace }}/k-Wave/testing"); cd("${{ github.workspace }}/k-Wave/testing/unit"); load('test_struct.mat', 'test_struct'); - runUnitTests_artifact(test_struct); + save_artifact(test_struct); startup-options: -nojvm - name: Upload artifact diff --git a/k-Wave/testing/unit/runUnitTests_artifact.m b/k-Wave/testing/unit/runUnitTests_artifact.m deleted file mode 100644 index d346a3e..0000000 --- a/k-Wave/testing/unit/runUnitTests_artifact.m +++ /dev/null @@ -1,16 +0,0 @@ -function runUnitTests_artifact(test_struct) -%RUNUNITTESTS_ARTIFACT -% -% DESCRIPTION: -% runUnitTests_actions processes the provided test_struct, saves the results -% as a test_results.json artifact. -% - -fid = fopen('test_results.json', 'w'); -if fid == -1 - warning('Could not open test_results.json for writing.'); -else - fwrite(fid, jsonencode(test_struct), 'char'); - fclose(fid); -end - diff --git a/k-Wave/testing/unit/runUnitTests_show_results.m b/k-Wave/testing/unit/runUnitTests_show_results.m deleted file mode 100644 index 2ca553e..0000000 --- a/k-Wave/testing/unit/runUnitTests_show_results.m +++ /dev/null @@ -1,89 +0,0 @@ -function runUnitTests_show_results(test_struct) -%RUNUNITTESTS_SHOW_RESULTS Display MATLAB unit test results in a formatted summary. -% -% DESCRIPTION: -% runUnitTests_show_results displays the results from the provided test_struct. -% -% ========================================================================= -% DISPLAY SUMMARY -% ========================================================================= - -info = test_struct.info; -results = test_struct.results; - -% display test header -disp(' '); -disp('-------------------------------------------------------------------------------------'); -disp(' _ __ __ _____ _ '); -disp(' | | __ \ \ / /_ ___ _____ |_ _|__ ___| |_ ___ _ __ '); -disp(' | |/ /___\ \ /\ / / _` \ \ / / _ \ | |/ _ \/ __| __/ _ \ ''__|'); -disp(' | <_____\ V V / (_| |\ V / __/ | | __/\__ \ || __/ | '); -disp(' |_|\_\ \_/\_/ \__,_| \_/ \___| |_|\___||___/\__\___|_| '); -disp(' '); -disp('-------------------------------------------------------------------------------------'); -disp(' '); -disp(['DATE: ' info.date]); -disp(['HOST NAME: ' info.computer_name]); -disp(['USER NAME: ' info.user_name]); -disp(['O/S TYPE: ' info.operating_system_type]); -disp(['O/S: ' info.operating_system]); -disp(['MATLAB VERSION: ' info.matlab_version]); -disp(['TESTED K-WAVE VERSION: ' info.kwave_version]); -disp(['TESTS COMPLETED IN: ' info.completion_time]); -disp(' '); - -% display test summary -disp(' '); -num_passed = sum([results.pass]); -num_failed = numel(results) - num_passed; -disp(['✅ Number of tests passed: ' num2str(num_passed)]); -disp(['❌ Number of tests failed: ' num2str(num_failed)]); -disp(' '); - -% Show failed tests using test_struct -failed_idx = find(~[results.pass]); -if ~isempty(failed_idx) - disp('FAILED TESTS:'); - for i = failed_idx - fn = results(i).test; - fn = fn(1:end - 2); - disp(['❌ ' fn 'failed']); - end - disp(' '); -end - -% display individual test results -disp('UNIT TEST RESULTS:'); - -for i = 1:length(results) - - % trim the filename - fn = results(i).test; - fn = [fn(1:end - 2), ':']; - - % add some spaces to align results - fn = sprintf('%-70s', fn); - - % append the test result - if results(i).pass - disp(['✅ ' fn 'passed']); - else - disp(['❌ ' fn 'failed']); - end - -end -disp(' '); - -% display test summary -disp('NOTE:'); -disp('Test output details are in the "Run unit tests" section of the workflow.'); -disp('You can also download a JSON summary from the "Upload Artifact" section in your CI logs or dashboard.'); - -disp(' '); -% Fail if any tests failed (for CI integration) -if num_failed > 0 - disp(' '); - disp('Exiting so that CI detects test failure.'); - exit(1); -end -end From b30fe10c53ad3fcd8f2ba84c689928c5b7f45300 Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Wed, 30 Jul 2025 13:32:21 +0100 Subject: [PATCH 37/38] add correct triggers (these were commented out for testing purposes) --- .github/workflows/run_tests.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index 8f21852..3a66087 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -2,11 +2,11 @@ name: Run Tests on: push: - # branches: - # - main - # pull_request: - # branches: - # - main + branches: + - main + pull_request: + branches: + - main jobs: unit-tests: From b49cb3af938a78c6d49a961d3ffc7a508c150974 Mon Sep 17 00:00:00 2001 From: Stella <30465823+stellaprins@users.noreply.github.com> Date: Wed, 30 Jul 2025 17:17:20 +0100 Subject: [PATCH 38/38] swap around the list of failed tests and summary (N failed / passed) I realised that when you open the CI output (if it has failed) it directs you to the end of the output, so it makes more sense to put this information at the end after all --- k-Wave/testing/show_test_results.m | 39 +++++++++++++++--------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/k-Wave/testing/show_test_results.m b/k-Wave/testing/show_test_results.m index a8fd425..f8f632b 100644 --- a/k-Wave/testing/show_test_results.m +++ b/k-Wave/testing/show_test_results.m @@ -32,25 +32,6 @@ function show_results(test_struct) disp(['TESTS COMPLETED IN: ' info.completion_time]); disp(' '); -% display test summary -disp(' '); -num_passed = sum([results.pass]); -num_failed = numel(results) - num_passed; -disp(['✅ Number of tests passed: ' num2str(num_passed)]); -disp(['❌ Number of tests failed: ' num2str(num_failed)]); -disp(' '); - -% Show failed tests using test_struct -failed_idx = find(~[results.pass]); -if ~isempty(failed_idx) - disp('FAILED TESTS:'); - for i = failed_idx - fn = results(i).test; - fn = fn(1:end - 2); - disp(['❌ ' fn 'failed']); - end - disp(' '); -end % display individual test results disp('TEST RESULTS:'); @@ -73,6 +54,26 @@ function show_results(test_struct) end +% display test summary +disp(' '); +num_passed = sum([results.pass]); +num_failed = numel(results) - num_passed; +disp(['✅ Number of tests passed: ' num2str(num_passed)]); +disp(['❌ Number of tests failed: ' num2str(num_failed)]); +disp(' '); + +% Show failed tests using test_struct +failed_idx = find(~[results.pass]); +if ~isempty(failed_idx) + disp('FAILED TESTS:'); + for i = failed_idx + fn = results(i).test; + fn = fn(1:end - 2); + disp(['❌ ' fn 'failed']); + end + disp(' '); +end + disp(' '); % Fail if any tests failed (for CI integration) if num_failed > 0