Skip to content

Commit

Permalink
Update cil to 24.0 (#2184)
Browse files Browse the repository at this point in the history
  • Loading branch information
MikeSullivan7 authored May 2, 2024
2 parents 9f08124 + 8144b44 commit 45171e6
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 34 deletions.
6 changes: 3 additions & 3 deletions conda/meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ requirements:
- python=3.10.*
- pip
- astropy=5.0.*
- scipy=1.7.*
- scipy=1.8.*
- scikit-image=0.19.*
- tifffile=2023.7.18
- imagecodecs=2023.1.23
- numpy=1.21.*
- numpy=1.23.*
- numexpr=2.8.*
- algotom=1.0.*
- tomopy=1.12.*
Expand All @@ -32,7 +32,7 @@ requirements:
- requests=2.27.*
- h5py=3.6.*
- psutil=5.9.*
- cil=23.0.*
- cil=24.0.*
- ccpi-regulariser
- jenkspy=0.2.0
- pyqt=5.15.*
Expand Down
2 changes: 2 additions & 0 deletions docs/release_notes/next/dev-2183-update-cil
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#2183 : Update CIL to 24.0, numpy 1.23, scipy 1.8

56 changes: 25 additions & 31 deletions mantidimaging/core/reconstruct/cil_recon.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@

from cil.framework import (AcquisitionData, AcquisitionGeometry, DataOrder, ImageGeometry, BlockGeometry,
BlockDataContainer)
from cil.optimisation.algorithms import PDHG, SPDHG
from cil.optimisation.algorithms import PDHG, SPDHG, Algorithm
from cil.optimisation.operators import GradientOperator, BlockOperator
from cil.optimisation.operators import SymmetrisedGradientOperator, ZeroOperator, IdentityOperator

from cil.optimisation.functions import MixedL21Norm, L2NormSquared, BlockFunction, ZeroFunction, IndicatorBox, Function
from cil.optimisation.utilities.callbacks import Callback
from cil.plugins.astra.operators import ProjectionOperator

from mantidimaging.core.data import ImageStack
Expand All @@ -34,6 +35,22 @@
cil_mutex = Lock()


class MIProgressCallback(Callback):

def __init__(self, verbose=1, progress: Progress | None = None) -> None:
super().__init__(verbose)
self.progress = progress
self.iteration_count = 1

def __call__(self, algo: Algorithm) -> None:
if self.progress:
self.progress.update(steps=1,
msg=f'CIL: Iteration {self.iteration_count } of {algo.max_iteration}'
f': Objective {algo.get_last_objective():.2f}',
force_continue=False)
self.iteration_count += 1


class CILRecon(BaseRecon):

@staticmethod
Expand Down Expand Up @@ -240,18 +257,12 @@ def single_sino(sino: np.ndarray,
else:
raise ValueError(f"Regulariser must be one of 'TV', 'TGV'. Received '{recon_params.regulariser}'")

max_iteration = 100000
# this should set to a sensible number as evaluating the objective is costly
update_objective_interval = 10
if recon_params.stochastic:
reg_percent = recon_params.regularisation_percent
probs = [(1 - reg_percent / 100) / num_subsets] * num_subsets + [reg_percent / 100]
algo = SPDHG(f=F,
g=G,
operator=K,
prob=probs,
max_iteration=max_iteration,
update_objective_interval=update_objective_interval)
algo = SPDHG(f=F, g=G, operator=K, prob=probs, update_objective_interval=update_objective_interval)
else:
normK = K.norm()
sigma = 1
Expand All @@ -261,19 +272,14 @@ def single_sino(sino: np.ndarray,
operator=K,
tau=tau,
sigma=sigma,
max_iteration=max_iteration,
update_objective_interval=update_objective_interval)

try:
# this may be confusing for the user in case of SPDHG, because they will
# input num_iter and they will run num_iter * num_subsets
for iter in range(num_iter):
if progress:
progress.update(steps=1,
msg=f'CIL: Iteration {iter + 1} of {num_iter}'
f': Objective {algo.get_last_objective():.2f}',
force_continue=False)
algo.next()
algo.max_iteration = num_iter
algo.run(num_iter, callbacks=[MIProgressCallback(progress=progress)])

finally:
if progress:
progress.mark_complete()
Expand Down Expand Up @@ -370,18 +376,12 @@ def full(images: ImageStack,
else:
raise ValueError(f"Regulariser must be one of 'TV', 'TGV'. Received '{recon_params.regulariser}'")

max_iteration = 100000
# this should set to a sensible number as evaluating the objective is costly
update_objective_interval = 10
if recon_params.stochastic:
reg_percent = recon_params.regularisation_percent
probs = [(1 - reg_percent / 100) / num_subsets] * num_subsets + [reg_percent / 100]
algo = SPDHG(f=F,
g=G,
operator=K,
prob=probs,
max_iteration=max_iteration,
update_objective_interval=update_objective_interval)
algo = SPDHG(f=F, g=G, operator=K, prob=probs, update_objective_interval=update_objective_interval)
else:
normK = K.norm()
sigma = 1
Expand All @@ -391,19 +391,13 @@ def full(images: ImageStack,
operator=K,
tau=tau,
sigma=sigma,
max_iteration=max_iteration,
update_objective_interval=update_objective_interval)

with progress:
# this may be confusing for the user in case of SPDHG, because they will
# input num_iter and they will run num_iter * num_subsets
for iter in range(num_iter):
if progress:
progress.update(steps=1,
msg=f'CIL: Iteration {iter + 1} of {num_iter}'
f': Objective {algo.get_last_objective():.2f}',
force_continue=False)
algo.next()
algo.max_iteration = num_iter
algo.run(num_iter, callbacks=[MIProgressCallback(progress=progress)])

if isinstance(algo.solution, BlockDataContainer):
# TGV case
Expand Down

0 comments on commit 45171e6

Please sign in to comment.