Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add wrapping and tests for PhasedArray3DSpecialCoordinatesImage #232

Merged
merged 5 commits into from
Jul 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build-test-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ on: [push,pull_request]

jobs:
cxx-build-workflow:
uses: InsightSoftwareConsortium/ITKRemoteModuleBuildTestPackageAction/.github/workflows/build-test-cxx.yml@f2191a014a93c0d0e7b9e7ffb32d2e1118fb2876
uses: InsightSoftwareConsortium/ITKRemoteModuleBuildTestPackageAction/.github/workflows/build-test-cxx.yml@edd0a4350396f533e9ec3755ed6c5af5ddfedb97
with:
itk-module-deps: '[email protected]:[email protected]:[email protected]:[email protected]:[email protected]'
warnings-to-ignore: "\"pointer is null\" \"in a call to non-static member function\""

python-build-workflow:
uses: InsightSoftwareConsortium/ITKRemoteModuleBuildTestPackageAction/.github/workflows/build-test-package-python.yml@f2191a014a93c0d0e7b9e7ffb32d2e1118fb2876
uses: InsightSoftwareConsortium/ITKRemoteModuleBuildTestPackageAction/.github/workflows/build-test-package-python.yml@edd0a4350396f533e9ec3755ed6c5af5ddfedb97
with:
itk-module-deps: 'InsightSoftwareConsortium/[email protected]:InsightSoftwareConsortium/[email protected]:InsightSoftwareConsortium/[email protected]:InsightSoftwareConsortium/[email protected]:KitwareMedical/[email protected]'
secrets:
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setup(
name='itk-ultrasound',
version='0.6.1',
version='0.6.2',
author='Matthew McCormick',
author_email='[email protected]',
packages=['itk'],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
8fc8129454b6ec93fb5c133d9835f8a49df0ab14584d44b3454e1b36dee60ef92e29bb9e8c3b9a1340129877fc0ec81d7beb5022eaf3bcbbed8fa3ebab8e6c74
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cf4bac01a2692100f1c2b2445f3468b26c754e380f4d0119b466c079639f309ad18f775106f341a72c6126a7a636d55c494ed40edf441de262418ff65b2a792e
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
6e589887b660f79513d1c09479cc70bd815e532e013fcb3bb185a21c641e417210d6a8286199a265b8e6b9159254e6237108539d0c5eb865a7bedb03d64cbf50
1 change: 1 addition & 0 deletions test/Input/ScanConvertPhasedArray3DTestInput.mha.sha512
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
7d5e6c2b070107a279277c48ead400bab15edd7aaa1b1b2238a8437da1435c41f75c3b2323fdba17f6415d10ea37992ff053f52a5f6d7a0937f78cfaf1f3687a
1 change: 1 addition & 0 deletions wrapping/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ set(WRAPPER_SUBMODULE_ORDER
itkCurvilinearArraySpecialCoordinatesImage
itkImageUltrasound # Extra itk::Image wrappings for SupportWindow filters
itkCurvilinearArraySpecialCoordinatesImageFilters
itkPhasedArray3DSpecialCoordinatesImage # CASCI needs to come before
itkAttenuationImageFilter
itkBlockMatchingMetricImageFilter
itkBlockMatchingNormalizedCrossCorrelationMetricImageFilter
Expand Down
16 changes: 4 additions & 12 deletions wrapping/itkCurvilinearArraySpecialCoordinatesImage.wrap
Original file line number Diff line number Diff line change
Expand Up @@ -29,27 +29,19 @@ string(APPEND ITK_WRAP_PYTHON_SWIG_EXT "

%extend swig_name {
itkIndex##template_params TransformPhysicalPointToIndex(const itkPointD##template_params & point ) {
itkIndex##template_params idx;
self->TransformPhysicalPointToIndex<double>( point, idx );
return idx;
return self->TransformPhysicalPointToIndex<double>( point );
}

itkContinuousIndexD##template_params TransformPhysicalPointToContinuousIndex(const itkPointD##template_params & point ) {
itkContinuousIndexD##template_params idx;
self->TransformPhysicalPointToContinuousIndex<double>( point, idx );
return idx;
return self->TransformPhysicalPointToContinuousIndex<double>( point );
}

itkPointD##template_params TransformContinuousIndexToPhysicalPoint(const itkContinuousIndexD##template_params & idx ) {
itkPointD##template_params point;
self->TransformContinuousIndexToPhysicalPoint<double>( idx, point );
return point;
return self->TransformContinuousIndexToPhysicalPoint<double>( idx );
}

itkPointD##template_params TransformIndexToPhysicalPoint(const itkIndex##template_params & idx ) {
itkPointD##template_params point;
self->TransformIndexToPhysicalPoint<double>( idx, point );
return point;
return self->TransformIndexToPhysicalPoint<double>( idx );
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# ITK image filters wrapped for ITKUltrasound `itk::CurvilinearArraySpecialCoordinatesImage` inputs.
# Must be wrapped in a separate file after `itkCurvilinearArraySpecialCoordinates.wrap` so that
# Must be wrapped in a separate file after `itkCurvilinearArraySpecialCoordinatesImage.wrap` so that
# SWIG does not implicitly define erroneous overrides for template methods such as
# `TransformPhysicalPointToContinuousIndex`, etc.

# See `WRAPPER_SUBMODULE_ORDER` in CMakeLists.txt for where `itkCASCIFilters.wrap` is set to
# always be wrapped after `itkCurvilinearArraySpecialCoordinatesImage.wrap`.
# See `WRAPPER_SUBMODULE_ORDER` in CMakeLists.txt for where
# `itkCurvilinearArraySpecialCoordinatesImageFilters.wrap` is set to
# be wrapped after `itkCurvilinearArraySpecialCoordinatesImage.wrap`.

itk_wrap_include("itkCurvilinearArraySpecialCoordinatesImage.h")
itk_wrap_class("itk::ImageSource" POINTER)
Expand Down
50 changes: 50 additions & 0 deletions wrapping/itkPhasedArray3DSpecialCoordinatesImage.wrap
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
itk_wrap_include("list")
itk_wrap_include("complex")

# Explicitly override template method wrappings so that implicit
# scalar type is always `double` for greatest precision.
# Adds wrapping overrides to `itkPhasedArray3DSpecialCoordinatesImage_ext.i` configured with
# CMake for input to SWIG wrapping generation.
# See `DECL_PYTHON_IMAGEBASE_CLASS` definition in `ITK/Wrapping/Generators/Python/PyBase/pyBase.i`
# for precedent.
string(APPEND ITK_WRAP_PYTHON_SWIG_EXT "
%inline %{
#include \"itkContinuousIndexSwigInterface.h\"
%}

%define DECL_PYTHON_PHASEDARRAY3DSPECIALCOORDINATESIMAGE_CLASS(swig_name, template_params)

%extend swig_name {
itkIndex##template_params TransformPhysicalPointToIndex(const itkPointD##template_params & point ) {
return self->TransformPhysicalPointToIndex<double>( point );
}

itkContinuousIndexD##template_params TransformPhysicalPointToContinuousIndex(const itkPointD##template_params & point ) {
return self->TransformPhysicalPointToContinuousIndex<double>( point );
}

itkPointD##template_params TransformContinuousIndexToPhysicalPoint(const itkContinuousIndexD##template_params & idx ) {
return self->TransformContinuousIndexToPhysicalPoint<double>( idx );
}

