Coverage for /usr/local/lib/python3.8/site-packages/spam/kalisphera/kalisphera.py: 100%

34 statements  

« prev     ^ index     » next       coverage.py v7.2.3, created at 2023-11-22 13:26 +0000

1""" 

2Library of SPAM functions for generating partial volume balls, see Tengattini et al. 2015 

3Copyright (C) 2020 SPAM Contributors 

4 

5This program is free software: you can redistribute it and/or modify it 

6under the terms of the GNU General Public License as published by the Free 

7Software Foundation, either version 3 of the License, or (at your option) 

8any later version. 

9 

10This program is distributed in the hope that it will be useful, but WITHOUT 

11ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 

12FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 

13more details. 

14 

15You should have received a copy of the GNU General Public License along with 

16this program. If not, see <http://www.gnu.org/licenses/>. 

17""" 

18 

19import numpy 

20 

21from . import kalispheraToolkit 

22 

23real_t = '<f8' 

24# also need to select double or float in kalisphera C call 

25 

26 

27def makeSphere(vol, centre, radius): 

28 """ 

29 This function creates a sphere in a given 3D volume, 

30 with analytically-calculated partial-volume effects. 

31 Background is assumed to have a greyvalue of zero, 

32 and a fully-occupied sphere voxel is considered to 

33 have a greyvalue of 1. 

34 

35 Greyvalues are added to the volume, so spheres can be 

36 added to an existing background. 

37 

38 Parameters 

39 ---------- 

40 vol : 3D numpy array of doubles 

41 A 3D image of greylevels (typically zeros) into which sphere(s) should be added 

42 

43 centre : 1D or 2D numpy array 

44 Either a 3-component vector, or an Nx3 matrix of sphere centres to draw with respect to 0,0,0 in `vol` 

45 

46 radius : float or 1D numpy array 

47 Raduis(ii) of spheres to draw in `vol` 

48 

49 

50 Returns 

51 ------- 

52 None : function updates vol 

53 """ 

54 

55 if len(vol.shape) != 3: 

56 print("\tkalisphera.makeSphere(), need 3D vol array") 

57 return -1 

58 

59 centre = numpy.array(centre, dtype=real_t) 

60 

61 # Turn centre into a numpy array in case it is passed as a list-of-lists 

62 if len(centre.shape) == 1: 

63 centre = numpy.array([centre]) 

64 

65 if len(centre.shape) == 2: 

66 if type(radius) == float or type(radius) == int: 

67 # print("\tkalisphera.makeSphere.run(), Got single radius for multiple spheres... fine") 

68 radius = [radius] * centre.shape[0] 

69 

70 if len(radius) == centre.shape[0]: 

71 for centre, radius in zip(centre, radius): 

72 volTemp = numpy.zeros_like(vol, dtype=real_t) 

73 # For compatibility with scipy centre of mass 

74 # centre+=0.5 

75 # print centre, radius 

76 # print vol.sum() 

77 kalispheraToolkit.kalisphera(volTemp, numpy.array(centre).astype(real_t), float(radius)) 

78 # print vol.sum() 

79 vol += volTemp # .copy() 

80 return 0 

81 

82 else: 

83 print("\tkalisphera.makeSphere(), Got multiple radii, but different number from number of centres") 

84 return -1 

85 

86def makeBlurryNoisySphere(dims, centre, radius, blur=0, noise=0, flatten=True, background=0.25, foreground=0.75): 

87 """ 

88 This function creates a sphere or series of spheres in a 3D volume, 

89 with analytically-calculated partial-volume effects. 

90 

91 This function can flattens overlaps, then adds gaussian blur 

92 and then gaussian noise to `makeSphere`. 

93 

94 Parameters 

95 ---------- 

96 dims : 3-component list 

97 Dimensions of volume to create 

98 

99 centre : 1D or 2D numpy array 

100 Either a 3-component vector, or an Nx3 array of sphere centres to draw with respect to 0,0,0 in `vol` 

101 

102 radius : float or 1D numpy array 

103 Radius(ii) of spheres to draw in `vol` 

104 

105 blur : float, optional 

106 Standard deviation of the blur kernel (in ~pixels) 

107 Default = 0 

108 

109 noise : float, optional 

110 Standard devitaion of the noise (in greylevels), noise is on the scale: background=0 and sphere=1 

111 Default = 0 

112 

113 flatten : bool, optional 

114 Flatten greyvalues >1 to 1 (caused by overlaps)? 

115 Default = True 

116 

117 background : float, optional 

118 Desired mean greyvalue of the background 

119 Default = 0.25 

120 

121 foreground : float, optional 

122 Desired mean greyvalue of the background 

123 Default = 0.75 

124 

125 Returns 

126 ------- 

127 vol : the input array 

128 Note this is different return behaviour than makeSphere, which doesn't return anything!! 

129 """ 

130 assert(foreground > background) 

131 

132 vol = numpy.zeros(dims, dtype=real_t) 

133 

134 makeSphere(vol, centre, radius) 

135 

136 if flatten: vol[vol>1]=1 

137 

138 if blur != 0: 

139 import scipy.ndimage 

140 vol = scipy.ndimage.gaussian_filter(vol, sigma=blur) 

141 

142 if noise != 0: 

143 vol += numpy.random.normal(size=dims, scale=noise) 

144 

145 vol *= float(foreground)-float(background) 

146 vol += float(background) 

147 

148 return vol