Coverage for local_installation_linux/mumott/pipelines/reconstruction/discrete_directions.py: 94%

25 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2024-08-11 23:08 +0000

1import logging 

2import sys 

3 

4import numpy as np 

5from numpy.typing import NDArray 

6import tqdm 

7from types import SimpleNamespace 

8 

9from mumott.data_handling import DataContainer 

10from mumott.methods.basis_sets import NearestNeighbor 

11from mumott.pipelines.reconstruction.sirt import run_sirt 

12 

13logger = logging.getLogger(__name__) 

14 

15 

16def run_discrete_directions(data_container: DataContainer, 

17 directions: NDArray[float], 

18 use_gpu: bool = False, 

19 maxiter: int = 20, 

20 no_tqdm: bool = False, 

21 ): 

22 """A reconstruction pipeline for the :term:`discrete directions <DD>` algorithm, which is 

23 similar the the algorithms first descibed in [Schaff2015]_. 

24 

25 Parameters 

26 ---------- 

27 data_container 

28 The :class:`DataContainer <mumott.data_handling.DataContainer>` 

29 from loading the data set of interest. 

30 directions 

31 A N by 3 Numpy array of unit-vectors descibing a grid covering the half unit sphere. 

32 use_gpu 

33 Whether to use GPU resources in computing the projections. 

34 Default is ``False``. If set to ``True``, the method will use 

35 :class:`SAXSProjectorCUDA <mumott.methods.projectors.SAXSProjectorCUDA>`. 

36 maxiter 

37 Maximum number of iterations for the gradient descent solution. 

38 no_tqdm: 

39 Flag whether ot not to print a progress bar for the reconstruction. 

40 """ 

41 basis_set = NearestNeighbor(directions) 

42 basis_set.integration_mode = 'midpoint' 

43 output_coefficients = np.zeros((*data_container.geometry.volume_shape, len(basis_set))) 

44 

45 if no_tqdm: 45 ↛ 46line 45 didn't jump to line 46, because the condition on line 45 was never true

46 iterator = range(len(basis_set)) 

47 else: 

48 iterator = tqdm.tqdm(range(len(basis_set)), file=sys.stdout) 

49 

50 for ii in iterator: 

51 sub_geometry, data_tuple = basis_set.get_sub_geometry(ii, data_container.geometry, data_container) 

52 

53 if data_tuple is None: 

54 continue 

55 

56 fake_data_container = SimpleNamespace( 

57 projections=SimpleNamespace(weights=data_tuple[1][..., np.newaxis]), 

58 geometry=sub_geometry, 

59 weights=data_tuple[1][..., np.newaxis]) 

60 

61 result = run_sirt(fake_data_container, 

62 maxiter=maxiter, 

63 enforce_non_negativity=True, 

64 use_gpu=use_gpu, 

65 use_absorbances=True, 

66 absorbances=data_tuple[0][..., np.newaxis], 

67 no_tqdm=True) 

68 output_coefficients[..., ii] = result['result']['x'][..., 0] 

69 

70 return dict(result={'x' : output_coefficients}, basis_set=basis_set)