itkPointD##template_params TransformIndexToPhysicalPoint(const itkIndex##template_params & idx ) {
return self->TransformIndexToPhysicalPoint<double>( idx );
}
}

%enddef
")

# Wrap class for real and complex pixel types. Dimension is always 3.
itk_wrap_class("itk::PhasedArray3DSpecialCoordinatesImage" POINTER_WITH_SUPERCLASS)
foreach(t ${WRAP_ITK_SCALAR})
itk_wrap_template("${ITKM_${t}}" "${ITKT_${t}}")
string(APPEND ITK_WRAP_PYTHON_SWIG_EXT "DECL_PYTHON_PHASEDARRAY3DSPECIALCOORDINATESIMAGE_CLASS(${WRAPPER_SWIG_NAME}${ITKM_${t}}, 3)\n")
endforeach()
foreach(t3 ${WRAP_ITK_COMPLEX_REAL})
itk_wrap_template("${ITKM_${t3}}" "${ITKT_${t3}}")
string(APPEND ITK_WRAP_PYTHON_SWIG_EXT "DECL_PYTHON_PHASEDARRAY3DSPECIALCOORDINATESIMAGE_CLASS(${WRAPPER_SWIG_NAME}${ITKM_${t3}}, 3)\n")
endforeach()
itk_end_wrap_class()

# Then wrap consuming filters in itkPhasedArray3DSpecialCoordinatesImageFilters.wrap
150 changes: 150 additions & 0 deletions wrapping/itkPhasedArray3DSpecialCoordinatesImageFilters.wrap
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# ITK image filters wrapped for ITKUltrasound `itk::PhasedArray3DSpecialCoordinatesImage` inputs.
# Must be wrapped in a separate file after `itkPhasedArray3DSpecialCoordinatesImage.wrap` so that
# SWIG does not implicitly define erroneous overrides for template methods such as
# `TransformPhysicalPointToContinuousIndex`, etc.

