Skip to content

Commit 848b9f4

Browse files
committed
Add 3D FB tests
Also add necessary attributes to 3D FB class.
1 parent c8c5afc commit 848b9f4

File tree

2 files changed

+92
-4
lines changed

2 files changed

+92
-4
lines changed

tests/_basis_util.py

Lines changed: 90 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
import numpy as np
44

55
from aspire.image import Image
6-
from aspire.volume import Volume
76
from aspire.utils import gaussian_2d, utest_tolerance
8-
from aspire.utils.coor_trans import grid_2d
7+
from aspire.utils.coor_trans import grid_2d, grid_3d
8+
from aspire.utils.misc import gaussian_3d
99
from aspire.utils.random import randn
10+
from aspire.volume import Volume
1011

1112

1213
class SteerableMixin:
@@ -139,4 +140,90 @@ def testModulated(self):
139140

140141

141142
class Steerable3DMixin(SteerableMixin):
142-
pass
143+
def testIndices(self):
144+
ell_max = self.basis.ell_max
145+
k_max = self.basis.k_max
146+
147+
indices = self.basis.indices()
148+
149+
i = 0
150+
151+
for ell in range(ell_max + 1):
152+
for m in range(-ell, ell + 1):
153+
for k in range(k_max[ell]):
154+
self.assertTrue(indices["ells"][i] == ell)
155+
self.assertTrue(indices["ms"][i] == m)
156+
self.assertTrue(indices["ks"][i] == k)
157+
158+
i += 1
159+
160+
def testGaussianExpand(self):
161+
# Offset slightly
162+
x0 = 0.50
163+
y0 = 0.75
164+
z0 = 0.25
165+
166+
# Want sigma to be as large as possible without the Gaussian
167+
# spilling too much outside the central disk.
168+
sigma = self.L / 8
169+
vol1 = gaussian_3d(
170+
self.L, mu=(x0, y0, z0), sigma=(sigma, sigma, sigma), dtype=self.dtype
171+
)
172+
173+
coef = self.basis.expand(vol1)
174+
vol2 = self.basis.evaluate(coef)
175+
176+
if isinstance(vol2, Volume):
177+
vol2 = vol2.asnumpy()
178+
179+
# For small L there's too much clipping at high freqs to get 1e-3
180+
# accuracy.
181+
if self.L < 16:
182+
atol = 1e-1
183+
elif self.L < 32:
184+
atol = 1e-2
185+
else:
186+
atol = 1e-3
187+
188+
self.assertTrue(vol1.shape == vol2.shape)
189+
self.assertTrue(np.allclose(vol1, vol2, atol=atol))
190+
191+
def testIsotropic(self):
192+
sigma = self.L / 8
193+
im = gaussian_3d(self.L, sigma=(sigma, sigma, sigma), dtype=self.dtype)
194+
195+
coef = self.basis.expand(im)
196+
197+
ells = self.basis.indices()["ells"]
198+
199+
energy_outside = np.sum(np.abs(coef[ells != 0]) ** 2)
200+
energy_total = np.sum(np.abs(coef) ** 2)
201+
202+
energy_ratio = energy_outside / energy_total
203+
204+
self.assertTrue(energy_ratio < 0.01)
205+
206+
def testModulated(self):
207+
if self.L < 32:
208+
raise SkipTest
209+
210+
ell = 1
211+
212+
sigma = self.L / 8
213+
vol = gaussian_3d(self.L, sigma=(sigma, sigma, sigma), dtype=self.dtype)
214+
215+
g3d = grid_3d(self.L)
216+
217+
for trig_fun in (np.sin, np.cos):
218+
vol1 = vol * trig_fun(ell * g3d["phi"])
219+
220+
coef = self.basis.expand(vol1)
221+
222+
ells = self.basis.indices()["ells"]
223+
224+
energy_outside = np.sum(np.abs(coef[ells != ell]) ** 2)
225+
energy_total = np.sum(np.abs(coef) ** 2)
226+
227+
energy_ratio = energy_outside / energy_total
228+
229+
self.assertTrue(energy_ratio < 0.10)

tests/test_FBbasis3D.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@
1313

1414
class FBBasis3DTestCase(TestCase, Steerable3DMixin):
1515
def setUp(self):
16+
self.L = 8
1617
self.dtype = np.float32
17-
self.basis = FBBasis3D((8, 8, 8), dtype=self.dtype)
18+
self.basis = FBBasis3D((self.L, self.L, self.L), dtype=self.dtype)
1819
self.seed = 9161341
1920

2021
def tearDown(self):

0 commit comments

Comments
 (0)