From 3892fb400d2a295e0228255a6c35a609ba127335 Mon Sep 17 00:00:00 2001 From: HastingsGreer Date: Fri, 8 Apr 2022 09:25:21 -0400 Subject: [PATCH 01/10] Update itk_torch_transform_bridge.py --- src/itk_torch_transform_bridge.py | 59 ++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 5 deletions(-) diff --git a/src/itk_torch_transform_bridge.py b/src/itk_torch_transform_bridge.py index fe1ad6a..c4bdd05 100644 --- a/src/itk_torch_transform_bridge.py +++ b/src/itk_torch_transform_bridge.py @@ -1,5 +1,6 @@ import itk import torch +import torch.nn.functional as F def monai_warp_to_itk_transform(image_fixed: "itk.Image", image_moving:"itk.Image", network_shape: "[int]", network: "torch.nn.Module", **kwargs)->"itk.Transform": tensor_fixed, tensor_moving, convert_back = itk_transform_bridge(image_fixed, image_moving, network_shape, phi_type="displacement_field", order="vector_first", **kwargs) @@ -13,18 +14,66 @@ def grid_sample_to_itk_transform(image_fixed: "itk.Image", image_moving:"itk.Ima return convert_back(phi) -def itk_transform_bridge(image_fixed: "itk.Image", image_moving:"itk.Image", network_shape: "[int]", **kwargs)->"(torch.Tensor, torch.Tensor, Callable[[torch.Tensor], itk.Transform])": - # Convert images to tensors +def itk_transform_bridge(image_fixed: "itk.Image", image_moving:"itk.Image", network_shape: "[int]", phi_type="displacement_field", range=(-1, 1))->"(torch.Tensor, torch.Tensor, Callable[[torch.Tensor], itk.Transform])": + to_network_space = resampling_transform(image_moving, network_shape) + from_network_space = resampling_transform(image_fixed, network_shape).GetInverse() + + moving_npy = np.array(image_moving) + fixed_npy = np.array(image_fixed) + + # turn images into torch Tensors: add feature and batch dimensions (each of length 1) + moving_trch = torch.Tensor(moving_npy)[None, None] + fixed_trch = torch.Tensor(fixed_npy)[None, None] - # ... + + # Here we resize the input images to the shape expected by the neural network. This affects the + # pixel stride as well as the magnitude of the displacement vectors of the resulting displacement field, which + # convert_back will have to compensate for. + + #TODO: it is crucial to blur before this step if we are downsampling! + moving_resized = F.interpolate(moving_trch, size=network_shape, mode="trilinear", align_corners=False) + fixed_resized = F.interpolate(fixed_trch, size=network_shape, mode="trilinear", align_corners=False) + # Create convert_back function def convert_back(phi: "torch.Tensor") -> "itk.Transform": + phi = phi.cpu().detach() + + if phi_type == "coordinate_field" and range == (-1, 1): + # itk.DeformationFieldTransform expects a displacement field, so we subtract off the identity map. + disp = (phi - ) + + dimension = len(network_shape_list) + + + # We convert the displacement field into an itk Vector Image. + scale = torch.Tensor(network_shape_list) + + for _ in network_shape_list: + scale = scale[:, None] + disp *= scale + + # disp is a shape [3, H, W, D] tensor with vector components in the order [vi, vj, vk] + disp_itk_format = disp.double().numpy()[list(reversed(range(dimension)))].transpose(list(range(1, dimension + 1)) + [0]) + # disp_itk_format is a shape [H, W, D, 3] array with vector components in the order [vk, vj, vi] + # as expected by itk. + + itk_disp_field = itk.image_from_array(disp_itk_format, is_vector=True) + + deformable_transform = itk.DisplacementFieldTransform[(itk.D, dimension)].New() + + deformable_transform.SetDisplacementField(itk_disp_field) + + final_transform = itk.CompositeTransform[itk.D, dimension].New() + + final_transform.PrependTransform(from_network_space) + final_transform.PrependTransform(deformable_transform) + final_transform.PrependTransform(to_network_space) - return itk.CompositeTransform(some_stuff) + return final_transform - return tensor_fixed, tensor_moving, convert_back + return fixed_resized, moving_resized, convert_back def resampling_transform(image, shape) -> itk.Transform: From 7e58bb1b6686cc1153d2ec491504d1b9a831a19f Mon Sep 17 00:00:00 2001 From: HastingsGreer Date: Fri, 8 Apr 2022 10:01:00 -0400 Subject: [PATCH 02/10] Create test_grid_sample.py --- test/test_grid_sample.py | 1 + 1 file changed, 1 insertion(+) create mode 100644 test/test_grid_sample.py diff --git a/test/test_grid_sample.py b/test/test_grid_sample.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/test/test_grid_sample.py @@ -0,0 +1 @@ + From e9f4f6f25e180df31e6dfd1bd4b98b6f97c07efd Mon Sep 17 00:00:00 2001 From: HastingsGreer Date: Fri, 8 Apr 2022 10:01:17 -0400 Subject: [PATCH 03/10] Update test_grid_sample.py --- test/test_grid_sample.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/test_grid_sample.py b/test/test_grid_sample.py index 8b13789..530117d 100644 --- a/test/test_grid_sample.py +++ b/test/test_grid_sample.py @@ -1 +1,4 @@ - +import itk_torch_transform +import torch +import itk +import torch.nn.functional as F From af64fa24aed6dc91f293d5ceb88782d40320c9c3 Mon Sep 17 00:00:00 2001 From: HastingsGreer Date: Fri, 8 Apr 2022 10:03:37 -0400 Subject: [PATCH 04/10] Create test-action.yml --- .github/workflows/test-action.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/test-action.yml diff --git a/.github/workflows/test-action.yml b/.github/workflows/test-action.yml new file mode 100644 index 0000000..c21c5c8 --- /dev/null +++ b/.github/workflows/test-action.yml @@ -0,0 +1,23 @@ +name: test + +on: [push, pull_request] + +jobs: + test-linux: + runs-on: [linux, windows] + strategy: + max-parallel: 5 + + steps: + - uses: actions/checkout@v2 + - name: Set up Python 3.7 + uses: actions/setup-python@v2 + with: + python-version: 3.7 + - name: Install dependencies + run: | + pip install -e . + + - name: test + run: | + python -m unittest discover From 5eae7af2f6cc0d9e173af650f3bffc0f197a2b7b Mon Sep 17 00:00:00 2001 From: HastingsGreer Date: Fri, 8 Apr 2022 10:05:10 -0400 Subject: [PATCH 05/10] Update test-action.yml --- .github/workflows/test-action.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test-action.yml b/.github/workflows/test-action.yml index c21c5c8..74432c7 100644 --- a/.github/workflows/test-action.yml +++ b/.github/workflows/test-action.yml @@ -4,7 +4,8 @@ on: [push, pull_request] jobs: test-linux: - runs-on: [linux, windows] + runs-on: ubuntu-latest + strategy: max-parallel: 5 From 5a45c009a4c24c5d030e103f67f11997db592e39 Mon Sep 17 00:00:00 2001 From: HastingsGreer Date: Fri, 8 Apr 2022 14:47:57 -0400 Subject: [PATCH 06/10] Create test_monai.py --- test/test_monai.py | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 test/test_monai.py diff --git a/test/test_monai.py b/test/test_monai.py new file mode 100644 index 0000000..3cacec5 --- /dev/null +++ b/test/test_monai.py @@ -0,0 +1,2 @@ +import torch +import monai From 32285c9db70f1064145586694a399c6fd4e0dfb6 Mon Sep 17 00:00:00 2001 From: HastingsGreer Date: Fri, 8 Apr 2022 14:51:09 -0400 Subject: [PATCH 07/10] Update setup.cfg --- setup.cfg | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/setup.cfg b/setup.cfg index c14eff5..778008c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -21,6 +21,10 @@ python_requires = >=3.4 install_requires = torch itk==5.3rc4 + +[options.extras_require] +testing = + monai [options.packages.find] where = src From c3796f352697d0ce99bddcd4b4375f1428fbcb38 Mon Sep 17 00:00:00 2001 From: HastingsGreer Date: Fri, 8 Apr 2022 14:52:12 -0400 Subject: [PATCH 08/10] Update test-action.yml --- .github/workflows/test-action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-action.yml b/.github/workflows/test-action.yml index 74432c7..284fece 100644 --- a/.github/workflows/test-action.yml +++ b/.github/workflows/test-action.yml @@ -17,7 +17,7 @@ jobs: python-version: 3.7 - name: Install dependencies run: | - pip install -e . + pip install -e ".[testing]" - name: test run: | From ba2c4f70f6614c95088ef026133ba4d3d676921b Mon Sep 17 00:00:00 2001 From: HastingsGreer Date: Fri, 8 Apr 2022 14:55:47 -0400 Subject: [PATCH 09/10] Update test-action.yml --- .github/workflows/test-action.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test-action.yml b/.github/workflows/test-action.yml index 284fece..3952eaa 100644 --- a/.github/workflows/test-action.yml +++ b/.github/workflows/test-action.yml @@ -1,6 +1,10 @@ name: test -on: [push, pull_request] +on: + pull_request: + push: + branches: + - master jobs: test-linux: From b7ba34c28d2d3548dc28dcf2a71379bc0e3f94a4 Mon Sep 17 00:00:00 2001 From: HastingsGreer Date: Sun, 10 Apr 2022 09:19:33 -0400 Subject: [PATCH 10/10] Update test_monai.py --- test/test_monai.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/test_monai.py b/test/test_monai.py index 3cacec5..e389d78 100644 --- a/test/test_monai.py +++ b/test/test_monai.py @@ -1,2 +1,6 @@ import torch import monai +import unittest + +class TestMonaiWarp(unittest.TestCase): +