# See `WRAPPER_SUBMODULE_ORDER` in CMakeLists.txt for where
# `itkPhasedArray3DSpecialCoordinatesImageFilters.wrap` is set to
# be wrapped after `itkPhasedArray3DSpecialCoordinatesImage.wrap`.

itk_wrap_include("itkPhasedArray3DSpecialCoordinatesImage.h")
itk_wrap_class("itk::ImageSource" POINTER)
foreach(real_type ${WRAP_ITK_SCALAR})
itk_wrap_template("PA3DSCI${ITKM_${real_type}}" "itk::PhasedArray3DSpecialCoordinatesImage<${ITKT_${real_type}}>")
endforeach()
foreach(complex_type ${WRAP_ITK_COMPLEX_REAL})
itk_wrap_template("PA3DSCI${ITKM_${complex_type}}" "itk::PhasedArray3DSpecialCoordinatesImage<${ITKT_${complex_type}}>")
endforeach()
itk_end_wrap_class()

itk_wrap_include("itkImage.h")
itk_wrap_class("itk::ImageToImageFilter" POINTER)
foreach(t ${WRAP_ITK_SCALAR})
foreach(ut ${WRAP_ITK_INT})
itk_wrap_template("I${ITKM_${t}}3PA3DSCI${ITKM_${ut}}"
"itk::Image< ${ITKT_${t}}, 3 >, itk::PhasedArray3DSpecialCoordinatesImage< ${ITKT_${ut}} >")
endforeach()
foreach(t2 ${WRAP_ITK_SCALAR})
itk_wrap_template("PA3DSCI${ITKM_${t}}PA3DSCI${ITKM_${t2}}"
"itk::PhasedArray3DSpecialCoordinatesImage< ${ITKT_${t}} >, itk::PhasedArray3DSpecialCoordinatesImage< ${ITKT_${t2}} >")
endforeach()
itk_wrap_template("PA3DSCI${ITKM_${t}}I${ITKM_${t}}3"
"itk::PhasedArray3DSpecialCoordinatesImage< ${ITKT_${t}} >, itk::Image< ${ITKT_${t}}, 3>")
endforeach()

foreach(rt ${WRAP_ITK_REAL})
foreach(ct ${WRAP_ITK_COMPLEX_REAL})
itk_wrap_template("PA3DSCI${ITKM_${rt}}PA3DSCI${ITKM_${ct}}"
"itk::PhasedArray3DSpecialCoordinatesImage< ${ITKT_${rt}} >, itk::PhasedArray3DSpecialCoordinatesImage< ${ITKT_${ct}} >")
itk_wrap_template("PA3DSCI${ITKM_${ct}}PA3DSCI${ITKM_${rt}}"
"itk::PhasedArray3DSpecialCoordinatesImage< ${ITKT_${ct}} >, itk::PhasedArray3DSpecialCoordinatesImage< ${ITKT_${rt}} >")
endforeach()
endforeach()

foreach(t3 ${WRAP_ITK_COMPLEX_REAL})
itk_wrap_template("PA3DSCI${ITKM_${t3}}PA3DSCI${ITKM_${t3}}"
"itk::PhasedArray3DSpecialCoordinatesImage< ${ITKT_${t3}} >, itk::PhasedArray3DSpecialCoordinatesImage< ${ITKT_${t3}} >")
endforeach()
itk_end_wrap_class()

itk_wrap_class("itk::ImageFileReader" POINTER_WITH_SUPERCLASS)
foreach(t ${WRAP_ITK_SCALAR})
itk_wrap_template("PA3DSCI${ITKM_${t}}"
"itk::PhasedArray3DSpecialCoordinatesImage< ${ITKT_${t}} >")
endforeach()
itk_end_wrap_class()

itk_wrap_class("itk::ImageFileWriter" POINTER)
foreach(t ${WRAP_ITK_SCALAR})
itk_wrap_template("PA3DSCI${ITKM_${t}}"
"itk::PhasedArray3DSpecialCoordinatesImage< ${ITKT_${t}} >")
endforeach()
itk_end_wrap_class()

