From 9014c4f970ec3be9e250e1aa6d53811e31a9204f Mon Sep 17 00:00:00 2001 From: Casper da Costa-Luis Date: Tue, 16 Apr 2024 17:31:45 +0100 Subject: [PATCH] octo-merge - closes #1713 bump astra - closes #1764 bump tigre - closes #1761 bump ccpi-regulariser - closes #1765 bumpy python & numpy --- .github/workflows/build.yml | 20 ++++----- CHANGELOG.md | 2 + Dockerfile | 4 +- README.md | 2 +- .../functions/regularisers.py | 29 ++++++++---- Wrappers/Python/cil/plugins/tigre/FBP.py | 4 +- Wrappers/Python/test/test_DataProcessor.py | 44 +++++++++---------- .../Python/test/test_PluginsRegularisation.py | 6 +-- Wrappers/Python/test/test_algorithms.py | 12 ++--- Wrappers/Python/test/test_functions.py | 44 +++++++++---------- Wrappers/Python/test/test_io.py | 2 +- Wrappers/Python/test/test_subset.py | 32 +++++++------- Wrappers/Python/test/utils.py | 3 +- recipe/conda_build_config.yaml | 28 +++++------- recipe/meta.yaml | 8 ++-- .../create_local_env_for_cil_development.sh | 4 +- scripts/requirements-test.yml | 5 ++- 17 files changed, 130 insertions(+), 119 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index df11e75fe..aba2771d7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -40,8 +40,8 @@ jobs: runs-on: [self-hosted, python, cuda] strategy: matrix: - python-version: [3.9] - numpy-version: [1.22] + python-version: [3.11] + numpy-version: [1.25] steps: - uses: actions/checkout@v4 with: {fetch-depth: 0, submodules: recursive} @@ -80,15 +80,15 @@ jobs: strategy: matrix: include: - - python-version: 3.8 - numpy-version: 1.21 - python-version: '3.10' - numpy-version: 1.24 + numpy-version: 1.23 + - python-version: 3.12 + numpy-version: 1.26 steps: - uses: actions/checkout@v4 with: {fetch-depth: 0, submodules: recursive} - name: set requirements - run: sed -ri -e '/ python=/d' -e 's/(.* numpy=).*/\1${{ matrix.numpy-version }}/' scripts/requirements-test.yml + run: sed -ri -e '/ python=/d' -e 's/(.* numpy=).*/\1${{ matrix.numpy-version }}/' -e '/tigre/d' scripts/requirements-test.yml - uses: conda-incubator/setup-miniconda@v3 with: python-version: ${{ matrix.python-version }} @@ -105,8 +105,8 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.9] - numpy-version: [1.22] + python-version: [3.11] + numpy-version: [1.25] steps: - uses: actions/checkout@v4 with: {fetch-depth: 0, submodules: recursive} @@ -132,12 +132,12 @@ jobs: - uses: actions/checkout@v4 with: {fetch-depth: 0, submodules: recursive} - uses: conda-incubator/setup-miniconda@v3 - with: {python-version: '3.10'} + with: {python-version: 3.11} - name: install dependencies run: | cd docs conda install -c conda-forge -yq conda-merge - conda-merge ../scripts/requirements-test.yml docs_environment.yml > environment.yml + conda-merge ../scripts/requirements-test.yml docs_environment.yml | sed '/tigre/d' > environment.yml conda env update -n test conda list - name: build cil diff --git a/CHANGELOG.md b/CHANGELOG.md index e2397fb50..c5d9dd5e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ * x.x.x + - Update to new CCPi-Regularisation toolkit v24.0.0. This is a backward incompatible release of the toolkit. - Set CMake Policy CMP0148 to OLD to avoid warnings in CMake 3.27 - AcquisitionGeometry prints the first and last 10 angles, or all if there are 30 or less, rather than the first 20 - Added a weight argument to the L1Norm function @@ -47,6 +48,7 @@ - `FBP` kwarg (and thus all kwargs) in `cil.processors.CentreOfRotationCorrector` and `cil.processors.CofR_image_sharpness` - `TXRMDataReader` - Added the ApproximateGradientSumFunction and SGFunction to allow for stochastic gradient algorithms to be created using functions with an approximate gradient and deterministic algorithms + - CIL plugin support for TIGRE version v2.6 * 23.1.0 diff --git a/Dockerfile b/Dockerfile index 899e8799a..ddedfd490 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,7 @@ LABEL org.opencontainers.image.source=https://github.com/TomographicImaging/CIL LABEL org.opencontainers.image.licenses="Apache-2.0 AND BSD-3-Clause AND GPL-3.0" # CUDA-specific packages -ARG CIL_EXTRA_PACKAGES="tigre=2.4 astra-toolbox<2.1" +ARG CIL_EXTRA_PACKAGES="tigre=2.6 astra-toolbox<2.1" # build & runtime dependencies # TODO: sync scripts/create_local_env_for_cil_development.sh, scripts/requirements-test.yml, recipe/meta.yaml (e.g. missing libstdcxx-ng _openmp_mutex pip)? # vis. https://github.com/TomographicImaging/CIL/pull/1590 @@ -20,7 +20,7 @@ COPY --chown="${NB_USER}" scripts/requirements-test.yml environment.yml RUN sed -ri '/tigre|astra-toolbox/d' environment.yml \ && for pkg in jupyter-server-proxy $CIL_EXTRA_PACKAGES; do echo " - $pkg" >> environment.yml; done \ && conda config --env --set channel_priority strict \ - && for ch in defaults ccpi intel conda-forge; do conda config --env --add channels $ch; done \ + && for ch in defaults nvidia ccpi intel conda-forge; do conda config --env --add channels $ch; done \ && mamba env update -n base \ && mamba clean -a -y -f \ && rm environment.yml \ diff --git a/README.md b/README.md index 1dead2d1b..e33351b46 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ where: - `astra-toolbox` (requires an NVIDIA GPU) enables CIL support for [ASTRA toolbox](http://www.astra-toolbox.com) projectors (GPLv3 license) - `tigre` (requires an NVIDIA GPU) enables support for [TIGRE](https://github.com/CERN/TIGRE) toolbox projectors (BSD license) -- `ccpi-regulariser` is the [CCPi Regularisation Toolkit](https://github.com/vais-ral/CCPi-Regularisation-Toolkit) +- `ccpi-regulariser` is the [CCPi Regularisation Toolkit](https://github.com/TomographicImaging/CCPi-Regularisation-Toolkit) - `tomophantom` can generate phantoms to use as test data [Tomophantom](https://github.com/dkazanc/TomoPhantom) ### Dependencies diff --git a/Wrappers/Python/cil/plugins/ccpi_regularisation/functions/regularisers.py b/Wrappers/Python/cil/plugins/ccpi_regularisation/functions/regularisers.py index 9b81f2c1c..04a4f9c64 100644 --- a/Wrappers/Python/cil/plugins/ccpi_regularisation/functions/regularisers.py +++ b/Wrappers/Python/cil/plugins/ccpi_regularisation/functions/regularisers.py @@ -18,9 +18,9 @@ try: from ccpi.filters import regularisers - from ccpi.filters.cpu_regularisers import TV_ENERGY + from ccpi.filters.TV import TV_ENERGY except ImportError as exc: - raise ImportError('Please `conda install "ccpi::ccpi-regulariser>=20.04"`') from exc + raise ImportError('Please `conda install "ccpi::ccpi-regulariser>=24"`') from exc from cil.framework import DataOrder @@ -229,14 +229,17 @@ def _fista_on_dual_rof(self, in_arr, tau): """ - res , info = regularisers.FGP_TV(\ + info = np.zeros((2,), dtype=np.float32) + + res = regularisers.FGP_TV(\ in_arr,\ self.alpha * tau,\ self.max_iteration,\ self.tolerance,\ self.methodTV,\ self.nonnegativity,\ - self.device) + infovector = info, + device = self.device) return res, info @@ -315,14 +318,18 @@ def alpha1(self): return 1. def proximal_numpy(self, in_arr, tau): - res , info = regularisers.TGV(in_arr, + + info = np.zeros((2,), dtype=np.float32) + + res = regularisers.TGV(in_arr, self.alpha * tau, self.alpha1, self.alpha2, self.max_iteration, self.LipshitzConstant, self.tolerance, - self.device) + infovector = info, + device = self.device) # info: return number of iteration and reached tolerance # https://github.com/vais-ral/CCPi-Regularisation-Toolkit/blob/master/src/Core/regularisers_CPU/TGV_core.c#L168 @@ -400,7 +407,10 @@ def __call__(self,x): return np.nan def proximal_numpy(self, in_arr, tau): - res , info = regularisers.FGP_dTV(\ + + info = np.zeros((2,), dtype=np.float32) + + res = regularisers.FGP_dTV(\ in_arr,\ self.reference,\ self.alpha * tau,\ @@ -409,7 +419,8 @@ def proximal_numpy(self, in_arr, tau): self.eta,\ self.methodTV,\ self.nonnegativity,\ - self.device) + infovector = info, + device = self.device) return res, info def convex_conjugate(self, x): @@ -454,7 +465,7 @@ def __call__(self,x): def proximal_numpy(self, in_arr, tau): # remove any dimension of size 1 in_arr = np.squeeze(in_arr) - + res = regularisers.TNV(in_arr, self.alpha * tau, self.max_iteration, diff --git a/Wrappers/Python/cil/plugins/tigre/FBP.py b/Wrappers/Python/cil/plugins/tigre/FBP.py index 933203e08..07aa33158 100644 --- a/Wrappers/Python/cil/plugins/tigre/FBP.py +++ b/Wrappers/Python/cil/plugins/tigre/FBP.py @@ -97,7 +97,9 @@ def process(self, out=None): arr_out = np.squeeze(arr_out, axis=0) else: if self.acquisition_geometry.geom_type == 'cone': - arr_out = fdk(self.get_input().as_array(), self.tigre_geom, self.tigre_angles) + # suppress print statements from TIGRE https://github.com/CERN/TIGRE/issues/532 + with contextlib.redirect_stdout(io.StringIO()): + arr_out = fdk(self.get_input().as_array(), self.tigre_geom, self.tigre_angles) else: arr_out = fbp(self.get_input().as_array(), self.tigre_geom, self.tigre_angles) diff --git a/Wrappers/Python/test/test_DataProcessor.py b/Wrappers/Python/test/test_DataProcessor.py index bea31dcdf..222d9fe4d 100644 --- a/Wrappers/Python/test/test_DataProcessor.py +++ b/Wrappers/Python/test/test_DataProcessor.py @@ -572,21 +572,21 @@ def test_process_acquisition(self): proc.set_input(data_in.geometry) geometry_out = proc.process() - self.assertEquals(geometry_out, geometry_gold, + self.assertEqual(geometry_out, geometry_gold, msg="Binner failed with geometry mismatch. Got:\n{0}\nExpected:\n{1}".format(geometry_out, geometry_gold)) proc.set_input(data_in) data_out = proc.process() numpy.testing.assert_array_equal(data_gold, data_out.array) - self.assertEquals(data_out.geometry, geometry_gold, + self.assertEqual(data_out.geometry, geometry_gold, msg="Binner failed with geometry mismatch. Got:\n{0}\nExpected:\n{1}".format(data_out.geometry, geometry_gold)) data_out.fill(0) proc.process(out=data_out) numpy.testing.assert_array_equal(data_gold, data_out.array) - self.assertEquals(data_out.geometry, geometry_gold, + self.assertEqual(data_out.geometry, geometry_gold, msg="Binner failed with geometry mismatch. Got:\n{0}\nExpected:\n{1}".format(data_out.geometry, geometry_gold)) @@ -606,21 +606,21 @@ def test_process_image(self): proc.set_input(data_in.geometry) geometry_out = proc.process() - self.assertEquals(geometry_out, geometry_gold, + self.assertEqual(geometry_out, geometry_gold, msg="Binner failed with geometry mismatch. Got:\n{0}\nExpected:\n{1}".format(geometry_out, geometry_gold)) proc.set_input(data_in) data_out = proc.process() numpy.testing.assert_array_equal(data_gold, data_out.array) - self.assertEquals(data_out.geometry, geometry_gold, + self.assertEqual(data_out.geometry, geometry_gold, msg="Binner failed with geometry mismatch. Got:\n{0}\nExpected:\n{1}".format(data_out.geometry, geometry_gold)) data_out.fill(0) proc.process(out=data_out) numpy.testing.assert_array_equal(data_gold, data_out.array) - self.assertEquals(data_out.geometry, geometry_gold, + self.assertEqual(data_out.geometry, geometry_gold, msg="Binner failed with geometry mismatch. Got:\n{0}\nExpected:\n{1}".format(data_out.geometry, geometry_gold)) @@ -1343,21 +1343,21 @@ def test_process_acquisition(self): proc.set_input(data_in.geometry) geometry_out = proc.process() - self.assertEquals(geometry_out, geometry_gold, + self.assertEqual(geometry_out, geometry_gold, msg="Slicer failed with geometry mismatch. Got:\n{0}\nExpected:\n{1}".format(geometry_out, geometry_gold)) proc.set_input(data_in) data_out = proc.process() numpy.testing.assert_array_equal(data_gold, data_out.array) - self.assertEquals(data_out.geometry, geometry_gold, + self.assertEqual(data_out.geometry, geometry_gold, msg="Slicer failed with geometry mismatch. Got:\n{0}\nExpected:\n{1}".format(data_out.geometry, geometry_gold)) data_out.fill(0) proc.process(out=data_out) numpy.testing.assert_array_equal(data_gold, data_out.array) - self.assertEquals(data_out.geometry, geometry_gold, + self.assertEqual(data_out.geometry, geometry_gold, msg="Slicer failed with geometry mismatch. Got:\n{0}\nExpected:\n{1}".format(data_out.geometry, geometry_gold)) @@ -1375,21 +1375,21 @@ def test_process_image(self): proc.set_input(data_in.geometry) geometry_out = proc.process() - self.assertEquals(geometry_out, geometry_gold, + self.assertEqual(geometry_out, geometry_gold, msg="Slicer failed with geometry mismatch. Got:\n{0}\nExpected:\n{1}".format(geometry_out, geometry_gold)) proc.set_input(data_in) data_out = proc.process() numpy.testing.assert_array_equal(data_gold, data_out.array) - self.assertEquals(data_out.geometry, geometry_gold, + self.assertEqual(data_out.geometry, geometry_gold, msg="Slicer failed with geometry mismatch. Got:\n{0}\nExpected:\n{1}".format(data_out.geometry, geometry_gold)) data_out.fill(0) proc.process(out=data_out) numpy.testing.assert_array_equal(data_gold, data_out.array) - self.assertEquals(data_out.geometry, geometry_gold, + self.assertEqual(data_out.geometry, geometry_gold, msg="Slicer failed with geometry mismatch. Got:\n{0}\nExpected:\n{1}".format(data_out.geometry, geometry_gold)) @@ -1770,7 +1770,7 @@ def test_process_acquisition_geometry(self): proc.set_input(geometry) geometry_padded = proc._process_acquisition_geometry() - self.assertEquals(geometry_padded, self.ag_padded, + self.assertEqual(geometry_padded, self.ag_padded, msg="Padder failed with geometry mismatch. Got:\n{0}\nExpected:\n{1}".format(geometry_padded, self.ag_padded)) @@ -1784,7 +1784,7 @@ def test_process_acquisition_geometry(self): 0., 90., 180., 270.,\ 360., 450., 540., 630., 720.] - self.assertEquals(geometry_padded, geometry_gold, + self.assertEqual(geometry_padded, geometry_gold, msg="Padder failed with geometry mismatch. Got:\n{0}\nExpected:\n{1}".format(geometry_padded, geometry_gold)) @@ -1795,7 +1795,7 @@ def test_process_acquisition_geometry_origin(self): proc.set_input(geometry) geometry_padded = proc._process_acquisition_geometry() - self.assertEquals(geometry_padded, self.ag2_padded, + self.assertEqual(geometry_padded, self.ag2_padded, msg="Padder failed with geometry mismatch. Got:\n{0}\nExpected:\n{1}".format(geometry_padded, self.ag2_padded)) @@ -1807,7 +1807,7 @@ def test_process_image_geometry(self): proc.set_input(geometry) geometry_padded = proc._process_image_geometry() - self.assertEquals(geometry_padded, self.ig_padded, + self.assertEqual(geometry_padded, self.ig_padded, msg="Padder failed with geometry mismatch. Got:\n{0}\nExpected:\n{1}".format(geometry_padded, self.ig_padded)) @@ -1846,21 +1846,21 @@ def test_process_acquisition(self): proc.set_input(data_in.geometry) geometry_out = proc.process() - self.assertEquals(geometry_out, self.ag_padded, + self.assertEqual(geometry_out, self.ag_padded, msg="Padder failed with geometry mismatch. Got:\n{0}\nExpected:\n{1}".format(geometry_out, self.ag_padded)) proc.set_input(data_in) data_out = proc.process() numpy.testing.assert_array_equal(data_gold.array, data_out.array) - self.assertEquals(data_out.geometry, self.ag_padded, + self.assertEqual(data_out.geometry, self.ag_padded, msg="Padder failed with geometry mismatch. Got:\n{0}\nExpected:\n{1}".format(data_out.geometry, self.ag_padded)) data_out.fill(0) proc.process(out=data_out) numpy.testing.assert_array_equal(data_gold.array, data_out.array) - self.assertEquals(data_out.geometry, self.ag_padded, + self.assertEqual(data_out.geometry, self.ag_padded, msg="Padder failed with geometry mismatch. Got:\n{0}\nExpected:\n{1}".format(data_out.geometry, self.ag_padded)) @@ -1880,21 +1880,21 @@ def test_process_image(self): proc.set_input(data_in.geometry) geometry_out = proc.process() - self.assertEquals(geometry_out, self.ig_padded, + self.assertEqual(geometry_out, self.ig_padded, msg="Padder failed with geometry mismatch. Got:\n{0}\nExpected:\n{1}".format(geometry_out, self.ig_padded)) proc.set_input(data_in) data_out = proc.process() numpy.testing.assert_array_equal(data_gold.array, data_out.array) - self.assertEquals(data_out.geometry, self.ig_padded, + self.assertEqual(data_out.geometry, self.ig_padded, msg="Padder failed with geometry mismatch. Got:\n{0}\nExpected:\n{1}".format(data_out.geometry, self.ig_padded)) data_out.fill(0) proc.process(out=data_out) numpy.testing.assert_array_equal(data_gold.array, data_out.array) - self.assertEquals(data_out.geometry, self.ig_padded, + self.assertEqual(data_out.geometry, self.ig_padded, msg="Padder failed with geometry mismatch. Got:\n{0}\nExpected:\n{1}".format(data_out.geometry, self.ig_padded)) diff --git a/Wrappers/Python/test/test_PluginsRegularisation.py b/Wrappers/Python/test/test_PluginsRegularisation.py index 63be777d4..05370c82f 100644 --- a/Wrappers/Python/test/test_PluginsRegularisation.py +++ b/Wrappers/Python/test/test_PluginsRegularisation.py @@ -105,7 +105,7 @@ def test_functionality_FGP_TV(self): fcil = FGP_TV() outcil = fcil.proximal(data, tau=tau) # use CIL defaults - outrgl, info = regularisers.FGP_TV(datarr, fcil.alpha*tau, fcil.max_iteration, fcil.tolerance, 0, 1, 'cpu' ) + outrgl = regularisers.FGP_TV(datarr, fcil.alpha*tau, fcil.max_iteration, fcil.tolerance, 0, 1, device='cpu' ) np.testing.assert_almost_equal(outrgl, outcil.as_array()) @@ -118,7 +118,7 @@ def test_functionality_TGV(self): fcil = TGV() outcil = fcil.proximal(data, tau=tau) # use CIL defaults - outrgl, info = regularisers.TGV(datarr, fcil.alpha*tau, 1,1, fcil.max_iteration, 12, fcil.tolerance, 'cpu' ) + outrgl = regularisers.TGV(datarr, fcil.alpha*tau, 1,1, fcil.max_iteration, 12, fcil.tolerance, device='cpu' ) np.testing.assert_almost_equal(outrgl, outcil.as_array()) @@ -133,7 +133,7 @@ def test_functionality_FGP_dTV(self): fcil = FGP_dTV(ref) outcil = fcil.proximal(data, tau=tau) # use CIL defaults - outrgl, info = regularisers.FGP_dTV(datarr, ref.as_array(), fcil.alpha*tau, fcil.max_iteration, fcil.tolerance, 0.01, 0, 1, 'cpu' ) + outrgl = regularisers.FGP_dTV(datarr, ref.as_array(), fcil.alpha*tau, fcil.max_iteration, fcil.tolerance, 0.01, 0, 1, device='cpu' ) np.testing.assert_almost_equal(outrgl, outcil.as_array()) diff --git a/Wrappers/Python/test/test_algorithms.py b/Wrappers/Python/test/test_algorithms.py index b90ff3485..7a3237547 100644 --- a/Wrappers/Python/test/test_algorithms.py +++ b/Wrappers/Python/test/test_algorithms.py @@ -523,9 +523,9 @@ def test_PDHG_strongly_convex_gamma_g(self): pdhg = PDHG(f=f, g=g, operator=operator, sigma = sigma, tau=tau, max_iteration=5, gamma_g=0.5) pdhg.run(1, verbose=0) - self.assertAlmostEquals(pdhg.theta, 1.0/ np.sqrt(1 + 2 * pdhg.gamma_g * tau)) - self.assertAlmostEquals(pdhg.tau, tau * pdhg.theta) - self.assertAlmostEquals(pdhg.sigma, sigma / pdhg.theta) + self.assertAlmostEqual(pdhg.theta, 1.0/ np.sqrt(1 + 2 * pdhg.gamma_g * tau)) + self.assertAlmostEqual(pdhg.tau, tau * pdhg.theta) + self.assertAlmostEqual(pdhg.sigma, sigma / pdhg.theta) pdhg.run(4, verbose=0) self.assertNotEqual(pdhg.sigma, sigma) self.assertNotEqual(pdhg.tau, tau) @@ -557,9 +557,9 @@ def test_PDHG_strongly_convex_gamma_fcong(self): pdhg = PDHG(f=f, g=g, operator=operator, sigma = sigma, tau=tau, max_iteration=5, gamma_fconj=0.5) pdhg.run(1, verbose=0) - self.assertEquals(pdhg.theta, 1.0/ np.sqrt(1 + 2 * pdhg.gamma_fconj * sigma)) - self.assertEquals(pdhg.tau, tau / pdhg.theta) - self.assertEquals(pdhg.sigma, sigma * pdhg.theta) + self.assertEqual(pdhg.theta, 1.0/ np.sqrt(1 + 2 * pdhg.gamma_fconj * sigma)) + self.assertEqual(pdhg.tau, tau / pdhg.theta) + self.assertEqual(pdhg.sigma, sigma * pdhg.theta) pdhg.run(4, verbose=0) self.assertNotEqual(pdhg.sigma, sigma) self.assertNotEqual(pdhg.tau, tau) diff --git a/Wrappers/Python/test/test_functions.py b/Wrappers/Python/test/test_functions.py index c94a529f9..1fd925abb 100644 --- a/Wrappers/Python/test/test_functions.py +++ b/Wrappers/Python/test/test_functions.py @@ -1121,16 +1121,16 @@ def setUp(self) -> None: self.alpha_arr = self.ig_real.allocate(0.15) def test_configure_tv_defaults(self): - self.assertEquals(self.tv.warm_start, True) - self.assertEquals(self.tv.iterations, 10) - self.assertEquals(self.tv.correlation, "Space") - self.assertEquals(self.tv.backend, "c") - self.assertEquals(self.tv.lower, -np.inf) - self.assertEquals(self.tv.upper, np.inf) - self.assertEquals(self.tv.isotropic, True) - self.assertEquals(self.tv.split, False) - self.assertEquals(self.tv.strong_convexity_constant, 0) - self.assertEquals(self.tv.tolerance, None) + self.assertEqual(self.tv.warm_start, True) + self.assertEqual(self.tv.iterations, 10) + self.assertEqual(self.tv.correlation, "Space") + self.assertEqual(self.tv.backend, "c") + self.assertEqual(self.tv.lower, -np.inf) + self.assertEqual(self.tv.upper, np.inf) + self.assertEqual(self.tv.isotropic, True) + self.assertEqual(self.tv.split, False) + self.assertEqual(self.tv.strong_convexity_constant, 0) + self.assertEqual(self.tv.tolerance, None) def test_configure_tv_not_defaults(self): tv=TotalVariation( max_iteration=100, @@ -1143,16 +1143,16 @@ def test_configure_tv_not_defaults(self): split = True, strong_convexity_constant = 1., warm_start=False) - self.assertEquals(tv.warm_start, False) - self.assertEquals(tv.iterations, 100) - self.assertEquals(tv.correlation, "SpaceChannels") - self.assertEquals(tv.backend, "numpy") - self.assertEquals(tv.lower, 0.) - self.assertEquals(tv.upper, 1.) - self.assertEquals(tv.isotropic, False) - self.assertEquals(tv.split, True) - self.assertEquals(tv.strong_convexity_constant, 1.) - self.assertEquals(tv.tolerance, 1e-5) + self.assertEqual(tv.warm_start, False) + self.assertEqual(tv.iterations, 100) + self.assertEqual(tv.correlation, "SpaceChannels") + self.assertEqual(tv.backend, "numpy") + self.assertEqual(tv.lower, 0.) + self.assertEqual(tv.upper, 1.) + self.assertEqual(tv.isotropic, False) + self.assertEqual(tv.split, True) + self.assertEqual(tv.strong_convexity_constant, 1.) + self.assertEqual(tv.tolerance, 1e-5) @@ -1407,7 +1407,7 @@ def test_non_scalar_tau_cil_tv(self): def test_get_p2_with_warm_start(self): data = dataexample.SHAPES.get(size=(16, 16)) tv=TotalVariation(warm_start=True, max_iteration=10) - self.assertEquals(tv._p2, None, msg="tv._p2 not initialised to None") + self.assertEqual(tv._p2, None, msg="tv._p2 not initialised to None") tv(data) checkp2=tv.gradient_operator.range_geometry().allocate(0) for i, x in enumerate(tv._get_p2()): @@ -1424,7 +1424,7 @@ def test_get_p2_with_warm_start(self): def test_get_p2_without_warm_start(self): data = dataexample.SHAPES.get(size=(16, 16)) tv=TotalVariation(warm_start=False) - self.assertEquals(tv._p2, None, msg="tv._p2 not initialised to None") + self.assertEqual(tv._p2, None, msg="tv._p2 not initialised to None") tv(data) checkp2=tv.gradient_operator.range_geometry().allocate(0) for i, x in enumerate(tv._get_p2()): diff --git a/Wrappers/Python/test/test_io.py b/Wrappers/Python/test/test_io.py index c47a23612..208ca926c 100644 --- a/Wrappers/Python/test/test_io.py +++ b/Wrappers/Python/test/test_io.py @@ -475,7 +475,7 @@ def test_get_dataset_metadata(self): dset_dict = HDF5_utilities.get_dataset_metadata(self.path, self.dset_path) dict_by_hand ={'ndim': 3, 'shape': (91, 135, 160), 'size': 1965600, 'dtype': np.float32, 'compression': None, 'chunks': None, 'is_virtual': False} - self.assertDictContainsSubset(dict_by_hand,dset_dict) + self.assertEqual(dset_dict, dict_by_hand | dset_dict) def test_read(self): diff --git a/Wrappers/Python/test/test_subset.py b/Wrappers/Python/test/test_subset.py index ed8323c3d..58db8a180 100644 --- a/Wrappers/Python/test/test_subset.py +++ b/Wrappers/Python/test/test_subset.py @@ -33,7 +33,7 @@ def test_DataContainer(self): arr = numpy.arange(0,120).reshape(2,3,4,5) data = DataContainer(arr, True,dimension_labels=['c','z','y','x']) data.reorder(['x','y','z','c']) - self.assertEquals(data.shape,(5,4,3,2)) + self.assertEqual(data.shape,(5,4,3,2)) numpy.testing.assert_array_equal(data.array, arr.transpose(3,2,1,0)) def test_ImageData(self): @@ -41,16 +41,16 @@ def test_ImageData(self): data = ig.allocate(None) new_order = ['horizontal_x', 'horizontal_y','vertical', 'channel'] data.reorder(new_order) - self.assertEquals(data.shape,(5,4,3,2)) - self.assertEquals(data.geometry.dimension_labels,tuple(new_order)) + self.assertEqual(data.shape,(5,4,3,2)) + self.assertEqual(data.geometry.dimension_labels,tuple(new_order)) def test_AcquisitionData(self): ag = AcquisitionGeometry.create_Parallel3D().set_panel([5,4]).set_angles([0,1,2]).set_channels(2).set_labels(['channel','angle','vertical','horizontal']) data = ag.allocate(None) new_order = ['horizontal', 'vertical','angle', 'channel'] data.reorder(new_order) - self.assertEquals(data.shape,(5,4,3,2)) - self.assertEquals(data.geometry.dimension_labels,tuple(new_order)) + self.assertEqual(data.shape,(5,4,3,2)) + self.assertEqual(data.geometry.dimension_labels,tuple(new_order)) def test_AcquisitionData_forastra(self): ag = AcquisitionGeometry.create_Parallel3D().set_panel([5,4]).set_angles([0,1,2]).set_channels(2).set_labels(['horizontal','vertical', 'angle', 'channel']) @@ -154,44 +154,44 @@ def test_DataContainer(self): data = DataContainer(arr, True,dimension_labels=['c','z','y','x']) data_new = data.get_slice(c=1) - self.assertEquals(data_new.shape,(3,4,5)) + self.assertEqual(data_new.shape,(3,4,5)) numpy.testing.assert_array_equal(data_new.array, arr[1]) data_new = data.get_slice(c=1,y=3) - self.assertEquals(data_new.shape,(3,5)) + self.assertEqual(data_new.shape,(3,5)) numpy.testing.assert_array_equal(data_new.array, arr[1,:,3,:]) data_new = data.get_slice(c=1,y=3,z=1) - self.assertEquals(data_new.shape,(5,)) + self.assertEqual(data_new.shape,(5,)) numpy.testing.assert_array_equal(data_new.array, arr[1,1,3,:]) def test_ImageData(self): ig = ImageGeometry(voxel_num_x=5, voxel_num_y=4, voxel_num_z=3, channels=2, dimension_labels=['channel','vertical','horizontal_y','horizontal_x']) data = ig.allocate(None) data_new = data.get_slice(vertical=1) - self.assertEquals(data_new.shape,(2,4,5)) - self.assertEquals(data_new.geometry.dimension_labels,('channel','horizontal_y','horizontal_x')) + self.assertEqual(data_new.shape,(2,4,5)) + self.assertEqual(data_new.geometry.dimension_labels,('channel','horizontal_y','horizontal_x')) def test_AcquisitionData(self): ag = AcquisitionGeometry.create_Parallel3D().set_panel([5,4]).set_angles([0,1,2]).set_channels(2).set_labels(['channel','angle','vertical','horizontal']) data = ag.allocate(None) data_new = data.get_slice(angle=2) - self.assertEquals(data_new.shape,(2,4,5)) - self.assertEquals(data_new.geometry.dimension_labels,('channel','vertical','horizontal')) + self.assertEqual(data_new.shape,(2,4,5)) + self.assertEqual(data_new.geometry.dimension_labels,('channel','vertical','horizontal')) #won't return a geometry for un-reconstructable slice ag = AcquisitionGeometry.create_Cone3D([0,-200,0],[0,200,0]).set_panel([5,4]).set_angles([0,1,2]).set_channels(2).set_labels(['channel','angle','vertical','horizontal']) data = ag.allocate('random') data_new = data.get_slice(vertical=1,force=True) - self.assertEquals(data_new.shape,(2,3,5)) + self.assertEqual(data_new.shape,(2,3,5)) self.assertTrue(isinstance(data_new,(DataContainer))) self.assertIsNone(data_new.geometry) - self.assertEquals(data_new.dimension_labels,('channel','angle','horizontal')) + self.assertEqual(data_new.dimension_labels,('channel','angle','horizontal')) #if 'centre' is between pixels interpolates data_new = data.get_slice(vertical='centre') - self.assertEquals(data_new.shape,(2,3,5)) - self.assertEquals(data_new.geometry.dimension_labels,('channel','angle','horizontal')) + self.assertEqual(data_new.shape,(2,3,5)) + self.assertEqual(data_new.geometry.dimension_labels,('channel','angle','horizontal')) numpy.testing.assert_allclose(data_new.array, (data.array[:,:,1,:] +data.array[:,:,2,:])/2 ) class TestSubset(unittest.TestCase): diff --git a/Wrappers/Python/test/utils.py b/Wrappers/Python/test/utils.py index 148bc6abd..e2e8d825b 100644 --- a/Wrappers/Python/test/utils.py +++ b/Wrappers/Python/test/utils.py @@ -100,12 +100,13 @@ def initialise_tests(): #ccpi-regularisation toolkit module_info = importlib.util.find_spec("ccpi") if module_info != None: - module_info = importlib.util.find_spec("ccpi.filters.cpu_regularisers") + module_info = importlib.util.find_spec("ccpi.filters.regularisers") if module_info is None: has_ccpi_regularisation = False else: has_ccpi_regularisation = True + system_state['has_ccpi_regularisation']= has_ccpi_regularisation diff --git a/recipe/conda_build_config.yaml b/recipe/conda_build_config.yaml index ca67db860..28e16d0af 100644 --- a/recipe/conda_build_config.yaml +++ b/recipe/conda_build_config.yaml @@ -19,31 +19,25 @@ #creates pairs of versions using zip_keys, lists must be the same length python: - - 3.8 - - 3.9 - 3.10 - - 3.8 - - 3.9 - 3.10 - - 3.8 - - 3.9 - 3.10 - - 3.8 - - 3.9 - 3.10 + - 3.11 + - 3.11 + - 3.11 + - 3.11 + - 3.12 numpy: - - 1.21 - - 1.21 - - 1.21 - - 1.22 - - 1.22 - - 1.22 - - 1.23 - - 1.23 - 1.23 - 1.24 + - 1.25 + - 1.26 + - 1.23 - 1.24 - - 1.24 + - 1.25 + - 1.26 + - 1.26 zip_keys: - python - numpy diff --git a/recipe/meta.yaml b/recipe/meta.yaml index beaf267de..3e4c42ec9 100644 --- a/recipe/meta.yaml +++ b/recipe/meta.yaml @@ -36,9 +36,9 @@ test: - cvxpy # [ linux ] - scikit-image - tomophantom=2.0.0 # [ linux ] - - tigre=2.4 # [ not osx ] + - tigre=2.6 - packaging - - ccpi-regulariser=22.0.0 # [ not osx ] + - ccpi-regulariser=24.0.0 # [ not osx ] - astra-toolbox>=1.9.9.dev5,<2.1 source_files: @@ -92,8 +92,8 @@ requirements: run_constrained: - tomophantom=2.0.0 - astra-toolbox>=1.9.9.dev5,<2.1 - - tigre=2.4 - - ccpi-regulariser=22.0.0 + - tigre>=2.4,<=2.6 + - ccpi-regulariser=24.0.0 - ipywidgets <8 about: diff --git a/scripts/create_local_env_for_cil_development.sh b/scripts/create_local_env_for_cil_development.sh index 16ef0222a..629b667c3 100755 --- a/scripts/create_local_env_for_cil_development.sh +++ b/scripts/create_local_env_for_cil_development.sh @@ -75,7 +75,7 @@ if test $test_deps = 0; then else conda_args+=( astra-toolbox'>=1.9.9.dev5,<2.1' - ccpi-regulariser=22.0.0 + ccpi-regulariser=24.0.0 cil-data cvxpy ipywidgets @@ -83,7 +83,7 @@ else python-wget setuptools scikit-image - tigre=2.4 + tigre=2.6 tomophantom=2.0.0 -c conda-forge -c intel diff --git a/scripts/requirements-test.yml b/scripts/requirements-test.yml index eb72894e9..f0be8a1a3 100644 --- a/scripts/requirements-test.yml +++ b/scripts/requirements-test.yml @@ -16,14 +16,15 @@ channels: - conda-forge - intel - ccpi + - nvidia - defaults dependencies: # base (vis. recipe/conda_build_config.yaml) - python=3.10 - numpy=1.24 - cil-data - - tigre=2.4 - - ccpi-regulariser=22.0.0 + - tigre=2.6 + - ccpi-regulariser=24.0.0 - tomophantom=2.0.0 - astra-toolbox >=1.9.9.dev5,<2.1 - cvxpy