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
« 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
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.
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.
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"""
19import numpy
21from . import kalispheraToolkit
23real_t = '<f8'
24# also need to select double or float in kalisphera C call
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.
35 Greyvalues are added to the volume, so spheres can be
36 added to an existing background.
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
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`
46 radius : float or 1D numpy array
47 Raduis(ii) of spheres to draw in `vol`
50 Returns
51 -------
52 None : function updates vol
53 """
55 if len(vol.shape) != 3:
56 print("\tkalisphera.makeSphere(), need 3D vol array")
57 return -1
59 centre = numpy.array(centre, dtype=real_t)
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])
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]
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
82 else:
83 print("\tkalisphera.makeSphere(), Got multiple radii, but different number from number of centres")
84 return -1
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.
91 This function can flattens overlaps, then adds gaussian blur
92 and then gaussian noise to `makeSphere`.
94 Parameters
95 ----------
96 dims : 3-component list
97 Dimensions of volume to create
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`
102 radius : float or 1D numpy array
103 Radius(ii) of spheres to draw in `vol`
105 blur : float, optional
106 Standard deviation of the blur kernel (in ~pixels)
107 Default = 0
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
113 flatten : bool, optional
114 Flatten greyvalues >1 to 1 (caused by overlaps)?
115 Default = True
117 background : float, optional
118 Desired mean greyvalue of the background
119 Default = 0.25
121 foreground : float, optional
122 Desired mean greyvalue of the background
123 Default = 0.75
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)
132 vol = numpy.zeros(dims, dtype=real_t)
134 makeSphere(vol, centre, radius)
136 if flatten: vol[vol>1]=1
138 if blur != 0:
139 import scipy.ndimage
140 vol = scipy.ndimage.gaussian_filter(vol, sigma=blur)
142 if noise != 0:
143 vol += numpy.random.normal(size=dims, scale=noise)
145 vol *= float(foreground)-float(background)
146 vol += float(background)
148 return vol