itk_wrap_class("itk::CastImageFilter" POINTER_WITH_2_SUPERCLASSES)
foreach(t1 ${WRAP_ITK_SCALAR})
foreach(t2 ${WRAP_ITK_SCALAR})
itk_wrap_template("PA3DSCI${ITKM_${t1}}PA3DSCI${ITKM_${t2}}"
"itk::PhasedArray3DSpecialCoordinatesImage< ${ITKT_${t1}} >, itk::PhasedArray3DSpecialCoordinatesImage< ${ITKT_${t2}} >")
itk_wrap_template("PA3DSCI${ITKM_${t1}}I${ITKM_${t2}}3"
"itk::PhasedArray3DSpecialCoordinatesImage< ${ITKT_${t1}} >, itk::Image< ${ITKT_${t2}}, 3 >")
endforeach()
endforeach()
itk_end_wrap_class()

itk_wrap_class("itk::RescaleIntensityImageFilter" POINTER_WITH_2_SUPERCLASSES)
foreach(t ${WRAP_ITK_SCALAR})
foreach(ut ${WRAP_ITK_INT})
itk_wrap_template("I${ITKM_${t}}3PA3DSCI${ITKM_${ut}}"
"itk::Image< ${ITKT_${t}}, 3 >, itk::PhasedArray3DSpecialCoordinatesImage< ${ITKT_${ut}} >")
endforeach()
endforeach()
itk_end_wrap_class()

itk_wrap_include("itkSpectra1DSupportWindowToMaskImageFilter.h")
itk_wrap_class("itk::Spectra1DSupportWindowToMaskImageFilter" POINTER_WITH_2_SUPERCLASSES)
foreach(t ${WRAP_ITK_INT})
itk_wrap_template("IlistitkIndex33PA3DSCI${ITKM_${t}}"
"itk::Image< std::list< itk::Index< 3 > >, 3 >, itk::PhasedArray3DSpecialCoordinatesImage< ${ITKT_${t}} >")
endforeach()
itk_end_wrap_class()

# The rest is needed for ResampleImageFilter and interpolator functions
set(resample_filter_pixel_types "F")
if(ITK_WRAP_unsigned_char)
list(APPEND resample_filter_pixel_types "UC")
endif()
itk_wrap_include("itkResampleImageFilter.h")
itk_wrap_class("itk::ResampleImageFilter" POINTER)
foreach(t ${resample_filter_pixel_types})
itk_wrap_template("PA3DSCI${ITKM_${t}}I${ITKM_${t}}3"
"itk::PhasedArray3DSpecialCoordinatesImage< ${ITKT_${t}} >, itk::Image< ${ITKT_${t}}, 3 >")
endforeach()
itk_end_wrap_class()

itk_wrap_class("itk::ImageFunction" POINTER)
foreach(t ${resample_filter_pixel_types})
itk_wrap_template("PA3DSCI${ITKM_${t}}${ITKM_D}"
"itk::PhasedArray3DSpecialCoordinatesImage< ${ITKT_${t}} >, ${ITKT_D}, ${ITKT_D}")
endforeach()
itk_end_wrap_class()

itk_wrap_class("itk::InterpolateImageFunction" POINTER)
foreach(t ${resample_filter_pixel_types})
itk_wrap_template("PA3DSCI${ITKM_${t}}${ITKM_D}" "itk::PhasedArray3DSpecialCoordinatesImage< ${ITKT_${t}} >, ${ITKT_D}")
endforeach()
itk_end_wrap_class()

itk_wrap_class("itk::NearestNeighborInterpolateImageFunction" POINTER)
foreach(t ${resample_filter_pixel_types})
itk_wrap_template("PA3DSCI${ITKM_${t}}${ITKM_D}"
"itk::PhasedArray3DSpecialCoordinatesImage< ${ITKT_${t}} >, ${ITKT_D}")
endforeach()
itk_end_wrap_class()

itk_wrap_class("itk::LinearInterpolateImageFunction" POINTER)
foreach(t ${resample_filter_pixel_types})
itk_wrap_template("PA3DSCI${ITKM_${t}}${ITKM_D}"
"itk::PhasedArray3DSpecialCoordinatesImage< ${ITKT_${t}} >, ${ITKT_D}")
endforeach()
itk_end_wrap_class()

itk_wrap_class("itk::GaussianInterpolateImageFunction" POINTER)
foreach(t ${resample_filter_pixel_types})
itk_wrap_template("PA3DSCI${ITKM_${t}}${ITKM_D}"
"itk::PhasedArray3DSpecialCoordinatesImage< ${ITKT_${t}} >, ${ITKT_D}")
endforeach()
itk_end_wrap_class()

itk_wrap_include("itkWindowedSincInterpolateImageFunction.h")
set(window_functions "Hamming" "Cosine" "Welch" "Lanczos")
set(radii 2 3)
itk_wrap_class("itk::WindowedSincInterpolateImageFunction" POINTER)
foreach(t ${resample_filter_pixel_types})
foreach(r ${radii}) # radius
foreach(function ${window_functions})
itk_wrap_template("PA3DSCI${ITKM_${t}}${r}${function}" "itk::PhasedArray3DSpecialCoordinatesImage< ${ITKT_${t}} >, ${r}, itk::Function::${function}WindowFunction< ${r} >")
endforeach()
endforeach()
endforeach()
itk_end_wrap_class()
54 changes: 53 additions & 1 deletion wrapping/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ itk_python_add_test(NAME PythonCurvilinearArraySpecialCoordinatesImageTemplateMe
COMMAND PythonCurvilinearArraySpecialCoordinatesImageTemplateMethodsTest.py
)

itk_python_expression_add_test(NAME PythonInstantiateGaussianInterpolateImageFunction
itk_python_expression_add_test(NAME PythonInstantiateGaussianInterpolateImageFunctionCASCI
EXPRESSION "iFunc = itk.GaussianInterpolateImageFunction[itk.CurvilinearArraySpecialCoordinatesImage[itk.UC, 2], itk.D].New()"
)

Expand All @@ -58,6 +58,58 @@ itk_python_add_test(NAME PythonCurvilinearResampleTest
--first-sample-distance 26.4
)

itk_python_expression_add_test(NAME PythonInstantiateGaussianInterpolateImageFunctionPA3DSCI
EXPRESSION "iFunc = itk.GaussianInterpolateImageFunction[itk.PhasedArray3DSpecialCoordinatesImage[itk.F], itk.D].New()"
)

itk_python_add_test(NAME PythonPhasedArray3DResampleNearestTest
TEST_DRIVER_ARGS
--compareIntensityTolerance 1
--compare
DATA{${test_baseline_dir}/ScanConvertPhasedArray3DITKNearestNeighborTestOutput.mha}
${ITK_TEST_OUTPUT_DIR}/ScanConvertPhasedArray3DITKNearestNeighborTestOutput.mha
COMMAND PythonPhasedArray3DResample.py
-i DATA{${test_input_dir}/ScanConvertPhasedArray3DTestInput.mha}
-o ${ITK_TEST_OUTPUT_DIR}/ScanConvertPhasedArray3DITKNearestNeighborTestOutput.mha
--azimuth-angular-separation 0.0872665
--elevation-angular-separation 0.0174533
--radius-sample-size 0.2
--first-sample-distance 8.0
--interpolation-type nearest
)

itk_python_add_test(NAME PythonPhasedArray3DResampleLinearTest
TEST_DRIVER_ARGS
--compareIntensityTolerance 1
--compare
DATA{${test_baseline_dir}/ScanConvertPhasedArray3DTestOutput.mha}
${ITK_TEST_OUTPUT_DIR}/ScanConvertPhasedArray3DTestOutput.mha
COMMAND PythonPhasedArray3DResample.py
-i DATA{${test_input_dir}/ScanConvertPhasedArray3DTestInput.mha}
-o ${ITK_TEST_OUTPUT_DIR}/ScanConvertPhasedArray3DTestOutput.mha
--azimuth-angular-separation 0.0872665
--elevation-angular-separation 0.0174533
--radius-sample-size 0.2
--first-sample-distance 8.0
# --interpolation-type linear # linear is the default
)

itk_python_add_test(NAME PythonPhasedArray3DResampleSincTest
TEST_DRIVER_ARGS
--compareIntensityTolerance 1
--compare
DATA{${test_baseline_dir}/ScanConvertPhasedArray3DITKWindowedSincTestOutput.mha}
${ITK_TEST_OUTPUT_DIR}/ScanConvertPhasedArray3DITKWindowedSincTestOutput.mha
COMMAND PythonPhasedArray3DResample.py
-i DATA{${test_input_dir}/ScanConvertPhasedArray3DTestInput.mha}
-o ${ITK_TEST_OUTPUT_DIR}/ScanConvertPhasedArray3DITKWindowedSincTestOutput.mha
--azimuth-angular-separation 0.0872665
--elevation-angular-separation 0.0174533
--radius-sample-size 0.2
--first-sample-distance 8.0
--interpolation-type sinc
)

itk_python_add_test(NAME PythonBackscatterImageFilterTest0
TEST_DRIVER_ARGS
--compareIntensityTolerance 0.01
Expand Down
Loading